diff options
-rw-r--r-- | compiler/aliases.nim | 6 | ||||
-rw-r--r-- | compiler/ast.nim | 129 | ||||
-rw-r--r-- | compiler/astalgo.nim | 275 | ||||
-rw-r--r-- | compiler/babelcmd.nim | 10 | ||||
-rw-r--r-- | compiler/bitsets.nim | 40 | ||||
-rw-r--r-- | compiler/c2nim/c2nim.nim | 24 | ||||
-rw-r--r-- | compiler/c2nim/clex.nim | 100 | ||||
-rw-r--r-- | compiler/c2nim/cparse.nim | 789 | ||||
-rw-r--r-- | compiler/c2nim/cpp.nim | 12 | ||||
-rw-r--r-- | compiler/c2nim/tests/vincent.c | 33 | ||||
-rw-r--r-- | compiler/c2nim/tests/vincent.h | 3 | ||||
-rw-r--r-- | compiler/ccgcalls.nim | 4 | ||||
-rw-r--r-- | compiler/ccgexprs.nim | 260 | ||||
-rw-r--r-- | compiler/ccgmerge.nim | 31 | ||||
-rw-r--r-- | compiler/ccgstmts.nim | 125 | ||||
-rw-r--r-- | compiler/ccgthreadvars.nim | 6 | ||||
-rw-r--r-- | compiler/ccgtrav.nim | 6 | ||||
-rw-r--r-- | compiler/ccgtypes.nim | 92 | ||||
-rw-r--r-- | compiler/ccgutils.nim | 49 | ||||
-rw-r--r-- | compiler/cgen.nim | 240 | ||||
-rw-r--r-- | compiler/cgendata.nim | 15 | ||||
-rw-r--r-- | compiler/cgmeth.nim | 22 | ||||
-rw-r--r-- | compiler/commands.nim | 204 | ||||
-rw-r--r-- | compiler/condsyms.nim | 76 | ||||
-rw-r--r-- | compiler/crc.nim | 14 | ||||
-rw-r--r-- | compiler/depends.nim | 2 | ||||
-rw-r--r-- | compiler/docgen.nim | 50 | ||||
-rw-r--r-- | compiler/evalffi.nim | 82 | ||||
-rw-r--r-- | compiler/evals.nim | 17 | ||||
-rw-r--r-- | compiler/evaltempl.nim | 59 | ||||
-rw-r--r-- | compiler/extccomp.nim | 124 | ||||
-rw-r--r-- | compiler/filter_tmpl.nim | 110 | ||||
-rw-r--r-- | compiler/filters.nim | 30 | ||||
-rw-r--r-- | compiler/guards.nim | 10 | ||||
-rw-r--r-- | compiler/hlo.nim | 6 | ||||
-rw-r--r-- | compiler/idents.nim | 2 | ||||
-rw-r--r-- | compiler/idgen.nim | 14 | ||||
-rw-r--r-- | compiler/importer.nim | 46 | ||||
-rw-r--r-- | compiler/jsgen.nim | 127 | ||||
-rw-r--r-- | compiler/jstypes.nim | 8 | ||||
-rw-r--r-- | compiler/lambdalifting.nim | 60 | ||||
-rw-r--r-- | compiler/lexer.nim | 228 | ||||
-rw-r--r-- | compiler/lists.nim | 40 | ||||
-rw-r--r-- | compiler/llstream.nim | 97 | ||||
-rw-r--r-- | compiler/lookups.nim | 107 | ||||
-rw-r--r-- | compiler/magicsys.nim | 33 | ||||
-rw-r--r-- | compiler/main.nim | 156 | ||||
-rw-r--r-- | compiler/modules.nim | 28 | ||||
-rw-r--r-- | compiler/msgs.nim | 120 | ||||
-rw-r--r-- | compiler/nimconf.nim | 26 | ||||
-rw-r--r-- | compiler/nimlexbase.nim | 45 | ||||
-rw-r--r-- | compiler/nimrod.nim | 16 | ||||
-rw-r--r-- | compiler/nimrod.nimrod.cfg | 3 | ||||
-rw-r--r-- | compiler/nimsets.nim | 38 | ||||
-rw-r--r-- | compiler/options.nim | 38 | ||||
-rw-r--r-- | compiler/parampatterns.nim | 14 | ||||
-rw-r--r-- | compiler/parser.nim | 96 | ||||
-rw-r--r-- | compiler/pas2nim/pas2nim.nim | 2 | ||||
-rw-r--r-- | compiler/pas2nim/paslex.nim | 74 | ||||
-rw-r--r-- | compiler/pas2nim/pasparse.nim | 52 | ||||
-rw-r--r-- | compiler/passaux.nim | 6 | ||||
-rw-r--r-- | compiler/passes.nim | 8 | ||||
-rw-r--r-- | compiler/patterns.nim | 12 | ||||
-rw-r--r-- | compiler/pbraces.nim | 2 | ||||
-rw-r--r-- | compiler/platform.nim | 20 | ||||
-rw-r--r-- | compiler/pragmas.nim | 264 | ||||
-rw-r--r-- | compiler/pretty.nim | 178 | ||||
-rw-r--r-- | compiler/procfind.nim | 52 | ||||
-rw-r--r-- | compiler/renderer.nim | 96 | ||||
-rw-r--r-- | compiler/rodread.nim | 156 | ||||
-rw-r--r-- | compiler/rodutils.nim | 6 | ||||
-rw-r--r-- | compiler/rodwrite.nim | 52 | ||||
-rw-r--r-- | compiler/ropes.nim | 67 | ||||
-rw-r--r-- | compiler/saturate.nim | 12 | ||||
-rw-r--r-- | compiler/sem.nim | 171 | ||||
-rw-r--r-- | compiler/semcall.nim | 56 | ||||
-rw-r--r-- | compiler/semdata.nim | 83 | ||||
-rw-r--r-- | compiler/semdestruct.nim | 94 | ||||
-rw-r--r-- | compiler/semexprs.nim | 301 | ||||
-rw-r--r-- | compiler/semfold.nim | 112 | ||||
-rw-r--r-- | compiler/semgnrc.nim | 33 | ||||
-rw-r--r-- | compiler/seminst.nim | 181 | ||||
-rw-r--r-- | compiler/semmacrosanity.nim | 89 | ||||
-rw-r--r-- | compiler/semmagic.nim | 39 | ||||
-rw-r--r-- | compiler/sempass2.nim | 30 | ||||
-rw-r--r-- | compiler/semstmts.nim | 245 | ||||
-rw-r--r-- | compiler/semtempl.nim | 142 | ||||
-rw-r--r-- | compiler/semthreads.nim | 40 | ||||
-rw-r--r-- | compiler/semtypes.nim | 393 | ||||
-rw-r--r-- | compiler/semtypinst.nim | 348 | ||||
-rw-r--r-- | compiler/service.nim | 12 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 379 | ||||
-rw-r--r-- | compiler/suggest.nim | 53 | ||||
-rw-r--r-- | compiler/syntaxes.nim | 60 | ||||
-rw-r--r-- | compiler/transf.nim | 85 | ||||
-rw-r--r-- | compiler/trees.nim | 40 | ||||
-rw-r--r-- | compiler/treetab.nim | 36 | ||||
-rw-r--r-- | compiler/types.nim | 383 | ||||
-rw-r--r-- | compiler/vm.nim | 624 | ||||
-rw-r--r-- | compiler/vmdef.nim | 40 | ||||
-rw-r--r-- | compiler/vmdeps.nim | 61 | ||||
-rw-r--r-- | compiler/vmgen.nim | 405 | ||||
-rw-r--r-- | compiler/wordrecg.nim | 14 | ||||
-rw-r--r-- | config/nimrod.cfg | 1 | ||||
-rw-r--r-- | doc/keywords.txt | 3 | ||||
-rw-r--r-- | doc/lib.txt | 114 | ||||
-rw-r--r-- | doc/manual.txt | 168 | ||||
-rw-r--r-- | doc/subexes.txt | 4 | ||||
-rw-r--r-- | doc/tut1.txt | 47 | ||||
-rw-r--r-- | koch.nim | 38 | ||||
-rw-r--r-- | lib/core/locks.nim | 50 | ||||
-rw-r--r-- | lib/core/macros.nim | 60 | ||||
-rw-r--r-- | lib/impure/db_mongo.nim | 6 | ||||
-rw-r--r-- | lib/impure/db_mysql.nim | 24 | ||||
-rw-r--r-- | lib/impure/db_postgres.nim | 22 | ||||
-rw-r--r-- | lib/impure/db_sqlite.nim | 42 | ||||
-rw-r--r-- | lib/impure/dialogs.nim | 8 | ||||
-rw-r--r-- | lib/impure/graphics.nim | 2 | ||||
-rw-r--r-- | lib/impure/osinfo_win.nim | 44 | ||||
-rw-r--r-- | lib/impure/rdstdin.nim | 10 | ||||
-rw-r--r-- | lib/impure/re.nim | 66 | ||||
-rw-r--r-- | lib/impure/zipfiles.nim | 4 | ||||
-rw-r--r-- | lib/packages/docutils/highlite.nim | 10 | ||||
-rw-r--r-- | lib/packages/docutils/rst.nim | 76 | ||||
-rw-r--r-- | lib/packages/docutils/rstast.nim | 10 | ||||
-rw-r--r-- | lib/packages/docutils/rstgen.nim | 39 | ||||
-rw-r--r-- | lib/posix/posix.nim | 468 | ||||
-rw-r--r-- | lib/pure/algorithm.nim | 4 | ||||
-rw-r--r-- | lib/pure/browsers.nim | 6 | ||||
-rw-r--r-- | lib/pure/collections/LockFreeHash.nim | 3 | ||||
-rw-r--r-- | lib/pure/collections/intsets.nim | 22 | ||||
-rw-r--r-- | lib/pure/collections/lists.nim | 8 | ||||
-rw-r--r-- | lib/pure/collections/sequtils.nim | 2 | ||||
-rw-r--r-- | lib/pure/collections/sets.nim | 40 | ||||
-rw-r--r-- | lib/pure/collections/tables.nim | 78 | ||||
-rw-r--r-- | lib/pure/encodings.nim | 72 | ||||
-rw-r--r-- | lib/pure/hashes.nim | 12 | ||||
-rw-r--r-- | lib/pure/htmlgen.nim | 2 | ||||
-rw-r--r-- | lib/pure/json.nim | 72 | ||||
-rw-r--r-- | lib/pure/lexbase.nim | 38 | ||||
-rw-r--r-- | lib/pure/math.nim | 8 | ||||
-rw-r--r-- | lib/pure/md5.nim | 60 | ||||
-rw-r--r-- | lib/pure/memfiles.nim | 52 | ||||
-rw-r--r-- | lib/pure/os.nim | 491 | ||||
-rw-r--r-- | lib/pure/osproc.nim | 214 | ||||
-rw-r--r-- | lib/pure/parsecfg.nim | 72 | ||||
-rw-r--r-- | lib/pure/parseopt.nim | 14 | ||||
-rw-r--r-- | lib/pure/parseutils.nim | 18 | ||||
-rw-r--r-- | lib/pure/pegs.nim | 128 | ||||
-rw-r--r-- | lib/pure/sockets.nim | 224 | ||||
-rw-r--r-- | lib/pure/streams.nim | 4 | ||||
-rw-r--r-- | lib/pure/strtabs.nim | 24 | ||||
-rw-r--r-- | lib/pure/strutils.nim | 2214 | ||||
-rw-r--r-- | lib/pure/terminal.nim | 86 | ||||
-rw-r--r-- | lib/pure/times.nim | 38 | ||||
-rw-r--r-- | lib/pure/unicode.nim | 60 | ||||
-rw-r--r-- | lib/pure/unittest.nim | 11 | ||||
-rw-r--r-- | lib/system.nim | 184 | ||||
-rw-r--r-- | lib/system/alloc.nim | 79 | ||||
-rw-r--r-- | lib/system/ansi_c.nim | 85 | ||||
-rw-r--r-- | lib/system/assign.nim | 54 | ||||
-rw-r--r-- | lib/system/atomics.nim | 126 | ||||
-rw-r--r-- | lib/system/avltree.nim | 10 | ||||
-rw-r--r-- | lib/system/cellsets.nim | 54 | ||||
-rw-r--r-- | lib/system/channels.nim | 26 | ||||
-rw-r--r-- | lib/system/chcks.nim | 4 | ||||
-rw-r--r-- | lib/system/dyncalls.nim | 17 | ||||
-rw-r--r-- | lib/system/excpt.nim | 8 | ||||
-rw-r--r-- | lib/system/gc.nim | 64 | ||||
-rw-r--r-- | lib/system/hti.nim | 2 | ||||
-rw-r--r-- | lib/system/mmdisp.nim | 2 | ||||
-rw-r--r-- | lib/system/repr.nim | 32 | ||||
-rw-r--r-- | lib/system/sysio.nim | 68 | ||||
-rw-r--r-- | lib/system/syslocks.nim | 57 | ||||
-rw-r--r-- | lib/system/sysstr.nim | 26 | ||||
-rw-r--r-- | lib/system/threads.nim | 60 | ||||
-rw-r--r-- | lib/system/widestrs.nim | 300 | ||||
-rw-r--r-- | lib/windows/windows.nim | 19 | ||||
-rw-r--r-- | lib/windows/winlean.nim | 244 | ||||
-rw-r--r-- | lib/wrappers/libffi/common/ffi.h | 331 | ||||
-rw-r--r-- | lib/wrappers/libffi/common/ffi_common.h | 77 | ||||
-rw-r--r-- | lib/wrappers/libffi/common/fficonfig.h | 96 | ||||
-rw-r--r-- | lib/wrappers/libffi/common/ffitarget.h | 150 | ||||
-rw-r--r-- | lib/wrappers/libffi/common/malloc_closure.c | 110 | ||||
-rw-r--r-- | lib/wrappers/libffi/common/raw_api.c | 254 | ||||
-rw-r--r-- | lib/wrappers/libffi/gcc/closures.c | 627 | ||||
-rw-r--r-- | lib/wrappers/libffi/gcc/ffi.c | 841 | ||||
-rw-r--r-- | lib/wrappers/libffi/gcc/ffi64.c | 673 | ||||
-rw-r--r-- | lib/wrappers/libffi/gcc/prep_cif.c | 237 | ||||
-rw-r--r-- | lib/wrappers/libffi/gcc/types.c | 77 | ||||
-rw-r--r-- | lib/wrappers/libffi/gcc/win32_asm.asm | 759 | ||||
-rw-r--r-- | lib/wrappers/libffi/gcc/win32_asm.s | 736 | ||||
-rw-r--r-- | lib/wrappers/libffi/gcc/win64_asm.asm | 467 | ||||
-rw-r--r-- | lib/wrappers/libffi/gcc/win64_asm.s | 227 | ||||
-rw-r--r-- | lib/wrappers/libffi/libffi.nim (renamed from lib/wrappers/libffi.nim) | 80 | ||||
-rw-r--r-- | lib/wrappers/libffi/msvc/ffi.c | 457 | ||||
-rw-r--r-- | lib/wrappers/libffi/msvc/prep_cif.c | 175 | ||||
-rw-r--r-- | lib/wrappers/libffi/msvc/types.c | 104 | ||||
-rw-r--r-- | lib/wrappers/libffi/msvc/win32.c | 162 | ||||
-rw-r--r-- | lib/wrappers/libffi/msvc/win32_asm.asm | 470 | ||||
-rw-r--r-- | lib/wrappers/libffi/msvc/win64_asm.asm | 156 | ||||
-rw-r--r-- | lib/wrappers/mysql.nim | 4 | ||||
-rw-r--r-- | lib/wrappers/pcre.nim | 18 | ||||
-rw-r--r-- | lib/wrappers/zip/libzip.nim | 108 | ||||
-rw-r--r-- | tests/actiontable/tactiontable.nim (renamed from tests/run/tactiontable.nim) | 0 | ||||
-rw-r--r-- | tests/actiontable/tactiontable2.nim (renamed from tests/reject/tactiontable2.nim) | 14 | ||||
-rw-r--r-- | tests/alias/talias.nim (renamed from tests/compile/talias.nim) | 0 | ||||
-rw-r--r-- | tests/ambsym/mambsym1.nim (renamed from tests/reject/mambsym1.nim) | 0 | ||||
-rw-r--r-- | tests/ambsym/mambsym2.nim (renamed from tests/reject/mambsym2.nim) | 0 | ||||
-rw-r--r-- | tests/ambsym/mambsys1.nim (renamed from tests/run/mambsys1.nim) | 0 | ||||
-rw-r--r-- | tests/ambsym/mambsys2.nim (renamed from tests/run/mambsys2.nim) | 0 | ||||
-rw-r--r-- | tests/ambsym/tambsym.nim (renamed from tests/reject/tambsym.nim) | 0 | ||||
-rw-r--r-- | tests/ambsym/tambsym2.nim (renamed from tests/run/tambsym2.nim) | 0 | ||||
-rw-r--r-- | tests/ambsym/tambsym3.nim (renamed from tests/reject/tambsym3.nim) | 0 | ||||
-rw-r--r-- | tests/ambsym/tambsys.nim (renamed from tests/run/tambsys.nim) | 0 | ||||
-rw-r--r-- | tests/array/tarray.nim (renamed from tests/run/tarray.nim) | 0 | ||||
-rw-r--r-- | tests/array/tarray2.nim (renamed from tests/run/tarray2.nim) | 0 | ||||
-rw-r--r-- | tests/array/tarray3.nim (renamed from tests/run/tarray3.nim) | 0 | ||||
-rw-r--r-- | tests/array/tarraycons.nim (renamed from tests/reject/tarraycons.nim) | 0 | ||||
-rw-r--r-- | tests/array/tarraycons2.nim (renamed from tests/run/tarraycons.nim) | 0 | ||||
-rw-r--r-- | tests/array/tarrayplus.nim (renamed from tests/reject/tarrayplus.nim) | 0 | ||||
-rw-r--r-- | tests/array/tarrindx.nim (renamed from tests/compile/tarrindx.nim) | 0 | ||||
-rw-r--r-- | tests/assert/tassert.nim (renamed from tests/run/tassert.nim) | 0 | ||||
-rw-r--r-- | tests/assert/tfailedassert.nim | 51 | ||||
-rw-r--r-- | tests/assert/tunittests.nim | 1 | ||||
-rw-r--r-- | tests/assert/tuserassert.nim (renamed from tests/run/tuserassert.nim) | 0 | ||||
-rw-r--r-- | tests/assign/tassign.nim (renamed from tests/compile/tassign.nim) | 0 | ||||
-rw-r--r-- | tests/assign/tcopy.nim (renamed from tests/run/tcopy.nim) | 0 | ||||
-rw-r--r-- | tests/assign/tgenericassign.nim (renamed from tests/run/tgenericassign.nim) | 0 | ||||
-rw-r--r-- | tests/assign/tgenericassigntuples.nim (renamed from tests/run/tgenericassigntuples.nim) | 0 | ||||
-rw-r--r-- | tests/assign/tobjasgn.nim (renamed from tests/run/tobjasgn.nim) | 0 | ||||
-rw-r--r-- | tests/assign/tvariantasgn.nim (renamed from tests/run/tvariantasgn.nim) | 0 | ||||
-rw-r--r-- | tests/astoverload/tastoverload1.nim (renamed from tests/run/tastoverload1.nim) | 0 | ||||
-rw-r--r-- | tests/async/tasynciossl.nim (renamed from tests/run/tasynciossl.nim) | 0 | ||||
-rw-r--r-- | tests/async/tasyncudp.nim (renamed from tests/run/tasyncudp.nim) | 0 | ||||
-rw-r--r-- | tests/bind/mbind3.nim (renamed from tests/run/mbind3.nim) | 0 | ||||
-rw-r--r-- | tests/bind/tbind1.nim (renamed from tests/run/tbind1.nim) | 0 | ||||
-rw-r--r-- | tests/bind/tbind2.nim (renamed from tests/reject/tbind2.nim) | 2 | ||||
-rw-r--r-- | tests/bind/tbind3.nim (renamed from tests/run/tbind3.nim) | 0 | ||||
-rw-r--r-- | tests/bind/tbindoverload.nim (renamed from tests/compile/tbindoverload.nim) | 0 | ||||
-rw-r--r-- | tests/bind/tbindtypedesc.nim (renamed from tests/reject/tbindtypedesc.nim) | 0 | ||||
-rw-r--r-- | tests/bind/tdatabind.nim (renamed from tests/compile/tdatabind.nim) | 0 | ||||
-rw-r--r-- | tests/bind/tmixin.nim (renamed from tests/run/tmixin.nim) | 0 | ||||
-rw-r--r-- | tests/bind/tnicerrorforsymchoice.nim (renamed from tests/reject/tnicerrorforsymchoice.nim) | 0 | ||||
-rw-r--r-- | tests/block/tblock1.nim (renamed from tests/reject/tblock1.nim) | 0 | ||||
-rw-r--r-- | tests/borrow/tborrow.nim (renamed from tests/run/tborrow.nim) | 0 | ||||
-rw-r--r-- | tests/borrow/tinvalidborrow.nim (renamed from tests/reject/tinvalidborrow.nim) | 0 | ||||
-rw-r--r-- | tests/casestmt/tcase_setconstr.nim (renamed from tests/run/tcase_setconstr.nim) | 0 | ||||
-rw-r--r-- | tests/casestmt/tcaseexpr1.nim (renamed from tests/reject/tcaseexpr1.nim) | 0 | ||||
-rw-r--r-- | tests/casestmt/tcaseoverlaprange.nim (renamed from tests/reject/tcaseoverlaprange.nim) | 0 | ||||
-rw-r--r-- | tests/casestmt/tcaseoverlaprange2.nim (renamed from tests/reject/tcaseoverlaprange2.nim) | 0 | ||||
-rw-r--r-- | tests/casestmt/tcasestm.nim (renamed from tests/run/tcasestm.nim) | 0 | ||||
-rw-r--r-- | tests/casestmt/tcomputedgoto.nim (renamed from tests/compile/tcomputedgoto.nim) | 31 | ||||
-rw-r--r-- | tests/casestmt/tlinearscanend.nim (renamed from tests/compile/tlinearscanend.nim) | 0 | ||||
-rw-r--r-- | tests/ccgbugs/tccgen1.nim (renamed from tests/compile/tccgen1.nim) | 0 | ||||
-rw-r--r-- | tests/ccgbugs/tcgbug.nim (renamed from tests/run/tcgbug.nim) | 0 | ||||
-rw-r--r-- | tests/ccgbugs/tcodegenbug1.nim (renamed from tests/compile/tcodegenbug1.nim) | 0 | ||||
-rw-r--r-- | tests/closure/tclosure.nim (renamed from tests/run/tclosure.nim) | 0 | ||||
-rw-r--r-- | tests/closure/tclosure2.nim (renamed from tests/run/tclosure2.nim) | 0 | ||||
-rw-r--r-- | tests/closure/tclosure3.nim (renamed from tests/run/tclosure3.nim) | 0 | ||||
-rw-r--r-- | tests/closure/tclosure4.nim (renamed from tests/compile/tclosure4.nim) | 0 | ||||
-rw-r--r-- | tests/closure/tclosurebug2.nim (renamed from tests/compile/tclosurebug2.nim) | 0 | ||||
-rw-r--r-- | tests/closure/tinterf.nim (renamed from tests/run/tinterf.nim) | 0 | ||||
-rw-r--r-- | tests/closure/tinvalidclosure.nim (renamed from tests/reject/tinvalidclosure.nim) | 0 | ||||
-rw-r--r-- | tests/closure/tinvalidclosure2.nim (renamed from tests/reject/tinvalidclosure2.nim) | 0 | ||||
-rw-r--r-- | tests/closure/tnamedparamanonproc.nim (renamed from tests/compile/tnamedparamanonproc.nim) | 0 | ||||
-rw-r--r-- | tests/closure/tnestedproc.nim (renamed from tests/compile/tnestedproc.nim) | 0 | ||||
-rw-r--r-- | tests/closure/uclosures.nim (renamed from tests/run/uclosures.nim) | 0 | ||||
-rw-r--r-- | tests/cnstseq/tcnstseq.nim (renamed from tests/run/tcnstseq.nim) | 0 | ||||
-rw-r--r-- | tests/cnstseq/tcnstseq2.nim (renamed from tests/run/tcnstseq2.nim) | 0 | ||||
-rw-r--r-- | tests/cnstseq/tcnstseq3.nim (renamed from tests/run/tcnstseq3.nim) | 0 | ||||
-rw-r--r-- | tests/compile/mvarious.nim | 6 | ||||
-rw-r--r-- | tests/compile/sunset.tmpl | 68 | ||||
-rw-r--r-- | tests/compile/tambsym2.nim | 6 | ||||
-rw-r--r-- | tests/compile/tbindtypedesc.nim | 87 | ||||
-rw-r--r-- | tests/compile/tcmdline.nim | 14 | ||||
-rw-r--r-- | tests/compile/tcolonisproc.nim | 12 | ||||
-rw-r--r-- | tests/compile/tdllvar.nim | 16 | ||||
-rw-r--r-- | tests/compile/temptyecho.nim | 2 | ||||
-rw-r--r-- | tests/compile/tendian.nim | 3 | ||||
-rw-r--r-- | tests/compile/tfib.nim | 11 | ||||
-rw-r--r-- | tests/compile/tgenericshardcases.nim | 30 | ||||
-rw-r--r-- | tests/compile/tgetstartmilsecs.nim | 7 | ||||
-rw-r--r-- | tests/compile/tgtk.nim | 51 | ||||
-rw-r--r-- | tests/compile/thallo.nim | 85 | ||||
-rw-r--r-- | tests/compile/theaproots.nim | 71 | ||||
-rw-r--r-- | tests/compile/tlastmod.nim | 18 | ||||
-rw-r--r-- | tests/compile/tlibs.nim | 24 | ||||
-rw-r--r-- | tests/compile/tloops.nim | 87 | ||||
-rw-r--r-- | tests/compile/tmandelbrot.nim | 57 | ||||
-rw-r--r-- | tests/compile/tnew.nim | 49 | ||||
-rw-r--r-- | tests/compile/tnewlibs.nim | 17 | ||||
-rw-r--r-- | tests/compile/tnewsets.nim | 6 | ||||
-rw-r--r-- | tests/compile/tnewuns.nim | 12 | ||||
-rw-r--r-- | tests/compile/tnoforward.nim | 10 | ||||
-rw-r--r-- | tests/compile/tparedef.nim | 4 | ||||
-rw-r--r-- | tests/compile/tprep.nim | 30 | ||||
-rw-r--r-- | tests/compile/tquicksort.nim | 26 | ||||
-rw-r--r-- | tests/compile/tradix.nim | 319 | ||||
-rw-r--r-- | tests/compile/treadln.nim | 12 | ||||
-rw-r--r-- | tests/compile/treadx.nim | 14 | ||||
-rw-r--r-- | tests/compile/tshadow_magic_type.nim | 24 | ||||
-rw-r--r-- | tests/compile/tsizeof.nim | 10 | ||||
-rw-r--r-- | tests/compile/tstrace.nim | 16 | ||||
-rw-r--r-- | tests/compile/tstrdesc.nim | 14 | ||||
-rw-r--r-- | tests/compile/tstrdist.nim | 26 | ||||
-rw-r--r-- | tests/compile/tvarious.nim | 63 | ||||
-rw-r--r-- | tests/compiles/tcompiles.nim (renamed from tests/compile/tcompiles.nim) | 0 | ||||
-rw-r--r-- | tests/concat/tconcat.nim (renamed from tests/run/tconcat.nim) | 0 | ||||
-rw-r--r-- | tests/concurrency/tnodeadlocks.nim (renamed from tests/run/tnodeadlocks.nim) | 0 | ||||
-rw-r--r-- | tests/constr/tconstr1.nim (renamed from tests/reject/tconstr1.nim) | 0 | ||||
-rw-r--r-- | tests/constr/tconstr2.nim (renamed from tests/run/tconstr2.nim) | 0 | ||||
-rw-r--r-- | tests/constraints/tconstraints.nim (renamed from tests/reject/tconstraints.nim) | 0 | ||||
-rw-r--r-- | tests/controlflow/tcontinue.nim (renamed from tests/run/tcontinue.nim) | 0 | ||||
-rw-r--r-- | tests/controlflow/tstatret.nim (renamed from tests/reject/tstatret.nim) | 0 | ||||
-rw-r--r-- | tests/converter/tconvcolors.nim (renamed from tests/compile/tconvcolors.nim) | 0 | ||||
-rw-r--r-- | tests/converter/tconvert.nim (renamed from tests/compile/tconvert.nim) | 0 | ||||
-rw-r--r-- | tests/converter/tgenericconverter.nim (renamed from tests/run/tgenericconverter.nim) | 0 | ||||
-rw-r--r-- | tests/converter/ttypeconverter1.nim (renamed from tests/compile/ttypeconverter1.nim) | 0 | ||||
-rw-r--r-- | tests/defaultprocparam/mdefaultprocparam.nim (renamed from tests/compile/mdefaultprocparam.nim) | 0 | ||||
-rw-r--r-- | tests/defaultprocparam/tdefaultprocparam.nim (renamed from tests/compile/tdefaultprocparam.nim) | 0 | ||||
-rw-r--r-- | tests/deprecated/tdeprecated.nim (renamed from tests/reject/tdeprecated.nim) | 0 | ||||
-rw-r--r-- | tests/destructor/tdestructor.nim | 84 | ||||
-rw-r--r-- | tests/destructor/tdestructor2.nim (renamed from tests/reject/tdestructor.nim) | 0 | ||||
-rw-r--r-- | tests/destructor/tdictdestruct.nim (renamed from tests/compile/tdictdestruct.nim) | 0 | ||||
-rw-r--r-- | tests/discard/tdiscardable.nim (renamed from tests/compile/tdiscardable.nim) | 0 | ||||
-rw-r--r-- | tests/discard/tneedsdiscard.nim (renamed from tests/reject/tneedsdiscard.nim) | 0 | ||||
-rw-r--r-- | tests/distinct/tcurrncy.nim (renamed from tests/run/tcurrncy.nim) | 0 | ||||
-rw-r--r-- | tests/effects/teffects1.nim (renamed from tests/reject/teffects1.nim) | 2 | ||||
-rw-r--r-- | tests/effects/teffects2.nim (renamed from tests/reject/teffects2.nim) | 0 | ||||
-rw-r--r-- | tests/effects/teffects3.nim (renamed from tests/reject/teffects3.nim) | 0 | ||||
-rw-r--r-- | tests/effects/teffects4.nim (renamed from tests/reject/teffects4.nim) | 0 | ||||
-rw-r--r-- | tests/effects/teffects5.nim (renamed from tests/reject/teffects5.nim) | 0 | ||||
-rw-r--r-- | tests/effects/teffects6.nim (renamed from tests/compile/teffects1.nim) | 0 | ||||
-rw-r--r-- | tests/effects/tsidee1.nim (renamed from tests/reject/tsidee1.nim) | 0 | ||||
-rw-r--r-- | tests/effects/tsidee2.nim (renamed from tests/run/tsidee2.nim) | 0 | ||||
-rw-r--r-- | tests/effects/tsidee3.nim (renamed from tests/run/tsidee3.nim) | 0 | ||||
-rw-r--r-- | tests/effects/tsidee4.nim (renamed from tests/reject/tsidee4.nim) | 0 | ||||
-rw-r--r-- | tests/enum/tenum.nim (renamed from tests/compile/tenum.nim) | 0 | ||||
-rw-r--r-- | tests/enum/tenum2.nim (renamed from tests/compile/tenum2.nim) | 0 | ||||
-rw-r--r-- | tests/enum/tenum3.nim (renamed from tests/compile/tenum3.nim) | 0 | ||||
-rw-r--r-- | tests/enum/tenumhole.nim (renamed from tests/run/tenumhole.nim) | 0 | ||||
-rw-r--r-- | tests/enum/tenumitems.nim (renamed from tests/reject/tenumitems.nim) | 0 | ||||
-rw-r--r-- | tests/enum/tenumitems2.nim (renamed from tests/run/tenumitems.nim) | 0 | ||||
-rw-r--r-- | tests/enum/tenummix.nim (renamed from tests/reject/tenummix.nim) | 4 | ||||
-rw-r--r-- | tests/enum/tnamedenumfields.nim (renamed from tests/run/tnamedenumfields.nim) | 0 | ||||
-rw-r--r-- | tests/enum/toptions.nim (renamed from tests/compile/toptions.nim) | 4 | ||||
-rw-r--r-- | tests/exception/tcontinuexc.nim (renamed from tests/run/tcontinuexc.nim) | 0 | ||||
-rw-r--r-- | tests/exception/texceptions.nim (renamed from tests/run/texceptions.nim) | 0 | ||||
-rw-r--r-- | tests/exception/texcpt1.nim (renamed from tests/run/texcpt1.nim) | 0 | ||||
-rw-r--r-- | tests/exception/texcsub.nim (renamed from tests/run/texcsub.nim) | 0 | ||||
-rw-r--r-- | tests/exception/tfinally.nim (renamed from tests/run/tfinally.nim) | 0 | ||||
-rw-r--r-- | tests/exception/tfinally2.nim (renamed from tests/run/tfinally2.nim) | 0 | ||||
-rw-r--r-- | tests/exception/tfinally3.nim (renamed from tests/run/tfinally3.nim) | 0 | ||||
-rw-r--r-- | tests/exception/tonraise.nim (renamed from tests/run/tonraise.nim) | 0 | ||||
-rw-r--r-- | tests/exception/treraise.nim (renamed from tests/run/treraise.nim) | 0 | ||||
-rw-r--r-- | tests/exception/tunhandledexc.nim (renamed from tests/run/tunhandledexc.nim) | 0 | ||||
-rw-r--r-- | tests/exception/twrongexc.nim (renamed from tests/run/twrongexc.nim) | 0 | ||||
-rw-r--r-- | tests/exprs/texprstmt.nim (renamed from tests/reject/texprstmt.nim) | 0 | ||||
-rw-r--r-- | tests/exprs/tstmtexp.nim (renamed from tests/reject/tstmtexp.nim) | 0 | ||||
-rw-r--r-- | tests/exprs/tstmtexprs.nim (renamed from tests/run/tstmtexprs.nim) | 0 | ||||
-rw-r--r-- | tests/fields/tfieldindex.nim (renamed from tests/run/tfieldindex.nim) | 0 | ||||
-rw-r--r-- | tests/fields/tfielditerator.nim (renamed from tests/run/tfielditerator.nim) | 0 | ||||
-rw-r--r-- | tests/fields/tfielditerator2.nim (renamed from tests/run/tfielditerator2.nim) | 0 | ||||
-rw-r--r-- | tests/float/tfloat1.nim (renamed from tests/run/tfloat1.nim) | 0 | ||||
-rw-r--r-- | tests/float/tfloat2.nim (renamed from tests/run/tfloat2.nim) | 0 | ||||
-rw-r--r-- | tests/float/tfloat3.nim (renamed from tests/run/tfloat3.nim) | 0 | ||||
-rw-r--r-- | tests/friends/mfriends.nim (renamed from tests/run/mfriends.nim) | 0 | ||||
-rw-r--r-- | tests/friends/tfriends.nim (renamed from tests/run/tfriends.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tbintre2.nim (renamed from tests/run/tbintre2.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tbintree.nim (renamed from tests/run/tbintree.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tcan_alias_generic.nim (renamed from tests/compile/tcan_alias_generic.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tcan_alias_specialised_generic.nim (renamed from tests/compile/tcan_alias_specialised_generic.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tcan_inherit_generic.nim (renamed from tests/compile/tcan_inherit_generic.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tcan_specialise_generic.nim (renamed from tests/compile/tcan_specialise_generic.nim) | 0 | ||||
-rw-r--r-- | tests/generics/texplicitgeneric1.nim (renamed from tests/run/texplicitgeneric1.nim) | 0 | ||||
-rw-r--r-- | tests/generics/texplicitgeneric2.nim (renamed from tests/run/texplicitgeneric2.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tforwardgeneric.nim (renamed from tests/compile/tforwardgeneric.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tgeneric0.nim (renamed from tests/compile/tgeneric.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tgeneric1.nim (renamed from tests/run/tgenerics1.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tgeneric2.nim (renamed from tests/compile/tgeneric2.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tgeneric3.nim (renamed from tests/compile/tgeneric3.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tgeneric4.nim (renamed from tests/compile/tgeneric4.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tgenericdefaults.nim (renamed from tests/compile/tgenericdefaults.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tgenericmatcher.nim (renamed from tests/compile/tgenericmatcher.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tgenericmatcher2.nim (renamed from tests/compile/tgenericmatcher2.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tgenericprocvar.nim (renamed from tests/run/tgenericprocvar.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tgenericprop.nim (renamed from tests/compile/tgenericprop.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tgenericrefs.nim (renamed from tests/compile/tgenericrefs.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tgenericshardcases.nim | 36 | ||||
-rw-r--r-- | tests/generics/tgenerictmpl.nim (renamed from tests/compile/tgenerictmpl.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tgenericvariant.nim (renamed from tests/compile/tgenericvariant.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tspecialised_is_equivalent.nim (renamed from tests/compile/tspecialised_is_equivalent.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tthread_generic.nim (renamed from tests/compile/tthread_generic.nim) | 0 | ||||
-rw-r--r-- | tests/generics/tvarargs_vs_generic.nim (renamed from tests/run/tvarargs_vs_generic.nim) | 0 | ||||
-rw-r--r-- | tests/gensym/tgensym.nim (renamed from tests/run/tgensym.nim) | 0 | ||||
-rw-r--r-- | tests/gensym/tgensymgeneric.nim (renamed from tests/compile/tgensymgeneric.nim) | 0 | ||||
-rw-r--r-- | tests/global/tglobal.nim (renamed from tests/run/tglobal.nim) | 0 | ||||
-rw-r--r-- | tests/global/tglobalforvar.nim (renamed from tests/compile/tglobalforvar.nim) | 0 | ||||
-rw-r--r-- | tests/ifstmt/tnestif.nim (renamed from tests/run/tnestif.nim) | 0 | ||||
-rw-r--r-- | tests/implicit/timplicititems.nim (renamed from tests/compile/timplicititems.nim) | 0 | ||||
-rw-r--r-- | tests/implicit/timplictderef.nim (renamed from tests/compile/timplictderef.nim) | 0 | ||||
-rw-r--r-- | tests/important/tdrdobbs_examples.nim (renamed from tests/run/tdrdobbs_examples.nim) | 0 | ||||
-rw-r--r-- | tests/init/tuninit1.nim (renamed from tests/reject/tuninit1.nim) | 0 | ||||
-rw-r--r-- | tests/init/tzeroarray.nim (renamed from tests/run/tzeroarray.nim) | 0 | ||||
-rw-r--r-- | tests/iter/tcountup.nim (renamed from tests/run/tcountup.nim) | 0 | ||||
-rw-r--r-- | tests/iter/titer.nim (renamed from tests/compile/titer.nim) | 0 | ||||
-rw-r--r-- | tests/iter/titer2.nim (renamed from tests/compile/titer2.nim) | 0 | ||||
-rw-r--r-- | tests/iter/titer3.nim (renamed from tests/run/titer3.nim) | 0 | ||||
-rw-r--r-- | tests/iter/titer4.nim (renamed from tests/reject/titer4.nim) | 0 | ||||
-rw-r--r-- | tests/iter/titer5.nim (renamed from tests/run/titer5.nim) | 0 | ||||
-rw-r--r-- | tests/iter/titer6.nim (renamed from tests/run/titer6.nim) | 0 | ||||
-rw-r--r-- | tests/iter/titer7.nim (renamed from tests/run/titer7.nim) | 0 | ||||
-rw-r--r-- | tests/iter/titer8.nim (renamed from tests/run/titer8.nim) | 0 | ||||
-rw-r--r-- | tests/iter/titer9.nim (renamed from tests/run/titer9.nim) | 0 | ||||
-rw-r--r-- | tests/iter/titer_no_tuple_unpack.nim (renamed from tests/compile/titer_no_tuple_unpack.nim) | 0 | ||||
-rw-r--r-- | tests/iter/titerovl.nim (renamed from tests/compile/titerovl.nim) | 0 | ||||
-rw-r--r-- | tests/iter/titerslice.nim (renamed from tests/run/titerslice.nim) | 0 | ||||
-rw-r--r-- | tests/iter/titervaropenarray.nim (renamed from tests/run/titervaropenarray.nim) | 0 | ||||
-rw-r--r-- | tests/iter/tmoditer.nim (renamed from tests/run/tmoditer.nim) | 0 | ||||
-rw-r--r-- | tests/iter/treciter.nim (renamed from tests/reject/treciter.nim) | 0 | ||||
-rw-r--r-- | tests/iter/twrongiter.nim (renamed from tests/reject/twrongiter.nim) | 2 | ||||
-rw-r--r-- | tests/let/tlet.nim (renamed from tests/reject/tlet.nim) | 0 | ||||
-rw-r--r-- | tests/let/tlet2.nim (renamed from tests/reject/tlet2.nim) | 0 | ||||
-rw-r--r-- | tests/lexer/thexlit.nim (renamed from tests/run/thexlit.nim) | 0 | ||||
-rw-r--r-- | tests/lexer/thexrange.nim (renamed from tests/compile/thexrange.nim) | 0 | ||||
-rw-r--r-- | tests/lexer/tident.nim (renamed from tests/compile/tident.nim) | 0 | ||||
-rw-r--r-- | tests/lexer/tind1.nim (renamed from tests/reject/tind1.nim) | 0 | ||||
-rw-r--r-- | tests/lexer/tindent1.nim (renamed from tests/run/tindent1.nim) | 0 | ||||
-rw-r--r-- | tests/lexer/tlexer.nim (renamed from tests/compile/tlexer.nim) | 0 | ||||
-rw-r--r-- | tests/lexer/tmissingnl.nim (renamed from tests/reject/tmissingnl.nim) | 0 | ||||
-rw-r--r-- | tests/lexer/tstrlits.nim (renamed from tests/run/tstrlits.nim) | 0 | ||||
-rw-r--r-- | tests/lexer/tunderscores.nim (renamed from tests/reject/tunderscores.nim) | 0 | ||||
-rw-r--r-- | tests/lookups/tkoeniglookup.nim (renamed from tests/run/tkoeniglookup.nim) | 0 | ||||
-rw-r--r-- | tests/lookups/tredef.nim (renamed from tests/compile/tredef.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tdumpast.nim (renamed from tests/compile/tdumpast.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tdumpast2.nim (renamed from tests/compile/tdumpast2.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tdumptree.nim (renamed from tests/run/tdumptree.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tidgen.nim (renamed from tests/run/tidgen.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tmacro1.nim (renamed from tests/compile/tmacro1.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tmacro2.nim (renamed from tests/run/tmacro2.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tmacro3.nim (renamed from tests/run/tmacro3.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tmacro4.nim (renamed from tests/run/tmacro4.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tmacro5.nim (renamed from tests/compile/tmacro2.nim) | 2 | ||||
-rw-r--r-- | tests/macros/tmacroaspragma.nim (renamed from tests/compile/tmacroaspragma.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tmacrogenerics.nim (renamed from tests/run/tmacrogenerics.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tmacros1.nim (renamed from tests/run/tmacros1.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tmacrostmt.nim (renamed from tests/compile/tmacrostmt.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tmacrotypes.nim (renamed from tests/compile/tmacrotypes.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tnimrodnode_for_runtime.nim (renamed from tests/compile/tnimrodnode_for_runtime.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tprintf.nim (renamed from tests/run/tprintf.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tquotewords.nim (renamed from tests/run/tquotewords.nim) | 0 | ||||
-rw-r--r-- | tests/macros/trecmacro.nim (renamed from tests/reject/trecmacro.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tstringinterp.nim (renamed from tests/run/tstringinterp.nim) | 0 | ||||
-rw-r--r-- | tests/macros/tvtable.nim (renamed from tests/run/tvtable.nim) | 0 | ||||
-rw-r--r-- | tests/magics/tlowhigh.nim (renamed from tests/run/tlowhigh.nim) | 0 | ||||
-rw-r--r-- | tests/matrix/tmatrix.nim (renamed from tests/run/tmatrix.nim) | 0 | ||||
-rw-r--r-- | tests/matrix/tmatrix1.nim (renamed from tests/compile/tmatrix1.nim) | 0 | ||||
-rw-r--r-- | tests/matrix/tmatrix2.nim (renamed from tests/compile/tmatrix2.nim) | 0 | ||||
-rw-r--r-- | tests/metatype/tbindtypedesc.nim | 91 | ||||
-rw-r--r-- | tests/metatype/tcompositetypeclasses.nim | 59 | ||||
-rw-r--r-- | tests/metatype/tconstraints.nim (renamed from tests/compile/tconstraints.nim) | 0 | ||||
-rw-r--r-- | tests/metatype/tsemistatic.nim | 24 | ||||
-rw-r--r-- | tests/metatype/ttypebar.nim | 14 | ||||
-rw-r--r-- | tests/metatype/ttypeclasses.nim (renamed from tests/compile/ttypeclasses.nim) | 0 | ||||
-rw-r--r-- | tests/metatype/ttypedesc1.nim (renamed from tests/run/ttypedesc1.nim) | 0 | ||||
-rw-r--r-- | tests/metatype/ttypeselectors.nim (renamed from tests/compile/ttypeselectors.nim) | 0 | ||||
-rw-r--r-- | tests/metatype/ttypetraits.nim (renamed from tests/run/ttypetraits.nim) | 2 | ||||
-rw-r--r-- | tests/metatype/tusertypeclasses.nim (renamed from tests/run/tusertypeclasses.nim) | 0 | ||||
-rw-r--r-- | tests/metatype/utypeclasses.nim (renamed from tests/run/utypeclasses.nim) | 0 | ||||
-rw-r--r-- | tests/method/mmultim3.nim (renamed from tests/run/mmultim3.nim) | 0 | ||||
-rw-r--r-- | tests/method/tmethod.nim (renamed from tests/reject/tmethod.nim) | 0 | ||||
-rw-r--r-- | tests/method/tmethods1.nim (renamed from tests/run/tmethods1.nim) | 0 | ||||
-rw-r--r-- | tests/method/tmultim1.nim (renamed from tests/run/tmultim1.nim) | 0 | ||||
-rw-r--r-- | tests/method/tmultim2.nim (renamed from tests/run/tmultim2.nim) | 0 | ||||
-rw-r--r-- | tests/method/tmultim3.nim (renamed from tests/run/tmultim3.nim) | 0 | ||||
-rw-r--r-- | tests/method/tmultim4.nim (renamed from tests/run/tmultim4.nim) | 0 | ||||
-rw-r--r-- | tests/method/tmultim6.nim (renamed from tests/run/tmultim6.nim) | 0 | ||||
-rw-r--r-- | tests/method/tsimmeth.nim (renamed from tests/run/tsimmeth.nim) | 0 | ||||
-rw-r--r-- | tests/module/mopaque.nim (renamed from tests/reject/mopaque.nim) | 0 | ||||
-rw-r--r-- | tests/module/mrecmod.nim (renamed from tests/compile/mrecmod.nim) | 0 | ||||
-rw-r--r-- | tests/module/mrecmod2.nim (renamed from tests/compile/mrecmod2.nim) | 0 | ||||
-rw-r--r-- | tests/module/topaque.nim (renamed from tests/reject/topaque.nim) | 0 | ||||
-rw-r--r-- | tests/module/trecinca.nim (renamed from tests/reject/trecinca.nim) | 0 | ||||
-rw-r--r-- | tests/module/trecincb.nim (renamed from tests/reject/trecincb.nim) | 0 | ||||
-rw-r--r-- | tests/module/trecmod.nim (renamed from tests/compile/trecmod.nim) | 0 | ||||
-rw-r--r-- | tests/module/trecmod2.nim (renamed from tests/compile/trecmod2.nim) | 0 | ||||
-rw-r--r-- | tests/modules/mexporta.nim (renamed from tests/compile/mexporta.nim) | 0 | ||||
-rw-r--r-- | tests/modules/mexportb.nim (renamed from tests/compile/mexportb.nim) | 0 | ||||
-rw-r--r-- | tests/modules/texport.nim (renamed from tests/compile/texport.nim) | 0 | ||||
-rw-r--r-- | tests/modules/timportexcept.nim (renamed from tests/reject/timportexcept.nim) | 0 | ||||
-rw-r--r-- | tests/namedparams/tnamedparams.nim (renamed from tests/reject/tnamedparams.nim) | 0 | ||||
-rw-r--r-- | tests/namedparams/tnamedparams2.nim (renamed from tests/compile/tnamedparams.nim) | 0 | ||||
-rw-r--r-- | tests/namspc/mnamspc1.nim (renamed from tests/reject/mnamspc1.nim) | 0 | ||||
-rw-r--r-- | tests/namspc/mnamspc2.nim (renamed from tests/reject/mnamspc2.nim) | 0 | ||||
-rw-r--r-- | tests/namspc/tnamspc.nim (renamed from tests/reject/tnamspc.nim) | 0 | ||||
-rw-r--r-- | tests/notnil/tnotnil.nim (renamed from tests/reject/tnotnil.nim) | 0 | ||||
-rw-r--r-- | tests/notnil/tnotnil1.nim (renamed from tests/reject/tnotnil1.nim) | 0 | ||||
-rw-r--r-- | tests/notnil/tnotnil2.nim (renamed from tests/reject/tnotnil2.nim) | 0 | ||||
-rw-r--r-- | tests/object/tobjconstr.nim (renamed from tests/run/tobjconstr.nim) | 0 | ||||
-rw-r--r-- | tests/object/tobjconstr2.nim (renamed from tests/compile/tobjconstr2.nim) | 0 | ||||
-rw-r--r-- | tests/object/tobjcov.nim (renamed from tests/compile/tobjcov.nim) | 0 | ||||
-rw-r--r-- | tests/object/tobject.nim (renamed from tests/run/tobject.nim) | 0 | ||||
-rw-r--r-- | tests/object/tobject2.nim (renamed from tests/compile/tobject2.nim) | 0 | ||||
-rw-r--r-- | tests/object/tobject3.nim (renamed from tests/compile/tobject3.nim) | 0 | ||||
-rw-r--r-- | tests/object/toop.nim (renamed from tests/compile/toop.nim) | 0 | ||||
-rw-r--r-- | tests/object/toop1.nim (renamed from tests/run/toop1.nim) | 0 | ||||
-rw-r--r-- | tests/objects/tobjects.nim (renamed from tests/compile/tobjects.nim) | 0 | ||||
-rw-r--r-- | tests/objvariant/tadrdisc.nim (renamed from tests/reject/tadrdisc.nim) | 0 | ||||
-rw-r--r-- | tests/objvariant/tcheckedfield1.nim (renamed from tests/reject/tcheckedfield1.nim) | 0 | ||||
-rw-r--r-- | tests/objvariant/temptycaseobj.nim (renamed from tests/reject/temptycaseobj.nim) | 0 | ||||
-rw-r--r-- | tests/objvariant/tvariantstack.nim (renamed from tests/run/tvariantstack.nim) | 0 | ||||
-rw-r--r-- | tests/openarray/topena1.nim (renamed from tests/reject/topena1.nim) | 0 | ||||
-rw-r--r-- | tests/openarray/topenarrayrepr.nim (renamed from tests/run/topenarrayrepr.nim) | 0 | ||||
-rw-r--r-- | tests/openarray/topenlen.nim (renamed from tests/run/topenlen.nim) | 0 | ||||
-rw-r--r-- | tests/operator/tofopr.nim (renamed from tests/run/tofopr.nim) | 0 | ||||
-rw-r--r-- | tests/operator/toprprec.nim (renamed from tests/run/toprprec.nim) | 0 | ||||
-rw-r--r-- | tests/operator/tprecedence.nim (renamed from tests/run/tprecedence.nim) | 0 | ||||
-rw-r--r-- | tests/overflw/toverflw.nim (renamed from tests/run/toverflw.nim) | 0 | ||||
-rw-r--r-- | tests/overflw/toverflw2.nim (renamed from tests/run/toverflw2.nim) | 0 | ||||
-rw-r--r-- | tests/overflw/tovfint.nim (renamed from tests/run/tovfint.nim) | 0 | ||||
-rw-r--r-- | tests/overload/toverl.nim (renamed from tests/reject/toverl.nim) | 0 | ||||
-rw-r--r-- | tests/overload/toverl2.nim (renamed from tests/run/toverl2.nim) | 0 | ||||
-rw-r--r-- | tests/overload/toverl3.nim (renamed from tests/run/toverl3.nim) | 0 | ||||
-rw-r--r-- | tests/overload/toverprc.nim (renamed from tests/compile/toverprc.nim) | 0 | ||||
-rw-r--r-- | tests/overload/toverwr.nim (renamed from tests/run/toverwr.nim) | 0 | ||||
-rw-r--r-- | tests/pattern/tpatterns.nim (renamed from tests/run/tpatterns.nim) | 0 | ||||
-rw-r--r-- | tests/patterns/tor.nim | 2 | ||||
-rw-r--r-- | tests/pragma/tuserpragma.nim (renamed from tests/compile/tuserpragma.nim) | 0 | ||||
-rw-r--r-- | tests/pragmas/tpush.nim (renamed from tests/compile/tpush.nim) | 0 | ||||
-rw-r--r-- | tests/proc/tnestprc.nim (renamed from tests/run/tnestprc.nim) | 0 | ||||
-rw-r--r-- | tests/proc/tprocredef.nim (renamed from tests/reject/tprocredef.nim) | 0 | ||||
-rw-r--r-- | tests/procvar/tgenericprocvar.nim (renamed from tests/compile/tgenericprocvar.nim) | 0 | ||||
-rw-r--r-- | tests/procvar/tprocvar.nim (renamed from tests/reject/tprocvar.nim) | 0 | ||||
-rw-r--r-- | tests/procvar/tprocvar2.nim (renamed from tests/run/tprocvar.nim) | 0 | ||||
-rw-r--r-- | tests/procvar/tprocvars.nim (renamed from tests/compile/tprocvars.nim) | 0 | ||||
-rw-r--r-- | tests/range/compilehelpers.nim | 6 | ||||
-rw-r--r-- | tests/range/tbug499771.nim (renamed from tests/run/tbug499771.nim) | 0 | ||||
-rw-r--r-- | tests/range/tcolors.nim (renamed from tests/compile/tcolors.nim) | 0 | ||||
-rw-r--r-- | tests/range/tmatrix3.nim | 41 | ||||
-rw-r--r-- | tests/range/tsubrange.nim (renamed from tests/reject/tsubrange.nim) | 0 | ||||
-rw-r--r-- | tests/range/tsubrange2.nim (renamed from tests/run/tsubrange2.nim) | 0 | ||||
-rw-r--r-- | tests/range/tsubrange3.nim (renamed from tests/run/tsubrange.nim) | 0 | ||||
-rw-r--r-- | tests/reject/99bottles.nim | 1 | ||||
-rw-r--r-- | tests/reject/mbind4.nim | 9 | ||||
-rw-r--r-- | tests/reject/t99bott.nim | 36 | ||||
-rw-r--r-- | tests/reject/tatomic.nim | 12 | ||||
-rw-r--r-- | tests/reject/tbind4.nim | 13 | ||||
-rw-r--r-- | tests/reject/tgenconstraints.nim | 30 | ||||
-rw-r--r-- | tests/reject/tinc.nim | 12 | ||||
-rw-r--r-- | tests/reject/tinout.nim | 16 | ||||
-rw-r--r-- | tests/reject/tinvalidarrayaccess.nim | 14 | ||||
-rw-r--r-- | tests/reject/tinvalidnewseq.nim | 27 | ||||
-rw-r--r-- | tests/reject/tinvwhen.nim | 15 | ||||
-rw-r--r-- | tests/reject/tnoinst.nim | 16 | ||||
-rw-r--r-- | tests/reject/tnolen.nim | 9 | ||||
-rw-r--r-- | tests/reject/tnoop.nim | 12 | ||||
-rw-r--r-- | tests/reject/tnot.nim | 21 | ||||
-rw-r--r-- | tests/reject/trawstr.nim | 12 | ||||
-rw-r--r-- | tests/reject/tsimtych.nim | 12 | ||||
-rw-r--r-- | tests/run/globalaux.nim | 15 | ||||
-rw-r--r-- | tests/run/globalaux2.nim | 4 | ||||
-rw-r--r-- | tests/run/minit.nim | 2 | ||||
-rw-r--r-- | tests/run/tack.nim | 21 | ||||
-rw-r--r-- | tests/run/tbug511622.nim | 16 | ||||
-rw-r--r-- | tests/run/tdestructor.nim | 26 | ||||
-rw-r--r-- | tests/run/tdomulttest.nim | 17 | ||||
-rw-r--r-- | tests/run/temit.nim | 20 | ||||
-rw-r--r-- | tests/run/teventemitter.nim | 33 | ||||
-rw-r--r-- | tests/run/tevents.nim | 48 | ||||
-rw-r--r-- | tests/run/tfilter.nim | 41 | ||||
-rw-r--r-- | tests/run/thintoff.nim | 12 | ||||
-rw-r--r-- | tests/run/tinit.nim | 12 | ||||
-rw-r--r-- | tests/run/tints.nim | 45 | ||||
-rw-r--r-- | tests/run/tlocals.nim | 11 | ||||
-rw-r--r-- | tests/run/tmemoization.nim | 17 | ||||
-rw-r--r-- | tests/run/tnewderef.nim | 11 | ||||
-rw-r--r-- | tests/run/tpos.nim | 35 | ||||
-rw-r--r-- | tests/run/tromans.nim | 71 | ||||
-rw-r--r-- | tests/run/tsimplesort.nim | 313 | ||||
-rw-r--r-- | tests/run/tslices.nim | 59 | ||||
-rw-r--r-- | tests/run/tsortdev.nim | 59 | ||||
-rw-r--r-- | tests/run/tstrange.nim | 23 | ||||
-rw-r--r-- | tests/run/tunittests.nim | 1 | ||||
-rw-r--r-- | tests/run/tvarious1.nim | 41 | ||||
-rw-r--r-- | tests/run/tvarnums.nim | 142 | ||||
-rw-r--r-- | tests/seq/tseq2.nim (renamed from tests/compile/tseq2.nim) | 0 | ||||
-rw-r--r-- | tests/seq/tseqcon.nim (renamed from tests/run/tseqcon.nim) | 0 | ||||
-rw-r--r-- | tests/seq/tseqcon2.nim (renamed from tests/compile/tseqcon2.nim) | 0 | ||||
-rw-r--r-- | tests/seq/tseqtuple.nim (renamed from tests/run/tseqtuple.nim) | 0 | ||||
-rw-r--r-- | tests/seq/tsequtils.nim (renamed from tests/run/tsequtils.nim) | 0 | ||||
-rw-r--r-- | tests/seq/ttoseq.nim (renamed from tests/run/ttoseq.nim) | 0 | ||||
-rw-r--r-- | tests/sets/tsets.nim (renamed from tests/run/tsets.nim) | 0 | ||||
-rw-r--r-- | tests/sets/tsets2.nim (renamed from tests/run/tsets2.nim) | 0 | ||||
-rw-r--r-- | tests/static/tstaticparams.nim (renamed from tests/run/tstaticparams.nim) | 16 | ||||
-rw-r--r-- | tests/stdlib/tcputime.nim (renamed from tests/compile/tcputime.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tcritbits.nim (renamed from tests/run/tcritbits.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tdialogs.nim (renamed from tests/compile/tdialogs.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/techo.nim (renamed from tests/compile/techo.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tformat.nim (renamed from tests/run/tformat.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/thashes.nim (renamed from tests/run/thashes.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tio.nim (renamed from tests/compile/tio.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tircbot.nim (renamed from tests/compile/tircbot.nim) | 6 | ||||
-rw-r--r-- | tests/stdlib/tlists.nim (renamed from tests/run/tlists.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tmarshal.nim (renamed from tests/compile/tmarshal.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tmath.nim (renamed from tests/run/tmath.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tmath2.nim (renamed from tests/compile/tmath.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tmongo.nim (renamed from tests/compile/tmongo.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tos.nim (renamed from tests/compile/tos.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tparscfg.nim (renamed from tests/compile/tparscfg.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tparsefloat.nim (renamed from tests/compile/tparsefloat.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tparsopt.nim (renamed from tests/compile/tparsopt.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tpegs.nim (renamed from tests/run/tpegs.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tposix.nim (renamed from tests/compile/tposix.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tquit.nim (renamed from tests/compile/tquit.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tregex.nim (renamed from tests/run/tregex.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/treguse.nim (renamed from tests/run/treguse.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/trepr.nim (renamed from tests/run/trepr.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/trepr2.nim (renamed from tests/compile/trepr.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tsockets.nim (renamed from tests/compile/tsockets.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tsortcall.nim (renamed from tests/compile/tsortcall.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tsplit.nim (renamed from tests/run/tsplit.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tstreams.nim (renamed from tests/compile/tstreams.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tstrset.nim (renamed from tests/compile/tstrset.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tstrtabs.nim (renamed from tests/compile/tstrtabs.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tstrutil.nim (renamed from tests/run/tstrutil.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/ttime.nim (renamed from tests/compile/ttime.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/tunidecode.nim (renamed from tests/run/tunidecode.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/twalker.nim (renamed from tests/compile/twalker.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/txmlgen.nim (renamed from tests/run/txmlgen.nim) | 0 | ||||
-rw-r--r-- | tests/stdlib/txmltree.nim (renamed from tests/run/txmltree.nim) | 0 | ||||
-rw-r--r-- | tests/table/ttableconstr.nim (renamed from tests/compile/ttableconstr.nim) | 0 | ||||
-rw-r--r-- | tests/table/ttables.nim (renamed from tests/run/ttables.nim) | 0 | ||||
-rw-r--r-- | tests/table/ttables2.nim (renamed from tests/run/ttables2.nim) | 0 | ||||
-rw-r--r-- | tests/template/mcan_access_hidden_field.nim | 9 | ||||
-rw-r--r-- | tests/template/mtempl5.nim (renamed from tests/compile/mtempl5.nim) | 0 | ||||
-rw-r--r-- | tests/template/tcan_access_hidden_field.nim | 9 | ||||
-rw-r--r-- | tests/template/thygienictempl.nim (renamed from tests/compile/thygienictempl.nim) | 0 | ||||
-rw-r--r-- | tests/template/tmodulealias.nim (renamed from tests/compile/tmodulealias.nim) | 0 | ||||
-rw-r--r-- | tests/template/tstempl.nim (renamed from tests/run/tstempl.nim) | 0 | ||||
-rw-r--r-- | tests/template/ttempl.nim (renamed from tests/compile/ttempl.nim) | 0 | ||||
-rw-r--r-- | tests/template/ttempl2.nim (renamed from tests/reject/ttempl2.nim) | 0 | ||||
-rw-r--r-- | tests/template/ttempl3.nim (renamed from tests/compile/ttempl3.nim) | 0 | ||||
-rw-r--r-- | tests/template/ttempl4.nim (renamed from tests/compile/ttempl4.nim) | 0 | ||||
-rw-r--r-- | tests/template/ttempl5.nim (renamed from tests/compile/ttempl5.nim) | 0 | ||||
-rw-r--r-- | tests/template/ttemplreturntype.nim (renamed from tests/compile/ttemplreturntype.nim) | 0 | ||||
-rw-r--r-- | tests/template/utemplates.nim (renamed from tests/run/utemplates.nim) | 2 | ||||
-rw-r--r-- | tests/testament/backend.nim | 121 | ||||
-rw-r--r-- | tests/testament/caasdriver.nim (renamed from tests/caasdriver.nim) | 0 | ||||
-rw-r--r-- | tests/testament/categories.nim | 264 | ||||
-rw-r--r-- | tests/testament/css/boilerplate.css (renamed from tests/css/boilerplate.css) | 0 | ||||
-rw-r--r-- | tests/testament/css/style.css (renamed from tests/css/style.css) | 0 | ||||
-rw-r--r-- | tests/testament/htmlgen.nim | 161 | ||||
-rw-r--r-- | tests/testament/specs.nim | 130 | ||||
-rw-r--r-- | tests/testament/tester.nim | 273 | ||||
-rw-r--r-- | tests/trmacros/tdisallowif.nim (renamed from tests/reject/tdisallowif.nim) | 3 | ||||
-rw-r--r-- | tests/tuples/tanontuples.nim (renamed from tests/run/tanontuples.nim) | 0 | ||||
-rw-r--r-- | tests/tuples/twrongtupleaccess.nim (renamed from tests/reject/twrongtupleaccess.nim) | 0 | ||||
-rw-r--r-- | tests/typerel/tcommontype.nim (renamed from tests/compile/tcommontype.nim) | 0 | ||||
-rw-r--r-- | tests/typerel/tno_int_in_bool_context.nim (renamed from tests/reject/tno_int_in_bool_context.nim) | 0 | ||||
-rw-r--r-- | tests/typerel/tnoargopenarray.nim (renamed from tests/compile/tnoargopenarray.nim) | 0 | ||||
-rw-r--r-- | tests/typerel/tnocontains.nim (renamed from tests/reject/tnocontains.nim) | 0 | ||||
-rw-r--r-- | tests/typerel/trectuple.nim (renamed from tests/compile/trectuple.nim) | 0 | ||||
-rw-r--r-- | tests/typerel/trectuples.nim (renamed from tests/compile/trectuples.nim) | 0 | ||||
-rw-r--r-- | tests/typerel/trectype.nim (renamed from tests/reject/trectype.nim) | 0 | ||||
-rw-r--r-- | tests/typerel/trefs.nim (renamed from tests/reject/trefs.nim) | 0 | ||||
-rw-r--r-- | tests/typerel/trettypeinference.nim (renamed from tests/run/trettypeinference.nim) | 0 | ||||
-rw-r--r-- | tests/typerel/tsecondarrayproperty.nim (renamed from tests/compile/tsecondarrayproperty.nim) | 0 | ||||
-rw-r--r-- | tests/typerel/ttuple1.nim (renamed from tests/compile/ttuple1.nim) | 0 | ||||
-rw-r--r-- | tests/typerel/ttypelessemptyset.nim (renamed from tests/reject/ttypelessemptyset.nim) | 0 | ||||
-rw-r--r-- | tests/typerel/ttypenoval.nim (renamed from tests/reject/ttypenoval.nim) | 0 | ||||
-rw-r--r-- | tests/typerel/ttypenovalue.nim (renamed from tests/reject/ttypenovalue.nim) | 0 | ||||
-rw-r--r-- | tests/typerel/tvoid.nim (renamed from tests/compile/tvoid.nim) | 0 | ||||
-rw-r--r-- | tests/typerel/typalias.nim (renamed from tests/compile/typalias.nim) | 0 | ||||
-rw-r--r-- | tests/typerel/typredef.nim (renamed from tests/reject/typredef.nim) | 6 | ||||
-rw-r--r-- | tests/types/tfinalobj.nim (renamed from tests/run/tfinalobj.nim) | 0 | ||||
-rw-r--r-- | tests/types/tforwty.nim (renamed from tests/compile/tforwty.nim) | 0 | ||||
-rw-r--r-- | tests/types/tforwty2.nim (renamed from tests/compile/tforwty2.nim) | 0 | ||||
-rw-r--r-- | tests/types/tillegaltyperecursion.nim (renamed from tests/reject/tillegaltyperecursion.nim) | 0 | ||||
-rw-r--r-- | tests/types/tillrec.nim (renamed from tests/reject/tillrec.nim) | 19 | ||||
-rw-r--r-- | tests/types/tinheritref.nim (renamed from tests/compile/tinheritref.nim) | 0 | ||||
-rw-r--r-- | tests/types/tisop.nim (renamed from tests/compile/tisop.nim) | 0 | ||||
-rw-r--r-- | tests/types/tisopr.nim (renamed from tests/run/tisopr.nim) | 0 | ||||
-rw-r--r-- | tests/usingstmt/tusingstatement.nim (renamed from tests/run/tusingstatement.nim) | 24 | ||||
-rw-r--r-- | tests/varres/tvarres1.nim (renamed from tests/reject/tvarres1.nim) | 0 | ||||
-rw-r--r-- | tests/varres/tvarres2.nim (renamed from tests/reject/tvarres2.nim) | 0 | ||||
-rw-r--r-- | tests/varres/tvarres3.nim (renamed from tests/run/tvarres1.nim) | 0 | ||||
-rw-r--r-- | tests/varres/tvarres4.nim (renamed from tests/run/tvarres2.nim) | 0 | ||||
-rw-r--r-- | tests/varres/tvartup.nim (renamed from tests/run/tvartup.nim) | 0 | ||||
-rw-r--r-- | tests/varstmt/tlet.nim (renamed from tests/run/tlet.nim) | 0 | ||||
-rw-r--r-- | tests/varstmt/tvardecl.nim (renamed from tests/run/tvardecl.nim) | 0 | ||||
-rw-r--r-- | tests/vm/tconsteval.nim (renamed from tests/compile/tconsteval.nim) | 0 | ||||
-rw-r--r-- | tests/vm/teval1.nim (renamed from tests/compile/teval1.nim) | 0 | ||||
-rw-r--r-- | tests/vm/tslurp.nim (renamed from tests/compile/tslurp.nim) | 0 | ||||
-rw-r--r-- | tests/vm/twrongconst.nim (renamed from tests/reject/twrongconst.nim) | 4 | ||||
-rw-r--r-- | todo.txt | 23 | ||||
-rw-r--r-- | tools/cmerge.nim | 4 | ||||
-rw-r--r-- | tools/detect/detect.nim | 23 | ||||
-rw-r--r-- | tools/detect/linux_amd64_consts.nim | 631 | ||||
-rw-r--r-- | tools/detect/macosx_consts.nim | 629 | ||||
-rw-r--r-- | tools/detect/windows_amd64_consts.nim | 152 | ||||
-rw-r--r-- | tools/detect/windows_i386_consts.nim | 96 | ||||
-rw-r--r-- | tools/nimgrep.nim | 6 | ||||
-rw-r--r-- | tools/niminst/buildbat.tmpl | 2 | ||||
-rw-r--r-- | tools/niminst/buildsh.tmpl | 2 | ||||
-rw-r--r-- | tools/niminst/debcreation.nim | 2 | ||||
-rw-r--r-- | tools/niminst/deinstall.tmpl | 2 | ||||
-rw-r--r-- | tools/niminst/inno.tmpl | 2 | ||||
-rw-r--r-- | tools/niminst/install.tmpl | 2 | ||||
-rw-r--r-- | tools/niminst/niminst.nim | 24 | ||||
-rw-r--r-- | tools/nimweb.nim | 22 | ||||
-rw-r--r-- | web/news.txt | 29 | ||||
-rw-r--r-- | web/nimrod.ini | 2 |
713 files changed, 19472 insertions, 10684 deletions
diff --git a/compiler/aliases.nim b/compiler/aliases.nim index 7accb8ce3..5be7b5f12 100644 --- a/compiler/aliases.nim +++ b/compiler/aliases.nim @@ -42,7 +42,7 @@ proc isPartOfAux(n: PNode, b: PType, marker: var TIntSet): TAnalysisResult = proc isPartOfAux(a, b: PType, marker: var TIntSet): TAnalysisResult = result = arNo if a == nil or b == nil: return - if ContainsOrIncl(marker, a.id): return + if containsOrIncl(marker, a.id): return if compareTypes(a, b, dcEqIgnoreDistinct): return arYes case a.kind of tyObject: @@ -58,7 +58,7 @@ proc isPartOfAux(a, b: PType, marker: var TIntSet): TAnalysisResult = proc isPartOf(a, b: PType): TAnalysisResult = ## checks iff 'a' can be part of 'b'. Iterates over VALUE types! - var marker = InitIntSet() + var marker = initIntSet() # watch out: parameters reversed because I'm too lazy to change the code... result = isPartOfAux(b, a, marker) @@ -115,7 +115,7 @@ proc isPartOf*(a, b: PNode): TAnalysisResult = var x = if a[1].kind == nkHiddenStdConv: a[1][1] else: a[1] var y = if b[1].kind == nkHiddenStdConv: b[1][1] else: b[1] - if SameValue(x, y): result = arYes + if sameValue(x, y): result = arYes else: result = arNo # else: maybe and no are accurate else: diff --git a/compiler/ast.nim b/compiler/ast.nim index 0790df0c4..1d356b6d8 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -192,6 +192,7 @@ type nkObjectTy, # object body nkTupleTy, # tuple body nkTypeClassTy, # user-defined type class + nkStaticTy, # ``static[T]`` nkRecList, # list of object parts nkRecCase, # case section of object nkRecWhen, # when section of object @@ -336,19 +337,38 @@ type tyIter, # unused tyProxy # used as errornous type (for idetools) tyTypeClass - tyAnd - tyOr - tyNot - tyAnything tyParametricTypeClass # structured similarly to tyGenericInst # lastSon is the body of the type class + + tyBuiltInTypeClass # Type such as the catch-all object, tuple, seq, etc + + tyCompositeTypeClass # + + tyAnd, tyOr, tyNot # boolean type classes such as `string|int`,`not seq`, + # `Sortable and Enumable`, etc + + tyAnything # a type class matching any type + + tyStatic # a value known at compile type (the underlying type is .base) + + tyFromExpr # This is a type representing an expression that depends + # on generic parameters (the exprsesion is stored in t.n) + # It will be converted to a real type only during generic + # instantiation and prior to this it has the potential to + # be any type. const tyPureObject* = tyTuple GcTypeKinds* = {tyRef, tySequence, tyString} tyError* = tyProxy # as an errornous node should match everything - tyTypeClasses* = {tyTypeClass, tyParametricTypeClass, tyAnd, tyOr, tyNot, tyAnything} + tyUnknownTypes* = {tyError, tyFromExpr} + + tyTypeClasses* = {tyTypeClass, tyBuiltInTypeClass, tyCompositeTypeClass, + tyParametricTypeClass, tyAnd, tyOr, tyNot, tyAnything} + + tyMetaTypes* = {tyGenericParam, tyTypeDesc, tyStatic, tyExpr} + tyTypeClasses + type TTypeKinds* = set[TTypeKind] @@ -364,6 +384,7 @@ type nfSem # node has been checked for semantics nfDelegate # the call can use a delegator nfExprCall # this is an attempt to call a regular expression + nfIsRef # this node is a 'ref' node; used for the VM TNodeFlags* = set[TNodeFlag] TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 23) @@ -382,9 +403,6 @@ type # proc foo(T: typedesc, list: seq[T]): var T tfRetType, # marks return types in proc (used to detect type classes # used as return types for return type inference) - tfAll, # type class requires all constraints to be met (default) - tfAny, # type class requires any constraint to be met - tfNot, # type class with a negative check tfCapturesEnv, # whether proc really captures some environment tfByCopy, # pass object/tuple by copy (C backend) tfByRef, # pass object/tuple by reference (C backend) @@ -395,8 +413,12 @@ type tfNeedsInit, # type constains a "not nil" constraint somewhere or some # other type so that it requires inititalization tfHasShared, # type constains a "shared" constraint modifier somewhere - tfHasMeta, # type has "typedesc" or "expr" somewhere; or uses '|' + tfHasMeta, # type contains "wildcard" sub-types such as generic params + # or other type classes tfHasGCedMem, # type contains GC'ed memory + tfHasStatic + tfGenericTypeParam + tfImplicitTypeParam TTypeFlags* = set[TTypeFlag] @@ -545,11 +567,11 @@ type typ*: PType info*: TLineInfo flags*: TNodeFlags - case Kind*: TNodeKind + case kind*: TNodeKind of nkCharLit..nkUInt64Lit: - intVal*: biggestInt + intVal*: BiggestInt of nkFloatLit..nkFloat128Lit: - floatVal*: biggestFloat + floatVal*: BiggestFloat of nkStrLit..nkTripleStrLit: strVal*: string of nkSym: @@ -773,9 +795,11 @@ const GenericTypes*: TTypeKinds = {tyGenericInvokation, tyGenericBody, tyGenericParam} + StructuralEquivTypes*: TTypeKinds = {tyArrayConstr, tyNil, tyTuple, tyArray, tySet, tyRange, tyPtr, tyRef, tyVar, tySequence, tyProc, tyOpenArray, tyVarargs} + ConcreteTypes*: TTypeKinds = { # types of the expr that may occur in:: # var x = expr tyBool, tyChar, tyEnum, tyArray, tyObject, @@ -792,7 +816,7 @@ const ExportableSymKinds* = {skVar, skConst, skProc, skMethod, skType, skIterator, skMacro, skTemplate, skConverter, skEnumField, skLet, skStub} PersistentNodeFlags*: TNodeFlags = {nfBase2, nfBase8, nfBase16, - nfAllConst, nfDelegate} + nfAllConst, nfDelegate, nfIsRef} namePos* = 0 patternPos* = 1 # empty except for term rewriting macros genericParamsPos* = 2 @@ -821,7 +845,7 @@ const # imported via 'importc: "fullname"' and no format string. # creator procs: -proc newSym*(symKind: TSymKind, Name: PIdent, owner: PSym, +proc newSym*(symKind: TSymKind, name: PIdent, owner: PSym, info: TLineInfo): PSym proc newType*(kind: TTypeKind, owner: PSym): PType proc newNode*(kind: TNodeKind): PNode @@ -894,6 +918,9 @@ template `{}=`*(n: PNode, i: int, s: PNode): stmt = var emptyNode* = newNode(nkEmpty) # There is a single empty node that is shared! Do not overwrite it! +proc isMetaType*(t: PType): bool = + return t.kind in tyMetaTypes or tfHasMeta in t.flags + proc linkTo*(t: PType, s: PSym): PType {.discardable.} = t.sym = s s.typ = t @@ -910,7 +937,7 @@ template fileIdx*(c: PSym): int32 = template filename*(c: PSym): string = # XXX: this should be used only on module symbols - c.position.int32.toFileName + c.position.int32.toFilename proc appendToModule*(m: PSym, n: PNode) = ## The compiler will use this internally to add nodes that will be @@ -929,7 +956,7 @@ const # for all kind of hash tables: proc copyStrTable(dest: var TStrTable, src: TStrTable) = dest.counter = src.counter if isNil(src.data): return - setlen(dest.data, len(src.data)) + setLen(dest.data, len(src.data)) for i in countup(0, high(src.data)): dest.data[i] = src.data[i] proc copyIdTable(dest: var TIdTable, src: TIdTable) = @@ -941,13 +968,13 @@ proc copyIdTable(dest: var TIdTable, src: TIdTable) = proc copyTable(dest: var TTable, src: TTable) = dest.counter = src.counter if isNil(src.data): return - setlen(dest.data, len(src.data)) + setLen(dest.data, len(src.data)) for i in countup(0, high(src.data)): dest.data[i] = src.data[i] proc copyObjectSet(dest: var TObjectSet, src: TObjectSet) = dest.counter = src.counter if isNil(src.data): return - setlen(dest.data, len(src.data)) + setLen(dest.data, len(src.data)) for i in countup(0, high(src.data)): dest.data[i] = src.data[i] proc discardSons(father: PNode) = @@ -1067,7 +1094,7 @@ proc newProcNode*(kind: TNodeKind, info: TLineInfo, body: PNode, pragmas, exceptions, body] -proc NewType(kind: TTypeKind, owner: PSym): PType = +proc newType(kind: TTypeKind, owner: PSym): PType = new(result) result.kind = kind result.owner = owner @@ -1107,7 +1134,7 @@ proc assignType(dest, src: PType) = for i in countup(0, sonsLen(src) - 1): dest.sons[i] = src.sons[i] proc copyType(t: PType, owner: PSym, keepId: bool): PType = - result = newType(t.Kind, owner) + result = newType(t.kind, owner) assignType(result, t) if keepId: result.id = t.id @@ -1147,12 +1174,12 @@ proc createModuleAlias*(s: PSym, newIdent: PIdent, info: TLineInfo): PSym = # XXX once usedGenerics is used, ensure module aliases keep working! assert s.usedGenerics == nil -proc newSym(symKind: TSymKind, Name: PIdent, owner: PSym, +proc newSym(symKind: TSymKind, name: PIdent, owner: PSym, info: TLineInfo): PSym = # generates a symbol and initializes the hash field too new(result) - result.Name = Name - result.Kind = symKind + result.name = name + result.kind = symKind result.flags = {} result.info = info result.options = gOptions @@ -1160,36 +1187,36 @@ proc newSym(symKind: TSymKind, Name: PIdent, owner: PSym, result.offset = - 1 result.id = getID() when debugIds: - RegisterId(result) + registerId(result) #if result.id < 2000: # MessageOut(name.s & " has id: " & toString(result.id)) proc initStrTable(x: var TStrTable) = x.counter = 0 - newSeq(x.data, startSize) + newSeq(x.data, StartSize) proc newStrTable*: TStrTable = initStrTable(result) proc initTable(x: var TTable) = x.counter = 0 - newSeq(x.data, startSize) + newSeq(x.data, StartSize) proc initIdTable(x: var TIdTable) = x.counter = 0 - newSeq(x.data, startSize) + newSeq(x.data, StartSize) proc initObjectSet(x: var TObjectSet) = x.counter = 0 - newSeq(x.data, startSize) + newSeq(x.data, StartSize) proc initIdNodeTable(x: var TIdNodeTable) = x.counter = 0 - newSeq(x.data, startSize) + newSeq(x.data, StartSize) proc initNodeTable(x: var TNodeTable) = x.counter = 0 - newSeq(x.data, startSize) + newSeq(x.data, StartSize) proc sonsLen(n: PType): int = if isNil(n.sons): result = 0 @@ -1203,7 +1230,7 @@ proc newSons(father: PType, length: int) = if isNil(father.sons): newSeq(father.sons, length) else: - setlen(father.sons, length) + setLen(father.sons, length) proc sonsLen(n: PNode): int = if isNil(n.sons): result = 0 @@ -1213,12 +1240,16 @@ proc newSons(father: PNode, length: int) = if isNil(father.sons): newSeq(father.sons, length) else: - setlen(father.sons, length) + setLen(father.sons, length) + +proc skipTypes*(t: PType, kinds: TTypeKinds): PType = + result = t + while result.kind in kinds: result = lastSon(result) proc propagateToOwner*(owner, elem: PType) = const HaveTheirOwnEmpty = {tySequence, tySet} owner.flags = owner.flags + (elem.flags * {tfHasShared, tfHasMeta, - tfHasGCedMem}) + tfHasStatic, tfHasGCedMem}) if tfNotNil in elem.flags: if owner.kind in {tyGenericInst, tyGenericBody, tyGenericInvokation}: owner.flags.incl tfNotNil @@ -1231,10 +1262,14 @@ proc propagateToOwner*(owner, elem: PType) = if tfShared in elem.flags: owner.flags.incl tfHasShared - - if elem.kind in {tyExpr, tyTypeDesc}: + + if elem.kind in tyMetaTypes: owner.flags.incl tfHasMeta - elif elem.kind in {tyString, tyRef, tySequence} or + + if elem.kind == tyStatic: + owner.flags.incl tfHasStatic + + if elem.kind in {tyString, tyRef, tySequence} or elem.kind == tyProc and elem.callConv == ccClosure: owner.flags.incl tfHasGCedMem @@ -1256,7 +1291,7 @@ proc delSon(father: PNode, idx: int) = if isNil(father.sons): return var length = sonsLen(father) for i in countup(idx, length - 2): father.sons[i] = father.sons[i + 1] - setlen(father.sons, length - 1) + setLen(father.sons, length - 1) proc copyNode(src: PNode): PNode = # does not copy its sons! @@ -1269,13 +1304,13 @@ proc copyNode(src: PNode): PNode = when defined(useNodeIds): if result.id == nodeIdToDebug: echo "COMES FROM ", src.id - case src.Kind + case src.kind of nkCharLit..nkUInt64Lit: result.intVal = src.intVal of nkFloatLit..nkFloat128Lit: result.floatVal = src.floatVal of nkSym: result.sym = src.sym of nkIdent: result.ident = src.ident of nkStrLit..nkTripleStrLit: result.strVal = src.strVal - else: nil + else: discard proc shallowCopy*(src: PNode): PNode = # does not copy its sons, but provides space for them: @@ -1287,7 +1322,7 @@ proc shallowCopy*(src: PNode): PNode = when defined(useNodeIds): if result.id == nodeIdToDebug: echo "COMES FROM ", src.id - case src.Kind + case src.kind of nkCharLit..nkUInt64Lit: result.intVal = src.intVal of nkFloatLit..nkFloat128Lit: result.floatVal = src.floatVal of nkSym: result.sym = src.sym @@ -1306,7 +1341,7 @@ proc copyTree(src: PNode): PNode = when defined(useNodeIds): if result.id == nodeIdToDebug: echo "COMES FROM ", src.id - case src.Kind + case src.kind of nkCharLit..nkUInt64Lit: result.intVal = src.intVal of nkFloatLit..nkFloat128Lit: result.floatVal = src.floatVal of nkSym: result.sym = src.sym @@ -1364,14 +1399,14 @@ proc sonsNotNil(n: PNode): bool = return false result = true -proc getInt*(a: PNode): biggestInt = +proc getInt*(a: PNode): BiggestInt = case a.kind of nkIntLit..nkUInt64Lit: result = a.intVal else: internalError(a.info, "getInt") result = 0 -proc getFloat*(a: PNode): biggestFloat = +proc getFloat*(a: PNode): BiggestFloat = case a.kind of nkFloatLit..nkFloat128Lit: result = a.floatVal else: @@ -1398,16 +1433,20 @@ proc isGenericRoutine*(s: PSym): bool = of skProcKinds: result = sfFromGeneric in s.flags or (s.ast != nil and s.ast[genericParamsPos].kind != nkEmpty) - else: nil + else: discard proc skipGenericOwner*(s: PSym): PSym = - InternalAssert s.kind in skProcKinds + internalAssert s.kind in skProcKinds ## Generic instantiations are owned by their originating generic ## symbol. This proc skips such owners and goes straigh to the owner ## of the generic itself (the module or the enclosing proc). result = if sfFromGeneric in s.flags: s.owner.owner else: s.owner +proc originatingModule*(s: PSym): PSym = + result = s.owner + while result.kind != skModule: result = result.owner + proc isRoutine*(s: PSym): bool {.inline.} = result = s.kind in {skProc, skTemplate, skMacro, skIterator, skMethod, skConverter} diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index 6c48dd00f..2505bc687 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -24,35 +24,35 @@ proc symToYaml*(n: PSym, indent: int = 0, maxRecDepth: int = - 1): PRope proc lineInfoToStr*(info: TLineInfo): PRope # ----------------------- node sets: --------------------------------------- -proc ObjectSetContains*(t: TObjectSet, obj: PObject): bool +proc objectSetContains*(t: TObjectSet, obj: PObject): bool # returns true whether n is in t -proc ObjectSetIncl*(t: var TObjectSet, obj: PObject) +proc objectSetIncl*(t: var TObjectSet, obj: PObject) # include an element n in the table t -proc ObjectSetContainsOrIncl*(t: var TObjectSet, obj: PObject): bool +proc objectSetContainsOrIncl*(t: var TObjectSet, obj: PObject): bool # more are not needed ... # ----------------------- (key, val)-Hashtables ---------------------------- -proc TablePut*(t: var TTable, key, val: PObject) -proc TableGet*(t: TTable, key: PObject): PObject +proc tablePut*(t: var TTable, key, val: PObject) +proc tableGet*(t: TTable, key: PObject): PObject type TCmpProc* = proc (key, closure: PObject): bool {.nimcall.} # true if found -proc TableSearch*(t: TTable, key, closure: PObject, +proc tableSearch*(t: TTable, key, closure: PObject, comparator: TCmpProc): PObject # return val as soon as comparator returns true; if this never happens, # nil is returned # ----------------------- str table ----------------------------------------- -proc StrTableContains*(t: TStrTable, n: PSym): bool -proc StrTableAdd*(t: var TStrTable, n: PSym) -proc StrTableGet*(t: TStrTable, name: PIdent): PSym +proc strTableContains*(t: TStrTable, n: PSym): bool +proc strTableAdd*(t: var TStrTable, n: PSym) +proc strTableGet*(t: TStrTable, name: PIdent): PSym type TTabIter*{.final.} = object # consider all fields here private h*: THash # current hash -proc InitTabIter*(ti: var TTabIter, tab: TStrTable): PSym -proc NextIter*(ti: var TTabIter, tab: TStrTable): PSym +proc initTabIter*(ti: var TTabIter, tab: TStrTable): PSym +proc nextIter*(ti: var TTabIter, tab: TStrTable): PSym # usage: # var # i: TTabIter @@ -69,8 +69,8 @@ type name*: PIdent -proc InitIdentIter*(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym -proc NextIdentIter*(ti: var TIdentIter, tab: TStrTable): PSym +proc initIdentIter*(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym +proc nextIdentIter*(ti: var TIdentIter, tab: TStrTable): PSym # these are for debugging only: They are not really deprecated, but I want # the warning so that release versions do not contain debugging statements: @@ -79,15 +79,14 @@ proc debug*(n: PType) {.deprecated.} proc debug*(n: PNode) {.deprecated.} # --------------------------- ident tables ---------------------------------- -proc IdTableGet*(t: TIdTable, key: PIdObj): PObject -proc IdTableGet*(t: TIdTable, key: int): PObject -proc IdTablePut*(t: var TIdTable, key: PIdObj, val: PObject) -proc IdTableHasObjectAsKey*(t: TIdTable, key: PIdObj): bool +proc idTableGet*(t: TIdTable, key: PIdObj): PObject +proc idTableGet*(t: TIdTable, key: int): PObject +proc idTablePut*(t: var TIdTable, key: PIdObj, val: PObject) +proc idTableHasObjectAsKey*(t: TIdTable, key: PIdObj): bool # checks if `t` contains the `key` (compared by the pointer value, not only # `key`'s id) -proc IdNodeTableGet*(t: TIdNodeTable, key: PIdObj): PNode -proc IdNodeTablePut*(t: var TIdNodeTable, key: PIdObj, val: PNode) -proc writeIdNodeTable*(t: TIdNodeTable) +proc idNodeTableGet*(t: TIdNodeTable, key: PIdObj): PNode +proc idNodeTablePut*(t: var TIdNodeTable, key: PIdObj, val: PNode) # --------------------------------------------------------------------------- @@ -111,9 +110,9 @@ type data*: TIIPairSeq -proc initIITable*(x: var TIITable) -proc IITableGet*(t: TIITable, key: int): int -proc IITablePut*(t: var TIITable, key, val: int) +proc initIiTable*(x: var TIITable) +proc iiTableGet*(t: TIITable, key: int): int +proc iiTablePut*(t: var TIITable, key, val: int) # implementation @@ -129,7 +128,7 @@ proc skipConvTakeType*(n: PNode): PNode = result = n.skipConv result.typ = n.typ -proc SameValue*(a, b: PNode): bool = +proc sameValue*(a, b: PNode): bool = result = false case a.kind of nkCharLit..nkInt64Lit: @@ -141,7 +140,7 @@ proc SameValue*(a, b: PNode): bool = else: # don't raise an internal error for 'nimrod check': #InternalError(a.info, "SameValue") - nil + discard proc leValue*(a, b: PNode): bool = # a <= b? @@ -156,7 +155,7 @@ proc leValue*(a, b: PNode): bool = else: # don't raise an internal error for 'nimrod check': #InternalError(a.info, "leValue") - nil + discard proc lookupInRecord(n: PNode, field: PIdent): PSym = result = nil @@ -166,7 +165,7 @@ proc lookupInRecord(n: PNode, field: PIdent): PSym = result = lookupInRecord(n.sons[i], field) if result != nil: return of nkRecCase: - if (n.sons[0].kind != nkSym): InternalError(n.info, "lookupInRecord") + if (n.sons[0].kind != nkSym): internalError(n.info, "lookupInRecord") result = lookupInRecord(n.sons[0], field) if result != nil: return for i in countup(1, sonsLen(n) - 1): @@ -182,14 +181,14 @@ proc lookupInRecord(n: PNode, field: PIdent): PSym = proc getModule(s: PSym): PSym = result = s assert((result.kind == skModule) or (result.owner != result)) - while (result != nil) and (result.kind != skModule): result = result.owner + while result != nil and result.kind != skModule: result = result.owner proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym = for i in countup(start, sonsLen(list) - 1): if list.sons[i].kind == nkSym: result = list.sons[i].sym if result.name.id == ident.id: return - else: InternalError(list.info, "getSymFromList") + else: internalError(list.info, "getSymFromList") result = nil proc hashNode(p: PObject): THash = @@ -203,7 +202,7 @@ proc spaces(x: int): PRope = # returns x spaces result = toRope(repeatChar(x)) -proc toYamlChar(c: Char): string = +proc toYamlChar(c: char): string = case c of '\0'..'\x1F', '\x80'..'\xFF': result = "\\u" & strutils.toHex(ord(c), 4) of '\'', '\"', '\\': result = '\\' & c @@ -216,7 +215,7 @@ proc makeYamlString*(s: string): PRope = const MaxLineLength = 64 result = nil var res = "\"" - for i in countup(0, len(s) - 1): + for i in countup(0, if s.isNil: -1 else: (len(s)-1)): if (i + 1) mod MaxLineLength == 0: add(res, '\"') add(res, "\n") @@ -262,7 +261,7 @@ proc strTableToYaml(n: TStrTable, marker: var TIntSet, indent: int, app(result, "]") assert(mycount == n.counter) -proc ropeConstr(indent: int, c: openarray[PRope]): PRope = +proc ropeConstr(indent: int, c: openArray[PRope]): PRope = # array of (name, value) pairs var istr = spaces(indent + 2) result = toRope("{") @@ -277,7 +276,7 @@ proc symToYamlAux(n: PSym, marker: var TIntSet, indent: int, maxRecDepth: int): PRope = if n == nil: result = toRope("null") - elif ContainsOrIncl(marker, n.id): + elif containsOrIncl(marker, n.id): result = ropef("\"$1 @$2\"", [toRope(n.name.s), toRope( strutils.toHex(cast[TAddress](n), sizeof(n) * 2))]) else: @@ -298,7 +297,7 @@ proc typeToYamlAux(n: PType, marker: var TIntSet, indent: int, maxRecDepth: int): PRope = if n == nil: result = toRope("null") - elif ContainsOrIncl(marker, n.id): + elif containsOrIncl(marker, n.id): result = ropef("\"$1 @$2\"", [toRope($n.kind), toRope( strutils.toHex(cast[TAddress](n), sizeof(n) * 2))]) else: @@ -315,7 +314,7 @@ proc typeToYamlAux(n: PType, marker: var TIntSet, indent: int, makeYamlString($n.kind), toRope("sym"), symToYamlAux(n.sym, marker, indent + 2, maxRecDepth - 1), toRope("n"), treeToYamlAux(n.n, marker, - indent + 2, maxRecDepth - 1), toRope("flags"), FlagsToStr(n.flags), + indent + 2, maxRecDepth - 1), toRope("flags"), flagsToStr(n.flags), toRope("callconv"), makeYamlString(CallingConvToStr[n.callConv]), toRope("size"), toRope(n.size), @@ -336,7 +335,7 @@ proc treeToYamlAux(n: PNode, marker: var TIntSet, indent: int, appf(result, ",$N$1\"intVal\": $2", [istr, toRope(n.intVal)]) of nkFloatLit, nkFloat32Lit, nkFloat64Lit: appf(result, ",$N$1\"floatVal\": $2", - [istr, toRope(n.floatVal.ToStrMaxPrecision)]) + [istr, toRope(n.floatVal.toStrMaxPrecision)]) of nkStrLit..nkTripleStrLit: appf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)]) of nkSym: @@ -360,15 +359,15 @@ proc treeToYamlAux(n: PNode, marker: var TIntSet, indent: int, appf(result, "$N$1}", [spaces(indent)]) proc treeToYaml(n: PNode, indent: int = 0, maxRecDepth: int = - 1): PRope = - var marker = InitIntSet() + var marker = initIntSet() result = treeToYamlAux(n, marker, indent, maxRecDepth) proc typeToYaml(n: PType, indent: int = 0, maxRecDepth: int = - 1): PRope = - var marker = InitIntSet() + var marker = initIntSet() result = typeToYamlAux(n, marker, indent, maxRecDepth) proc symToYaml(n: PSym, indent: int = 0, maxRecDepth: int = - 1): PRope = - var marker = InitIntSet() + var marker = initIntSet() result = symToYamlAux(n, marker, indent, maxRecDepth) proc debugTree(n: PNode, indent: int, maxRecDepth: int): PRope @@ -406,7 +405,7 @@ proc debugTree(n: PNode, indent: int, maxRecDepth: int): PRope = appf(result, ",$N$1\"intVal\": $2", [istr, toRope(n.intVal)]) of nkFloatLit, nkFloat32Lit, nkFloat64Lit: appf(result, ",$N$1\"floatVal\": $2", - [istr, toRope(n.floatVal.ToStrMaxPrecision)]) + [istr, toRope(n.floatVal.toStrMaxPrecision)]) of nkStrLit..nkTripleStrLit: appf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)]) of nkSym: @@ -433,6 +432,8 @@ proc debugTree(n: PNode, indent: int, maxRecDepth: int): PRope = proc debug(n: PSym) = if n == nil: writeln(stdout, "null") + elif n.kind == skUnknown: + writeln(stdout, "skUnknown") else: #writeln(stdout, ropeToStr(symToYaml(n, 0, 1))) writeln(stdout, ropeToStr(ropef("$1_$2: $3, $4", [ @@ -454,18 +455,18 @@ proc nextTry(h, maxHash: THash): THash = # generates each int in range(maxHash) exactly once (see any text on # random-number generation for proof). -proc objectSetContains(t: TObjectSet, obj: PObject): bool = +proc objectSetContains(t: TObjectSet, obj: PObject): bool = # returns true whether n is in t var h: THash = hashNode(obj) and high(t.data) # start with real hash value - while t.data[h] != nil: - if (t.data[h] == obj): + while t.data[h] != nil: + if t.data[h] == obj: return true h = nextTry(h, high(t.data)) result = false -proc objectSetRawInsert(data: var TObjectSeq, obj: PObject) = - var h: THash = HashNode(obj) and high(data) - while data[h] != nil: +proc objectSetRawInsert(data: var TObjectSeq, obj: PObject) = + var h: THash = hashNode(obj) and high(data) + while data[h] != nil: assert(data[h] != obj) h = nextTry(h, high(data)) assert(data[h] == nil) @@ -473,8 +474,8 @@ proc objectSetRawInsert(data: var TObjectSeq, obj: PObject) = proc objectSetEnlarge(t: var TObjectSet) = var n: TObjectSeq - newSeq(n, len(t.data) * growthFactor) - for i in countup(0, high(t.data)): + newSeq(n, len(t.data) * GrowthFactor) + for i in countup(0, high(t.data)): if t.data[i] != nil: objectSetRawInsert(n, t.data[i]) swap(t.data, n) @@ -485,7 +486,7 @@ proc objectSetIncl(t: var TObjectSet, obj: PObject) = proc objectSetContainsOrIncl(t: var TObjectSet, obj: PObject): bool = # returns true if obj is already in the string table: - var h: THash = HashNode(obj) and high(t.data) + var h: THash = hashNode(obj) and high(t.data) while true: var it = t.data[h] if it == nil: break @@ -501,7 +502,7 @@ proc objectSetContainsOrIncl(t: var TObjectSet, obj: PObject): bool = inc(t.counter) result = false -proc TableRawGet(t: TTable, key: PObject): int = +proc tableRawGet(t: TTable, key: PObject): int = var h: THash = hashNode(key) and high(t.data) # start with real hash value while t.data[h].key != nil: if t.data[h].key == key: @@ -509,7 +510,7 @@ proc TableRawGet(t: TTable, key: PObject): int = h = nextTry(h, high(t.data)) result = -1 -proc TableSearch(t: TTable, key, closure: PObject, +proc tableSearch(t: TTable, key, closure: PObject, comparator: TCmpProc): PObject = var h: THash = hashNode(key) and high(t.data) # start with real hash value while t.data[h].key != nil: @@ -520,13 +521,13 @@ proc TableSearch(t: TTable, key, closure: PObject, h = nextTry(h, high(t.data)) result = nil -proc TableGet(t: TTable, key: PObject): PObject = - var index = TableRawGet(t, key) +proc tableGet(t: TTable, key: PObject): PObject = + var index = tableRawGet(t, key) if index >= 0: result = t.data[index].val else: result = nil -proc TableRawInsert(data: var TPairSeq, key, val: PObject) = - var h: THash = HashNode(key) and high(data) +proc tableRawInsert(data: var TPairSeq, key, val: PObject) = + var h: THash = hashNode(key) and high(data) while data[h].key != nil: assert(data[h].key != key) h = nextTry(h, high(data)) @@ -534,23 +535,23 @@ proc TableRawInsert(data: var TPairSeq, key, val: PObject) = data[h].key = key data[h].val = val -proc TableEnlarge(t: var TTable) = +proc tableEnlarge(t: var TTable) = var n: TPairSeq - newSeq(n, len(t.data) * growthFactor) + newSeq(n, len(t.data) * GrowthFactor) for i in countup(0, high(t.data)): - if t.data[i].key != nil: TableRawInsert(n, t.data[i].key, t.data[i].val) + if t.data[i].key != nil: tableRawInsert(n, t.data[i].key, t.data[i].val) swap(t.data, n) -proc TablePut(t: var TTable, key, val: PObject) = - var index = TableRawGet(t, key) +proc tablePut(t: var TTable, key, val: PObject) = + var index = tableRawGet(t, key) if index >= 0: t.data[index].val = val else: - if mustRehash(len(t.data), t.counter): TableEnlarge(t) - TableRawInsert(t.data, key, val) + if mustRehash(len(t.data), t.counter): tableEnlarge(t) + tableRawInsert(t.data, key, val) inc(t.counter) -proc StrTableContains(t: TStrTable, n: PSym): bool = +proc strTableContains(t: TStrTable, n: PSym): bool = var h: THash = n.name.h and high(t.data) # start with real hash value while t.data[h] != nil: if (t.data[h] == n): @@ -558,7 +559,7 @@ proc StrTableContains(t: TStrTable, n: PSym): bool = h = nextTry(h, high(t.data)) result = false -proc StrTableRawInsert(data: var TSymSeq, n: PSym) = +proc strTableRawInsert(data: var TSymSeq, n: PSym) = var h: THash = n.name.h and high(data) while data[h] != nil: if data[h] == n: @@ -569,7 +570,7 @@ proc StrTableRawInsert(data: var TSymSeq, n: PSym) = assert(data[h] == nil) data[h] = n -proc SymTabReplaceRaw(data: var TSymSeq, prevSym: PSym, newSym: PSym) = +proc symTabReplaceRaw(data: var TSymSeq, prevSym: PSym, newSym: PSym) = assert prevSym.name.h == newSym.name.h var h: THash = prevSym.name.h and high(data) while data[h] != nil: @@ -579,22 +580,22 @@ proc SymTabReplaceRaw(data: var TSymSeq, prevSym: PSym, newSym: PSym) = h = nextTry(h, high(data)) assert false -proc SymTabReplace*(t: var TStrTable, prevSym: PSym, newSym: PSym) = - SymTabReplaceRaw(t.data, prevSym, newSym) +proc symTabReplace*(t: var TStrTable, prevSym: PSym, newSym: PSym) = + symTabReplaceRaw(t.data, prevSym, newSym) -proc StrTableEnlarge(t: var TStrTable) = +proc strTableEnlarge(t: var TStrTable) = var n: TSymSeq - newSeq(n, len(t.data) * growthFactor) + newSeq(n, len(t.data) * GrowthFactor) for i in countup(0, high(t.data)): - if t.data[i] != nil: StrTableRawInsert(n, t.data[i]) + if t.data[i] != nil: strTableRawInsert(n, t.data[i]) swap(t.data, n) -proc StrTableAdd(t: var TStrTable, n: PSym) = - if mustRehash(len(t.data), t.counter): StrTableEnlarge(t) - StrTableRawInsert(t.data, n) +proc strTableAdd(t: var TStrTable, n: PSym) = + if mustRehash(len(t.data), t.counter): strTableEnlarge(t) + strTableRawInsert(t.data, n) inc(t.counter) -proc StrTableIncl*(t: var TStrTable, n: PSym): bool {.discardable.} = +proc strTableIncl*(t: var TStrTable, n: PSym): bool {.discardable.} = # returns true if n is already in the string table: # It is essential that `n` is written nevertheless! # This way the newest redefinition is picked by the semantic analyses! @@ -608,15 +609,15 @@ proc StrTableIncl*(t: var TStrTable, n: PSym): bool {.discardable.} = return true # found it h = nextTry(h, high(t.data)) if mustRehash(len(t.data), t.counter): - StrTableEnlarge(t) - StrTableRawInsert(t.data, n) + strTableEnlarge(t) + strTableRawInsert(t.data, n) else: assert(t.data[h] == nil) t.data[h] = n inc(t.counter) result = false -proc StrTableGet(t: TStrTable, name: PIdent): PSym = +proc strTableGet(t: TStrTable, name: PIdent): PSym = var h: THash = name.h and high(t.data) while true: result = t.data[h] @@ -624,19 +625,19 @@ proc StrTableGet(t: TStrTable, name: PIdent): PSym = if result.name.id == name.id: break h = nextTry(h, high(t.data)) -proc InitIdentIter(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym = +proc initIdentIter(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym = ti.h = s.h ti.name = s - if tab.Counter == 0: result = nil - else: result = NextIdentIter(ti, tab) + if tab.counter == 0: result = nil + else: result = nextIdentIter(ti, tab) -proc NextIdentIter(ti: var TIdentIter, tab: TStrTable): PSym = +proc nextIdentIter(ti: var TIdentIter, tab: TStrTable): PSym = var h, start: THash h = ti.h and high(tab.data) start = h result = tab.data[h] while result != nil: - if result.Name.id == ti.name.id: break + if result.name.id == ti.name.id: break h = nextTry(h, high(tab.data)) if h == start: result = nil @@ -644,13 +645,13 @@ proc NextIdentIter(ti: var TIdentIter, tab: TStrTable): PSym = result = tab.data[h] ti.h = nextTry(h, high(tab.data)) -proc NextIdentExcluding*(ti: var TIdentIter, tab: TStrTable, +proc nextIdentExcluding*(ti: var TIdentIter, tab: TStrTable, excluding: TIntSet): PSym = var h: THash = ti.h and high(tab.data) var start = h result = tab.data[h] while result != nil: - if result.Name.id == ti.name.id and not Contains(excluding, result.id): + if result.name.id == ti.name.id and not contains(excluding, result.id): break h = nextTry(h, high(tab.data)) if h == start: @@ -658,35 +659,35 @@ proc NextIdentExcluding*(ti: var TIdentIter, tab: TStrTable, break result = tab.data[h] ti.h = nextTry(h, high(tab.data)) - if result != nil and Contains(excluding, result.id): result = nil + if result != nil and contains(excluding, result.id): result = nil -proc FirstIdentExcluding*(ti: var TIdentIter, tab: TStrTable, s: PIdent, +proc firstIdentExcluding*(ti: var TIdentIter, tab: TStrTable, s: PIdent, excluding: TIntSet): PSym = ti.h = s.h ti.name = s - if tab.Counter == 0: result = nil - else: result = NextIdentExcluding(ti, tab, excluding) + if tab.counter == 0: result = nil + else: result = nextIdentExcluding(ti, tab, excluding) -proc InitTabIter(ti: var TTabIter, tab: TStrTable): PSym = +proc initTabIter(ti: var TTabIter, tab: TStrTable): PSym = ti.h = 0 # we start by zero ... if tab.counter == 0: result = nil # FIX 1: removed endless loop else: - result = NextIter(ti, tab) + result = nextIter(ti, tab) -proc NextIter(ti: var TTabIter, tab: TStrTable): PSym = +proc nextIter(ti: var TTabIter, tab: TStrTable): PSym = result = nil while (ti.h <= high(tab.data)): result = tab.data[ti.h] - Inc(ti.h) # ... and increment by one always + inc(ti.h) # ... and increment by one always if result != nil: break iterator items*(tab: TStrTable): PSym = var it: TTabIter - var s = InitTabIter(it, tab) + var s = initTabIter(it, tab) while s != nil: yield s - s = NextIter(it, tab) + s = nextIter(it, tab) proc hasEmptySlot(data: TIdPairSeq): bool = for h in countup(0, high(data)): @@ -694,27 +695,27 @@ proc hasEmptySlot(data: TIdPairSeq): bool = return true result = false -proc IdTableRawGet(t: TIdTable, key: int): int = +proc idTableRawGet(t: TIdTable, key: int): int = var h: THash h = key and high(t.data) # start with real hash value while t.data[h].key != nil: - if (t.data[h].key.id == key): + if t.data[h].key.id == key: return h h = nextTry(h, high(t.data)) result = - 1 -proc IdTableHasObjectAsKey(t: TIdTable, key: PIdObj): bool = - var index = IdTableRawGet(t, key.id) +proc idTableHasObjectAsKey(t: TIdTable, key: PIdObj): bool = + var index = idTableRawGet(t, key.id) if index >= 0: result = t.data[index].key == key else: result = false -proc IdTableGet(t: TIdTable, key: PIdObj): PObject = - var index = IdTableRawGet(t, key.id) +proc idTableGet(t: TIdTable, key: PIdObj): PObject = + var index = idTableRawGet(t, key.id) if index >= 0: result = t.data[index].val else: result = nil -proc IdTableGet(t: TIdTable, key: int): PObject = - var index = IdTableRawGet(t, key) +proc idTableGet(t: TIdTable, key: int): PObject = + var index = idTableRawGet(t, key) if index >= 0: result = t.data[index].val else: result = nil @@ -723,7 +724,7 @@ iterator pairs*(t: TIdTable): tuple[key: int, value: PObject] = if t.data[i].key != nil: yield (t.data[i].key.id, t.data[i].val) -proc IdTableRawInsert(data: var TIdPairSeq, key: PIdObj, val: PObject) = +proc idTableRawInsert(data: var TIdPairSeq, key: PIdObj, val: PObject) = var h: THash h = key.id and high(data) while data[h].key != nil: @@ -733,33 +734,30 @@ proc IdTableRawInsert(data: var TIdPairSeq, key: PIdObj, val: PObject) = data[h].key = key data[h].val = val -proc IdTablePut(t: var TIdTable, key: PIdObj, val: PObject) = +proc idTablePut(t: var TIdTable, key: PIdObj, val: PObject) = var index: int n: TIdPairSeq - index = IdTableRawGet(t, key.id) + index = idTableRawGet(t, key.id) if index >= 0: assert(t.data[index].key != nil) t.data[index].val = val else: if mustRehash(len(t.data), t.counter): - newSeq(n, len(t.data) * growthFactor) + newSeq(n, len(t.data) * GrowthFactor) for i in countup(0, high(t.data)): if t.data[i].key != nil: - IdTableRawInsert(n, t.data[i].key, t.data[i].val) + idTableRawInsert(n, t.data[i].key, t.data[i].val) assert(hasEmptySlot(n)) swap(t.data, n) - IdTableRawInsert(t.data, key, val) + idTableRawInsert(t.data, key, val) inc(t.counter) -iterator IdTablePairs*(t: TIdTable): tuple[key: PIdObj, val: PObject] = +iterator idTablePairs*(t: TIdTable): tuple[key: PIdObj, val: PObject] = for i in 0 .. high(t.data): if not isNil(t.data[i].key): yield (t.data[i].key, t.data[i].val) -proc writeIdNodeTable(t: TIdNodeTable) = - nil - -proc IdNodeTableRawGet(t: TIdNodeTable, key: PIdObj): int = +proc idNodeTableRawGet(t: TIdNodeTable, key: PIdObj): int = var h: THash h = key.id and high(t.data) # start with real hash value while t.data[h].key != nil: @@ -768,17 +766,17 @@ proc IdNodeTableRawGet(t: TIdNodeTable, key: PIdObj): int = h = nextTry(h, high(t.data)) result = - 1 -proc IdNodeTableGet(t: TIdNodeTable, key: PIdObj): PNode = +proc idNodeTableGet(t: TIdNodeTable, key: PIdObj): PNode = var index: int - index = IdNodeTableRawGet(t, key) + index = idNodeTableRawGet(t, key) if index >= 0: result = t.data[index].val else: result = nil -proc IdNodeTableGetLazy*(t: TIdNodeTable, key: PIdObj): PNode = +proc idNodeTableGetLazy*(t: TIdNodeTable, key: PIdObj): PNode = if not isNil(t.data): - result = IdNodeTableGet(t, key) + result = idNodeTableGet(t, key) -proc IdNodeTableRawInsert(data: var TIdNodePairSeq, key: PIdObj, val: PNode) = +proc idNodeTableRawInsert(data: var TIdNodePairSeq, key: PIdObj, val: PNode) = var h: THash h = key.id and high(data) while data[h].key != nil: @@ -788,25 +786,25 @@ proc IdNodeTableRawInsert(data: var TIdNodePairSeq, key: PIdObj, val: PNode) = data[h].key = key data[h].val = val -proc IdNodeTablePut(t: var TIdNodeTable, key: PIdObj, val: PNode) = - var index = IdNodeTableRawGet(t, key) +proc idNodeTablePut(t: var TIdNodeTable, key: PIdObj, val: PNode) = + var index = idNodeTableRawGet(t, key) if index >= 0: assert(t.data[index].key != nil) t.data[index].val = val else: if mustRehash(len(t.data), t.counter): var n: TIdNodePairSeq - newSeq(n, len(t.data) * growthFactor) + newSeq(n, len(t.data) * GrowthFactor) for i in countup(0, high(t.data)): if t.data[i].key != nil: - IdNodeTableRawInsert(n, t.data[i].key, t.data[i].val) + idNodeTableRawInsert(n, t.data[i].key, t.data[i].val) swap(t.data, n) - IdNodeTableRawInsert(t.data, key, val) + idNodeTableRawInsert(t.data, key, val) inc(t.counter) -proc IdNodeTablePutLazy*(t: var TIdNodeTable, key: PIdObj, val: PNode) = +proc idNodeTablePutLazy*(t: var TIdNodeTable, key: PIdObj, val: PNode) = if isNil(t.data): initIdNodeTable(t) - IdNodeTablePut(t, key, val) + idNodeTablePut(t, key, val) iterator pairs*(t: TIdNodeTable): tuple[key: PIdObj, val: PNode] = for i in 0 .. high(t.data): @@ -814,24 +812,23 @@ iterator pairs*(t: TIdNodeTable): tuple[key: PIdObj, val: PNode] = proc initIITable(x: var TIITable) = x.counter = 0 - newSeq(x.data, startSize) - for i in countup(0, startSize - 1): x.data[i].key = InvalidKey + newSeq(x.data, StartSize) + for i in countup(0, StartSize - 1): x.data[i].key = InvalidKey -proc IITableRawGet(t: TIITable, key: int): int = +proc iiTableRawGet(t: TIITable, key: int): int = var h: THash h = key and high(t.data) # start with real hash value while t.data[h].key != InvalidKey: - if (t.data[h].key == key): - return h + if t.data[h].key == key: return h h = nextTry(h, high(t.data)) - result = - 1 + result = -1 -proc IITableGet(t: TIITable, key: int): int = - var index = IITableRawGet(t, key) +proc iiTableGet(t: TIITable, key: int): int = + var index = iiTableRawGet(t, key) if index >= 0: result = t.data[index].val else: result = InvalidKey -proc IITableRawInsert(data: var TIIPairSeq, key, val: int) = +proc iiTableRawInsert(data: var TIIPairSeq, key, val: int) = var h: THash h = key and high(data) while data[h].key != InvalidKey: @@ -841,19 +838,19 @@ proc IITableRawInsert(data: var TIIPairSeq, key, val: int) = data[h].key = key data[h].val = val -proc IITablePut(t: var TIITable, key, val: int) = - var index = IITableRawGet(t, key) +proc iiTablePut(t: var TIITable, key, val: int) = + var index = iiTableRawGet(t, key) if index >= 0: assert(t.data[index].key != InvalidKey) t.data[index].val = val else: if mustRehash(len(t.data), t.counter): var n: TIIPairSeq - newSeq(n, len(t.data) * growthFactor) + newSeq(n, len(t.data) * GrowthFactor) for i in countup(0, high(n)): n[i].key = InvalidKey for i in countup(0, high(t.data)): if t.data[i].key != InvalidKey: - IITableRawInsert(n, t.data[i].key, t.data[i].val) + iiTableRawInsert(n, t.data[i].key, t.data[i].val) swap(t.data, n) - IITableRawInsert(t.data, key, val) + iiTableRawInsert(t.data, key, val) inc(t.counter) diff --git a/compiler/babelcmd.nim b/compiler/babelcmd.nim index b67a26040..7fa233732 100644 --- a/compiler/babelcmd.nim +++ b/compiler/babelcmd.nim @@ -13,7 +13,7 @@ import parseutils, strutils, strtabs, os, options, msgs, lists proc addPath*(path: string, info: TLineInfo) = if not contains(options.searchPaths, path): - lists.PrependStr(options.searchPaths, path) + lists.prependStr(options.searchPaths, path) proc versionSplitPos(s: string): int = result = s.len-2 @@ -45,9 +45,9 @@ proc `<.`(a, b: string): bool = proc addPackage(packages: PStringTable, p: string) = let x = versionSplitPos(p) - let name = p.subStr(0, x-1) + let name = p.substr(0, x-1) if x < p.len: - let version = p.subStr(x+1) + let version = p.substr(x+1) if packages[name] <. version: packages[name] = version else: @@ -60,8 +60,8 @@ iterator chosen(packages: PStringTable): string = proc addBabelPath(p: string, info: TLineInfo) = if not contains(options.searchPaths, p): - if gVerbosity >= 1: Message(info, hintPath, p) - lists.PrependStr(options.lazyPaths, p) + if gVerbosity >= 1: message(info, hintPath, p) + lists.prependStr(options.lazyPaths, p) proc addPathWithNimFiles(p: string, info: TLineInfo) = proc hasNimFile(dir: string): bool = diff --git a/compiler/bitsets.nim b/compiler/bitsets.nim index dfb23b06d..740bdd5ef 100644 --- a/compiler/bitsets.nim +++ b/compiler/bitsets.nim @@ -18,53 +18,53 @@ type const ElemSize* = sizeof(int8) * 8 -proc BitSetInit*(b: var TBitSet, length: int) -proc BitSetUnion*(x: var TBitSet, y: TBitSet) -proc BitSetDiff*(x: var TBitSet, y: TBitSet) -proc BitSetSymDiff*(x: var TBitSet, y: TBitSet) -proc BitSetIntersect*(x: var TBitSet, y: TBitSet) -proc BitSetIncl*(x: var TBitSet, elem: BiggestInt) -proc BitSetExcl*(x: var TBitSet, elem: BiggestInt) -proc BitSetIn*(x: TBitSet, e: BiggestInt): bool -proc BitSetEquals*(x, y: TBitSet): bool -proc BitSetContains*(x, y: TBitSet): bool +proc bitSetInit*(b: var TBitSet, length: int) +proc bitSetUnion*(x: var TBitSet, y: TBitSet) +proc bitSetDiff*(x: var TBitSet, y: TBitSet) +proc bitSetSymDiff*(x: var TBitSet, y: TBitSet) +proc bitSetIntersect*(x: var TBitSet, y: TBitSet) +proc bitSetIncl*(x: var TBitSet, elem: BiggestInt) +proc bitSetExcl*(x: var TBitSet, elem: BiggestInt) +proc bitSetIn*(x: TBitSet, e: BiggestInt): bool +proc bitSetEquals*(x, y: TBitSet): bool +proc bitSetContains*(x, y: TBitSet): bool # implementation -proc BitSetIn(x: TBitSet, e: BiggestInt): bool = +proc bitSetIn(x: TBitSet, e: BiggestInt): bool = result = (x[int(e div ElemSize)] and toU8(int(1 shl (e mod ElemSize)))) != toU8(0) -proc BitSetIncl(x: var TBitSet, elem: BiggestInt) = +proc bitSetIncl(x: var TBitSet, elem: BiggestInt) = assert(elem >= 0) x[int(elem div ElemSize)] = x[int(elem div ElemSize)] or toU8(int(1 shl (elem mod ElemSize))) -proc BitSetExcl(x: var TBitSet, elem: BiggestInt) = +proc bitSetExcl(x: var TBitSet, elem: BiggestInt) = x[int(elem div ElemSize)] = x[int(elem div ElemSize)] and not toU8(int(1 shl (elem mod ElemSize))) -proc BitSetInit(b: var TBitSet, length: int) = +proc bitSetInit(b: var TBitSet, length: int) = newSeq(b, length) -proc BitSetUnion(x: var TBitSet, y: TBitSet) = +proc bitSetUnion(x: var TBitSet, y: TBitSet) = for i in countup(0, high(x)): x[i] = x[i] or y[i] -proc BitSetDiff(x: var TBitSet, y: TBitSet) = +proc bitSetDiff(x: var TBitSet, y: TBitSet) = for i in countup(0, high(x)): x[i] = x[i] and not y[i] -proc BitSetSymDiff(x: var TBitSet, y: TBitSet) = +proc bitSetSymDiff(x: var TBitSet, y: TBitSet) = for i in countup(0, high(x)): x[i] = x[i] xor y[i] -proc BitSetIntersect(x: var TBitSet, y: TBitSet) = +proc bitSetIntersect(x: var TBitSet, y: TBitSet) = for i in countup(0, high(x)): x[i] = x[i] and y[i] -proc BitSetEquals(x, y: TBitSet): bool = +proc bitSetEquals(x, y: TBitSet): bool = for i in countup(0, high(x)): if x[i] != y[i]: return false result = true -proc BitSetContains(x, y: TBitSet): bool = +proc bitSetContains(x, y: TBitSet): bool = for i in countup(0, high(x)): if (x[i] and not y[i]) != int8(0): return false diff --git a/compiler/c2nim/c2nim.nim b/compiler/c2nim/c2nim.nim index df1e42f23..9b12b9e47 100644 --- a/compiler/c2nim/c2nim.nim +++ b/compiler/c2nim/c2nim.nim @@ -34,25 +34,36 @@ Options: --skipcomments do not copy comments --ignoreRValueRefs translate C++'s ``T&&`` to ``T`` instead ``of var T`` --keepBodies keep C++'s method bodies + --spliceHeader parse and emit header before source file -v, --version write c2nim's version -h, --help show this help """ -proc main(infile, outfile: string, options: PParserOptions) = - var start = getTime() - var stream = LLStreamOpen(infile, fmRead) +proc parse(infile: string, options: PParserOptions): PNode = + var stream = llStreamOpen(infile, fmRead) if stream == nil: rawMessage(errCannotOpenFile, infile) var p: TParser openParser(p, infile, stream, options) - var module = parseUnit(p) + result = parseUnit(p) closeParser(p) - renderModule(module, outfile) + +proc main(infile, outfile: string, options: PParserOptions, spliceHeader: bool) = + var start = getTime() + if spliceHeader and infile.splitFile.ext == ".c" and existsFile(infile.changeFileExt(".h")): + var header_module = parse(infile.changeFileExt(".h"), options) + var source_module = parse(infile, options) + for n in source_module: + addson(header_module, n) + renderModule(header_module, outfile) + else: + renderModule(parse(infile, options), outfile) rawMessage(hintSuccessX, [$gLinesCompiled, $(getTime() - start), formatSize(getTotalMem())]) var infile = "" outfile = "" + spliceHeader = false parserOptions = newParserOptions() for kind, key, val in getopt(): case kind @@ -66,6 +77,7 @@ for kind, key, val in getopt(): stdout.write(Version & "\n") quit(0) of "o", "out": outfile = val + of "spliceheader": spliceHeader = true else: if not parserOptions.setOption(key, val): stdout.writeln("[Error] unknown option: " & key) @@ -77,4 +89,4 @@ else: if outfile.len == 0: outfile = changeFileExt(infile, "nim") infile = addFileExt(infile, "h") - main(infile, outfile, parserOptions) + main(infile, outfile, parserOptions, spliceHeader) diff --git a/compiler/c2nim/clex.nim b/compiler/c2nim/clex.nim index f949b97cb..3934eea63 100644 --- a/compiler/c2nim/clex.nim +++ b/compiler/c2nim/clex.nim @@ -103,7 +103,7 @@ type inDirective: bool proc getTok*(L: var TLexer, tok: var TToken) -proc PrintTok*(tok: TToken) +proc printTok*(tok: TToken) proc `$`*(tok: TToken): string # implementation @@ -138,7 +138,7 @@ proc lexMessagePos(L: var TLexer, msg: TMsgKind, pos: int, arg = "") = var info = newLineInfo(L.fileIdx, L.linenumber, pos - L.lineStart) msgs.GlobalError(info, msg, arg) -proc TokKindToStr*(k: TTokKind): string = +proc tokKindToStr*(k: TTokKind): string = case k of pxEof: result = "[EOF]" of pxInvalid: result = "[invalid]" @@ -211,9 +211,9 @@ proc `$`(tok: TToken): string = of pxSymbol, pxInvalid, pxStarComment, pxLineComment, pxStrLit: result = tok.s of pxIntLit, pxInt64Lit: result = $tok.iNumber of pxFloatLit: result = $tok.fNumber - else: result = TokKindToStr(tok.xkind) + else: result = tokKindToStr(tok.xkind) -proc PrintTok(tok: TToken) = +proc printTok(tok: TToken) = writeln(stdout, $tok) proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: TCharSet) = @@ -223,12 +223,12 @@ proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: TCharSet) = while true: if buf[pos] in chars: add(tok.s, buf[pos]) - Inc(pos) + inc(pos) else: break if buf[pos] == '_': add(tok.s, '_') - Inc(pos) + inc(pos) L.bufPos = pos proc isFloatLiteral(s: string): bool = @@ -239,7 +239,7 @@ proc isFloatLiteral(s: string): bool = proc getNumber2(L: var TLexer, tok: var TToken) = var pos = L.bufpos + 2 # skip 0b tok.base = base2 - var xi: biggestInt = 0 + var xi: BiggestInt = 0 var bits = 0 while true: case L.buf[pos] @@ -264,7 +264,7 @@ proc getNumber2(L: var TLexer, tok: var TToken) = proc getNumber8(L: var TLexer, tok: var TToken) = var pos = L.bufpos + 1 # skip 0 tok.base = base8 - var xi: biggestInt = 0 + var xi: BiggestInt = 0 var bits = 0 while true: case L.buf[pos] @@ -289,7 +289,7 @@ proc getNumber8(L: var TLexer, tok: var TToken) = proc getNumber16(L: var TLexer, tok: var TToken) = var pos = L.bufpos + 2 # skip 0x tok.base = base16 - var xi: biggestInt = 0 + var xi: BiggestInt = 0 var bits = 0 while true: case L.buf[pos] @@ -315,19 +315,34 @@ proc getNumber16(L: var TLexer, tok: var TToken) = else: tok.xkind = pxIntLit L.bufpos = pos +proc getFloating(L: var TLexer, tok: var TToken) = + matchUnderscoreChars(L, tok, {'0'..'9'}) + if L.buf[L.bufpos] in {'e', 'E'}: + add(tok.s, L.buf[L.bufpos]) + inc(L.bufpos) + if L.buf[L.bufpos] in {'+', '-'}: + add(tok.s, L.buf[L.bufpos]) + inc(L.bufpos) + matchUnderscoreChars(L, tok, {'0'..'9'}) + proc getNumber(L: var TLexer, tok: var TToken) = tok.base = base10 - matchUnderscoreChars(L, tok, {'0'..'9'}) - if (L.buf[L.bufpos] == '.') and (L.buf[L.bufpos + 1] in {'0'..'9'}): - add(tok.s, '.') + if L.buf[L.bufpos] == '.': + add(tok.s, "0.") inc(L.bufpos) - matchUnderscoreChars(L, tok, {'e', 'E', '+', '-', '0'..'9'}) + getFloating(L, tok) + else: + matchUnderscoreChars(L, tok, {'0'..'9'}) + if L.buf[L.bufpos] == '.': + add(tok.s, '.') + inc(L.bufpos) + getFloating(L, tok) try: if isFloatLiteral(tok.s): tok.fnumber = parseFloat(tok.s) tok.xkind = pxFloatLit else: - tok.iNumber = ParseInt(tok.s) + tok.iNumber = parseInt(tok.s) if (tok.iNumber < low(int32)) or (tok.iNumber > high(int32)): tok.xkind = pxInt64Lit else: @@ -339,10 +354,10 @@ proc getNumber(L: var TLexer, tok: var TToken) = # ignore type suffix: while L.buf[L.bufpos] in {'A'..'Z', 'a'..'z'}: inc(L.bufpos) -proc HandleCRLF(L: var TLexer, pos: int): int = +proc handleCRLF(L: var TLexer, pos: int): int = case L.buf[pos] - of CR: result = nimlexbase.HandleCR(L, pos) - of LF: result = nimlexbase.HandleLF(L, pos) + of CR: result = nimlexbase.handleCR(L, pos) + of LF: result = nimlexbase.handleLF(L, pos) else: result = pos proc escape(L: var TLexer, tok: var TToken, allowEmpty=false) = @@ -382,6 +397,23 @@ proc escape(L: var TLexer, tok: var TToken, allowEmpty=false) = xi = (xi shl 3) or (ord(L.buf[L.bufpos]) - ord('0')) inc(L.bufpos) add(tok.s, chr(xi)) + of 'x': + var xi = 0 + inc(L.bufpos) + while true: + case L.buf[L.bufpos] + of '0'..'9': + xi = `shl`(xi, 4) or (ord(L.buf[L.bufpos]) - ord('0')) + inc(L.bufpos) + of 'a'..'f': + xi = `shl`(xi, 4) or (ord(L.buf[L.bufpos]) - ord('a') + 10) + inc(L.bufpos) + of 'A'..'F': + xi = `shl`(xi, 4) or (ord(L.buf[L.bufpos]) - ord('A') + 10) + inc(L.bufpos) + else: + break + add(tok.s, chr(xi)) elif not allowEmpty: lexMessage(L, errInvalidCharacterConstant) @@ -405,7 +437,7 @@ proc getString(L: var TLexer, tok: var TToken) = while true: case buf[pos] of '\"': - Inc(pos) + inc(pos) break of CR: pos = nimlexbase.HandleCR(L, pos) @@ -427,7 +459,7 @@ proc getString(L: var TLexer, tok: var TToken) = pos = L.bufpos else: add(tok.s, buf[pos]) - Inc(pos) + inc(pos) L.bufpos = pos tok.xkind = pxStrLit @@ -438,7 +470,7 @@ proc getSymbol(L: var TLexer, tok: var TToken) = var c = buf[pos] if c notin SymChars: break add(tok.s, c) - Inc(pos) + inc(pos) L.bufpos = pos tok.xkind = pxSymbol @@ -475,7 +507,7 @@ proc scanStarComment(L: var TLexer, tok: var TToken) = while true: case buf[pos] of CR, LF: - pos = HandleCRLF(L, pos) + pos = handleCRLF(L, pos) buf = L.buf add(tok.s, "\n#") # skip annoying stars as line prefix: (eg. @@ -511,12 +543,12 @@ proc skip(L: var TLexer, tok: var TToken) = if L.inDirective: while buf[pos] in {' ', '\t'}: inc(pos) if buf[pos] in {CR, LF}: - pos = HandleCRLF(L, pos) + pos = handleCRLF(L, pos) buf = L.buf of ' ', Tabulator: - Inc(pos) # newline is special: + inc(pos) # newline is special: of CR, LF: - pos = HandleCRLF(L, pos) + pos = handleCRLF(L, pos) buf = L.buf if L.inDirective: tok.xkind = pxNewLine @@ -559,13 +591,13 @@ proc getTok(L: var TLexer, tok: var TToken) = of 'b', 'B': getNumber2(L, tok) of '1'..'7': getNumber8(L, tok) else: getNumber(L, tok) - elif c in {'1'..'9'}: + elif c in {'1'..'9'} or (c == '.' and L.buf[L.bufpos+1] in {'0'..'9'}): getNumber(L, tok) else: case c of ';': tok.xkind = pxSemicolon - Inc(L.bufpos) + inc(L.bufpos) of '/': if L.buf[L.bufpos + 1] == '/': scanLineComment(L, tok) @@ -580,9 +612,9 @@ proc getTok(L: var TLexer, tok: var TToken) = inc(L.bufpos) of ',': tok.xkind = pxComma - Inc(L.bufpos) + inc(L.bufpos) of '(': - Inc(L.bufpos) + inc(L.bufpos) tok.xkind = pxParLe of '*': inc(L.bufpos) @@ -592,13 +624,13 @@ proc getTok(L: var TLexer, tok: var TToken) = else: tok.xkind = pxStar of ')': - Inc(L.bufpos) + inc(L.bufpos) tok.xkind = pxParRi of '[': - Inc(L.bufpos) + inc(L.bufpos) tok.xkind = pxBracketLe of ']': - Inc(L.bufpos) + inc(L.bufpos) tok.xkind = pxBracketRi of '.': inc(L.bufpos) @@ -608,10 +640,10 @@ proc getTok(L: var TLexer, tok: var TToken) = else: tok.xkind = pxDot of '{': - Inc(L.bufpos) + inc(L.bufpos) tok.xkind = pxCurlyLe of '}': - Inc(L.bufpos) + inc(L.bufpos) tok.xkind = pxCurlyRi of '+': inc(L.bufpos) @@ -752,4 +784,4 @@ proc getTok(L: var TLexer, tok: var TToken) = tok.s = $c tok.xkind = pxInvalid lexMessage(L, errInvalidToken, c & " (\\" & $(ord(c)) & ')') - Inc(L.bufpos) + inc(L.bufpos) diff --git a/compiler/c2nim/cparse.nim b/compiler/c2nim/cparse.nim index 44be556db..ffab05788 100644 --- a/compiler/c2nim/cparse.nim +++ b/compiler/c2nim/cparse.nim @@ -61,6 +61,8 @@ type TReplaceTuple* = array[0..1, string] + ERetryParsing = object of ESynch + proc newParserOptions*(): PParserOptions = new(result) result.prefixes = @[] @@ -93,16 +95,16 @@ proc setOption*(parserOptions: PParserOptions, key: string, val=""): bool = of "class": parserOptions.classes[val] = "true" else: result = false -proc ParseUnit*(p: var TParser): PNode +proc parseUnit*(p: var TParser): PNode proc openParser*(p: var TParser, filename: string, inputStream: PLLStream, options = newParserOptions()) proc closeParser*(p: var TParser) # implementation -proc OpenParser(p: var TParser, filename: string, +proc openParser(p: var TParser, filename: string, inputStream: PLLStream, options = newParserOptions()) = - OpenLexer(p.lex, filename, inputStream) + openLexer(p.lex, filename, inputStream) p.options = options p.backtrack = @[] new(p.tok) @@ -111,7 +113,7 @@ proc parMessage(p: TParser, msg: TMsgKind, arg = "") = #assert false lexMessage(p.lex, msg, arg) -proc CloseParser(p: var TParser) = CloseLexer(p.lex) +proc closeParser(p: var TParser) = closeLexer(p.lex) proc saveContext(p: var TParser) = p.backtrack.add(p.tok) proc closeContext(p: var TParser) = discard p.backtrack.pop() proc backtrackContext(p: var TParser) = p.tok = p.backtrack.pop() @@ -145,7 +147,7 @@ proc findMacro(p: TParser): int = proc rawEat(p: var TParser, xkind: TTokKind) = if p.tok.xkind == xkind: rawGetTok(p) - else: parMessage(p, errTokenExpected, TokKindToStr(xkind)) + else: parMessage(p, errTokenExpected, tokKindToStr(xkind)) proc parseMacroArguments(p: var TParser): seq[seq[ref TToken]] = result = @[] @@ -228,7 +230,7 @@ proc skipComAux(p: var TParser, n: PNode) = getTok(p) proc skipCom(p: var TParser, n: PNode) = - while p.tok.xkind in {pxLineComment, pxStarComment}: skipcomAux(p, n) + while p.tok.xkind in {pxLineComment, pxStarComment}: skipComAux(p, n) proc skipStarCom(p: var TParser, n: PNode) = while p.tok.xkind == pxStarComment: skipComAux(p, n) @@ -242,11 +244,11 @@ proc expectIdent(p: TParser) = proc eat(p: var TParser, xkind: TTokKind, n: PNode) = if p.tok.xkind == xkind: getTok(p, n) - else: parMessage(p, errTokenExpected, TokKindToStr(xkind)) + else: parMessage(p, errTokenExpected, tokKindToStr(xkind)) proc eat(p: var TParser, xkind: TTokKind) = if p.tok.xkind == xkind: getTok(p) - else: parMessage(p, errTokenExpected, TokKindToStr(xkind)) + else: parMessage(p, errTokenExpected, tokKindToStr(xkind)) proc eat(p: var TParser, tok: string, n: PNode) = if p.tok.s == tok: getTok(p, n) @@ -420,9 +422,9 @@ proc markTypeIdent(p: var TParser, typ: PNode) = # avoids to build a symbol table, which can't be done reliably anyway for our # purposes. -proc expression(p: var TParser): PNode -proc constantExpression(p: var TParser): PNode -proc assignmentExpression(p: var TParser): PNode +proc expression(p: var TParser, rbp: int = 0): PNode +proc constantExpression(p: var TParser): PNode = expression(p, 40) +proc assignmentExpression(p: var TParser): PNode = expression(p, 30) proc compoundStatement(p: var TParser): PNode proc statement(p: var TParser): PNode @@ -605,7 +607,7 @@ proc addPragmas(father, pragmas: PNode) = proc addReturnType(params, rettyp: PNode) = if rettyp == nil: addSon(params, ast.emptyNode) elif rettyp.kind != nkNilLit: addSon(params, rettyp) - else: addson(params, ast.emptyNode) + else: addSon(params, ast.emptyNode) proc parseFormalParams(p: var TParser, params, pragmas: PNode) @@ -651,6 +653,22 @@ proc parseTypeSuffix(p: var TParser, typ: PNode): PNode = proc typeDesc(p: var TParser): PNode = result = pointer(p, typeAtom(p)) +proc abstractDeclarator(p: var TParser, a: PNode): PNode + +proc directAbstractDeclarator(p: var TParser, a: PNode): PNode = + if p.tok.xkind == pxParLe: + getTok(p, a) + if p.tok.xkind in {pxStar, pxAmp, pxAmpAmp}: + result = abstractDeclarator(p, a) + eat(p, pxParRi, result) + return parseTypeSuffix(p, a) + +proc abstractDeclarator(p: var TParser, a: PNode): PNode = + return directAbstractDeclarator(p, pointer(p, a)) + +proc typeName(p: var TParser): PNode = + return abstractDeclarator(p, typeAtom(p)) + proc parseField(p: var TParser, kind: TNodeKind): PNode = if p.tok.xkind == pxParLe: getTok(p, nil) @@ -690,8 +708,8 @@ proc parseStructBody(p: var TParser, isUnion: bool, proc structPragmas(p: TParser, name: PNode, origName: string): PNode = assert name.kind == nkIdent result = newNodeP(nkPragmaExpr, p) - addson(result, exportSym(p, name, origName)) - var pragmas = newNodep(nkPragma, p) + addSon(result, exportSym(p, name, origName)) + var pragmas = newNodeP(nkPragma, p) addSon(pragmas, newIdentNodeP("pure", p), newIdentNodeP("final", p)) if p.options.header.len > 0: addSon(pragmas, newIdentStrLitPair("importc", origName, p), @@ -700,8 +718,8 @@ proc structPragmas(p: TParser, name: PNode, origName: string): PNode = proc enumPragmas(p: TParser, name: PNode): PNode = result = newNodeP(nkPragmaExpr, p) - addson(result, name) - var pragmas = newNodep(nkPragma, p) + addSon(result, name) + var pragmas = newNodeP(nkPragma, p) var e = newNodeP(nkExprColonExpr, p) # HACK: sizeof(cint) should be constructed as AST addSon(e, newIdentNodeP("size", p), newIdentNodeP("sizeof(cint)", p)) @@ -716,18 +734,36 @@ proc parseStruct(p: var TParser, isUnion: bool): PNode = else: addSon(result, newNodeP(nkRecList, p)) +proc declarator(p: var TParser, a: PNode, ident: ptr PNode): PNode + +proc directDeclarator(p: var TParser, a: PNode, ident: ptr PNode): PNode = + case p.tok.xkind + of pxSymbol: + ident[] = skipIdent(p) + of pxParLe: + getTok(p, a) + if p.tok.xkind in {pxStar, pxAmp, pxAmpAmp, pxSymbol}: + result = declarator(p, a, ident) + eat(p, pxParRi, result) + else: + nil + return parseTypeSuffix(p, a) + +proc declarator(p: var TParser, a: PNode, ident: ptr PNode): PNode = + return directDeclarator(p, pointer(p, a), ident) + +# parameter-declaration +# declaration-specifiers declarator +# declaration-specifiers asbtract-declarator(opt) proc parseParam(p: var TParser, params: PNode) = var typ = typeDesc(p) # support for ``(void)`` parameter list: if typ.kind == nkNilLit and p.tok.xkind == pxParRi: return var name: PNode - if p.tok.xkind == pxSymbol: - name = skipIdent(p) - else: - # generate a name for the formal parameter: + typ = declarator(p, typ, addr name) + if name == nil: var idx = sonsLen(params)+1 name = newIdentNodeP("a" & $idx, p) - typ = parseTypeSuffix(p, typ) var x = newNodeP(nkIdentDefs, p) addSon(x, name, typ) if p.tok.xkind == pxAsgn: @@ -1045,7 +1081,7 @@ proc declaration(p: var TParser): PNode = of pxSemicolon: getTok(p) addSon(result, ast.emptyNode) # nobody - if p.scopeCounter == 0: DoImport(origName, pragmas, p) + if p.scopeCounter == 0: doImport(origName, pragmas, p) of pxCurlyLe: addSon(result, compoundStatement(p)) else: @@ -1134,224 +1170,27 @@ proc setBaseFlags(n: PNode, base: TNumericalBase) = of base8: incl(n.flags, nfBase8) of base16: incl(n.flags, nfBase16) -proc unaryExpression(p: var TParser): PNode - -proc isDefinitelyAType(p: var TParser): bool = - var starFound = false - var words = 0 - while true: - case p.tok.xkind - of pxSymbol: - if declKeyword(p, p.tok.s): return true - elif starFound: return false - else: inc(words) - of pxStar, pxAmp, pxAmpAmp: - starFound = true - of pxParRi: return words == 0 or words > 1 or starFound - else: return false - getTok(p, nil) - -proc castExpression(p: var TParser): PNode = - if p.tok.xkind == pxParLe: - saveContext(p) - result = newNodeP(nkCast, p) - getTok(p, result) - var t = isDefinitelyAType(p) - backtrackContext(p) - if t: - eat(p, pxParLe, result) - var a = typeDesc(p) - eat(p, pxParRi, result) - addSon(result, a) - addSon(result, castExpression(p)) - else: - # else it is just an expression in (): - result = newNodeP(nkPar, p) - eat(p, pxParLe, result) - addSon(result, expression(p)) - if p.tok.xkind != pxParRi: - # ugh, it is a cast, even though it does not look like one: - result.kind = nkCast - addSon(result, castExpression(p)) - eat(p, pxParRi, result) - #result = unaryExpression(p) - else: - result = unaryExpression(p) - -proc primaryExpression(p: var TParser): PNode = - case p.tok.xkind - of pxSymbol: - if p.tok.s == "NULL": - result = newNodeP(nkNilLit, p) - else: - result = mangledIdent(p.tok.s, p) - getTok(p, result) - result = optScope(p, result) - of pxIntLit: - result = newIntNodeP(nkIntLit, p.tok.iNumber, p) - setBaseFlags(result, p.tok.base) - getTok(p, result) - of pxInt64Lit: - result = newIntNodeP(nkInt64Lit, p.tok.iNumber, p) - setBaseFlags(result, p.tok.base) - getTok(p, result) - of pxFloatLit: - result = newFloatNodeP(nkFloatLit, p.tok.fNumber, p) - setBaseFlags(result, p.tok.base) - getTok(p, result) - of pxStrLit: - # Ansi C allows implicit string literal concatenations: - result = newStrNodeP(nkStrLit, p.tok.s, p) - getTok(p, result) - while p.tok.xkind == pxStrLit: - add(result.strVal, p.tok.s) - getTok(p, result) - of pxCharLit: - result = newIntNodeP(nkCharLit, ord(p.tok.s[0]), p) - getTok(p, result) - of pxParLe: - result = castExpression(p) - else: - result = ast.emptyNode - -proc multiplicativeExpression(p: var TParser): PNode = - result = castExpression(p) - while true: - case p.tok.xkind - of pxStar: - var a = result - result = newNodeP(nkInfix, p) - addSon(result, newIdentNodeP("*", p), a) - getTok(p, result) - var b = castExpression(p) - addSon(result, b) - of pxSlash: - var a = result - result = newNodeP(nkInfix, p) - addSon(result, newIdentNodeP("div", p), a) - getTok(p, result) - var b = castExpression(p) - addSon(result, b) - of pxMod: - var a = result - result = newNodeP(nkInfix, p) - addSon(result, newIdentNodeP("mod", p), a) - getTok(p, result) - var b = castExpression(p) - addSon(result, b) - else: break - -proc additiveExpression(p: var TParser): PNode = - result = multiplicativeExpression(p) - while true: - case p.tok.xkind - of pxPlus: - var a = result - result = newNodeP(nkInfix, p) - addSon(result, newIdentNodeP("+", p), a) - getTok(p, result) - var b = multiplicativeExpression(p) - addSon(result, b) - of pxMinus: - var a = result - result = newNodeP(nkInfix, p) - addSon(result, newIdentNodeP("-", p), a) - getTok(p, result) - var b = multiplicativeExpression(p) - addSon(result, b) - else: break - -proc incdec(p: var TParser, opr: string): PNode = - result = newNodeP(nkCall, p) - addSon(result, newIdentNodeP(opr, p)) - gettok(p, result) - addSon(result, unaryExpression(p)) - -proc unaryOp(p: var TParser, kind: TNodeKind): PNode = - result = newNodeP(kind, p) - getTok(p, result) - addSon(result, castExpression(p)) - -proc prefixCall(p: var TParser, opr: string): PNode = - result = newNodeP(nkPrefix, p) - addSon(result, newIdentNodeP(opr, p)) - gettok(p, result) - addSon(result, castExpression(p)) - -proc postfixExpression(p: var TParser): PNode = - result = primaryExpression(p) - while true: - case p.tok.xkind - of pxBracketLe: - var a = result - result = newNodeP(nkBracketExpr, p) - addSon(result, a) - getTok(p, result) - var b = expression(p) - addSon(result, b) - eat(p, pxBracketRi, result) - of pxParLe: - var a = result - result = newNodeP(nkCall, p) - addSon(result, a) - getTok(p, result) - if p.tok.xkind != pxParRi: - a = assignmentExpression(p) - addSon(result, a) - while p.tok.xkind == pxComma: - getTok(p, a) - a = assignmentExpression(p) - addSon(result, a) - eat(p, pxParRi, result) - of pxDot, pxArrow: - var a = result - result = newNodeP(nkDotExpr, p) - addSon(result, a) - getTok(p, result) - addSon(result, skipIdent(p)) - of pxPlusPlus: - var a = result - result = newNodeP(nkCall, p) - addSon(result, newIdentNodeP("inc", p)) - gettok(p, result) - addSon(result, a) - of pxMinusMinus: - var a = result - result = newNodeP(nkCall, p) - addSon(result, newIdentNodeP("dec", p)) - gettok(p, result) - addSon(result, a) - of pxLt: - if isTemplateAngleBracket(p): - result = optAngle(p, result) - else: break - else: break - -proc unaryExpression(p: var TParser): PNode = - case p.tok.xkind - of pxPlusPlus: result = incdec(p, "inc") - of pxMinusMinus: result = incdec(p, "dec") - of pxAmp: result = unaryOp(p, nkAddr) - of pxStar: result = unaryOp(p, nkBracketExpr) - of pxPlus: result = prefixCall(p, "+") - of pxMinus: result = prefixCall(p, "-") - of pxTilde: result = prefixCall(p, "not") - of pxNot: result = prefixCall(p, "not") +proc startExpression(p : var TParser, tok : TToken) : PNode = + #echo "nud ", $tok + case tok.xkind: of pxSymbol: - if p.tok.s == "sizeof": + if tok.s == "NULL": + result = newNodeP(nkNilLit, p) + elif tok.s == "sizeof": result = newNodeP(nkCall, p) addSon(result, newIdentNodeP("sizeof", p)) - getTok(p, result) - if p.tok.xkind == pxParLe: - getTok(p, result) - addSon(result, typeDesc(p)) - eat(p, pxParRi, result) - else: - addSon(result, unaryExpression(p)) - elif p.tok.s == "new" or p.tok.s == "delete" and pfCpp in p.options.flags: - var opr = p.tok.s + saveContext(p) + try: + addSon(result, expression(p, 139)) + closeContext(p) + except ERetryParsing: + backtrackContext(p) + eat(p, pxParLe) + addSon(result, typeName(p)) + eat(p, pxParRi) + elif (tok.s == "new" or tok.s == "delete") and pfCpp in p.options.flags: + var opr = tok.s result = newNodeP(nkCall, p) - getTok(p, result) if p.tok.xkind == pxBracketLe: getTok(p) eat(p, pxBracketRi) @@ -1362,148 +1201,269 @@ proc unaryExpression(p: var TParser): PNode = addSon(result, typeDesc(p)) eat(p, pxParRi, result) else: - addSon(result, unaryExpression(p)) + addSon(result, expression(p, 139)) else: - result = postfixExpression(p) - else: result = postfixExpression(p) - -proc expression(p: var TParser): PNode = - # we cannot support C's ``,`` operator - result = assignmentExpression(p) - if p.tok.xkind == pxComma: - getTok(p, result) - parMessage(p, errOperatorExpected, ",") - -proc conditionalExpression(p: var TParser): PNode - -proc constantExpression(p: var TParser): PNode = - result = conditionalExpression(p) - -proc lvalue(p: var TParser): PNode = - result = unaryExpression(p) - -proc asgnExpr(p: var TParser, opr: string, a: PNode): PNode = - closeContext(p) - getTok(p, a) - var b = assignmentExpression(p) - result = newNodeP(nkAsgn, p) - addSon(result, a, newBinary(opr, copyTree(a), b, p)) - -proc incdec(p: var TParser, opr: string, a: PNode): PNode = - closeContext(p) - getTok(p, a) - var b = assignmentExpression(p) - result = newNodeP(nkCall, p) - addSon(result, newIdentNodeP(getIdent(opr), p), a, b) - -proc assignmentExpression(p: var TParser): PNode = - saveContext(p) - var a = lvalue(p) - case p.tok.xkind - of pxAsgn: - closeContext(p) - getTok(p, a) - var b = assignmentExpression(p) + result = mangledIdent(tok.s, p) + result = optScope(p, result) + result = optAngle(p, result) + of pxIntLit: + result = newIntNodeP(nkIntLit, tok.iNumber, p) + setBaseFlags(result, tok.base) + of pxInt64Lit: + result = newIntNodeP(nkInt64Lit, tok.iNumber, p) + setBaseFlags(result, tok.base) + of pxFloatLit: + result = newFloatNodeP(nkFloatLit, tok.fNumber, p) + setBaseFlags(result, tok.base) + of pxStrLit: + result = newStrNodeP(nkStrLit, tok.s, p) + while p.tok.xkind == pxStrLit: + add(result.strVal, p.tok.s) + getTok(p, result) + of pxCharLit: + result = newIntNodeP(nkCharLit, ord(tok.s[0]), p) + of pxParLe: + try: + saveContext(p) + result = newNodeP(nkPar, p) + addSon(result, expression(p, 0)) + if p.tok.xkind != pxParRi: + raise newException(ERetryParsing, "expected a ')'") + getTok(p, result) + if p.tok.xkind in {pxSymbol, pxIntLit, pxFloatLit, pxStrLit, pxCharLit}: + raise newException(ERetryParsing, "expected a non literal token") + closeContext(p) + except ERetryParsing: + backtrackContext(p) + result = newNodeP(nkCast, p) + addSon(result, typeName(p)) + eat(p, pxParRi, result) + addSon(result, expression(p, 139)) + of pxPlusPlus: + result = newNodeP(nkCall, p) + addSon(result, newIdentNodeP("inc", p)) + addSon(result, expression(p, 139)) + of pxMinusMinus: + result = newNodeP(nkCall, p) + addSon(result, newIdentNodeP("dec", p)) + addSon(result, expression(p, 139)) + of pxAmp: + result = newNodeP(nkAddr, p) + addSon(result, expression(p, 139)) + of pxStar: + result = newNodeP(nkBracketExpr, p) + addSon(result, expression(p, 139)) + of pxPlus: + result = newNodeP(nkPrefix, p) + addSon(result, newIdentNodeP("+", p)) + addSon(result, expression(p, 139)) + of pxMinus: + result = newNodeP(nkPrefix, p) + addSon(result, newIdentNodeP("-", p)) + addSon(result, expression(p, 139)) + of pxTilde: + result = newNodeP(nkPrefix, p) + addSon(result, newIdentNodeP("not", p)) + addSon(result, expression(p, 139)) + of pxNot: + result = newNodeP(nkPrefix, p) + addSon(result, newIdentNodeP("not", p)) + addSon(result, expression(p, 139)) + else: + # probably from a failed sub expression attempt, try a type cast + raise newException(ERetryParsing, "did not expect " & $tok) + +proc leftBindingPower(p : var TParser, tok : ref TToken) : int = + #echo "lbp ", $tok[] + case tok.xkind: + of pxComma: + return 10 + # throw == 20 + of pxAsgn, pxPlusAsgn, pxMinusAsgn, pxStarAsgn, pxSlashAsgn, pxModAsgn, pxShlAsgn, pxShrAsgn, pxAmpAsgn, pxHatAsgn, pxBarAsgn: + return 30 + of pxConditional: + return 40 + of pxBarBar: + return 50 + of pxAmpAmp: + return 60 + of pxBar: + return 70 + of pxHat: + return 80 + of pxAmp: + return 90 + of pxEquals, pxNeq: + return 100 + of pxLt, pxLe, pxGt, pxGe: + return 110 + of pxShl, pxShr: + return 120 + of pxPlus, pxMinus: + return 130 + of pxStar, pxSlash, pxMod: + return 140 + # .* ->* == 150 + of pxPlusPlus, pxMinusMinus, pxParLe, pxDot, pxArrow, pxBracketLe: + return 160 + # :: == 170 + else: + return 0 + +proc buildStmtList(a: PNode): PNode + +proc leftExpression(p : var TParser, tok : TToken, left : PNode) : PNode = + #echo "led ", $tok + case tok.xkind: + of pxComma: # 10 + # not supported as an expression, turns into a statement list + result = buildStmtList(left) + addSon(result, expression(p, 0)) + # throw == 20 + of pxAsgn: # 30 + result = newNodeP(nkAsgn, p) + addSon(result, left, expression(p, 29)) + of pxPlusAsgn: # 30 + result = newNodeP(nkCall, p) + addSon(result, newIdentNodeP(getIdent("inc"), p), left, expression(p, 29)) + of pxMinusAsgn: # 30 + result = newNodeP(nkCall, p) + addSon(result, newIdentNodeP(getIdent("dec"), p), left, expression(p, 29)) + of pxStarAsgn: # 30 + result = newNodeP(nkAsgn, p) + var right = expression(p, 29) + addSon(result, left, newBinary("*", copyTree(left), right, p)) + of pxSlashAsgn: # 30 + result = newNodeP(nkAsgn, p) + var right = expression(p, 29) + addSon(result, left, newBinary("/", copyTree(left), right, p)) + of pxModAsgn: # 30 + result = newNodeP(nkAsgn, p) + var right = expression(p, 29) + addSon(result, left, newBinary("mod", copyTree(left), right, p)) + of pxShlAsgn: # 30 + result = newNodeP(nkAsgn, p) + var right = expression(p, 29) + addSon(result, left, newBinary("shl", copyTree(left), right, p)) + of pxShrAsgn: # 30 + result = newNodeP(nkAsgn, p) + var right = expression(p, 29) + addSon(result, left, newBinary("shr", copyTree(left), right, p)) + of pxAmpAsgn: # 30 + result = newNodeP(nkAsgn, p) + var right = expression(p, 29) + addSon(result, left, newBinary("and", copyTree(left), right, p)) + of pxHatAsgn: # 30 + result = newNodeP(nkAsgn, p) + var right = expression(p, 29) + addSon(result, left, newBinary("xor", copyTree(left), right, p)) + of pxBarAsgn: # 30 result = newNodeP(nkAsgn, p) - addSon(result, a, b) - of pxPlusAsgn: result = incDec(p, "inc", a) - of pxMinusAsgn: result = incDec(p, "dec", a) - of pxStarAsgn: result = asgnExpr(p, "*", a) - of pxSlashAsgn: result = asgnExpr(p, "/", a) - of pxModAsgn: result = asgnExpr(p, "mod", a) - of pxShlAsgn: result = asgnExpr(p, "shl", a) - of pxShrAsgn: result = asgnExpr(p, "shr", a) - of pxAmpAsgn: result = asgnExpr(p, "and", a) - of pxHatAsgn: result = asgnExpr(p, "xor", a) - of pxBarAsgn: result = asgnExpr(p, "or", a) + var right = expression(p, 29) + addSon(result, left, newBinary("or", copyTree(left), right, p)) + of pxConditional: # 40 + var a = expression(p, 0) + eat(p, pxColon, a) + var b = expression(p, 39) + result = newNodeP(nkIfExpr, p) + var branch = newNodeP(nkElifExpr, p) + addSon(branch, left, a) + addSon(result, branch) + branch = newNodeP(nkElseExpr, p) + addSon(branch, b) + addSon(result, branch) + of pxBarBar: # 50 + result = newBinary("or", left, expression(p, 50), p) + of pxAmpAmp: # 60 + result = newBinary("and", left, expression(p, 60), p) + of pxBar: # 70 + result = newBinary("or", left, expression(p, 70), p) + of pxHat: # 80 + result = newBinary("^", left, expression(p, 80), p) + of pxAmp: # 90 + result = newBinary("and", left, expression(p, 90), p) + of pxEquals: # 100 + result = newBinary("==", left, expression(p, 100), p) + of pxNeq: # 100 + result = newBinary("!=", left, expression(p, 100), p) + of pxLt: # 110 + result = newBinary("<", left, expression(p, 110), p) + of pxLe: # 110 + result = newBinary("<=", left, expression(p, 110), p) + of pxGt: # 110 + result = newBinary(">", left, expression(p, 110), p) + of pxGe: # 110 + result = newBinary(">=", left, expression(p, 110), p) + of pxShl: # 120 + result = newBinary("shl", left, expression(p, 120), p) + of pxShr: # 120 + result = newBinary("shr", left, expression(p, 120), p) + of pxPlus: # 130 + result = newNodeP(nkInfix, p) + addSon(result, newIdentNodeP("+", p), left) + addSon(result, expression(p, 130)) + of pxMinus: # 130 + result = newNodeP(nkInfix, p) + addSon(result, newIdentNodeP("+", p), left) + addSon(result, expression(p, 130)) + of pxStar: # 140 + result = newNodeP(nkInfix, p) + addSon(result, newIdentNodeP("*", p), left) + addSon(result, expression(p, 140)) + of pxSlash: # 140 + result = newNodeP(nkInfix, p) + addSon(result, newIdentNodeP("div", p), left) + addSon(result, expression(p, 140)) + of pxMod: # 140 + result = newNodeP(nkInfix, p) + addSon(result, newIdentNodeP("mod", p), left) + addSon(result, expression(p, 140)) + # .* ->* == 150 + of pxPlusPlus: # 160 + result = newNodeP(nkCall, p) + addSon(result, newIdentNodeP("inc", p), left) + of pxMinusMinus: # 160 + result = newNodeP(nkCall, p) + addSon(result, newIdentNodeP("dec", p), left) + of pxParLe: # 160 + result = newNodeP(nkCall, p) + addSon(result, left) + while p.tok.xkind != pxParRi: + var a = expression(p, 29) + addSon(result, a) + while p.tok.xkind == pxComma: + getTok(p, a) + a = expression(p, 29) + addSon(result, a) + eat(p, pxParRi, result) + of pxDot: # 160 + result = newNodeP(nkDotExpr, p) + addSon(result, left) + addSon(result, skipIdent(p)) + of pxArrow: # 160 + result = newNodeP(nkDotExpr, p) + addSon(result, left) + addSon(result, skipIdent(p)) + of pxBracketLe: # 160 + result = newNodeP(nkBracketExpr, p) + addSon(result, left, expression(p)) + eat(p, pxBracketRi, result) + # :: == 170 else: - backtrackContext(p) - result = conditionalExpression(p) - -proc shiftExpression(p: var TParser): PNode = - result = additiveExpression(p) - while p.tok.xkind in {pxShl, pxShr}: - var op = if p.tok.xkind == pxShl: "shl" else: "shr" - getTok(p, result) - var a = result - var b = additiveExpression(p) - result = newBinary(op, a, b, p) - -proc relationalExpression(p: var TParser): PNode = - result = shiftExpression(p) - # Nimrod uses ``<`` and ``<=``, etc. too: - while p.tok.xkind in {pxLt, pxLe, pxGt, pxGe}: - var op = TokKindToStr(p.tok.xkind) - getTok(p, result) - var a = result - var b = shiftExpression(p) - result = newBinary(op, a, b, p) - -proc equalityExpression(p: var TParser): PNode = - result = relationalExpression(p) - # Nimrod uses ``==`` and ``!=`` too: - while p.tok.xkind in {pxEquals, pxNeq}: - var op = TokKindToStr(p.tok.xkind) - getTok(p, result) - var a = result - var b = relationalExpression(p) - result = newBinary(op, a, b, p) + result = left -proc andExpression(p: var TParser): PNode = - result = equalityExpression(p) - while p.tok.xkind == pxAmp: - getTok(p, result) - var a = result - var b = equalityExpression(p) - result = newBinary("and", a, b, p) +proc expression*(p : var TParser, rbp : int = 0) : PNode = + var tok : TToken -proc exclusiveOrExpression(p: var TParser): PNode = - result = andExpression(p) - while p.tok.xkind == pxHat: - getTok(p, result) - var a = result - var b = andExpression(p) - result = newBinary("^", a, b, p) + tok = p.tok[] + getTok(p, result) -proc inclusiveOrExpression(p: var TParser): PNode = - result = exclusiveOrExpression(p) - while p.tok.xkind == pxBar: - getTok(p, result) - var a = result - var b = exclusiveOrExpression(p) - result = newBinary("or", a, b, p) - -proc logicalAndExpression(p: var TParser): PNode = - result = inclusiveOrExpression(p) - while p.tok.xkind == pxAmpAmp: - getTok(p, result) - var a = result - var b = inclusiveOrExpression(p) - result = newBinary("and", a, b, p) + result = startExpression(p, tok) -proc logicalOrExpression(p: var TParser): PNode = - result = logicalAndExpression(p) - while p.tok.xkind == pxBarBar: + while rbp < leftBindingPower(p, p.tok): + tok = p.tok[] getTok(p, result) - var a = result - var b = logicalAndExpression(p) - result = newBinary("or", a, b, p) - -proc conditionalExpression(p: var TParser): PNode = - result = logicalOrExpression(p) - if p.tok.xkind == pxConditional: - getTok(p, result) # skip '?' - var a = result - var b = expression(p) - eat(p, pxColon, b) - var c = conditionalExpression(p) - result = newNodeP(nkIfExpr, p) - var branch = newNodeP(nkElifExpr, p) - addSon(branch, a, b) - addSon(result, branch) - branch = newNodeP(nkElseExpr, p) - addSon(branch, c) - addSon(result, branch) + result = leftExpression(p, tok, result) # Statements @@ -1549,12 +1509,12 @@ proc parseIf(p: var TParser): PNode = while true: getTok(p) # skip ``if`` var branch = newNodeP(nkElifBranch, p) - skipCom(p, branch) eat(p, pxParLe, branch) addSon(branch, expression(p)) eat(p, pxParRi, branch) addSon(branch, nestedStatement(p)) addSon(result, branch) + skipCom(p, branch) if p.tok.s == "else": getTok(p, result) if p.tok.s != "if": @@ -1574,19 +1534,51 @@ proc parseWhile(p: var TParser): PNode = eat(p, pxParRi, result) addSon(result, nestedStatement(p)) +proc embedStmts(sl, a: PNode) + proc parseDoWhile(p: var TParser): PNode = - # we only support ``do stmt while (0)`` as an idiom for - # ``block: stmt`` - result = newNodeP(nkBlockStmt, p) - getTok(p, result) # skip "do" - addSon(result, ast.emptyNode, nestedStatement(p)) + # parsing + result = newNodeP(nkWhileStmt, p) + getTok(p, result) + var stm = nestedStatement(p) eat(p, "while", result) eat(p, pxParLe, result) - if p.tok.xkind == pxIntLit and p.tok.iNumber == 0: getTok(p, result) - else: parMessage(p, errTokenExpected, "0") + var exp = expression(p) eat(p, pxParRi, result) if p.tok.xkind == pxSemicolon: getTok(p) + # while true: + # stmt + # if not expr: + # break + addSon(result, newIdentNodeP("true", p)) + + stm = buildStmtList(stm) + + # get the last exp if it is a stmtlist + var cleanedExp = exp + if exp.kind == nkStmtList: + cleanedExp = exp.sons[exp.len-1] + exp.sons = exp.sons[0..exp.len-2] + embedStmts(stm, exp) + + var notExp = newNodeP(nkPrefix, p) + addSon(notExp, newIdentNodeP("not", p)) + addSon(notExp, cleanedExp) + + var brkStm = newNodeP(nkBreakStmt, p) + addSon(brkStm, ast.emptyNode) + + var ifStm = newNodeP(nkIfStmt, p) + var ifBranch = newNodeP(nkElifBranch, p) + addSon(ifBranch, notExp) + addSon(ifBranch, brkStm) + addSon(ifStm, ifBranch) + + embedStmts(stm, ifStm) + + addSon(result, stm) + proc declarationOrStatement(p: var TParser): PNode = if p.tok.xkind != pxSymbol: result = expressionStatement(p) @@ -1666,7 +1658,7 @@ proc parseFor(p: var TParser, result: PNode) = eat(p, pxParLe, result) var initStmt = declarationOrStatement(p) if initStmt.kind != nkEmpty: - addSon(result, initStmt) + embedStmts(result, initStmt) var w = newNodeP(nkWhileStmt, p) var condition = expressionStatement(p) if condition.kind == nkEmpty: condition = newIdentNodeP("true", p) @@ -1676,7 +1668,7 @@ proc parseFor(p: var TParser, result: PNode) = var loopBody = nestedStatement(p) if step.kind != nkEmpty: loopBody = buildStmtList(loopBody) - addSon(loopBody, step) + embedStmts(loopBody, step) addSon(w, loopBody) addSon(result, w) @@ -1818,7 +1810,7 @@ proc parseConstructor(p: var TParser, pragmas: PNode, else: parMessage(p, errTokenExpected, ";") if result.sons[bodyPos].kind == nkEmpty: - DoImport((if isDestructor: "~" else: "") & origName, pragmas, p) + doImport((if isDestructor: "~" else: "") & origName, pragmas, p) elif isDestructor: addSon(pragmas, newIdentNodeP("destructor", p)) if sonsLen(result.sons[pragmasPos]) == 0: @@ -1862,8 +1854,8 @@ proc parseMethod(p: var TParser, origName: string, rettyp, pragmas: PNode, else: parMessage(p, errTokenExpected, ";") if result.sons[bodyPos].kind == nkEmpty: - if isStatic: DoImport(origName, pragmas, p) - else: DoImportCpp(origName, pragmas, p) + if isStatic: doImport(origName, pragmas, p) + else: doImportCpp(origName, pragmas, p) if sonsLen(result.sons[pragmasPos]) == 0: result.sons[pragmasPos] = ast.emptyNode @@ -1880,7 +1872,7 @@ proc parseOperator(p: var TParser, origName: var string): bool = case p.tok.xkind of pxAmp..pxArrow: # ordinary operator symbol: - origName.add(TokKindToStr(p.tok.xkind)) + origName.add(tokKindToStr(p.tok.xkind)) getTok(p) of pxSymbol: if p.tok.s == "new" or p.tok.s == "delete": @@ -2048,6 +2040,10 @@ proc parseStandaloneClass(p: var TParser, isStruct: bool): PNode = result = declaration(p) p.currentClass = oldClass +proc unwrap(a: PNode): PNode = + if a.kind == nkPar: + return a.sons[0] + return a include cpp @@ -2082,16 +2078,10 @@ proc statement(p: var TParser): PNode = of "return": result = newNodeP(nkReturnStmt, p) getTok(p) - # special case for ``return (expr)`` because I hate the redundant - # parenthesis ;-) - if p.tok.xkind == pxParLe: - getTok(p, result) - addSon(result, expression(p)) - eat(p, pxParRi, result) - elif p.tok.xkind != pxSemicolon: - addSon(result, expression(p)) - else: + if p.tok.xkind == pxSemicolon: addSon(result, ast.emptyNode) + else: + addSon(result, unwrap(expression(p))) eat(p, pxSemicolon) of "enum": result = enumSpecifier(p) of "typedef": result = parseTypeDef(p) @@ -2140,9 +2130,12 @@ proc statement(p: var TParser): PNode = assert result != nil proc parseUnit(p: var TParser): PNode = - result = newNodeP(nkStmtList, p) - getTok(p) # read first token - while p.tok.xkind != pxEof: - var s = statement(p) - if s.kind != nkEmpty: embedStmts(result, s) + try: + result = newNodeP(nkStmtList, p) + getTok(p) # read first token + while p.tok.xkind != pxEof: + var s = statement(p) + if s.kind != nkEmpty: embedStmts(result, s) + except ERetryParsing: + parMessage(p, errGenerated, "Uncaught parsing exception raised") diff --git a/compiler/c2nim/cpp.nim b/compiler/c2nim/cpp.nim index 2ce64e59b..1707b75db 100644 --- a/compiler/c2nim/cpp.nim +++ b/compiler/c2nim/cpp.nim @@ -226,7 +226,7 @@ proc skipUntilElifElseEndif(p: var TParser): TEndifMarker = proc parseIfdef(p: var TParser): PNode = getTok(p) # skip #ifdef - ExpectIdent(p) + expectIdent(p) case p.tok.s of "__cplusplus": skipUntilEndif(p) @@ -245,7 +245,7 @@ proc parseIfdef(p: var TParser): PNode = proc parseIfndef(p: var TParser): PNode = result = ast.emptyNode getTok(p) # skip #ifndef - ExpectIdent(p) + expectIdent(p) if p.tok.s == c2nimSymbol: skipLine(p) case skipUntilElifElseEndif(p) @@ -282,11 +282,11 @@ proc parseIfDir(p: var TParser): PNode = proc parsePegLit(p: var TParser): TPeg = var col = getColumn(p.lex) + 2 getTok(p) - if p.tok.xkind != pxStrLit: ExpectIdent(p) + if p.tok.xkind != pxStrLit: expectIdent(p) try: result = parsePeg( pattern = if p.tok.xkind == pxStrLit: p.tok.s else: escapePeg(p.tok.s), - filename = p.lex.fileIdx.ToFilename, + filename = p.lex.fileIdx.toFilename, line = p.lex.linenumber, col = col) getTok(p) @@ -295,7 +295,7 @@ proc parsePegLit(p: var TParser): TPeg = proc parseMangleDir(p: var TParser) = var pattern = parsePegLit(p) - if p.tok.xkind != pxStrLit: ExpectIdent(p) + if p.tok.xkind != pxStrLit: expectIdent(p) p.options.mangleRules.add((pattern, p.tok.s)) getTok(p) eatNewLine(p, nil) @@ -326,7 +326,7 @@ proc parseDir(p: var TParser): PNode = of "dynlib", "header", "prefix", "suffix", "class": var key = p.tok.s getTok(p) - if p.tok.xkind != pxStrLit: ExpectIdent(p) + if p.tok.xkind != pxStrLit: expectIdent(p) discard setOption(p.options, key, p.tok.s) getTok(p) eatNewLine(p, nil) diff --git a/compiler/c2nim/tests/vincent.c b/compiler/c2nim/tests/vincent.c new file mode 100644 index 000000000..24c6d6425 --- /dev/null +++ b/compiler/c2nim/tests/vincent.c @@ -0,0 +1,33 @@ +#include <stdlib.h> +#include <stdio.h> + +int rand(void); + +int id2(void) { + return (int *)1; +} + +int id(void (*f)(void)) { + f(); + ((void (*)(int))f)(10); + return 10; + return (20+1); + return (int *)id; +} + +int main() { + float f = .2, + g = 2., + h = 1.0+rand(), + i = 1.0e+3; + int j, a; + for(j = 0, a = 10; j < 0; j++, a++) ; + do { + printf("howdy"); + } while(--i, 0); + if(1) + printf("1"); // error from this comment + else + printf("2"); + return '\x00'; +} diff --git a/compiler/c2nim/tests/vincent.h b/compiler/c2nim/tests/vincent.h new file mode 100644 index 000000000..b4e761ee1 --- /dev/null +++ b/compiler/c2nim/tests/vincent.h @@ -0,0 +1,3 @@ +struct foo { + int x,y,z; +}; diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index 07fba95a3..ec1250155 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -88,7 +88,7 @@ proc openArrayLoc(p: BProc, n: PNode): PRope = result = ropef("$1->data, $1->$2", [a.rdLoc, lenField()]) of tyArray, tyArrayConstr: result = ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))]) - else: InternalError("openArrayLoc: " & typeToString(a.t)) + else: internalError("openArrayLoc: " & typeToString(a.t)) proc genArgStringToCString(p: BProc, n: PNode): PRope {.inline.} = @@ -243,7 +243,7 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) = for i in countup(3, length-1): assert(sonsLen(typ) == sonsLen(typ.n)) if i >= sonsLen(typ): - InternalError(ri.info, "varargs for objective C method?") + internalError(ri.info, "varargs for objective C method?") assert(typ.n.sons[i].kind == nkSym) var param = typ.n.sons[i].sym app(pl, ~" ") diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 873c61ed4..22a00cf29 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -11,7 +11,7 @@ # -------------------------- constant expressions ------------------------ -proc intLiteral(i: biggestInt): PRope = +proc intLiteral(i: BiggestInt): PRope = if (i > low(int32)) and (i <= high(int32)): result = toRope(i) elif i == low(int32): @@ -22,7 +22,7 @@ proc intLiteral(i: biggestInt): PRope = else: result = ~"(IL64(-9223372036854775807) - IL64(1))" -proc int32Literal(i: Int): PRope = +proc int32Literal(i: int): PRope = if i == int(low(int32)): result = ~"(-2147483647 -1)" else: @@ -39,7 +39,7 @@ proc getStrLit(m: BModule, s: string): PRope = discard cgsym(m, "TGenericSeq") result = con("TMP", toRope(backendId())) appf(m.s[cfsData], "STRING_LITERAL($1, $2, $3);$n", - [result, makeCString(s), ToRope(len(s))]) + [result, makeCString(s), toRope(len(s))]) proc genLiteral(p: BProc, n: PNode, ty: PType): PRope = if ty == nil: internalError(n.info, "genLiteral: ty is nil") @@ -62,7 +62,7 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): PRope = of nkNilLit: let t = skipTypes(ty, abstractVarRange) if t.kind == tyProc and t.callConv == ccClosure: - var id = NodeTableTestOrSet(p.module.dataCache, n, gBackendId) + var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId) result = con("TMP", toRope(id)) if id == gBackendId: # not found in cache: @@ -74,7 +74,7 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): PRope = result = toRope("NIM_NIL") of nkStrLit..nkTripleStrLit: if skipTypes(ty, abstractVarRange).kind == tyString: - var id = NodeTableTestOrSet(p.module.dataCache, n, gBackendId) + var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId) if id == gBackendId: # string literal not found in the cache: result = ropecg(p.module, "((#NimStringDesc*) &$1)", @@ -84,9 +84,9 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): PRope = else: result = makeCString(n.strVal) of nkFloatLit..nkFloat64Lit: - result = toRope(n.floatVal.ToStrMaxPrecision) + result = toRope(n.floatVal.toStrMaxPrecision) else: - InternalError(n.info, "genLiteral(" & $n.kind & ')') + internalError(n.info, "genLiteral(" & $n.kind & ')') result = nil proc genLiteral(p: BProc, n: PNode): PRope = @@ -96,7 +96,7 @@ proc bitSetToWord(s: TBitSet, size: int): BiggestInt = result = 0 when true: for j in countup(0, size - 1): - if j < len(s): result = result or `shl`(Ze64(s[j]), j * 8) + if j < len(s): result = result or `shl`(ze64(s[j]), j * 8) else: # not needed, too complex thinking: if CPU[platform.hostCPU].endian == CPU[targetCPU].endian: @@ -117,7 +117,7 @@ proc genRawSetData(cs: TBitSet, size: int): PRope = else: frmt = "0x$1, " else: frmt = "0x$1}$n" - appf(result, frmt, [toRope(toHex(Ze64(cs[i]), 2))]) + appf(result, frmt, [toRope(toHex(ze64(cs[i]), 2))]) else: result = intLiteral(bitSetToWord(cs, size)) # result := toRope('0x' + ToHex(bitSetToWord(cs, size), size * 2)) @@ -127,7 +127,7 @@ proc genSetNode(p: BProc, n: PNode): PRope = var size = int(getSize(n.typ)) toBitSet(n, cs) if size > 8: - var id = NodeTableTestOrSet(p.module.dataCache, n, gBackendId) + var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId) result = con("TMP", toRope(id)) if id == gBackendId: # not found in cache: @@ -155,7 +155,7 @@ proc getStorageLoc(n: PNode): TStorageLoc = of tyVar: result = OnUnknown of tyPtr: result = OnStack of tyRef: result = OnHeap - else: InternalError(n.info, "getStorageLoc") + else: internalError(n.info, "getStorageLoc") of nkBracketExpr, nkDotExpr, nkObjDownConv, nkObjUpConv: result = getStorageLoc(n.sons[0]) else: result = OnUnknown @@ -343,7 +343,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = of tyPtr, tyPointer, tyChar, tyBool, tyEnum, tyCString, tyInt..tyUInt64, tyRange, tyVar: linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) - else: InternalError("genAssignment(" & $ty.kind & ')') + else: internalError("genAssignment(" & $ty.kind & ')') proc getDestLoc(p: BProc, d: var TLoc, typ: PType) = if d.k == locNone: getTemp(p, typ, d) @@ -373,62 +373,62 @@ proc putIntoDest(p: BProc, d: var TLoc, t: PType, r: PRope) = proc binaryStmt(p: BProc, e: PNode, d: var TLoc, frmt: string) = var a, b: TLoc - if d.k != locNone: InternalError(e.info, "binaryStmt") - InitLocExpr(p, e.sons[1], a) - InitLocExpr(p, e.sons[2], b) + if d.k != locNone: internalError(e.info, "binaryStmt") + initLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[2], b) lineCg(p, cpsStmts, frmt, rdLoc(a), rdLoc(b)) proc unaryStmt(p: BProc, e: PNode, d: var TLoc, frmt: string) = var a: TLoc - if d.k != locNone: InternalError(e.info, "unaryStmt") - InitLocExpr(p, e.sons[1], a) + if d.k != locNone: internalError(e.info, "unaryStmt") + initLocExpr(p, e.sons[1], a) lineCg(p, cpsStmts, frmt, [rdLoc(a)]) proc binaryStmtChar(p: BProc, e: PNode, d: var TLoc, frmt: string) = var a, b: TLoc - if (d.k != locNone): InternalError(e.info, "binaryStmtChar") - InitLocExpr(p, e.sons[1], a) - InitLocExpr(p, e.sons[2], b) + if (d.k != locNone): internalError(e.info, "binaryStmtChar") + initLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[2], b) lineCg(p, cpsStmts, frmt, [rdCharLoc(a), rdCharLoc(b)]) proc binaryExpr(p: BProc, e: PNode, d: var TLoc, frmt: string) = var a, b: TLoc assert(e.sons[1].typ != nil) assert(e.sons[2].typ != nil) - InitLocExpr(p, e.sons[1], a) - InitLocExpr(p, e.sons[2], b) + initLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[2], b) putIntoDest(p, d, e.typ, ropecg(p.module, frmt, [rdLoc(a), rdLoc(b)])) proc binaryExprChar(p: BProc, e: PNode, d: var TLoc, frmt: string) = var a, b: TLoc assert(e.sons[1].typ != nil) assert(e.sons[2].typ != nil) - InitLocExpr(p, e.sons[1], a) - InitLocExpr(p, e.sons[2], b) + initLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[2], b) putIntoDest(p, d, e.typ, ropecg(p.module, frmt, [a.rdCharLoc, b.rdCharLoc])) proc unaryExpr(p: BProc, e: PNode, d: var TLoc, frmt: string) = var a: TLoc - InitLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[1], a) putIntoDest(p, d, e.typ, ropecg(p.module, frmt, [rdLoc(a)])) proc unaryExprChar(p: BProc, e: PNode, d: var TLoc, frmt: string) = var a: TLoc - InitLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[1], a) putIntoDest(p, d, e.typ, ropecg(p.module, frmt, [rdCharLoc(a)])) proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) = const - prc: array[mAddi..mModi64, string] = ["addInt", "subInt", "mulInt", + prc: array[mAddI..mModI64, string] = ["addInt", "subInt", "mulInt", "divInt", "modInt", "addInt64", "subInt64", "mulInt64", "divInt64", "modInt64"] - opr: array[mAddi..mModi64, string] = ["+", "-", "*", "/", "%", "+", "-", + opr: array[mAddI..mModI64, string] = ["+", "-", "*", "/", "%", "+", "-", "*", "/", "%"] var a, b: TLoc assert(e.sons[1].typ != nil) assert(e.sons[2].typ != nil) - InitLocExpr(p, e.sons[1], a) - InitLocExpr(p, e.sons[2], b) + initLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[2], b) var t = skipTypes(e.typ, abstractRange) if optOverflowCheck notin p.options: putIntoDest(p, d, e.typ, ropef("(NI$4)($2 $1 $3)", [toRope(opr[m]), @@ -436,7 +436,7 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) = else: var storage: PRope var size = getSize(t) - if size < platform.IntSize: + if size < platform.intSize: storage = toRope("NI") else: storage = getTypeDesc(p.module, t) @@ -444,7 +444,7 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) = linefmt(p, cpsLocals, "$1 $2;$n", storage, tmp) lineCg(p, cpsStmts, "$1 = #$2($3, $4);$n", tmp, toRope(prc[m]), rdLoc(a), rdLoc(b)) - if size < platform.IntSize or t.kind in {tyRange, tyEnum, tySet}: + if size < platform.intSize or t.kind in {tyRange, tyEnum, tySet}: linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n", tmp, intLiteral(firstOrd(t)), intLiteral(lastOrd(t))) putIntoDest(p, d, e.typ, ropef("(NI$1)($2)", [toRope(getSize(t)*8), tmp])) @@ -460,7 +460,7 @@ proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) = a: TLoc t: PType assert(e.sons[1].typ != nil) - InitLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[1], a) t = skipTypes(e.typ, abstractRange) if optOverflowCheck in p.options: linefmt(p, cpsStmts, "if ($1 == $2) #raiseOverflow();$n", @@ -526,11 +526,11 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = "($1 != $2)"] # Xor var a, b: TLoc - s: biggestInt + s: BiggestInt assert(e.sons[1].typ != nil) assert(e.sons[2].typ != nil) - InitLocExpr(p, e.sons[1], a) - InitLocExpr(p, e.sons[2], b) + initLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[2], b) # BUGFIX: cannot use result-type here, as it may be a boolean s = max(getSize(a.t), getSize(b.t)) * 8 putIntoDest(p, d, e.typ, @@ -541,8 +541,8 @@ proc genEqProc(p: BProc, e: PNode, d: var TLoc) = var a, b: TLoc assert(e.sons[1].typ != nil) assert(e.sons[2].typ != nil) - InitLocExpr(p, e.sons[1], a) - InitLocExpr(p, e.sons[2], b) + initLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[2], b) if a.t.callConv == ccClosure: putIntoDest(p, d, e.typ, ropef("($1.ClPrc == $2.ClPrc && $1.ClEnv == $2.ClEnv)", [ @@ -585,7 +585,7 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = a: TLoc t: PType assert(e.sons[1].typ != nil) - InitLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[1], a) t = skipTypes(e.typ, abstractRange) putIntoDest(p, d, e.typ, ropef(unArithTab[op], [rdLoc(a), toRope(getSize(t) * 8), @@ -606,21 +606,21 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc) = d.s = OnUnknown of tyPtr: d.s = OnUnknown # BUGFIX! - else: InternalError(e.info, "genDeref " & $a.t.kind) + else: internalError(e.info, "genDeref " & $a.t.kind) putIntoDest(p, d, a.t.sons[0], ropef("(*$1)", [rdLoc(a)])) proc genAddr(p: BProc, e: PNode, d: var TLoc) = # careful 'addr(myptrToArray)' needs to get the ampersand: if e.sons[0].typ.skipTypes(abstractInst).kind in {tyRef, tyPtr}: var a: TLoc - InitLocExpr(p, e.sons[0], a) + initLocExpr(p, e.sons[0], a) putIntoDest(p, d, e.typ, con("&", a.r)) #Message(e.info, warnUser, "HERE NEW &") elif mapType(e.sons[0].typ) == ctArray: expr(p, e.sons[0], d) else: var a: TLoc - InitLocExpr(p, e.sons[0], a) + initLocExpr(p, e.sons[0], a) putIntoDest(p, d, e.typ, addrLoc(a)) template inheritLocation(d: var TLoc, a: TLoc) = @@ -630,7 +630,7 @@ template inheritLocation(d: var TLoc, a: TLoc) = proc genRecordFieldAux(p: BProc, e: PNode, d, a: var TLoc): PType = initLocExpr(p, e.sons[0], a) - if e.sons[1].kind != nkSym: InternalError(e.info, "genRecordFieldAux") + if e.sons[1].kind != nkSym: internalError(e.info, "genRecordFieldAux") d.inheritLocation(a) discard getTypeDesc(p.module, a.t) # fill the record's fields.loc result = a.t @@ -664,13 +664,13 @@ proc genRecordField(p: BProc, e: PNode, d: var TLoc) = var field: PSym = nil while ty != nil: if ty.kind notin {tyTuple, tyObject}: - InternalError(e.info, "genRecordField") + internalError(e.info, "genRecordField") field = lookupInRecord(ty.n, f.name) if field != nil: break if gCmd != cmdCompileToCpp: app(r, ".Sup") - ty = GetUniqueType(ty.sons[0]) - if field == nil: InternalError(e.info, "genRecordField 2 ") - if field.loc.r == nil: InternalError(e.info, "genRecordField 3") + ty = getUniqueType(ty.sons[0]) + if field == nil: internalError(e.info, "genRecordField 2 ") + if field.loc.r == nil: internalError(e.info, "genRecordField 3") appf(r, ".$1", [field.loc.r]) putIntoDest(p, d, field.typ, r) @@ -686,11 +686,11 @@ proc genFieldCheck(p: BProc, e: PNode, obj: PRope, field: PSym) = if op.magic == mNot: it = it.sons[1] assert(it.sons[2].kind == nkSym) initLoc(test, locNone, it.typ, OnStack) - InitLocExpr(p, it.sons[1], u) + initLocExpr(p, it.sons[1], u) initLoc(v, locExpr, it.sons[2].typ, OnUnknown) v.r = ropef("$1.$2", [obj, it.sons[2].sym.loc.r]) genInExprAux(p, it, u, v, test) - let id = NodeTableTestOrSet(p.module.dataCache, + let id = nodeTableTestOrSet(p.module.dataCache, newStrNode(nkStrLit, field.name.s), gBackendId) let strLit = if id == gBackendId: getStrLit(p.module, field.name.s) else: con("TMP", toRope(id)) @@ -720,9 +720,9 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) = if field != nil: break if gCmd != cmdCompileToCpp: app(r, ".Sup") ty = getUniqueType(ty.sons[0]) - if field == nil: InternalError(e.info, "genCheckedRecordField") + if field == nil: internalError(e.info, "genCheckedRecordField") if field.loc.r == nil: - InternalError(e.info, "genCheckedRecordField") # generate the checks: + internalError(e.info, "genCheckedRecordField") # generate the checks: genFieldCheck(p, e, r, field) app(r, rfmt(nil, ".$1", field.loc.r)) putIntoDest(p, d, field.typ, r) @@ -774,7 +774,7 @@ proc genOpenArrayElem(p: BProc, e: PNode, d: var TLoc) = putIntoDest(p, d, elemType(skipTypes(a.t, abstractVar)), rfmt(nil, "$1[$2]", rdLoc(a), rdCharLoc(b))) -proc genSeqElem(p: BPRoc, e: PNode, d: var TLoc) = +proc genSeqElem(p: BProc, e: PNode, d: var TLoc) = var a, b: TLoc initLocExpr(p, e.sons[0], a) initLocExpr(p, e.sons[1], b) @@ -838,7 +838,7 @@ proc genAndOr(p: BProc, e: PNode, d: var TLoc, m: TMagic) = proc genEcho(p: BProc, n: PNode) = # this unusal way of implementing it ensures that e.g. ``echo("hallo", 45)`` # is threadsafe. - discard lists.IncludeStr(p.module.headerFiles, "<stdio.h>") + discard lists.includeStr(p.module.headerFiles, "<stdio.h>") var args: PRope = nil var a: TLoc for i in countup(1, n.len-1): @@ -872,12 +872,12 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) = for i in countup(0, sonsLen(e) - 2): # compute the length expression: initLocExpr(p, e.sons[i + 1], a) - if skipTypes(e.sons[i + 1].Typ, abstractVarRange).kind == tyChar: - Inc(L) + if skipTypes(e.sons[i + 1].typ, abstractVarRange).kind == tyChar: + inc(L) app(appends, rfmt(p.module, "#appendChar($1, $2);$n", tmp.r, rdLoc(a))) else: if e.sons[i + 1].kind in {nkStrLit..nkTripleStrLit}: - Inc(L, len(e.sons[i + 1].strVal)) + inc(L, len(e.sons[i + 1].strVal)) else: appf(lens, "$1->$2 + ", [rdLoc(a), lenField()]) app(appends, rfmt(p.module, "#appendString($1, $2);$n", tmp.r, rdLoc(a))) @@ -910,13 +910,13 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) = for i in countup(0, sonsLen(e) - 3): # compute the length expression: initLocExpr(p, e.sons[i + 2], a) - if skipTypes(e.sons[i + 2].Typ, abstractVarRange).kind == tyChar: - Inc(L) + if skipTypes(e.sons[i + 2].typ, abstractVarRange).kind == tyChar: + inc(L) app(appends, rfmt(p.module, "#appendChar($1, $2);$n", rdLoc(dest), rdLoc(a))) else: if e.sons[i + 2].kind in {nkStrLit..nkTripleStrLit}: - Inc(L, len(e.sons[i + 2].strVal)) + inc(L, len(e.sons[i + 2].strVal)) else: appf(lens, "$1->$2 + ", [rdLoc(a), lenField()]) app(appends, rfmt(p.module, "#appendString($1, $2);$n", @@ -935,12 +935,12 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) = else: "$1 = ($2) #incrSeq($1, sizeof($3));$n" var a, b, dest: TLoc - InitLocExpr(p, e.sons[1], a) - InitLocExpr(p, e.sons[2], b) + initLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[2], b) lineCg(p, cpsStmts, seqAppendPattern, [ rdLoc(a), getTypeDesc(p.module, skipTypes(e.sons[1].typ, abstractVar)), - getTypeDesc(p.module, skipTypes(e.sons[2].Typ, abstractVar))]) + getTypeDesc(p.module, skipTypes(e.sons[2].typ, abstractVar))]) keepAlive(p, a) initLoc(dest, locExpr, b.t, OnHeap) dest.r = rfmt(nil, "$1->data[$1->$2-1]", rdLoc(a), lenField()) @@ -948,7 +948,7 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) = proc genReset(p: BProc, n: PNode) = var a: TLoc - InitLocExpr(p, n.sons[1], a) + initLocExpr(p, n.sons[1], a) linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n", addrLoc(a), genTypeInfo(p.module, skipTypes(a.t, abstractVarRange))) @@ -959,8 +959,8 @@ proc rawGenNew(p: BProc, a: TLoc, sizeExpr: PRope) = initLoc(b, locExpr, a.t, OnHeap) if sizeExpr.isNil: sizeExpr = ropef("sizeof($1)", - getTypeDesc(p.module, skipTypes(reftype.sons[0], abstractRange))) - let args = [getTypeDesc(p.module, reftype), + getTypeDesc(p.module, skipTypes(refType.sons[0], abstractRange))) + let args = [getTypeDesc(p.module, refType), genTypeInfo(p.module, refType), sizeExpr] if a.s == OnHeap and usesNativeGC(): @@ -979,11 +979,11 @@ proc rawGenNew(p: BProc, a: TLoc, sizeExpr: PRope) = proc genNew(p: BProc, e: PNode) = var a: TLoc - InitLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[1], a) # 'genNew' also handles 'unsafeNew': if e.len == 3: var se: TLoc - InitLocExpr(p, e.sons[2], se) + initLocExpr(p, e.sons[2], se) rawGenNew(p, a, se.rdLoc) else: rawGenNew(p, a, nil) @@ -991,7 +991,7 @@ proc genNew(p: BProc, e: PNode) = proc genNewSeqAux(p: BProc, dest: TLoc, length: PRope) = let seqtype = skipTypes(dest.t, abstractVarRange) let args = [getTypeDesc(p.module, seqtype), - genTypeInfo(p.module, seqType), length] + genTypeInfo(p.module, seqtype), length] var call: TLoc initLoc(call, locExpr, dest.t, OnHeap) if dest.s == OnHeap and usesNativeGC(): @@ -1007,8 +1007,8 @@ proc genNewSeqAux(p: BProc, dest: TLoc, length: PRope) = proc genNewSeq(p: BProc, e: PNode) = var a, b: TLoc - InitLocExpr(p, e.sons[1], a) - InitLocExpr(p, e.sons[2], b) + initLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[2], b) genNewSeqAux(p, a, b.rdLoc) proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = @@ -1032,15 +1032,15 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = field = lookupInRecord(ty.n, it.sons[0].sym.name) if field != nil: break if gCmd != cmdCompileToCpp: app(tmp2.r, ".Sup") - ty = GetUniqueType(ty.sons[0]) - if field == nil or field.loc.r == nil: InternalError(e.info, "genObjConstr") + ty = getUniqueType(ty.sons[0]) + if field == nil or field.loc.r == nil: internalError(e.info, "genObjConstr") if it.len == 3 and optFieldCheck in p.options: genFieldCheck(p, it.sons[2], r, field) app(tmp2.r, ".") app(tmp2.r, field.loc.r) tmp2.k = locTemp tmp2.t = field.loc.t - tmp2.s = onHeap + tmp2.s = OnHeap tmp2.heapRoot = tmp.r expr(p, it.sons[1], tmp2) if d.k == locNone: @@ -1088,14 +1088,14 @@ proc genNewFinalize(p: BProc, e: PNode) = ti: PRope oldModule: BModule refType = skipTypes(e.sons[1].typ, abstractVarRange) - InitLocExpr(p, e.sons[1], a) - InitLocExpr(p, e.sons[2], f) + initLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[2], f) initLoc(b, locExpr, a.t, OnHeap) ti = genTypeInfo(p.module, refType) appf(p.module.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)]) b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [ getTypeDesc(p.module, refType), - ti, getTypeDesc(p.module, skipTypes(reftype.sons[0], abstractRange))]) + ti, getTypeDesc(p.module, skipTypes(refType.sons[0], abstractRange))]) genAssignment(p, a, b, {needToKeepAlive}) # set the object type: bt = skipTypes(refType.sons[0], abstractRange) genObjectInit(p, cpsStmts, bt, a, false) @@ -1116,7 +1116,7 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) = app(r, ~".Sup") t = skipTypes(t.sons[0], typedescInst) if isObjLackingTypeField(t): - GlobalError(x.info, errGenerated, + globalError(x.info, errGenerated, "no 'of' operator available for pure objects") if nilCheck != nil: r = rfmt(p.module, "(($1) && #isObj($2.m_type, $3))", @@ -1132,7 +1132,7 @@ proc genOf(p: BProc, n: PNode, d: var TLoc) = proc genRepr(p: BProc, e: PNode, d: var TLoc) = # XXX we don't generate keep alive info for now here var a: TLoc - InitLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[1], a) var t = skipTypes(e.sons[1].typ, abstractVarRange) case t.kind of tyInt..tyInt64, tyUInt..tyUInt64: @@ -1164,7 +1164,7 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) = of tyArray, tyArrayConstr: putIntoDest(p, b, e.typ, ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))])) - else: InternalError(e.sons[0].info, "genRepr()") + else: internalError(e.sons[0].info, "genRepr()") putIntoDest(p, d, e.typ, ropecg(p.module, "#reprOpenArray($1, $2)", [rdLoc(b), genTypeInfo(p.module, elemType(t))])) @@ -1183,7 +1183,7 @@ proc genGetTypeInfo(p: BProc, e: PNode, d: var TLoc) = proc genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) = var a: TLoc - InitLocExpr(p, n.sons[1], a) + initLocExpr(p, n.sons[1], a) a.r = ropecg(p.module, frmt, [rdLoc(a)]) if d.k == locNone: getTemp(p, n.typ, d) genAssignment(p, d, a, {needToKeepAlive}) @@ -1191,12 +1191,12 @@ proc genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) = proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) = var a = e.sons[1] if a.kind == nkHiddenAddr: a = a.sons[0] - var typ = skipTypes(a.Typ, abstractVar) + var typ = skipTypes(a.typ, abstractVar) case typ.kind of tyOpenArray, tyVarargs: if op == mHigh: unaryExpr(p, e, d, "($1Len0-1)") else: unaryExpr(p, e, d, "$1Len0") - of tyCstring: + of tyCString: if op == mHigh: unaryExpr(p, e, d, "(strlen($1)-1)") else: unaryExpr(p, e, d, "strlen($1)") of tyString, tySequence: @@ -1208,15 +1208,15 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) = else: unaryExpr(p, e, d, "$1->len") of tyArray, tyArrayConstr: # YYY: length(sideeffect) is optimized away incorrectly? - if op == mHigh: putIntoDest(p, d, e.typ, toRope(lastOrd(Typ))) + if op == mHigh: putIntoDest(p, d, e.typ, toRope(lastOrd(typ))) else: putIntoDest(p, d, e.typ, toRope(lengthOrd(typ))) - else: InternalError(e.info, "genArrayLen()") + else: internalError(e.info, "genArrayLen()") proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) = var a, b: TLoc assert(d.k == locNone) - InitLocExpr(p, e.sons[1], a) - InitLocExpr(p, e.sons[2], b) + initLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[2], b) var t = skipTypes(e.sons[1].typ, abstractVar) let setLenPattern = if gCmd != cmdCompileToCpp: "$1 = ($3) #setLengthSeq(&($1)->Sup, sizeof($4), $2);$n" @@ -1230,7 +1230,7 @@ proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) = proc genSetLengthStr(p: BProc, e: PNode, d: var TLoc) = binaryStmt(p, e, d, "$1 = #setLengthStr($1, $2);$n") - keepAlive(P, d) + keepAlive(p, d) proc genSwap(p: BProc, e: PNode, d: var TLoc) = # swap(a, b) --> @@ -1239,8 +1239,8 @@ proc genSwap(p: BProc, e: PNode, d: var TLoc) = # b = temp var a, b, tmp: TLoc getTemp(p, skipTypes(e.sons[1].typ, abstractVar), tmp) - InitLocExpr(p, e.sons[1], a) # eval a - InitLocExpr(p, e.sons[2], b) # eval b + initLocExpr(p, e.sons[1], a) # eval a + initLocExpr(p, e.sons[2], b) # eval b genAssignment(p, tmp, a, {}) genAssignment(p, a, b, {}) genAssignment(p, b, tmp, {}) @@ -1256,10 +1256,10 @@ proc rdSetElemLoc(a: TLoc, setType: PType): PRope = proc fewCmps(s: PNode): bool = # this function estimates whether it is better to emit code # for constructing the set or generating a bunch of comparisons directly - if s.kind != nkCurly: InternalError(s.info, "fewCmps") + if s.kind != nkCurly: internalError(s.info, "fewCmps") if (getSize(s.typ) <= platform.intSize) and (nfAllConst in s.flags): result = false # it is better to emit the set generation code - elif elemType(s.typ).Kind in {tyInt, tyInt16..tyInt64}: + elif elemType(s.typ).kind in {tyInt, tyInt16..tyInt64}: result = true # better not emit the set if int is basetype! else: result = sonsLen(s) <= 8 # 8 seems to be a good value @@ -1278,13 +1278,13 @@ proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc) = proc binaryStmtInExcl(p: BProc, e: PNode, d: var TLoc, frmt: string) = var a, b: TLoc assert(d.k == locNone) - InitLocExpr(p, e.sons[1], a) - InitLocExpr(p, e.sons[2], b) + initLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[2], b) lineF(p, cpsStmts, frmt, [rdLoc(a), rdSetElemLoc(b, a.t)]) proc genInOp(p: BProc, e: PNode, d: var TLoc) = var a, b, x, y: TLoc - if (e.sons[1].Kind == nkCurly) and fewCmps(e.sons[1]): + if (e.sons[1].kind == nkCurly) and fewCmps(e.sons[1]): # a set constructor but not a constant set: # do not emit the set, but generate a bunch of comparisons; and if we do # so, we skip the unnecessary range check: This is a semantical extension @@ -1298,13 +1298,13 @@ proc genInOp(p: BProc, e: PNode, d: var TLoc) = b.r = toRope("(") var length = sonsLen(e.sons[1]) for i in countup(0, length - 1): - if e.sons[1].sons[i].Kind == nkRange: - InitLocExpr(p, e.sons[1].sons[i].sons[0], x) - InitLocExpr(p, e.sons[1].sons[i].sons[1], y) + if e.sons[1].sons[i].kind == nkRange: + initLocExpr(p, e.sons[1].sons[i].sons[0], x) + initLocExpr(p, e.sons[1].sons[i].sons[1], y) appf(b.r, "$1 >= $2 && $1 <= $3", [rdCharLoc(a), rdCharLoc(x), rdCharLoc(y)]) else: - InitLocExpr(p, e.sons[1].sons[i], x) + initLocExpr(p, e.sons[1].sons[i], x) appf(b.r, "$1 == $2", [rdCharLoc(a), rdCharLoc(x)]) if i < length - 1: app(b.r, " || ") app(b.r, ")") @@ -1312,8 +1312,8 @@ proc genInOp(p: BProc, e: PNode, d: var TLoc) = else: assert(e.sons[1].typ != nil) assert(e.sons[2].typ != nil) - InitLocExpr(p, e.sons[1], a) - InitLocExpr(p, e.sons[2], b) + initLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[2], b) genInExprAux(p, e, a, b, d) proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) = @@ -1326,7 +1326,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) = "if ($3) $3 = (memcmp($4, $5, $2) != 0);$n", "&", "|", "& ~", "^"] var a, b, i: TLoc - var setType = skipTypes(e.sons[1].Typ, abstractVar) + var setType = skipTypes(e.sons[1].typ, abstractVar) var size = int(getSize(setType)) case size of 1, 2, 4, 8: @@ -1391,7 +1391,7 @@ proc genSomeCast(p: BProc, e: PNode, d: var TLoc) = # we use whatever C gives us. Except if we have a value-type, we need to go # through its address: var a: TLoc - InitLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[1], a) let etyp = skipTypes(e.typ, abstractRange) if etyp.kind in ValueTypes and lfIndirect notin a.flags: putIntoDest(p, d, e.typ, ropef("(*($1*) ($2))", @@ -1433,13 +1433,13 @@ proc genRangeChck(p: BProc, n: PNode, d: var TLoc, magic: string) = var dest = skipTypes(n.typ, abstractVar) # range checks for unsigned turned out to be buggy and annoying: if optRangeCheck notin p.options or dest.kind in {tyUInt..tyUInt64}: - InitLocExpr(p, n.sons[0], a) + initLocExpr(p, n.sons[0], a) putIntoDest(p, d, n.typ, ropef("(($1) ($2))", [getTypeDesc(p.module, dest), rdCharLoc(a)])) else: - InitLocExpr(p, n.sons[0], a) + initLocExpr(p, n.sons[0], a) if leValue(n.sons[2], n.sons[1]): - InternalError(n.info, "range check will always fail; empty range") + internalError(n.info, "range check will always fail; empty range") putIntoDest(p, d, dest, ropecg(p.module, "(($1)#$5($2, $3, $4))", [ getTypeDesc(p.module, dest), rdCharLoc(a), genLiteral(p, n.sons[1], dest), genLiteral(p, n.sons[2], dest), @@ -1481,17 +1481,17 @@ proc genStrEquals(p: BProc, e: PNode, d: var TLoc) = binaryExpr(p, e, d, "#eqStrings($1, $2)") proc binaryFloatArith(p: BProc, e: PNode, d: var TLoc, m: TMagic) = - if {optNanCheck, optInfCheck} * p.options != {}: + if {optNaNCheck, optInfCheck} * p.options != {}: const opr: array[mAddF64..mDivF64, string] = ["+", "-", "*", "/"] var a, b: TLoc assert(e.sons[1].typ != nil) assert(e.sons[2].typ != nil) - InitLocExpr(p, e.sons[1], a) - InitLocExpr(p, e.sons[2], b) + initLocExpr(p, e.sons[1], a) + initLocExpr(p, e.sons[2], b) putIntoDest(p, d, e.typ, rfmt(nil, "(($4)($2) $1 ($4)($3))", toRope(opr[m]), rdLoc(a), rdLoc(b), getSimpleTypeDesc(p.module, e[1].typ))) - if optNanCheck in p.options: + if optNaNCheck in p.options: linefmt(p, cpsStmts, "#nanCheck($1);$n", rdLoc(d)) if optInfCheck in p.options: linefmt(p, cpsStmts, "#infCheck($1);$n", rdLoc(d)) @@ -1507,30 +1507,30 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = of mAddF64..mDivF64: binaryFloatArith(p, e, d, op) of mShrI..mXor: binaryArith(p, e, d, op) of mEqProc: genEqProc(p, e, d) - of mAddi..mModi64: binaryArithOverflow(p, e, d, op) + of mAddI..mModI64: binaryArithOverflow(p, e, d, op) of mRepr: genRepr(p, e, d) of mGetTypeInfo: genGetTypeInfo(p, e, d) of mSwap: genSwap(p, e, d) of mUnaryLt: - if not (optOverflowCheck in p.Options): unaryExpr(p, e, d, "$1 - 1") + if not (optOverflowCheck in p.options): unaryExpr(p, e, d, "$1 - 1") else: unaryExpr(p, e, d, "#subInt($1, 1)") of mPred: # XXX: range checking? - if not (optOverflowCheck in p.Options): binaryExpr(p, e, d, "$1 - $2") + if not (optOverflowCheck in p.options): binaryExpr(p, e, d, "$1 - $2") else: binaryExpr(p, e, d, "#subInt($1, $2)") of mSucc: # XXX: range checking? - if not (optOverflowCheck in p.Options): binaryExpr(p, e, d, "$1 + $2") + if not (optOverflowCheck in p.options): binaryExpr(p, e, d, "$1 + $2") else: binaryExpr(p, e, d, "#addInt($1, $2)") of mInc: - if not (optOverflowCheck in p.Options): + if not (optOverflowCheck in p.options): binaryStmt(p, e, d, "$1 += $2;$n") elif skipTypes(e.sons[1].typ, abstractVar).kind == tyInt64: binaryStmt(p, e, d, "$1 = #addInt64($1, $2);$n") else: binaryStmt(p, e, d, "$1 = #addInt($1, $2);$n") of ast.mDec: - if not (optOverflowCheck in p.Options): + if not (optOverflowCheck in p.options): binaryStmt(p, e, d, "$1 -= $2;$n") elif skipTypes(e.sons[1].typ, abstractVar).kind == tyInt64: binaryStmt(p, e, d, "$1 = #subInt64($1, $2);$n") @@ -1593,7 +1593,7 @@ proc handleConstExpr(p: BProc, n: PNode, d: var TLoc): bool = if (nfAllConst in n.flags) and (d.k == locNone) and (sonsLen(n) > 0): var t = getUniqueType(n.typ) discard getTypeDesc(p.module, t) # so that any fields are initialized - var id = NodeTableTestOrSet(p.module.dataCache, n, gBackendId) + var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId) fillLoc(d, locData, t, con("TMP", toRope(id)), OnHeap) if id == gBackendId: # expression not found in the cache: @@ -1669,14 +1669,14 @@ proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) = [rdLoc(d), mangleRecFieldName(t.n.sons[i].sym, t)]) expr(p, it, rec) -proc IsConstClosure(n: PNode): bool {.inline.} = +proc isConstClosure(n: PNode): bool {.inline.} = result = n.sons[0].kind == nkSym and isRoutine(n.sons[0].sym) and n.sons[1].kind == nkNilLit proc genClosure(p: BProc, n: PNode, d: var TLoc) = assert n.kind == nkClosure - if IsConstClosure(n): + if isConstClosure(n): inc(p.labels) var tmp = con("LOC", toRope(p.labels)) appf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n", @@ -1760,7 +1760,7 @@ proc downConv(p: BProc, n: PNode, d: var TLoc) = proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) = var t = getUniqueType(n.typ) discard getTypeDesc(p.module, t) # so that any fields are initialized - var id = NodeTableTestOrSet(p.module.dataCache, n, gBackendId) + var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId) var tmp = con("TMP", toRope(id)) if id == gBackendId: @@ -1778,7 +1778,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = case n.kind of nkSym: var sym = n.sym - case sym.Kind + case sym.kind of skMethod: if sym.getBody.kind == nkEmpty or sfDispatcher in sym.flags: # we cannot produce code for the dispatcher yet: @@ -1790,7 +1790,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = of skProc, skConverter, skIterator: genProc(p.module, sym) if sym.loc.r == nil or sym.loc.t == nil: - InternalError(n.info, "expr: proc not init " & sym.name.s) + internalError(n.info, "expr: proc not init " & sym.name.s) putLocIntoDest(p, d, sym.loc) of skConst: if sfFakeConst in sym.flags: @@ -1805,9 +1805,9 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = of skVar, skForVar, skResult, skLet: if sfGlobal in sym.flags: genVarPrototype(p.module, sym) if sym.loc.r == nil or sym.loc.t == nil: - InternalError(n.info, "expr: var not init " & sym.name.s) + internalError(n.info, "expr: var not init " & sym.name.s) if sfThread in sym.flags: - AccessThreadLocalVar(p, sym) + accessThreadLocalVar(p, sym) if emulatedThreadVars(): putIntoDest(p, d, sym.loc.t, con("NimTV->", sym.loc.r)) else: @@ -1816,13 +1816,13 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = putLocIntoDest(p, d, sym.loc) of skTemp: if sym.loc.r == nil or sym.loc.t == nil: - InternalError(n.info, "expr: temp not init " & sym.name.s) + internalError(n.info, "expr: temp not init " & sym.name.s) putLocIntoDest(p, d, sym.loc) of skParam: if sym.loc.r == nil or sym.loc.t == nil: - InternalError(n.info, "expr: param not init " & sym.name.s) + internalError(n.info, "expr: param not init " & sym.name.s) putLocIntoDest(p, d, sym.loc) - else: InternalError(n.info, "expr(" & $sym.kind & "); unknown symbol") + else: internalError(n.info, "expr(" & $sym.kind & "); unknown symbol") of nkNilLit: if not isEmptyType(n.typ): putIntoDest(p, d, n.typ, genLiteral(p, n)) @@ -1876,7 +1876,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = of tySequence, tyString: genSeqElem(p, n, d) of tyCString: genCStringElem(p, n, d) of tyTuple: genTupleElem(p, n, d) - else: InternalError(n.info, "expr(nkBracketExpr, " & $ty.kind & ')') + else: internalError(n.info, "expr(nkBracketExpr, " & $ty.kind & ')') of nkDerefExpr, nkHiddenDeref: genDeref(p, n, d) of nkDotExpr: genRecordField(p, n, d) of nkCheckedFieldExpr: genCheckedRecordField(p, n, d) @@ -1896,7 +1896,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = var sym = n.sons[namePos].sym genProc(p.module, sym) if sym.loc.r == nil or sym.loc.t == nil: - InternalError(n.info, "expr: proc not init " & sym.name.s) + internalError(n.info, "expr: proc not init " & sym.name.s) putLocIntoDest(p, d, sym.loc) of nkClosure: genClosure(p, n, d) of nkMetaNode: expr(p, n.sons[0], d) @@ -1952,7 +1952,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = of nkState: genState(p, n) of nkGotoState: genGotoState(p, n) of nkBreakState: genBreakState(p, n) - else: InternalError(n.info, "expr(" & $n.kind & "); unknown node kind") + else: internalError(n.info, "expr(" & $n.kind & "); unknown node kind") proc genNamedConstExpr(p: BProc, n: PNode): PRope = if n.kind == nkExprColonExpr: result = genConstExpr(p, n.sons[1]) @@ -1990,7 +1990,7 @@ proc genConstSeq(p: BProc, n: PNode, t: PType): PRope = result = ropef("(($1)&$2)", [getTypeDesc(p.module, t), result]) proc genConstExpr(p: BProc, n: PNode): PRope = - case n.Kind + case n.kind of nkHiddenStdConv, nkHiddenSubConv: result = genConstExpr(p, n.sons[1]) of nkCurly: diff --git a/compiler/ccgmerge.nim b/compiler/ccgmerge.nim index c6c294b97..514b77b73 100644 --- a/compiler/ccgmerge.nim +++ b/compiler/ccgmerge.nim @@ -108,7 +108,7 @@ proc genMergeInfo*(m: BModule): PRope = s.add("labels:") encodeVInt(m.labels, s) s.add(" hasframe:") - encodeVInt(ord(m.FrameDeclared), s) + encodeVInt(ord(m.frameDeclared), s) s.add(tnl) s.add("*/") result = s.toRope @@ -119,8 +119,8 @@ proc skipWhite(L: var TBaseLexer) = var pos = L.bufpos while true: case ^pos - of CR: pos = nimlexbase.HandleCR(L, pos) - of LF: pos = nimlexbase.HandleLF(L, pos) + of CR: pos = nimlexbase.handleCR(L, pos) + of LF: pos = nimlexbase.handleLF(L, pos) of ' ': inc pos else: break L.bufpos = pos @@ -129,8 +129,8 @@ proc skipUntilCmd(L: var TBaseLexer) = var pos = L.bufpos while true: case ^pos - of CR: pos = nimlexbase.HandleCR(L, pos) - of LF: pos = nimlexbase.HandleLF(L, pos) + of CR: pos = nimlexbase.handleCR(L, pos) + of LF: pos = nimlexbase.handleLF(L, pos) of '\0': break of '/': if ^(pos+1) == '*' and ^(pos+2) == '\t': @@ -179,15 +179,15 @@ proc readVerbatimSection(L: var TBaseLexer): PRope = while true: case buf[pos] of CR: - pos = nimlexbase.HandleCR(L, pos) + pos = nimlexbase.handleCR(L, pos) buf = L.buf r.add(tnl) of LF: - pos = nimlexbase.HandleLF(L, pos) + pos = nimlexbase.handleLF(L, pos) buf = L.buf r.add(tnl) of '\0': - InternalError("ccgmerge: expected: " & NimMergeEndMark) + internalError("ccgmerge: expected: " & NimMergeEndMark) break else: if atEndMark(buf, pos): @@ -208,7 +208,7 @@ proc readKey(L: var TBaseLexer, result: var string) = if buf[pos] != ':': internalError("ccgmerge: ':' expected") L.bufpos = pos + 1 # skip ':' -proc NewFakeType(id: int): PType = +proc newFakeType(id: int): PType = new(result) result.id = id @@ -224,7 +224,7 @@ proc readTypeCache(L: var TBaseLexer, result: var TIdTable) = # XXX little hack: we create a "fake" type object with the correct Id # better would be to adapt the data structure to not even store the # object as key, but only the Id - IdTablePut(result, newFakeType(key), value.toRope) + idTablePut(result, newFakeType(key), value.toRope) inc L.bufpos proc readIntSet(L: var TBaseLexer, result: var TIntSet) = @@ -249,14 +249,14 @@ proc processMergeInfo(L: var TBaseLexer, m: BModule) = of "declared": readIntSet(L, m.declaredThings) of "typeInfo": readIntSet(L, m.typeInfoMarker) of "labels": m.labels = decodeVInt(L.buf, L.bufpos) - of "hasframe": m.FrameDeclared = decodeVInt(L.buf, L.bufpos) != 0 - else: InternalError("ccgmerge: unkown key: " & k) + of "hasframe": m.frameDeclared = decodeVInt(L.buf, L.bufpos) != 0 + else: internalError("ccgmerge: unkown key: " & k) when not defined(nimhygiene): {.pragma: inject.} template withCFile(cfilename: string, body: stmt) {.immediate.} = - var s = LLStreamOpen(cfilename, fmRead) + var s = llStreamOpen(cfilename, fmRead) if s == nil: return var L {.inject.}: TBaseLexer openBaseLexer(L, s) @@ -300,9 +300,9 @@ proc readMergeSections(cfilename: string, m: var TMergeSections) = if sectionB >= 0 and sectionB <= high(TCProcSection).int: m.p[TCProcSection(sectionB)] = verbatim else: - InternalError("ccgmerge: unknown section: " & k) + internalError("ccgmerge: unknown section: " & k) else: - InternalError("ccgmerge: '*/' expected") + internalError("ccgmerge: '*/' expected") proc mergeRequired*(m: BModule): bool = for i in cfsHeaders..cfsProcs: @@ -323,4 +323,3 @@ proc mergeFiles*(cfilename: string, m: BModule) = m.s[i] = con(old.f[i], m.s[i]) for i in low(TCProcSection)..high(TCProcSection): m.initProc.s(i) = con(old.p[i], m.initProc.s(i)) - diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index ac4bbb79f..af0d657f1 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -16,7 +16,7 @@ const # above X strings a hash-switch for strings is generated proc registerGcRoot(p: BProc, v: PSym) = - if gSelectedGc in {gcMarkAndSweep, gcGenerational} and + if gSelectedGC in {gcMarkAndSweep, gcGenerational} and containsGarbageCollectedRef(v.loc.t): # we register a specialized marked proc here; this has the advantage # that it works out of the box for thread local storage then :-) @@ -26,7 +26,7 @@ proc registerGcRoot(p: BProc, v: PSym) = proc genVarTuple(p: BProc, n: PNode) = var tup, field: TLoc - if n.kind != nkVarTuple: InternalError(n.info, "genVarTuple") + if n.kind != nkVarTuple: internalError(n.info, "genVarTuple") var L = sonsLen(n) genLineDir(p, n) initLocExpr(p, n.sons[L-1], tup) @@ -45,7 +45,7 @@ proc genVarTuple(p: BProc, n: PNode) = if t.kind == tyTuple: field.r = ropef("$1.Field$2", [rdLoc(tup), toRope(i)]) else: - if t.n.sons[i].kind != nkSym: InternalError(n.info, "genVarTuple") + if t.n.sons[i].kind != nkSym: internalError(n.info, "genVarTuple") field.r = ropef("$1.$2", [rdLoc(tup), mangleRecFieldName(t.n.sons[i].sym, t)]) putLocIntoDest(p, v.loc, field) @@ -62,7 +62,7 @@ proc startBlock(p: BProc, start: TFormatStr = "{$n", lineCg(p, cpsStmts, start, args) inc(p.labels) result = len(p.blocks) - setlen(p.blocks, result + 1) + setLen(p.blocks, result + 1) p.blocks[result].id = p.labels p.blocks[result].nestedTryStmts = p.nestedTryStmts.len.int16 @@ -81,7 +81,7 @@ proc endBlock(p: BProc, blockEnd: PRope) = let topBlock = p.blocks.len-1 # the block is merged into the parent block app(p.blocks[topBlock-1].sections[cpsStmts], p.blocks[topBlock].blockBody) - setlen(p.blocks, topBlock) + setLen(p.blocks, topBlock) # this is done after the block is popped so $n is # properly indented when pretty printing is enabled line(p, cpsStmts, blockEnd) @@ -126,7 +126,7 @@ proc genGotoState(p: BProc, n: PNode) = var a: TLoc initLocExpr(p, n.sons[0], a) lineF(p, cpsStmts, "switch ($1) {$n", [rdLoc(a)]) - p.BeforeRetNeeded = true + p.beforeRetNeeded = true lineF(p, cpsStmts, "case -1: goto BeforeRet;$n", []) for i in 0 .. lastOrd(n.sons[0].typ): lineF(p, cpsStmts, "case $1: goto STATE$1;$n", [toRope(i)]) @@ -200,7 +200,7 @@ proc genConstStmt(p: BProc, t: PNode) = for i in countup(0, sonsLen(t) - 1): var it = t.sons[i] if it.kind == nkCommentStmt: continue - if it.kind != nkConstDef: InternalError(t.info, "genConstStmt") + if it.kind != nkConstDef: internalError(t.info, "genConstStmt") var c = it.sons[0].sym if c.typ.containsCompileTimeOnly: continue if sfFakeConst in c.flags: @@ -232,33 +232,33 @@ proc genIf(p: BProc, n: PNode, d: var TLoc) = # Lend: var a: TLoc - Lelse: TLabel + lelse: TLabel if not isEmptyType(n.typ) and d.k == locNone: getTemp(p, n.typ, d) genLineDir(p, n) - let Lend = getLabel(p) + let lend = getLabel(p) for i in countup(0, sonsLen(n) - 1): let it = n.sons[i] if it.len == 2: when newScopeForIf: startBlock(p) initLocExpr(p, it.sons[0], a) - Lelse = getLabel(p) + lelse = getLabel(p) inc(p.labels) lineFF(p, cpsStmts, "if (!$1) goto $2;$n", "br i1 $1, label %LOC$3, label %$2$nLOC$3: $n", - [rdLoc(a), Lelse, toRope(p.labels)]) + [rdLoc(a), lelse, toRope(p.labels)]) when not newScopeForIf: startBlock(p) expr(p, it.sons[1], d) endBlock(p) if sonsLen(n) > 1: - lineFF(p, cpsStmts, "goto $1;$n", "br label %$1$n", [Lend]) - fixLabel(p, Lelse) + lineFF(p, cpsStmts, "goto $1;$n", "br label %$1$n", [lend]) + fixLabel(p, lelse) elif it.len == 1: startBlock(p) expr(p, it.sons[0], d) endBlock(p) else: internalError(n.info, "genIf()") - if sonsLen(n) > 1: fixLabel(p, Lend) + if sonsLen(n) > 1: fixLabel(p, lend) proc blockLeaveActions(p: BProc, howMany: int) = var L = p.nestedTryStmts.len @@ -296,7 +296,7 @@ proc genReturnStmt(p: BProc, t: PNode) = proc genComputedGoto(p: BProc; n: PNode) = # first pass: Generate array of computed labels: var casePos = -1 - var arraySize: Int + var arraySize: int for i in 0 .. <n.len: let it = n.sons[i] if it.kind == nkCaseStmt: @@ -322,8 +322,20 @@ proc genComputedGoto(p: BProc; n: PNode) = gotoArray.appf("&&TMP$#, ", (id+i).toRope) gotoArray.appf("&&TMP$#};$n", (id+arraySize).toRope) line(p, cpsLocals, gotoArray) + + let topBlock = p.blocks.len-1 + let oldBody = p.blocks[topBlock].sections[cpsStmts] + p.blocks[topBlock].sections[cpsStmts] = nil + for j in casePos+1 .. <n.len: genStmts(p, n.sons[j]) + let tailB = p.blocks[topBlock].sections[cpsStmts] + + p.blocks[topBlock].sections[cpsStmts] = nil for j in 0 .. casePos-1: genStmts(p, n.sons[j]) + let tailA = p.blocks[topBlock].sections[cpsStmts] + + p.blocks[topBlock].sections[cpsStmts] = oldBody.con(tailA) + let caseStmt = n.sons[casePos] var a: TLoc initLocExpr(p, caseStmt.sons[0], a) @@ -340,8 +352,11 @@ proc genComputedGoto(p: BProc; n: PNode) = let val = getOrdValue(it.sons[j]) lineF(p, cpsStmts, "TMP$#:$n", intLiteral(val+id+1)) genStmts(p, it.lastSon) - for j in casePos+1 .. <n.len: genStmts(p, n.sons[j]) - for j in 0 .. casePos-1: genStmts(p, n.sons[j]) + #for j in casePos+1 .. <n.len: genStmts(p, n.sons[j]) # tailB + #for j in 0 .. casePos-1: genStmts(p, n.sons[j]) # tailA + app(p.s(cpsStmts), tailB) + app(p.s(cpsStmts), tailA) + var a: TLoc initLocExpr(p, caseStmt.sons[0], a) lineF(p, cpsStmts, "goto *$#[$#];$n", tmp, a.rdLoc) @@ -352,7 +367,7 @@ proc genWhileStmt(p: BProc, t: PNode) = # significantly worse code var a: TLoc - Labl: TLabel + labl: TLabel assert(sonsLen(t) == 2) inc(p.withinLoop) genLineDir(p, t) @@ -366,7 +381,7 @@ proc genWhileStmt(p: BProc, t: PNode) = lineF(p, cpsStmts, "if (!$1) goto $2;$n", [rdLoc(a), label]) var loopBody = t.sons[1] if loopBody.stmtsContainPragma(wComputedGoto) and - hasComputedGoto in CC[ccompiler].props: + hasComputedGoto in CC[cCompiler].props: # for closure support weird loop bodies are generated: if loopBody.len == 2 and loopBody.sons[0].kind == nkEmpty: loopBody = loopBody.sons[1] @@ -401,7 +416,7 @@ proc genParForStmt(p: BProc, t: PNode) = preserveBreakIdx: let forLoopVar = t.sons[0].sym var rangeA, rangeB: TLoc - assignLocalVar(P, forLoopVar) + assignLocalVar(p, forLoopVar) #initLoc(forLoopVar.loc, locLocalVar, forLoopVar.typ, onStack) #discard mangleName(forLoopVar) let call = t.sons[1] @@ -433,7 +448,7 @@ proc genBreakStmt(p: BProc, t: PNode) = # an unnamed 'break' can only break a loop after 'transf' pass: while idx >= 0 and not p.blocks[idx].isLoop: dec idx if idx < 0 or not p.blocks[idx].isLoop: - InternalError(t.info, "no loop to break") + internalError(t.info, "no loop to break") let label = assignLabel(p.blocks[idx]) blockLeaveActions(p, p.nestedTryStmts.len - p.blocks[idx].nestedTryStmts) genLineDir(p, t) @@ -454,7 +469,7 @@ proc genRaiseStmt(p: BProc, t: PNode) = genSimpleBlock(p, finallyBlock.sons[0]) if t.sons[0].kind != nkEmpty: var a: TLoc - InitLocExpr(p, t.sons[0], a) + initLocExpr(p, t.sons[0], a) var e = rdLoc(a) var typ = skipTypes(t.sons[0].typ, abstractPtrs) genLineDir(p, t) @@ -484,16 +499,16 @@ proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc, proc genCaseSecondPass(p: BProc, t: PNode, d: var TLoc, labId, until: int): TLabel = - var Lend = getLabel(p) + var lend = getLabel(p) for i in 1..until: lineF(p, cpsStmts, "LA$1: ;$n", [toRope(labId + i)]) if t.sons[i].kind == nkOfBranch: var length = sonsLen(t.sons[i]) exprBlock(p, t.sons[i].sons[length - 1], d) - lineF(p, cpsStmts, "goto $1;$n", [Lend]) + lineF(p, cpsStmts, "goto $1;$n", [lend]) else: exprBlock(p, t.sons[i].sons[0], d) - result = Lend + result = lend proc genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc, rangeFormat, eqFormat: TFormatStr, @@ -520,8 +535,8 @@ proc genCaseGeneric(p: BProc, t: PNode, d: var TLoc, rangeFormat, eqFormat: TFormatStr) = var a: TLoc initLocExpr(p, t.sons[0], a) - var Lend = genIfForCaseUntil(p, t, d, rangeFormat, eqFormat, sonsLen(t)-1, a) - fixLabel(p, Lend) + var lend = genIfForCaseUntil(p, t, d, rangeFormat, eqFormat, sonsLen(t)-1, a) + fixLabel(p, lend) proc genCaseStringBranch(p: BProc, b: PNode, e: TLoc, labl: TLabel, branches: var openArray[PRope]) = @@ -565,25 +580,25 @@ proc genStringCase(p: BProc, t: PNode, d: var TLoc) = if t.sons[sonsLen(t)-1].kind != nkOfBranch: lineF(p, cpsStmts, "goto LA$1;$n", [toRope(p.labels)]) # third pass: generate statements - var Lend = genCaseSecondPass(p, t, d, labId, sonsLen(t)-1) - fixLabel(p, Lend) + var lend = genCaseSecondPass(p, t, d, labId, sonsLen(t)-1) + fixLabel(p, lend) else: genCaseGeneric(p, t, d, "", "if (#eqStrings($1, $2)) goto $3;$n") proc branchHasTooBigRange(b: PNode): bool = for i in countup(0, sonsLen(b)-2): # last son is block - if (b.sons[i].Kind == nkRange) and + if (b.sons[i].kind == nkRange) and b.sons[i].sons[1].intVal - b.sons[i].sons[0].intVal > RangeExpandLimit: return true -proc IfSwitchSplitPoint(p: BProc, n: PNode): int = +proc ifSwitchSplitPoint(p: BProc, n: PNode): int = for i in 1..n.len-1: var branch = n[i] var stmtBlock = lastSon(branch) if stmtBlock.stmtsContainPragma(wLinearScanEnd): result = i - elif hasSwitchRange notin CC[ccompiler].props: + elif hasSwitchRange notin CC[cCompiler].props: if branch.kind == nkOfBranch and branchHasTooBigRange(branch): result = i @@ -591,7 +606,7 @@ proc genCaseRange(p: BProc, branch: PNode) = var length = branch.len for j in 0 .. length-2: if branch[j].kind == nkRange: - if hasSwitchRange in CC[ccompiler].props: + if hasSwitchRange in CC[cCompiler].props: lineF(p, cpsStmts, "case $1 ... $2:$n", [ genLiteral(p, branch[j][0]), genLiteral(p, branch[j][1])]) @@ -599,18 +614,18 @@ proc genCaseRange(p: BProc, branch: PNode) = var v = copyNode(branch[j][0]) while v.intVal <= branch[j][1].intVal: lineF(p, cpsStmts, "case $1:$n", [genLiteral(p, v)]) - Inc(v.intVal) + inc(v.intVal) else: lineF(p, cpsStmts, "case $1:$n", [genLiteral(p, branch[j])]) proc genOrdinalCase(p: BProc, n: PNode, d: var TLoc) = # analyse 'case' statement: - var splitPoint = IfSwitchSplitPoint(p, n) + var splitPoint = ifSwitchSplitPoint(p, n) # generate if part (might be empty): var a: TLoc initLocExpr(p, n.sons[0], a) - var Lend = if splitPoint > 0: genIfForCaseUntil(p, n, d, + var lend = if splitPoint > 0: genIfForCaseUntil(p, n, d, rangeFormat = "if ($1 >= $2 && $1 <= $3) goto $4;$n", eqFormat = "if ($1 == $2) goto $3;$n", splitPoint, a) else: nil @@ -629,10 +644,10 @@ proc genOrdinalCase(p: BProc, n: PNode, d: var TLoc) = hasDefault = true exprBlock(p, branch.lastSon, d) lineF(p, cpsStmts, "break;$n") - if (hasAssume in CC[ccompiler].props) and not hasDefault: + if (hasAssume in CC[cCompiler].props) and not hasDefault: lineF(p, cpsStmts, "default: __assume(0);$n") lineF(p, cpsStmts, "}$n") - if Lend != nil: fixLabel(p, Lend) + if lend != nil: fixLabel(p, lend) proc genCase(p: BProc, t: PNode, d: var TLoc) = genLineDir(p, t) @@ -691,7 +706,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) = expr(p, t.sons[0], d) length = sonsLen(t) endBlock(p, ropecg(p.module, "} catch (NimException& $1) {$n", [exc])) - if optStackTrace in p.Options: + if optStackTrace in p.options: linefmt(p, cpsStmts, "#setFrame((TFrame*)&F);$n") inc p.inExceptBlock i = 1 @@ -764,7 +779,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) = # if not isEmptyType(t.typ) and d.k == locNone: getTemp(p, t.typ, d) - discard lists.IncludeStr(p.module.headerFiles, "<setjmp.h>") + discard lists.includeStr(p.module.headerFiles, "<setjmp.h>") genLineDir(p, t) var safePoint = getTempName() discard cgsym(p.module, "E_Base") @@ -779,7 +794,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) = endBlock(p) startBlock(p, "else {$n") linefmt(p, cpsStmts, "#popSafePoint();$n") - if optStackTrace in p.Options: + if optStackTrace in p.options: linefmt(p, cpsStmts, "#setFrame((TFrame*)&F);$n") inc p.inExceptBlock var i = 1 @@ -818,7 +833,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) = proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): PRope = var res = "" for i in countup(0, sonsLen(t) - 1): - case t.sons[i].Kind + case t.sons[i].kind of nkStrLit..nkTripleStrLit: res.add(t.sons[i].strVal) of nkSym: @@ -835,9 +850,9 @@ proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): PRope = r = mangleName(sym) sym.loc.r = r # but be consequent! res.add(r.ropeToStr) - else: InternalError(t.sons[i].info, "genAsmOrEmitStmt()") + else: internalError(t.sons[i].info, "genAsmOrEmitStmt()") - if isAsmStmt and hasGnuAsm in CC[ccompiler].props: + if isAsmStmt and hasGnuAsm in CC[cCompiler].props: for x in splitLines(res): var j = 0 while x[j] in {' ', '\t'}: inc(j) @@ -858,9 +873,9 @@ proc genAsmStmt(p: BProc, t: PNode) = var s = genAsmOrEmitStmt(p, t, isAsmStmt=true) if p.prc == nil: # top level asm statement? - appf(p.module.s[cfsProcHeaders], CC[ccompiler].asmStmtFrmt, [s]) + appf(p.module.s[cfsProcHeaders], CC[cCompiler].asmStmtFrmt, [s]) else: - lineF(p, cpsStmts, CC[ccompiler].asmStmtFrmt, [s]) + lineF(p, cpsStmts, CC[cCompiler].asmStmtFrmt, [s]) proc genEmit(p: BProc, t: PNode) = genLineDir(p, t) @@ -877,7 +892,7 @@ var proc genBreakPoint(p: BProc, t: PNode) = var name: string - if optEndb in p.Options: + if optEndb in p.options: if t.kind == nkExprColonExpr: assert(t.sons[1].kind in {nkStrLit..nkTripleStrLit}) name = normalize(t.sons[1].strVal) @@ -891,7 +906,7 @@ proc genBreakPoint(p: BProc, t: PNode) = makeCString(name)]) proc genWatchpoint(p: BProc, n: PNode) = - if optEndb notin p.Options: return + if optEndb notin p.options: return var a: TLoc initLocExpr(p, n.sons[1], a) let typ = skipTypes(n.sons[1].typ, abstractVarRange) @@ -905,7 +920,7 @@ proc genPragma(p: BProc, n: PNode) = case whichPragma(it) of wEmit: genEmit(p, it) of wBreakpoint: genBreakPoint(p, it) - of wWatchpoint: genWatchpoint(p, it) + of wWatchPoint: genWatchpoint(p, it) of wInjectStmt: var p = newProc(nil, p.module) p.options = p.options - {optLineTrace, optStackTrace} @@ -913,7 +928,7 @@ proc genPragma(p: BProc, n: PNode) = p.module.injectStmt = p.s(cpsStmts) else: discard -proc FieldDiscriminantCheckNeeded(p: BProc, asgn: PNode): bool = +proc fieldDiscriminantCheckNeeded(p: BProc, asgn: PNode): bool = if optFieldCheck in p.options: var le = asgn.sons[0] if le.kind == nkCheckedFieldExpr: @@ -929,7 +944,7 @@ proc genDiscriminantCheck(p: BProc, a, tmp: TLoc, objtype: PType, assert t.kind == tyObject discard genTypeInfo(p.module, t) var L = lengthOrd(field.typ) - if not ContainsOrIncl(p.module.declaredThings, field.id): + if not containsOrIncl(p.module.declaredThings, field.id): appcg(p.module, cfsVars, "extern $1", discriminatorTableDecl(p.module, t, field)) lineCg(p, cpsStmts, @@ -942,7 +957,7 @@ proc asgnFieldDiscriminant(p: BProc, e: PNode) = var dotExpr = e.sons[0] var d: PSym if dotExpr.kind == nkCheckedFieldExpr: dotExpr = dotExpr.sons[0] - InitLocExpr(p, e.sons[0], a) + initLocExpr(p, e.sons[0], a) getTemp(p, a.t, tmp) expr(p, e.sons[1], tmp) genDiscriminantCheck(p, a, tmp, dotExpr.sons[0].typ, dotExpr.sons[1].sym) @@ -950,9 +965,9 @@ proc asgnFieldDiscriminant(p: BProc, e: PNode) = proc genAsgn(p: BProc, e: PNode, fastAsgn: bool) = genLineDir(p, e) - if not FieldDiscriminantCheckNeeded(p, e): + if not fieldDiscriminantCheckNeeded(p, e): var a: TLoc - InitLocExpr(p, e.sons[0], a) + initLocExpr(p, e.sons[0], a) if fastAsgn: incl(a.flags, lfNoDeepCopy) assert(a.t != nil) loadInto(p, e.sons[0], e.sons[1], a) @@ -962,4 +977,4 @@ proc genAsgn(p: BProc, e: PNode, fastAsgn: bool) = proc genStmts(p: BProc, t: PNode) = var a: TLoc expr(p, t, a) - InternalAssert a.k in {locNone, locTemp, locLocalVar} + internalAssert a.k in {locNone, locTemp, locLocalVar} diff --git a/compiler/ccgthreadvars.nim b/compiler/ccgthreadvars.nim index d312ea027..c00b931ef 100644 --- a/compiler/ccgthreadvars.nim +++ b/compiler/ccgthreadvars.nim @@ -16,8 +16,8 @@ proc emulatedThreadVars(): bool = result = {optThreads, optTlsEmulation} <= gGlobalOptions proc accessThreadLocalVar(p: BProc, s: PSym) = - if emulatedThreadVars() and not p.ThreadVarAccessed: - p.ThreadVarAccessed = true + if emulatedThreadVars() and not p.threadVarAccessed: + p.threadVarAccessed = true p.module.usesThreadVars = true appf(p.procSec(cpsLocals), "\tNimThreadVars* NimTV;$n") app(p.procSec(cpsInit), @@ -55,7 +55,7 @@ proc generateThreadLocalStorage(m: BModule) = for t in items(nimtvDeps): discard getTypeDesc(m, t) appf(m.s[cfsSeqTypes], "typedef struct {$1} NimThreadVars;$n", [nimtv]) -proc GenerateThreadVarsSize(m: BModule) = +proc generateThreadVarsSize(m: BModule) = if nimtv != nil: app(m.s[cfsProcs], "NI NimThreadVarsSize(){return (NI)sizeof(NimThreadVars);}" & tnl) diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim index 9534eae91..ecf1eb152 100644 --- a/compiler/ccgtrav.nim +++ b/compiler/ccgtrav.nim @@ -28,7 +28,7 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, n: PNode) = for i in countup(0, sonsLen(n) - 1): genTraverseProc(c, accessor, n.sons[i]) of nkRecCase: - if (n.sons[0].kind != nkSym): InternalError(n.info, "genTraverseProc") + if (n.sons[0].kind != nkSym): internalError(n.info, "genTraverseProc") var p = c.p let disc = n.sons[0].sym lineF(p, cpsStmts, "switch ($1.$2) {$n", accessor, disc.loc.r) @@ -74,7 +74,7 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType) = genTraverseProc(c, accessor.parentObj, typ.sons[i]) if typ.n != nil: genTraverseProc(c, accessor, typ.n) of tyTuple: - let typ = GetUniqueType(typ) + let typ = getUniqueType(typ) for i in countup(0, sonsLen(typ) - 1): genTraverseProc(c, rfmt(nil, "$1.Field$2", accessor, i.toRope), typ.sons[i]) of tyRef, tyString, tySequence: @@ -111,7 +111,7 @@ proc genTraverseProc(m: BModule, typ: PType, reason: TTypeInfoReason): PRope = lineF(p, cpsInit, "a = ($1)p;$n", t) c.p = p - assert typ.kind != tyTypedesc + assert typ.kind != tyTypeDesc if typ.kind == tySequence: genTraverseProcSeq(c, "a".toRope, typ) else: diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 4548ac641..79f10b981 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -76,7 +76,7 @@ proc mangleName(s: PSym): PRope = else: result = ~"%" of skTemp, skParam, skType, skEnumField, skModule: result = ~"%" - else: InternalError(s.info, "mangleName") + else: internalError(s.info, "mangleName") when oKeepVariableNames: let keepOrigName = s.kind in skLocalVars - {skForVar} and {sfFromGeneric, sfGlobal, sfShadowed, sfGenSym} * s.flags == {} and @@ -150,7 +150,7 @@ proc getTypeName(typ: PType): PRope = typ.loc.r = if gCmd != cmdCompileToLLVM: con(typ.typeName, typ.id.toRope) else: con([~"%", typ.typeName, typ.id.toRope]) result = typ.loc.r - if result == nil: InternalError("getTypeName: " & $typ.kind) + if result == nil: internalError("getTypeName: " & $typ.kind) proc mapSetType(typ: PType): TCTypeKind = case int(getSize(typ)) @@ -194,7 +194,7 @@ proc mapType(typ: PType): TCTypeKind = of tyCString: result = ctCString of tyInt..tyUInt64: result = TCTypeKind(ord(typ.kind) - ord(tyInt) + ord(ctInt)) - else: InternalError("mapType") + else: internalError("mapType") proc mapReturnType(typ: PType): TCTypeKind = if skipTypes(typ, typedescInst).kind == tyArray: result = ctPtr @@ -229,11 +229,11 @@ const "stdcall $1", "ccc $1", "safecall $1", "syscall $1", "$1 alwaysinline", "$1 noinline", "fastcc $1", "ccc $1", "$1"] -proc CacheGetType(tab: TIdTable, key: PType): PRope = +proc cacheGetType(tab: TIdTable, key: PType): PRope = # returns nil if we need to declare this type # since types are now unique via the ``GetUniqueType`` mechanism, this slow # linear search is not necessary anymore: - result = PRope(IdTableGet(tab, key)) + result = PRope(idTableGet(tab, key)) proc getTempName(): PRope = result = rfmt(nil, "TMP$1", toRope(backendId())) @@ -246,7 +246,7 @@ proc ccgIntroducedPtr(s: PSym): bool = assert skResult != s.kind if tfByRef in pt.flags: return true elif tfByCopy in pt.flags: return false - case pt.Kind + case pt.kind of tyObject: if (optByRef in s.options) or (getSize(pt) > platform.floatSize * 2): result = true # requested anyway @@ -262,7 +262,7 @@ proc ccgIntroducedPtr(s: PSym): bool = proc fillResult(param: PSym) = fillLoc(param.loc, locParam, param.typ, ~"Result", OnStack) - if (mapReturnType(param.typ) != ctArray) and IsInvalidReturnType(param.typ): + if (mapReturnType(param.typ) != ctArray) and isInvalidReturnType(param.typ): incl(param.loc.flags, lfIndirect) param.loc.s = OnUnknown @@ -288,7 +288,7 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var PRope, else: rettype = getTypeDescAux(m, t.sons[0], check) for i in countup(1, sonsLen(t.n) - 1): - if t.n.sons[i].kind != nkSym: InternalError(t.n.info, "genProcParams") + if t.n.sons[i].kind != nkSym: internalError(t.n.info, "genProcParams") var param = t.n.sons[i].sym if isCompileTimeOnly(param.typ): continue if params != nil: app(params, ~", ") @@ -305,7 +305,7 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var PRope, var arr = param.typ if arr.kind == tyVar: arr = arr.sons[0] var j = 0 - while arr.Kind in {tyOpenArray, tyVarargs}: + while arr.kind in {tyOpenArray, tyVarargs}: # this fixes the 'sort' bug: if param.typ.kind == tyVar: param.loc.s = OnUnknown # need to pass hidden parameter: @@ -344,7 +344,7 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): PRope = "NI", "NI8", "NI16", "NI32", "NI64", "NF", "NF32", "NF64", "NF128", "NU", "NU8", "NU16", "NU32", "NU64",] - case typ.Kind + case typ.kind of tyPointer: result = typeNameOrLiteral(typ, "void*") of tyEnum: @@ -362,12 +362,12 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): PRope = of tyString: discard cgsym(m, "NimStringDesc") result = typeNameOrLiteral(typ, "NimStringDesc*") - of tyCstring: result = typeNameOrLiteral(typ, "NCSTRING") + of tyCString: result = typeNameOrLiteral(typ, "NCSTRING") of tyBool: result = typeNameOrLiteral(typ, "NIM_BOOL") of tyChar: result = typeNameOrLiteral(typ, "NIM_CHAR") of tyNil: result = typeNameOrLiteral(typ, "0") of tyInt..tyUInt64: - result = typeNameOrLiteral(typ, NumericalTypeToStr[typ.Kind]) + result = typeNameOrLiteral(typ, NumericalTypeToStr[typ.kind]) of tyRange: result = getSimpleTypeDesc(m, typ.sons[0]) else: result = nil @@ -375,14 +375,14 @@ proc getTypePre(m: BModule, typ: PType): PRope = if typ == nil: result = toRope("void") else: result = getSimpleTypeDesc(m, typ) - if result == nil: result = CacheGetType(m.typeCache, typ) + if result == nil: result = cacheGetType(m.typeCache, typ) proc getForwardStructFormat(): string = if gCmd == cmdCompileToCpp: result = "struct $1;$n" else: result = "typedef struct $1 $1;$n" proc getTypeForward(m: BModule, typ: PType): PRope = - result = CacheGetType(m.forwTypeCache, typ) + result = cacheGetType(m.forwTypeCache, typ) if result != nil: return result = getTypePre(m, typ) if result != nil: return @@ -391,8 +391,8 @@ proc getTypeForward(m: BModule, typ: PType): PRope = result = getTypeName(typ) if not isImportedType(typ): appf(m.s[cfsForwardTypes], getForwardStructFormat(), [result]) - IdTablePut(m.forwTypeCache, typ, result) - else: InternalError("getTypeForward(" & $typ.kind & ')') + idTablePut(m.forwTypeCache, typ, result) + else: internalError("getTypeForward(" & $typ.kind & ')') proc mangleRecFieldName(field: PSym, rectype: PType): PRope = if (rectype.sym != nil) and @@ -400,7 +400,7 @@ proc mangleRecFieldName(field: PSym, rectype: PType): PRope = result = field.loc.r else: result = toRope(mangleField(field.name.s)) - if result == nil: InternalError(field.info, "mangleRecFieldName") + if result == nil: internalError(field.info, "mangleRecFieldName") proc genRecordFieldsAux(m: BModule, n: PNode, accessExpr: PRope, rectype: PType, @@ -415,7 +415,7 @@ proc genRecordFieldsAux(m: BModule, n: PNode, for i in countup(0, sonsLen(n) - 1): app(result, genRecordFieldsAux(m, n.sons[i], accessExpr, rectype, check)) of nkRecCase: - if (n.sons[0].kind != nkSym): InternalError(n.info, "genRecordFieldsAux") + if (n.sons[0].kind != nkSym): internalError(n.info, "genRecordFieldsAux") app(result, genRecordFieldsAux(m, n.sons[0], accessExpr, rectype, check)) uname = toRope(mangle(n.sons[0].sym.name.s) & 'U') if accessExpr != nil: ae = ropef("$1.$2", [accessExpr, uname]) @@ -497,49 +497,49 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var TIntSet): PRope = # returns only the type's name var name, rettype, desc, recdesc: PRope - n: biggestInt + n: BiggestInt t, et: PType t = getUniqueType(typ) - if t == nil: InternalError("getTypeDescAux: t == nil") + if t == nil: internalError("getTypeDescAux: t == nil") if t.sym != nil: useHeader(m, t.sym) result = getTypePre(m, t) if result != nil: return - if ContainsOrIncl(check, t.id): - InternalError("cannot generate C type for: " & typeToString(typ)) + if containsOrIncl(check, t.id): + internalError("cannot generate C type for: " & typeToString(typ)) # XXX: this BUG is hard to fix -> we need to introduce helper structs, # but determining when this needs to be done is hard. We should split # C type generation into an analysis and a code generation phase somehow. - case t.Kind + case t.kind of tyRef, tyPtr, tyVar: et = getUniqueType(t.sons[0]) if et.kind in {tyArrayConstr, tyArray, tyOpenArray, tyVarargs}: # this is correct! sets have no proper base type, so we treat # ``var set[char]`` in `getParamTypeDesc` et = getUniqueType(elemType(et)) - case et.Kind + case et.kind of tyObject, tyTuple: # no restriction! We have a forward declaration for structs name = getTypeForward(m, et) result = con(name, "*") - IdTablePut(m.typeCache, t, result) + idTablePut(m.typeCache, t, result) pushType(m, et) of tySequence: # no restriction! We have a forward declaration for structs name = getTypeForward(m, et) result = con(name, "**") - IdTablePut(m.typeCache, t, result) + idTablePut(m.typeCache, t, result) pushType(m, et) else: # else we have a strong dependency :-( result = con(getTypeDescAux(m, et, check), "*") - IdTablePut(m.typeCache, t, result) + idTablePut(m.typeCache, t, result) of tyOpenArray, tyVarargs: et = getUniqueType(t.sons[0]) result = con(getTypeDescAux(m, et, check), "*") - IdTablePut(m.typeCache, t, result) + idTablePut(m.typeCache, t, result) of tyProc: result = getTypeName(t) - IdTablePut(m.typeCache, t, result) + idTablePut(m.typeCache, t, result) genProcParams(m, t, rettype, desc, check) if not isImportedType(t): if t.callConv != ccClosure: # procedure vars may need a closure! @@ -553,14 +553,14 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var TIntSet): PRope = of tySequence: # we cannot use getTypeForward here because then t would be associated # with the name of the struct, not with the pointer to the struct: - result = CacheGetType(m.forwTypeCache, t) + result = cacheGetType(m.forwTypeCache, t) if result == nil: result = getTypeName(t) if not isImportedType(t): appf(m.s[cfsForwardTypes], getForwardStructFormat(), [result]) - IdTablePut(m.forwTypeCache, t, result) - assert(CacheGetType(m.typeCache, t) == nil) - IdTablePut(m.typeCache, t, con(result, "*")) + idTablePut(m.forwTypeCache, t, result) + assert(cacheGetType(m.typeCache, t) == nil) + idTablePut(m.typeCache, t, con(result, "*")) if not isImportedType(t): if skipTypes(t.sons[0], typedescInst).kind != tyEmpty: const @@ -579,18 +579,18 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var TIntSet): PRope = if n <= 0: n = 1 # make an array of at least one element result = getTypeName(t) - IdTablePut(m.typeCache, t, result) + idTablePut(m.typeCache, t, result) if not isImportedType(t): appf(m.s[cfsTypes], "typedef $1 $2[$3];$n", - [getTypeDescAux(m, t.sons[1], check), result, ToRope(n)]) + [getTypeDescAux(m, t.sons[1], check), result, toRope(n)]) of tyObject, tyTuple: - result = CacheGetType(m.forwTypeCache, t) + result = cacheGetType(m.forwTypeCache, t) if result == nil: result = getTypeName(t) if not isImportedType(t): appf(m.s[cfsForwardTypes], getForwardStructFormat(), [result]) - IdTablePut(m.forwTypeCache, t, result) - IdTablePut(m.typeCache, t, result) # always call for sideeffects: + idTablePut(m.forwTypeCache, t, result) + idTablePut(m.typeCache, t, result) # always call for sideeffects: if t.kind != tyTuple: recdesc = getRecordDesc(m, t, result, check) else: recdesc = getTupleDesc(m, t, result, check) if not isImportedType(t): app(m.s[cfsTypes], recdesc) @@ -602,7 +602,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var TIntSet): PRope = of 8: result = toRope("NU64") else: result = getTypeName(t) - IdTablePut(m.typeCache, t, result) + idTablePut(m.typeCache, t, result) if not isImportedType(t): appf(m.s[cfsTypes], "typedef NU8 $1[$2];$n", [result, toRope(getSize(t))]) @@ -610,7 +610,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var TIntSet): PRope = tyIter, tyTypeDesc: result = getTypeDescAux(m, lastSon(t), check) else: - InternalError("getTypeDescAux(" & $t.kind & ')') + internalError("getTypeDescAux(" & $t.kind & ')') result = nil # fixes bug #145: excl(check, t.id) @@ -737,10 +737,10 @@ proc discriminatorTableName(m: BModule, objtype: PType, d: PSym): PRope = var objtype = objtype while lookupInRecord(objtype.n, d.name) == nil: objtype = objtype.sons[0] - if objType.sym == nil: - InternalError(d.info, "anonymous obj with discriminator") + if objtype.sym == nil: + internalError(d.info, "anonymous obj with discriminator") result = ropef("NimDT_$1_$2", [ - toRope(objType.sym.name.s.mangle), toRope(d.name.s.mangle)]) + toRope(objtype.sym.name.s.mangle), toRope(d.name.s.mangle)]) proc discriminatorTableDecl(m: BModule, objtype: PType, d: PSym): PRope = discard cgsym(m, "TNimNode") @@ -911,7 +911,7 @@ include ccgtrav proc genTypeInfo(m: BModule, t: PType): PRope = var t = getUniqueType(t) result = ropef("NTI$1", [toRope(t.id)]) - if ContainsOrIncl(m.typeInfoMarker, t.id): + if containsOrIncl(m.typeInfoMarker, t.id): return con("(&".toRope, result, ")".toRope) let owner = t.skipTypes(typedescPtrs).owner.getModule if owner != m.module: @@ -948,8 +948,8 @@ proc genTypeInfo(m: BModule, t: PType): PRope = # BUGFIX: use consistently RTTI without proper field names; otherwise # results are not deterministic! genTupleInfo(m, t, result) - else: InternalError("genTypeInfo(" & $t.kind & ')') + else: internalError("genTypeInfo(" & $t.kind & ')') result = con("(&".toRope, result, ")".toRope) proc genTypeSection(m: BModule, n: PNode) = - nil + discard diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim index 310f7204a..fe349174f 100644 --- a/compiler/ccgutils.nim +++ b/compiler/ccgutils.nim @@ -22,19 +22,19 @@ proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode = of nkPragma: for i in 0 .. < n.len: if whichPragma(n[i]) == w: return n[i] - else: nil + else: discard proc stmtsContainPragma*(n: PNode, w: TSpecialWord): bool = result = getPragmaStmt(n, w) != nil -proc hashString*(s: string): biggestInt = +proc hashString*(s: string): BiggestInt = # has to be the same algorithm as system.hashString! if CPU[targetCPU].bit == 64: # we have to use the same bitwidth # as the target CPU var b = 0'i64 for i in countup(0, len(s) - 1): - b = b +% Ord(s[i]) + b = b +% ord(s[i]) b = b +% `shl`(b, 10) b = b xor `shr`(b, 6) b = b +% `shl`(b, 3) @@ -44,7 +44,7 @@ proc hashString*(s: string): biggestInt = else: var a = 0'i32 for i in countup(0, len(s) - 1): - a = a +% Ord(s[i]).int32 + a = a +% ord(s[i]).int32 a = a +% `shl`(a, 10'i32) a = a xor `shr`(a, 6'i32) a = a +% `shl`(a, 3'i32) @@ -57,7 +57,7 @@ var gCanonicalTypes: array[TTypeKind, PType] proc initTypeTables() = - for i in countup(low(TTypeKind), high(TTypeKind)): InitIdTable(gTypeTable[i]) + for i in countup(low(TTypeKind), high(TTypeKind)): initIdTable(gTypeTable[i]) proc resetCaches* = ## XXX: fix that more properly @@ -70,7 +70,7 @@ when false: for i in countup(low(TTypeKind), high(TTypeKind)): echo i, " ", gTypeTable[i].counter -proc GetUniqueType*(key: PType): PType = +proc getUniqueType*(key: PType): PType = # this is a hotspot in the compiler! if key == nil: return var k = key.kind @@ -86,12 +86,11 @@ proc GetUniqueType*(key: PType): PType = if result == nil: gCanonicalTypes[k] = key result = key - of tyTypeDesc, tyTypeClasses: - InternalError("value expected, but got a type") - of tyGenericParam: - InternalError("GetUniqueType") + of tyTypeDesc, tyTypeClasses, tyGenericParam, + tyFromExpr, tyStatic: + internalError("GetUniqueType") of tyGenericInst, tyDistinct, tyOrdinal, tyMutable, tyConst, tyIter: - result = GetUniqueType(lastSon(key)) + result = getUniqueType(lastSon(key)) of tyArrayConstr, tyGenericInvokation, tyGenericBody, tyOpenArray, tyArray, tySet, tyRange, tyTuple, tyPtr, tyRef, tySequence, tyForward, tyVarargs, tyProxy, tyVar: @@ -102,33 +101,33 @@ proc GetUniqueType*(key: PType): PType = # we have to do a slow linear search because types may need # to be compared by their structure: - if IdTableHasObjectAsKey(gTypeTable[k], key): return key + if idTableHasObjectAsKey(gTypeTable[k], key): return key for h in countup(0, high(gTypeTable[k].data)): var t = PType(gTypeTable[k].data[h].key) if t != nil and sameBackendType(t, key): return t - IdTablePut(gTypeTable[k], key, key) + idTablePut(gTypeTable[k], key, key) result = key of tyObject: if tfFromGeneric notin key.flags: # fast case; lookup per id suffices: - result = PType(IdTableGet(gTypeTable[k], key)) + result = PType(idTableGet(gTypeTable[k], key)) if result == nil: - IdTablePut(gTypeTable[k], key, key) + idTablePut(gTypeTable[k], key, key) result = key else: # ugly slow case: need to compare by structure - if IdTableHasObjectAsKey(gTypeTable[k], key): return key + if idTableHasObjectAsKey(gTypeTable[k], key): return key for h in countup(0, high(gTypeTable[k].data)): var t = PType(gTypeTable[k].data[h].key) if t != nil and sameType(t, key): return t - IdTablePut(gTypeTable[k], key, key) + idTablePut(gTypeTable[k], key, key) result = key of tyEnum: - result = PType(IdTableGet(gTypeTable[k], key)) + result = PType(idTableGet(gTypeTable[k], key)) if result == nil: - IdTablePut(gTypeTable[k], key, key) + idTablePut(gTypeTable[k], key, key) result = key of tyProc: # tyVar is not 100% correct, but would speeds things up a little: @@ -136,17 +135,17 @@ proc GetUniqueType*(key: PType): PType = result = key else: # ugh, we need the canon here: - if IdTableHasObjectAsKey(gTypeTable[k], key): return key + if idTableHasObjectAsKey(gTypeTable[k], key): return key for h in countup(0, high(gTypeTable[k].data)): var t = PType(gTypeTable[k].data[h].key) if t != nil and sameBackendType(t, key): return t - IdTablePut(gTypeTable[k], key, key) + idTablePut(gTypeTable[k], key, key) result = key -proc TableGetType*(tab: TIdTable, key: PType): PObject = +proc tableGetType*(tab: TIdTable, key: PType): PObject = # returns nil if we need to declare this type - result = IdTableGet(tab, key) + result = idTableGet(tab, key) if (result == nil) and (tab.counter > 0): # we have to do a slow linear search because types may need # to be compared by their structure: @@ -169,7 +168,7 @@ proc makeLLVMString*(s: string): PRope = for i in countup(0, len(s) - 1): if (i + 1) mod MaxLineLength == 0: app(result, toRope(res)) - setlen(res, 0) + setLen(res, 0) case s[i] of '\0'..'\x1F', '\x80'..'\xFF', '\"', '\\': add(res, '\\') @@ -178,4 +177,4 @@ proc makeLLVMString*(s: string): PRope = add(res, "\\00\"") app(result, toRope(res)) -InitTypeTables() +initTypeTables() diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 6ccef5fde..c7de1091b 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2013 Andreas Rumpf +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -52,7 +52,7 @@ proc emitLazily(s: PSym): bool {.inline.} = proc initLoc(result: var TLoc, k: TLocKind, typ: PType, s: TStorageLoc) = result.k = k result.s = s - result.t = GetUniqueType(typ) + result.t = getUniqueType(typ) result.r = nil result.a = - 1 result.flags = {} @@ -75,12 +75,12 @@ proc isSimpleConst(typ: PType): bool = proc useStringh(m: BModule) = if not m.includesStringh: m.includesStringh = true - discard lists.IncludeStr(m.headerFiles, "<string.h>") + discard lists.includeStr(m.headerFiles, "<string.h>") proc useHeader(m: BModule, sym: PSym) = - if lfHeader in sym.loc.Flags: + if lfHeader in sym.loc.flags: assert(sym.annex != nil) - discard lists.IncludeStr(m.headerFiles, getStr(sym.annex.path)) + discard lists.includeStr(m.headerFiles, getStr(sym.annex.path)) proc cgsym(m: BModule, name: string): PRope @@ -103,7 +103,7 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope = of '0'..'9': var j = 0 while true: - j = (j * 10) + Ord(frmt[i]) - ord('0') + j = (j * 10) + ord(frmt[i]) - ord('0') inc(i) if i >= length or not (frmt[i] in {'0'..'9'}): break num = j @@ -116,7 +116,7 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope = of 'N': app(result, rnl) inc(i) - else: InternalError("ropes: invalid format string $" & frmt[i]) + else: internalError("ropes: invalid format string $" & frmt[i]) elif frmt[i] == '#' and frmt[i+1] in IdentStartChars: inc(i) var j = i @@ -128,7 +128,7 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope = inc(i, 2) var j = 0 while frmt[i] in Digits: - j = (j * 10) + Ord(frmt[i]) - ord('0') + j = (j * 10) + ord(frmt[i]) - ord('0') inc(i) app(result, cgsym(m, args[j-1].ropeToStr)) var start = i @@ -194,7 +194,7 @@ when compileTimeRopeFmt: if i - 1 >= start: yield (kind: ffLit, value: substr(s, start, i-1), intValue: 0) - macro rfmt(m: BModule, fmt: expr[string], args: varargs[PRope]): expr = + macro rfmt(m: BModule, fmt: static[string], args: varargs[PRope]): expr = ## Experimental optimized rope-formatting operator ## The run-time code it produces will be very fast, but will it speed up ## the compilation of nimrod itself or will the macro execution time @@ -209,7 +209,7 @@ when compileTimeRopeFmt: of ffParam: result.add(args[frag.intValue]) else: - template rfmt(m: BModule, fmt: expr[string], args: varargs[PRope]): expr = + template rfmt(m: BModule, fmt: string, args: varargs[PRope]): expr = ropecg(m, fmt, args) proc appcg(m: BModule, c: var PRope, frmt: TFormatStr, @@ -279,11 +279,11 @@ proc genLineDir(p: BProc, t: PNode) = if optEmbedOrigSrc in gGlobalOptions: app(p.s(cpsStmts), con(~"//", t.info.sourceLine, rnl)) genCLineDir(p.s(cpsStmts), t.info.toFullPath, line) - if ({optStackTrace, optEndb} * p.Options == {optStackTrace, optEndb}) and + if ({optStackTrace, optEndb} * p.options == {optStackTrace, optEndb}) and (p.prc == nil or sfPure notin p.prc.flags): linefmt(p, cpsStmts, "#endb($1, $2);$n", line.toRope, makeCString(toFilename(t.info))) - elif ({optLineTrace, optStackTrace} * p.Options == + elif ({optLineTrace, optStackTrace} * p.options == {optLineTrace, optStackTrace}) and (p.prc == nil or sfPure notin p.prc.flags): linefmt(p, cpsStmts, "nimln($1, $2);$n", @@ -351,7 +351,7 @@ proc resetLoc(p: BProc, loc: var TLoc) = if not isComplexValueType(skipTypes(loc.t, abstractVarRange)): if containsGcRef: var nilLoc: TLoc - initLoc(nilLoc, locTemp, loc.t, onStack) + initLoc(nilLoc, locTemp, loc.t, OnStack) nilLoc.r = toRope("NIM_NIL") genRefAssign(p, loc, nilLoc, {afSrcIsNil}) else: @@ -513,7 +513,7 @@ proc assignLocalVar(p: BProc, s: PSym) = include ccgthreadvars -proc VarInDynamicLib(m: BModule, sym: PSym) +proc varInDynamicLib(m: BModule, sym: PSym) proc mangleDynLibProc(sym: PSym): PRope proc assignGlobalVar(p: BProc, s: PSym) = @@ -522,8 +522,8 @@ proc assignGlobalVar(p: BProc, s: PSym) = if lfDynamicLib in s.loc.flags: var q = findPendingModule(p.module, s) - if q != nil and not ContainsOrIncl(q.declaredThings, s.id): - VarInDynamicLib(q, s) + if q != nil and not containsOrIncl(q.declaredThings, s.id): + varInDynamicLib(q, s) else: s.loc.r = mangleDynLibProc(s) return @@ -578,7 +578,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) proc genProcPrototype(m: BModule, sym: PSym) proc putLocIntoDest(p: BProc, d: var TLoc, s: TLoc) proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) -proc intLiteral(i: biggestInt): PRope +proc intLiteral(i: BiggestInt): PRope proc genLiteral(p: BProc, n: PNode): PRope proc initLocExpr(p: BProc, e: PNode, result: var TLoc) = @@ -610,7 +610,7 @@ proc loadDynamicLib(m: BModule, lib: PLib) = var s: TStringSeq = @[] libCandidates(lib.path.strVal, s) if gVerbosity >= 2: - MsgWriteln("Dependency: " & lib.path.strVal) + msgWriteln("Dependency: " & lib.path.strVal) var loadlib: PRope = nil for i in countup(0, high(s)): inc(m.labels) @@ -632,7 +632,7 @@ proc loadDynamicLib(m: BModule, lib: PLib) = "if (!($1 = #nimLoadLibrary($2))) #nimLoadLibraryError($2);$n", [tmp, rdLoc(dest)]) - if lib.name == nil: InternalError("loadDynamicLib") + if lib.name == nil: internalError("loadDynamicLib") proc mangleDynLibProc(sym: PSym): PRope = if sfCompilerProc in sym.flags: @@ -641,7 +641,7 @@ proc mangleDynLibProc(sym: PSym): PRope = else: result = ropef("Dl_$1", [toRope(sym.id)]) -proc SymInDynamicLib(m: BModule, sym: PSym) = +proc symInDynamicLib(m: BModule, sym: PSym) = var lib = sym.annex let isCall = isGetProcAddr(lib) var extname = sym.loc.r @@ -665,14 +665,14 @@ proc SymInDynamicLib(m: BModule, sym: PSym) = params, cstringLit(m, m.s[cfsDynLibInit], ropeToStr(extname))]) var last = lastSon(n) if last.kind == nkHiddenStdConv: last = last.sons[1] - InternalAssert(last.kind == nkStrLit) + internalAssert(last.kind == nkStrLit) let idx = last.strVal if idx.len == 0: app(m.initProc.s(cpsStmts), load) elif idx.len == 1 and idx[0] in {'0'..'9'}: app(m.extensionLoaders[idx[0]], load) else: - InternalError(sym.info, "wrong index: " & idx) + internalError(sym.info, "wrong index: " & idx) else: appcg(m, m.s[cfsDynLibInit], "\t$1 = ($2) #nimGetProcAddr($3, $4);$n", @@ -682,7 +682,7 @@ proc SymInDynamicLib(m: BModule, sym: PSym) = "$1 = linkonce global $2 zeroinitializer$n", [sym.loc.r, getTypeDesc(m, sym.loc.t)]) -proc VarInDynamicLib(m: BModule, sym: PSym) = +proc varInDynamicLib(m: BModule, sym: PSym) = var lib = sym.annex var extname = sym.loc.r loadDynamicLib(m, lib) @@ -697,7 +697,7 @@ proc VarInDynamicLib(m: BModule, sym: PSym) = appf(m.s[cfsVars], "$2* $1;$n", [sym.loc.r, getTypeDesc(m, sym.loc.t)]) -proc SymInDynamicLibPartial(m: BModule, sym: PSym) = +proc symInDynamicLibPartial(m: BModule, sym: PSym) = sym.loc.r = mangleDynLibProc(sym) sym.typ.sym = nil # generate a new name @@ -708,7 +708,7 @@ proc cgsym(m: BModule, name: string): PRope = of skProc, skMethod, skConverter, skIterator: genProc(m, sym) of skVar, skResult, skLet: genVarPrototype(m, sym) of skType: discard getTypeDesc(m, sym.typ) - else: InternalError("cgsym: " & name) + else: internalError("cgsym: " & name) else: # we used to exclude the system module from this check, but for DLL # generation support this sloppyness leads to hard to detect bugs, so @@ -724,7 +724,7 @@ proc generateHeaders(m: BModule) = appf(m.s[cfsHeaders], "$N#include \"$1\"$N", [toRope(it.data)]) else: appf(m.s[cfsHeaders], "$N#include $1$N", [toRope(it.data)]) - it = PStrEntry(it.Next) + it = PStrEntry(it.next) proc retIsNotVoid(s: PSym): bool = result = (s.typ.sons[0] != nil) and not isInvalidReturnType(s.typ.sons[0]) @@ -747,7 +747,7 @@ proc closureSetup(p: BProc, prc: PSym) = # prc.ast[paramsPos].last contains the type we're after: var ls = lastSon(prc.ast[paramsPos]) if ls.kind != nkSym: - InternalError(prc.info, "closure generation failed") + internalError(prc.info, "closure generation failed") var env = ls.sym #echo "created environment: ", env.id, " for ", prc.name.s assignLocalVar(p, env) @@ -784,7 +784,7 @@ proc genProcAux(m: BModule, prc: PSym) = genStmts(p, prc.getBody) # modifies p.locals, p.init, etc. var generatedProc: PRope if sfPure in prc.flags: - if hasNakedDeclspec in extccomp.CC[extccomp.ccompiler].props: + if hasNakedDeclspec in extccomp.CC[extccomp.cCompiler].props: header = con("__declspec(naked) ", header) generatedProc = rfmt(nil, "$N$1 {$n$2$3$4}$N$N", header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)) @@ -793,7 +793,7 @@ proc genProcAux(m: BModule, prc: PSym) = app(generatedProc, initGCFrame(p)) if optStackTrace in prc.options: app(generatedProc, p.s(cpsLocals)) - var procname = CStringLit(p, generatedProc, prc.name.s) + var procname = cstringLit(p, generatedProc, prc.name.s) app(generatedProc, initFrame(p, procname, prc.info.quotedFilename)) else: app(generatedProc, p.s(cpsLocals)) @@ -811,16 +811,16 @@ proc genProcAux(m: BModule, prc: PSym) = proc genProcPrototype(m: BModule, sym: PSym) = useHeader(m, sym) - if lfNoDecl in sym.loc.Flags: return - if lfDynamicLib in sym.loc.Flags: + if lfNoDecl in sym.loc.flags: return + if lfDynamicLib in sym.loc.flags: if getModule(sym).id != m.module.id and - not ContainsOrIncl(m.declaredThings, sym.id): + not containsOrIncl(m.declaredThings, sym.id): app(m.s[cfsVars], rfmt(nil, "extern $1 $2;$n", getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym))) if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect) - elif not ContainsOrIncl(m.declaredProtos, sym.id): + elif not containsOrIncl(m.declaredProtos, sym.id): var header = genProcHeader(m, sym) - if sfPure in sym.flags and hasNakedAttribute in CC[ccompiler].props: + if sfPure in sym.flags and hasNakedAttribute in CC[cCompiler].props: header.app(" __attribute__((naked))") app(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", header)) @@ -832,21 +832,21 @@ proc genProcNoForward(m: BModule, prc: PSym) = discard cgsym(m, prc.name.s) return genProcPrototype(m, prc) - if lfNoDecl in prc.loc.Flags: nil + if lfNoDecl in prc.loc.flags: nil elif prc.typ.callConv == ccInline: # We add inline procs to the calling module to enable C based inlining. # This also means that a check with ``q.declaredThings`` is wrong, we need # a check for ``m.declaredThings``. - if not ContainsOrIncl(m.declaredThings, prc.id): genProcAux(m, prc) + if not containsOrIncl(m.declaredThings, prc.id): genProcAux(m, prc) elif lfDynamicLib in prc.loc.flags: var q = findPendingModule(m, prc) - if q != nil and not ContainsOrIncl(q.declaredThings, prc.id): - SymInDynamicLib(q, prc) + if q != nil and not containsOrIncl(q.declaredThings, prc.id): + symInDynamicLib(q, prc) else: - SymInDynamicLibPartial(m, prc) + symInDynamicLibPartial(m, prc) elif sfImportc notin prc.flags: var q = findPendingModule(m, prc) - if q != nil and not ContainsOrIncl(q.declaredThings, prc.id): + if q != nil and not containsOrIncl(q.declaredThings, prc.id): genProcAux(q, prc) proc requestConstImpl(p: BProc, sym: PSym) = @@ -854,15 +854,15 @@ proc requestConstImpl(p: BProc, sym: PSym) = useHeader(m, sym) if sym.loc.k == locNone: fillLoc(sym.loc, locData, sym.typ, mangleName(sym), OnUnknown) - if lfNoDecl in sym.loc.Flags: return + if lfNoDecl in sym.loc.flags: return # declare implementation: var q = findPendingModule(m, sym) - if q != nil and not ContainsOrIncl(q.declaredThings, sym.id): + if q != nil and not containsOrIncl(q.declaredThings, sym.id): assert q.initProc.module == q appf(q.s[cfsData], "NIM_CONST $1 $2 = $3;$n", [getTypeDesc(q, sym.typ), sym.loc.r, genConstExpr(q.initProc, sym.ast)]) # declare header: - if q != m and not ContainsOrIncl(m.declaredThings, sym.id): + if q != m and not containsOrIncl(m.declaredThings, sym.id): assert(sym.loc.r != nil) let headerDecl = ropef("extern NIM_CONST $1 $2;$n", [getTypeDesc(m, sym.loc.t), sym.loc.r]) @@ -879,17 +879,17 @@ proc genProc(m: BModule, prc: PSym) = else: genProcNoForward(m, prc) if {sfExportc, sfCompilerProc} * prc.flags == {sfExportc} and - generatedHeader != nil and lfNoDecl notin prc.loc.Flags: + generatedHeader != nil and lfNoDecl notin prc.loc.flags: genProcPrototype(generatedHeader, prc) if prc.typ.callConv == ccInline: - if not ContainsOrIncl(generatedHeader.declaredThings, prc.id): + if not containsOrIncl(generatedHeader.declaredThings, prc.id): genProcAux(generatedHeader, prc) proc genVarPrototypeAux(m: BModule, sym: PSym) = assert(sfGlobal in sym.flags) useHeader(m, sym) fillLoc(sym.loc, locGlobalVar, sym.typ, mangleName(sym), OnHeap) - if (lfNoDecl in sym.loc.Flags) or ContainsOrIncl(m.declaredThings, sym.id): + if (lfNoDecl in sym.loc.flags) or containsOrIncl(m.declaredThings, sym.id): return if sym.owner.id != m.module.id: # else we already have the symbol generated! @@ -914,23 +914,23 @@ proc addIntTypes(result: var PRope) {.inline.} = proc getCopyright(cfilenoext: string): PRope = if optCompileOnly in gGlobalOptions: result = ropeff("/* Generated by Nimrod Compiler v$1 */$n" & - "/* (c) 2012 Andreas Rumpf */$n" & + "/* (c) 2014 Andreas Rumpf */$n" & "/* The generated code is subject to the original license. */$n", "; Generated by Nimrod Compiler v$1$n" & - "; (c) 2012 Andreas Rumpf$n", [toRope(versionAsString)]) + "; (c) 2012 Andreas Rumpf$n", [toRope(VersionAsString)]) else: result = ropeff("/* Generated by Nimrod Compiler v$1 */$n" & - "/* (c) 2012 Andreas Rumpf */$n" & + "/* (c) 2014 Andreas Rumpf */$n" & "/* The generated code is subject to the original license. */$n" & "/* Compiled for: $2, $3, $4 */$n" & "/* Command for C compiler:$n $5 */$n", "; Generated by Nimrod Compiler v$1$n" & - "; (c) 2012 Andreas Rumpf$n" & + "; (c) 2014 Andreas Rumpf$n" & "; Compiled for: $2, $3, $4$n" & - "; Command for LLVM compiler:$n $5$n", [toRope(versionAsString), + "; Command for LLVM compiler:$n $5$n", [toRope(VersionAsString), toRope(platform.OS[targetOS].name), toRope(platform.CPU[targetCPU].name), - toRope(extccomp.CC[extccomp.ccompiler].name), + toRope(extccomp.CC[extccomp.cCompiler].name), toRope(getCompileCFileCmd(cfilenoext))]) proc getFileHeader(cfilenoext: string): PRope = @@ -943,44 +943,60 @@ proc genFilenames(m: BModule): PRope = for i in 0.. <fileInfos.len: result.appf("dbgRegisterFilename($1);$n", fileInfos[i].projPath.makeCString) -proc genMainProc(m: BModule) = +proc genMainProc(m: BModule) = const - CommonMainBody = - "\tsystemDatInit();$n" & - "\tsystemInit();$n" & - "$1" & - "$2" & - "$3" & - "$4" - PosixNimMain = - "int cmdCount;$n" & - "char** cmdLine;$n" & - "char** gEnv;$n" & - "N_CDECL(void, NimMain)(void) {$n" & - CommonMainBody & "}$n" + PreMainBody = + "\tsystemDatInit();$n" & + "\tsystemInit();$n" & + "$1" & + "$2" & + "$3" & + "$4" + + MainProcs = + "\tPreMain();$n" & + "\tNimMain();$n" + + MainProcsWithResult = + MainProcs & "\treturn nim_program_result;$n" + + PosixNimMain = + "int cmdCount;$n" & + "char** cmdLine;$n" & + "char** gEnv;$n" & + "N_CDECL(void, NimMain)(void) {$n$1}$n" + PosixCMain = "int main(int argc, char** args, char** env) {$n" & - "\tcmdLine = args;$n" & "\tcmdCount = argc;$n" & "\tgEnv = env;$n" & - "\tNimMain();$n" & "\treturn nim_program_result;$n" & "}$n" + "\tcmdLine = args;$n" & "\tcmdCount = argc;$n" & "\tgEnv = env;$n" & + MainProcsWithResult & + "}$n" + StandaloneCMain = "int main(void) {$n" & - "\tNimMain();$n" & - "\treturn 0;$n" & "}$n" - WinNimMain = "N_CDECL(void, NimMain)(void) {$n" & - CommonMainBody & "}$n" + MainProcs & + "\treturn 0;$n" & "}$n" + + WinNimMain = "N_CDECL(void, NimMain)(void) {$n$1}$n" + WinCMain = "N_STDCALL(int, WinMain)(HINSTANCE hCurInstance, $n" & - " HINSTANCE hPrevInstance, $n" & - " LPSTR lpCmdLine, int nCmdShow) {$n" & - "\tNimMain();$n" & "\treturn nim_program_result;$n" & "}$n" - WinNimDllMain = "N_LIB_EXPORT N_CDECL(void, NimMain)(void) {$n" & - CommonMainBody & "}$n" - WinCDllMain = - "BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, $n" & - " LPVOID lpvReserved) {$n" & - "\tif(fwdreason == DLL_PROCESS_ATTACH) NimMain();$n" & - "\treturn 1;$n" & "}$n" + " HINSTANCE hPrevInstance, $n" & + " LPSTR lpCmdLine, int nCmdShow) {$n" & + MainProcsWithResult & "}$n" + + WinNimDllMain = "N_LIB_EXPORT N_CDECL(void, NimMain)(void) {$n$1}$n" + + WinCDllMain = + "BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, $n" & + " LPVOID lpvReserved) {$n" & + "\tif(fwdreason == DLL_PROCESS_ATTACH) {" & MainProcs & "}$n" & + "\treturn 1;$n}$n" + PosixNimDllMain = WinNimDllMain - PosixCDllMain = - "void NIM_POSIX_INIT NimMainInit(void) {$n" & - "\tNimMain();$n}$n" + + PosixCDllMain = + "void NIM_POSIX_INIT NimMainInit(void) {$n" & + MainProcs & + "}$n" + var nimMain, otherMain: TFormatStr if platform.targetOS == osWindows and gGlobalOptions * {optGenGuiApp, optGenDynLib} != {}: @@ -990,10 +1006,10 @@ proc genMainProc(m: BModule) = else: nimMain = WinNimDllMain otherMain = WinCDllMain - discard lists.IncludeStr(m.headerFiles, "<windows.h>") + discard lists.includeStr(m.headerFiles, "<windows.h>") elif optGenDynLib in gGlobalOptions: - nimMain = posixNimDllMain - otherMain = posixCDllMain + nimMain = PosixNimDllMain + otherMain = PosixCDllMain elif platform.targetOS == osStandalone: nimMain = PosixNimMain otherMain = StandaloneCMain @@ -1008,8 +1024,10 @@ proc genMainProc(m: BModule) = platform.targetOS == osStandalone: "".toRope else: ropecg(m, "\t#initStackBottom();$n") inc(m.labels) - appcg(m, m.s[cfsProcs], nimMain, [mainDatInit, initStackBottomCall, - gBreakpoints, mainModInit, toRope(m.labels)]) + appcg(m, m.s[cfsProcs], "void PreMain() {$n" & PreMainBody & "}$n", [ + mainDatInit, initStackBottomCall, gBreakpoints, otherModsInit]) + + appcg(m, m.s[cfsProcs], nimMain, [mainModInit, toRope(m.labels)]) if optNoMain notin gGlobalOptions: appcg(m, m.s[cfsProcs], otherMain, []) @@ -1030,10 +1048,14 @@ proc registerModuleToMain(m: PSym) = "declare void $1() noinline$N", [init]) appff(mainModProcs, "N_NOINLINE(void, $1)(void);$N", "declare void $1() noinline$N", [datInit]) - if not (sfSystemModule in m.flags): - appff(mainModInit, "\t$1();$n", "call void ()* $1$n", [init]) + if sfSystemModule notin m.flags: appff(mainDatInit, "\t$1();$n", "call void ()* $1$n", [datInit]) - + let initCall = ropeff("\t$1();$n", "call void ()* $1$n", [init]) + if sfMainModule in m.flags: + app(mainModInit, initCall) + else: + app(otherModsInit, initCall) + proc genInitCode(m: BModule) = var initname = getInitName(m.module) var prc = ropeff("N_NOINLINE(void, $1)(void) {$n", @@ -1053,12 +1075,12 @@ proc genInitCode(m: BModule) = app(prc, m.postInitProc.s(cpsLocals)) app(prc, genSectionEnd(cpsLocals)) - if optStackTrace in m.initProc.options and not m.FrameDeclared: + if optStackTrace in m.initProc.options and not m.frameDeclared: # BUT: the generated init code might depend on a current frame, so # declare it nevertheless: - m.FrameDeclared = true - if not m.PreventStackTrace: - var procname = CStringLit(m.initProc, prc, m.module.name.s) + m.frameDeclared = true + if not m.preventStackTrace: + var procname = cstringLit(m.initProc, prc, m.module.name.s) app(prc, initFrame(m.initProc, procname, m.module.info.quotedFilename)) else: app(prc, ~"\tTFrame F; F.len = 0;$N") @@ -1074,7 +1096,7 @@ proc genInitCode(m: BModule) = app(prc, m.initProc.s(cpsStmts)) app(prc, m.postInitProc.s(cpsStmts)) app(prc, genSectionEnd(cpsStmts)) - if optStackTrace in m.initProc.options and not m.PreventStackTrace: + if optStackTrace in m.initProc.options and not m.preventStackTrace: app(prc, deinitFrame(m.initProc)) app(prc, deinitGCFrame(m.initProc)) appf(prc, "}$N$N") @@ -1127,7 +1149,7 @@ proc initProcOptions(m: BModule): TOptions = proc rawNewModule(module: PSym, filename: string): BModule = new(result) - InitLinkedList(result.headerFiles) + initLinkedList(result.headerFiles) result.declaredThings = initIntSet() result.declaredProtos = initIntSet() result.cfilename = filename @@ -1148,7 +1170,7 @@ proc rawNewModule(module: PSym, filename: string): BModule = # no line tracing for the init sections of the system module so that we # don't generate a TFrame which can confuse the stack botton initialization: if sfSystemModule in module.flags: - result.PreventStackTrace = true + result.preventStackTrace = true excl(result.preInitProc.options, optStackTrace) excl(result.postInitProc.options, optStackTrace) @@ -1159,7 +1181,7 @@ proc nullify[T](arr: var T) = proc resetModule*(m: var BModule) = # between two compilations in CAAS mode, we can throw # away all the data that was written to disk - InitLinkedList(m.headerFiles) + initLinkedList(m.headerFiles) m.declaredProtos = initIntSet() initIdTable(m.forwTypeCache) m.initProc = newProc(nil, m) @@ -1171,7 +1193,7 @@ proc resetModule*(m: var BModule) = m.forwardedProcs = @[] m.typeNodesName = getTempName() m.nimTypesName = getTempName() - m.PreventStackTrace = sfSystemModule in m.module.flags + m.preventStackTrace = sfSystemModule in m.module.flags nullify m.s m.usesThreadVars = false m.typeNodes = 0 @@ -1202,7 +1224,7 @@ proc rawNewModule(module: PSym): BModule = proc newModule(module: PSym): BModule = # we should create only one cgen module for each module sym - InternalAssert getCgenModule(module) == nil + internalAssert getCgenModule(module) == nil result = rawNewModule(module) growCache gModules, module.position @@ -1210,7 +1232,7 @@ proc newModule(module: PSym): BModule = if (optDeadCodeElim in gGlobalOptions): if (sfDeadCodeElim in module.flags): - InternalError("added pending module twice: " & module.filename) + internalError("added pending module twice: " & module.filename) proc myOpen(module: PSym): PPassContext = result = newModule(module) @@ -1263,19 +1285,19 @@ proc finishModule(m: BModule) = # a ``for`` loop here var prc = m.forwardedProcs[i] if sfForward in prc.flags: - InternalError(prc.info, "still forwarded: " & prc.name.s) + internalError(prc.info, "still forwarded: " & prc.name.s) genProcNoForward(m, prc) inc(i) assert(gForwardedProcsCounter >= i) dec(gForwardedProcsCounter, i) - setlen(m.forwardedProcs, 0) + setLen(m.forwardedProcs, 0) proc shouldRecompile(code: PRope, cfile, cfilenoext: string): bool = result = true if optForceFullMake notin gGlobalOptions: var objFile = toObjFile(cfilenoext) if writeRopeIfNotEqual(code, cfile): return - if ExistsFile(objFile) and os.FileNewer(objFile, cfile): result = false + if existsFile(objFile) and os.fileNewer(objFile, cfile): result = false else: writeRope(code, cfile) @@ -1296,7 +1318,7 @@ proc writeModule(m: BModule, pending: bool) = if sfMainModule in m.module.flags: # generate main file: app(m.s[cfsProcHeaders], mainModProcs) - GenerateThreadVarsSize(m) + generateThreadVarsSize(m) var code = genModule(m, cfilenoext) when hasTinyCBackend: @@ -1313,7 +1335,7 @@ proc writeModule(m: BModule, pending: bool) = var code = genModule(m, cfilenoext) writeRope(code, cfile) addFileToCompile(cfilenoext) - elif not ExistsFile(toObjFile(cfilenoext)): + elif not existsFile(toObjFile(cfilenoext)): # Consider: first compilation compiles ``system.nim`` and produces # ``system.c`` but then compilation fails due to an error. This means # that ``system.o`` is missing, so we need to call the C compiler for it: diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index a803c0ba1..9cd2c0d87 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -61,8 +61,8 @@ type TCProc{.final.} = object # represents C proc that is currently generated prc*: PSym # the Nimrod proc that this C proc belongs to - BeforeRetNeeded*: bool # true iff 'BeforeRet' label for proc is needed - ThreadVarAccessed*: bool # true if the proc already accessed some threadvar + beforeRetNeeded*: bool # true iff 'BeforeRet' label for proc is needed + threadVarAccessed*: bool # true if the proc already accessed some threadvar nestedTryStmts*: seq[PNode] # in how many nested try statements we are # (the vars must be volatile then) inExceptBlock*: int # are we currently inside an except block? @@ -78,7 +78,7 @@ type maxFrameLen*: int # max length of frame descriptor module*: BModule # used to prevent excessive parameter passing withinLoop*: int # > 0 if we are within a loop - gcFrameId*: natural # for the GC stack marking + gcFrameId*: Natural # for the GC stack marking gcFrameType*: PRope # the struct {} we put the GC markers into TTypeSeq* = seq[PType] @@ -86,9 +86,9 @@ type module*: PSym filename*: string s*: TCFileSections # sections of the C file - PreventStackTrace*: bool # true if stack traces need to be prevented + preventStackTrace*: bool # true if stack traces need to be prevented usesThreadVars*: bool # true if the module uses a thread var - FrameDeclared*: bool # hack for ROD support so that we don't declare + frameDeclared*: bool # hack for ROD support so that we don't declare # a frame var twice in an init proc isHeaderFile*: bool # C source file is the header file includesStringh*: bool # C source file already includes ``<string.h>`` @@ -108,13 +108,14 @@ type forwardedProcs*: TSymSeq # keep forwarded procs here typeNodes*, nimTypes*: int # used for type info generation typeNodesName*, nimTypesName*: PRope # used for type info generation - labels*: natural # for generating unique module-scope names + labels*: Natural # for generating unique module-scope names extensionLoaders*: array['0'..'9', PRope] # special procs for the # OpenGL wrapper injectStmt*: PRope var - mainModProcs*, mainModInit*, mainDatInit*: PRope # parts of the main module + mainModProcs*, mainModInit*, otherModsInit*, mainDatInit*: PRope + # varuious parts of the main module gMapping*: PRope # the generated mapping file (if requested) gModules*: seq[BModule] = @[] # list of all compiled modules gForwardedProcsCounter*: int = 0 diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index 33bb94b38..9613eb525 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -18,16 +18,16 @@ proc genConv(n: PNode, d: PType, downcast: bool): PNode = var source = skipTypes(n.typ, abstractPtrs) if (source.kind == tyObject) and (dest.kind == tyObject): var diff = inheritanceDiff(dest, source) - if diff == high(int): InternalError(n.info, "cgmeth.genConv") + if diff == high(int): internalError(n.info, "cgmeth.genConv") if diff < 0: result = newNodeIT(nkObjUpConv, n.info, d) addSon(result, n) - if downCast: InternalError(n.info, "cgmeth.genConv: no upcast allowed") + if downcast: internalError(n.info, "cgmeth.genConv: no upcast allowed") elif diff > 0: result = newNodeIT(nkObjDownConv, n.info, d) addSon(result, n) - if not downCast: - InternalError(n.info, "cgmeth.genConv: no downcast allowed") + if not downcast: + internalError(n.info, "cgmeth.genConv: no downcast allowed") else: result = n else: @@ -112,12 +112,12 @@ proc relevantCol(methods: TSymSeq, col: int): bool = if t.kind == tyObject: for i in countup(1, high(methods)): let t2 = skipTypes(methods[i].typ.sons[col], skipPtrs) - if not SameType(t2, t): + if not sameType(t2, t): return true proc cmpSignatures(a, b: PSym, relevantCols: TIntSet): int = for col in countup(1, sonsLen(a.typ) - 1): - if Contains(relevantCols, col): + if contains(relevantCols, col): var aa = skipTypes(a.typ.sons[col], skipPtrs) var bb = skipTypes(b.typ.sons[col], skipPtrs) var d = inheritanceDiff(aa, bb) @@ -126,14 +126,14 @@ proc cmpSignatures(a, b: PSym, relevantCols: TIntSet): int = proc sortBucket(a: var TSymSeq, relevantCols: TIntSet) = # we use shellsort here; fast and simple - var N = len(a) + var n = len(a) var h = 1 while true: h = 3 * h + 1 - if h > N: break + if h > n: break while true: h = h div 3 - for i in countup(h, N - 1): + for i in countup(h, n - 1): var v = a[i] var j = i while cmpSignatures(a[j - h], v, relevantCols) >= 0: @@ -154,7 +154,7 @@ proc genDispatcher(methods: TSymSeq, relevantCols: TIntSet): PSym = var curr = methods[meth] # generate condition: var cond: PNode = nil for col in countup(1, paramLen - 1): - if Contains(relevantCols, col): + if contains(relevantCols, col): var isn = newNodeIT(nkCall, base.info, getSysType(tyBool)) addSon(isn, newSymNode(iss)) addSon(isn, newSymNode(base.typ.n.sons[col].sym)) @@ -195,7 +195,7 @@ proc generateMethodDispatchers*(): PNode = for bucket in countup(0, len(gMethods) - 1): var relevantCols = initIntSet() for col in countup(1, sonsLen(gMethods[bucket][0].typ) - 1): - if relevantCol(gMethods[bucket], col): Incl(relevantCols, col) + if relevantCol(gMethods[bucket], col): incl(relevantCols, col) sortBucket(gMethods[bucket], relevantCols) addSon(result, newSymNode(genDispatcher(gMethods[bucket], relevantCols))) diff --git a/compiler/commands.nim b/compiler/commands.nim index fa7841275..18bdb54d3 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2013 Andreas Rumpf +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -21,40 +21,40 @@ type passCmd2, # second pass over the command line passPP # preprocessor called ProcessCommand() -proc ProcessCommand*(switch: string, pass: TCmdLinePass) -proc processSwitch*(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) +proc processCommand*(switch: string, pass: TCmdLinePass) +proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) # implementation const - HelpMessage = "Nimrod Compiler Version $1 (" & compileDate & ") [$2: $3]\n" & - "Copyright (c) 2004-2013 by Andreas Rumpf\n" + HelpMessage = "Nimrod Compiler Version $1 (" & CompileDate & ") [$2: $3]\n" & + "Copyright (c) 2006-2014 by Andreas Rumpf\n" const Usage = slurp"doc/basicopt.txt".replace("//", "") AdvancedUsage = slurp"doc/advopt.txt".replace("//", "") proc getCommandLineDesc(): string = - result = (HelpMessage % [VersionAsString, platform.os[platform.hostOS].name, - cpu[platform.hostCPU].name]) & Usage + result = (HelpMessage % [VersionAsString, platform.OS[platform.hostOS].name, + CPU[platform.hostCPU].name]) & Usage -proc HelpOnError(pass: TCmdLinePass) = +proc helpOnError(pass: TCmdLinePass) = if pass == passCmd1: - MsgWriteln(getCommandLineDesc()) + msgWriteln(getCommandLineDesc()) quit(0) proc writeAdvancedUsage(pass: TCmdLinePass) = if pass == passCmd1: - MsgWriteln(`%`(HelpMessage, [VersionAsString, - platform.os[platform.hostOS].name, - cpu[platform.hostCPU].name]) & AdvancedUsage) + msgWriteln(`%`(HelpMessage, [VersionAsString, + platform.OS[platform.hostOS].name, + CPU[platform.hostCPU].name]) & AdvancedUsage) quit(0) proc writeVersionInfo(pass: TCmdLinePass) = if pass == passCmd1: - MsgWriteln(`%`(HelpMessage, [VersionAsString, - platform.os[platform.hostOS].name, - cpu[platform.hostCPU].name])) + msgWriteln(`%`(HelpMessage, [VersionAsString, + platform.OS[platform.hostOS].name, + CPU[platform.hostCPU].name])) quit(0) var @@ -62,16 +62,16 @@ var proc writeCommandLineUsage() = if not helpWritten: - MsgWriteln(getCommandLineDesc()) + msgWriteln(getCommandLineDesc()) helpWritten = true proc addPrefix(switch: string): string = if len(switch) == 1: result = "-" & switch else: result = "--" & switch -proc InvalidCmdLineOption(pass: TCmdLinePass, switch: string, info: TLineInfo) = - if switch == " ": LocalError(info, errInvalidCmdLineOption, "-") - else: LocalError(info, errInvalidCmdLineOption, addPrefix(switch)) +proc invalidCmdLineOption(pass: TCmdLinePass, switch: string, info: TLineInfo) = + if switch == " ": localError(info, errInvalidCmdLineOption, "-") + else: localError(info, errInvalidCmdLineOption, addPrefix(switch)) proc splitSwitch(switch: string, cmd, arg: var string, pass: TCmdLinePass, info: TLineInfo) = @@ -86,29 +86,29 @@ proc splitSwitch(switch: string, cmd, arg: var string, pass: TCmdLinePass, inc(i) if i >= len(switch): arg = "" elif switch[i] in {':', '=', '['}: arg = substr(switch, i + 1) - else: InvalidCmdLineOption(pass, switch, info) + else: invalidCmdLineOption(pass, switch, info) -proc ProcessOnOffSwitch(op: TOptions, arg: string, pass: TCmdlinePass, +proc processOnOffSwitch(op: TOptions, arg: string, pass: TCmdLinePass, info: TLineInfo) = case whichKeyword(arg) of wOn: gOptions = gOptions + op of wOff: gOptions = gOptions - op - else: LocalError(info, errOnOrOffExpectedButXFound, arg) + else: localError(info, errOnOrOffExpectedButXFound, arg) -proc ProcessOnOffSwitchG(op: TGlobalOptions, arg: string, pass: TCmdlinePass, +proc processOnOffSwitchG(op: TGlobalOptions, arg: string, pass: TCmdLinePass, info: TLineInfo) = case whichKeyword(arg) of wOn: gGlobalOptions = gGlobalOptions + op of wOff: gGlobalOptions = gGlobalOptions - op - else: LocalError(info, errOnOrOffExpectedButXFound, arg) + else: localError(info, errOnOrOffExpectedButXFound, arg) -proc ExpectArg(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) = - if arg == "": LocalError(info, errCmdLineArgExpected, addPrefix(switch)) +proc expectArg(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) = + if arg == "": localError(info, errCmdLineArgExpected, addPrefix(switch)) -proc ExpectNoArg(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) = - if arg != "": LocalError(info, errCmdLineNoArgExpected, addPrefix(switch)) +proc expectNoArg(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) = + if arg != "": localError(info, errCmdLineNoArgExpected, addPrefix(switch)) -proc ProcessSpecificNote(arg: string, state: TSpecialWord, pass: TCmdlinePass, +proc processSpecificNote(arg: string, state: TSpecialWord, pass: TCmdLinePass, info: TLineInfo) = var id = "" # arg = "X]:on|off" var i = 0 @@ -117,21 +117,21 @@ proc ProcessSpecificNote(arg: string, state: TSpecialWord, pass: TCmdlinePass, add(id, arg[i]) inc(i) if i < len(arg) and (arg[i] == ']'): inc(i) - else: InvalidCmdLineOption(pass, arg, info) + else: invalidCmdLineOption(pass, arg, info) if i < len(arg) and (arg[i] in {':', '='}): inc(i) - else: InvalidCmdLineOption(pass, arg, info) + else: invalidCmdLineOption(pass, arg, info) if state == wHint: var x = findStr(msgs.HintsToStr, id) if x >= 0: n = TNoteKind(x + ord(hintMin)) - else: InvalidCmdLineOption(pass, arg, info) + else: invalidCmdLineOption(pass, arg, info) else: var x = findStr(msgs.WarningsToStr, id) if x >= 0: n = TNoteKind(x + ord(warnMin)) - else: InvalidCmdLineOption(pass, arg, info) + else: invalidCmdLineOption(pass, arg, info) case whichKeyword(substr(arg, i)) of wOn: incl(gNotes, n) of wOff: excl(gNotes, n) - else: LocalError(info, errOnOrOffExpectedButXFound, arg) + else: localError(info, errOnOrOffExpectedButXFound, arg) proc processCompile(filename: string) = var found = findFile(filename) @@ -150,14 +150,14 @@ proc testCompileOptionArg*(switch, arg: string, info: TLineInfo): bool = of "markandsweep": result = gSelectedGC == gcMarkAndSweep of "generational": result = gSelectedGC == gcGenerational of "none": result = gSelectedGC == gcNone - else: LocalError(info, errNoneBoehmRefcExpectedButXFound, arg) + else: localError(info, errNoneBoehmRefcExpectedButXFound, arg) of "opt": case arg.normalize of "speed": result = contains(gOptions, optOptimizeSpeed) of "size": result = contains(gOptions, optOptimizeSize) of "none": result = gOptions * {optOptimizeSpeed, optOptimizeSize} == {} - else: LocalError(info, errNoneSpeedOrSizeExpectedButXFound, arg) - else: InvalidCmdLineOption(passCmd1, switch, info) + else: localError(info, errNoneSpeedOrSizeExpectedButXFound, arg) + else: invalidCmdLineOption(passCmd1, switch, info) proc testCompileOption*(switch: string, info: TLineInfo): bool = case switch.normalize @@ -173,11 +173,11 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool = of "linetrace": result = contains(gOptions, optLineTrace) of "debugger": result = contains(gOptions, optEndb) of "profiler": result = contains(gOptions, optProfiler) - of "checks", "x": result = gOptions * checksOptions == checksOptions + of "checks", "x": result = gOptions * ChecksOptions == ChecksOptions of "floatchecks": - result = gOptions * {optNanCheck, optInfCheck} == {optNanCheck, optInfCheck} + result = gOptions * {optNaNCheck, optInfCheck} == {optNaNCheck, optInfCheck} of "infchecks": result = contains(gOptions, optInfCheck) - of "nanchecks": result = contains(gOptions, optNanCheck) + of "nanchecks": result = contains(gOptions, optNaNCheck) of "objchecks": result = contains(gOptions, optObjCheck) of "fieldchecks": result = contains(gOptions, optFieldCheck) of "rangechecks": result = contains(gOptions, optRangeCheck) @@ -194,7 +194,7 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool = of "tlsemulation": result = contains(gGlobalOptions, optTlsEmulation) of "implicitstatic": result = contains(gOptions, optImplicitStatic) of "patterns": result = contains(gOptions, optPatterns) - else: InvalidCmdLineOption(passCmd1, switch, info) + else: invalidCmdLineOption(passCmd1, switch, info) proc processPath(path: string, notRelativeToProj = false): string = let p = if notRelativeToProj or os.isAbsolute(path) or @@ -202,20 +202,20 @@ proc processPath(path: string, notRelativeToProj = false): string = path else: options.gProjectPath / path - result = UnixToNativePath(p % ["nimrod", getPrefixDir(), "lib", libpath, + result = unixToNativePath(p % ["nimrod", getPrefixDir(), "lib", libpath, "home", removeTrailingDirSep(os.getHomeDir()), "projectname", options.gProjectName, "projectpath", options.gProjectPath]) proc trackDirty(arg: string, info: TLineInfo) = var a = arg.split(',') - if a.len != 4: LocalError(info, errTokenExpected, + if a.len != 4: localError(info, errTokenExpected, "DIRTY_BUFFER,ORIGINAL_FILE,LINE,COLUMN") var line, column: int if parseUtils.parseInt(a[2], line) <= 0: - LocalError(info, errInvalidNumber, a[1]) + localError(info, errInvalidNumber, a[1]) if parseUtils.parseInt(a[3], column) <= 0: - LocalError(info, errInvalidNumber, a[2]) + localError(info, errInvalidNumber, a[2]) gDirtyBufferIdx = a[0].fileInfoIdx gDirtyOriginalIdx = a[1].fileInfoIdx @@ -225,21 +225,21 @@ proc trackDirty(arg: string, info: TLineInfo) = proc track(arg: string, info: TLineInfo) = var a = arg.split(',') - if a.len != 3: LocalError(info, errTokenExpected, "FILE,LINE,COLUMN") + if a.len != 3: localError(info, errTokenExpected, "FILE,LINE,COLUMN") var line, column: int if parseUtils.parseInt(a[1], line) <= 0: - LocalError(info, errInvalidNumber, a[1]) + localError(info, errInvalidNumber, a[1]) if parseUtils.parseInt(a[2], column) <= 0: - LocalError(info, errInvalidNumber, a[2]) + localError(info, errInvalidNumber, a[2]) optTrackPos = newLineInfo(a[0], line, column) msgs.addCheckpoint(optTrackPos) -proc dynlibOverride(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = +proc dynlibOverride(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) = if pass in {passCmd2, passPP}: expectArg(switch, arg, pass, info) options.inclDynlibOverride(arg) -proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = +proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) = var theOS: TSystemOS cpu: TSystemCPU @@ -259,8 +259,8 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = of "excludepath": expectArg(switch, arg, pass, info) let path = processPath(arg) - lists.ExcludeStr(options.searchPaths, path) - lists.ExcludeStr(options.lazyPaths, path) + lists.excludeStr(options.searchPaths, path) + lists.excludeStr(options.lazyPaths, path) of "nimcache": expectArg(switch, arg, pass, info) options.nimcacheDir = processPath(arg) @@ -272,10 +272,10 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = optMainModule = arg of "define", "d": expectArg(switch, arg, pass, info) - DefineSymbol(arg) + defineSymbol(arg) of "undef", "u": expectArg(switch, arg, pass, info) - UndefSymbol(arg) + undefSymbol(arg) of "compile": expectArg(switch, arg, pass, info) if pass in {passCmd2, passPP}: processCompile(arg) @@ -308,7 +308,7 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = case arg.normalize of "boehm": gSelectedGC = gcBoehm - DefineSymbol("boehmgc") + defineSymbol("boehmgc") of "refc": gSelectedGC = gcRefc of "v2": @@ -322,42 +322,42 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = of "none": gSelectedGC = gcNone defineSymbol("nogc") - else: LocalError(info, errNoneBoehmRefcExpectedButXFound, arg) - of "warnings", "w": ProcessOnOffSwitch({optWarns}, arg, pass, info) - of "warning": ProcessSpecificNote(arg, wWarning, pass, info) - of "hint": ProcessSpecificNote(arg, wHint, pass, info) - of "hints": ProcessOnOffSwitch({optHints}, arg, pass, info) - of "threadanalysis": ProcessOnOffSwitchG({optThreadAnalysis}, arg, pass, info) - of "stacktrace": ProcessOnOffSwitch({optStackTrace}, arg, pass, info) - of "linetrace": ProcessOnOffSwitch({optLineTrace}, arg, pass, info) + else: localError(info, errNoneBoehmRefcExpectedButXFound, arg) + of "warnings", "w": processOnOffSwitch({optWarns}, arg, pass, info) + of "warning": processSpecificNote(arg, wWarning, pass, info) + of "hint": processSpecificNote(arg, wHint, pass, info) + of "hints": processOnOffSwitch({optHints}, arg, pass, info) + of "threadanalysis": processOnOffSwitchG({optThreadAnalysis}, arg, pass, info) + of "stacktrace": processOnOffSwitch({optStackTrace}, arg, pass, info) + of "linetrace": processOnOffSwitch({optLineTrace}, arg, pass, info) of "debugger": - ProcessOnOffSwitch({optEndb}, arg, pass, info) - if optEndb in gOptions: DefineSymbol("endb") - else: UndefSymbol("endb") + processOnOffSwitch({optEndb}, arg, pass, info) + if optEndb in gOptions: defineSymbol("endb") + else: undefSymbol("endb") of "profiler": - ProcessOnOffSwitch({optProfiler}, arg, pass, info) - if optProfiler in gOptions: DefineSymbol("profiler") - else: UndefSymbol("profiler") - of "checks", "x": ProcessOnOffSwitch(checksOptions, arg, pass, info) + processOnOffSwitch({optProfiler}, arg, pass, info) + if optProfiler in gOptions: defineSymbol("profiler") + else: undefSymbol("profiler") + of "checks", "x": processOnOffSwitch(ChecksOptions, arg, pass, info) of "floatchecks": - ProcessOnOffSwitch({optNanCheck, optInfCheck}, arg, pass, info) - of "infchecks": ProcessOnOffSwitch({optInfCheck}, arg, pass, info) - of "nanchecks": ProcessOnOffSwitch({optNanCheck}, arg, pass, info) - of "objchecks": ProcessOnOffSwitch({optObjCheck}, arg, pass, info) - of "fieldchecks": ProcessOnOffSwitch({optFieldCheck}, arg, pass, info) - of "rangechecks": ProcessOnOffSwitch({optRangeCheck}, arg, pass, info) - of "boundchecks": ProcessOnOffSwitch({optBoundsCheck}, arg, pass, info) - of "overflowchecks": ProcessOnOffSwitch({optOverflowCheck}, arg, pass, info) - of "linedir": ProcessOnOffSwitch({optLineDir}, arg, pass, info) - of "assertions", "a": ProcessOnOffSwitch({optAssert}, arg, pass, info) - of "deadcodeelim": ProcessOnOffSwitchG({optDeadCodeElim}, arg, pass, info) - of "threads": ProcessOnOffSwitchG({optThreads}, arg, pass, info) - of "tlsemulation": ProcessOnOffSwitchG({optTlsEmulation}, arg, pass, info) - of "taintmode": ProcessOnOffSwitchG({optTaintMode}, arg, pass, info) + processOnOffSwitch({optNaNCheck, optInfCheck}, arg, pass, info) + of "infchecks": processOnOffSwitch({optInfCheck}, arg, pass, info) + of "nanchecks": processOnOffSwitch({optNaNCheck}, arg, pass, info) + of "objchecks": processOnOffSwitch({optObjCheck}, arg, pass, info) + of "fieldchecks": processOnOffSwitch({optFieldCheck}, arg, pass, info) + of "rangechecks": processOnOffSwitch({optRangeCheck}, arg, pass, info) + of "boundchecks": processOnOffSwitch({optBoundsCheck}, arg, pass, info) + of "overflowchecks": processOnOffSwitch({optOverflowCheck}, arg, pass, info) + of "linedir": processOnOffSwitch({optLineDir}, arg, pass, info) + of "assertions", "a": processOnOffSwitch({optAssert}, arg, pass, info) + of "deadcodeelim": processOnOffSwitchG({optDeadCodeElim}, arg, pass, info) + of "threads": processOnOffSwitchG({optThreads}, arg, pass, info) + of "tlsemulation": processOnOffSwitchG({optTlsEmulation}, arg, pass, info) + of "taintmode": processOnOffSwitchG({optTaintMode}, arg, pass, info) of "implicitstatic": - ProcessOnOffSwitch({optImplicitStatic}, arg, pass, info) + processOnOffSwitch({optImplicitStatic}, arg, pass, info) of "patterns": - ProcessOnOffSwitch({optPatterns}, arg, pass, info) + processOnOffSwitch({optPatterns}, arg, pass, info) of "opt": expectArg(switch, arg, pass, info) case arg.normalize @@ -370,7 +370,7 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = of "none": excl(gOptions, optOptimizeSpeed) excl(gOptions, optOptimizeSize) - else: LocalError(info, errNoneSpeedOrSizeExpectedButXFound, arg) + else: localError(info, errNoneSpeedOrSizeExpectedButXFound, arg) of "app": expectArg(switch, arg, pass, info) case arg.normalize @@ -392,7 +392,7 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = excl(gGlobalOptions, optGenGuiApp) defineSymbol("library") defineSymbol("staticlib") - else: LocalError(info, errGuiConsoleOrLibExpectedButXFound, arg) + else: localError(info, errGuiConsoleOrLibExpectedButXFound, arg) of "passc", "t": expectArg(switch, arg, pass, info) if pass in {passCmd2, passPP}: extccomp.addCompileOption(arg) @@ -401,18 +401,18 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = if pass in {passCmd2, passPP}: extccomp.addLinkOption(arg) of "cincludes": expectArg(switch, arg, pass, info) - if pass in {passCmd2, passPP}: cIncludes.add arg + if pass in {passCmd2, passPP}: cIncludes.add arg.processPath of "clibdir": expectArg(switch, arg, pass, info) - if pass in {passCmd2, passPP}: cLibs.add arg + if pass in {passCmd2, passPP}: cLibs.add arg.processPath of "clib": expectArg(switch, arg, pass, info) - if pass in {passCmd2, passPP}: cLinkedLibs.add arg + if pass in {passCmd2, passPP}: cLinkedLibs.add arg.processPath of "header": headerFile = arg incl(gGlobalOptions, optGenIndex) of "index": - ProcessOnOffSwitchG({optGenIndex}, arg, pass, info) + processOnOffSwitchG({optGenIndex}, arg, pass, info) of "import": expectArg(switch, arg, pass, info) if pass in {passCmd2, passPP}: implicitImports.add arg @@ -428,19 +428,19 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = of "os": expectArg(switch, arg, pass, info) if pass in {passCmd1, passPP}: - theOS = platform.NameToOS(arg) - if theOS == osNone: LocalError(info, errUnknownOS, arg) + theOS = platform.nameToOS(arg) + if theOS == osNone: localError(info, errUnknownOS, arg) elif theOS != platform.hostOS: setTarget(theOS, targetCPU) - condsyms.InitDefines() + condsyms.initDefines() of "cpu": expectArg(switch, arg, pass, info) if pass in {passCmd1, passPP}: - cpu = platform.NameToCPU(arg) - if cpu == cpuNone: LocalError(info, errUnknownCPU, arg) + cpu = platform.nameToCPU(arg) + if cpu == cpuNone: localError(info, errUnknownCPU, arg) elif cpu != platform.hostCPU: setTarget(targetOS, cpu) - condsyms.InitDefines() + condsyms.initDefines() of "run", "r": expectNoArg(switch, arg, pass, info) incl(gGlobalOptions, optRun) @@ -460,7 +460,7 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = expectNoArg(switch, arg, pass, info) helpOnError(pass) of "symbolfiles": - ProcessOnOffSwitchG({optSymbolFiles}, arg, pass, info) + processOnOffSwitchG({optSymbolFiles}, arg, pass, info) of "skipcfg": expectNoArg(switch, arg, pass, info) incl(gGlobalOptions, optSkipConfigFile) @@ -520,13 +520,13 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = case arg of "partial": idents.firstCharIsCS = true of "none": idents.firstCharIsCS = false - else: LocalError(info, errGenerated, + else: localError(info, errGenerated, "'partial' or 'none' expected, but found " & arg) else: if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg) - else: InvalidCmdLineOption(pass, switch, info) + else: invalidCmdLineOption(pass, switch, info) -proc ProcessCommand(switch: string, pass: TCmdLinePass) = +proc processCommand(switch: string, pass: TCmdLinePass) = var cmd, arg: string splitSwitch(switch, cmd, arg, pass, gCmdLineInfo) processSwitch(cmd, arg, pass, gCmdLineInfo) diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index 21095072b..c79fda13e 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -16,10 +16,10 @@ import # to be style insensitive. Otherwise hell would break lose. var gSymbols: PStringTable -proc DefineSymbol*(symbol: string) = +proc defineSymbol*(symbol: string) = gSymbols[symbol] = "true" -proc UndefSymbol*(symbol: string) = +proc undefSymbol*(symbol: string) = gSymbols[symbol] = "false" proc isDefined*(symbol: string): bool = @@ -37,52 +37,52 @@ proc countDefinedSymbols*(): int = for key, val in pairs(gSymbols): if val == "true": inc(result) -proc InitDefines*() = +proc initDefines*() = gSymbols = newStringTable(modeStyleInsensitive) - DefineSymbol("nimrod") # 'nimrod' is always defined + defineSymbol("nimrod") # 'nimrod' is always defined # for bootstrapping purposes and old code: - DefineSymbol("nimhygiene") - DefineSymbol("niminheritable") - DefineSymbol("nimmixin") - DefineSymbol("nimeffects") - DefineSymbol("nimbabel") - DefineSymbol("nimcomputedgoto") + defineSymbol("nimhygiene") + defineSymbol("niminheritable") + defineSymbol("nimmixin") + defineSymbol("nimeffects") + defineSymbol("nimbabel") + defineSymbol("nimcomputedgoto") # add platform specific symbols: case targetCPU - of cpuI386: DefineSymbol("x86") - of cpuIa64: DefineSymbol("itanium") - of cpuAmd64: DefineSymbol("x8664") + of cpuI386: defineSymbol("x86") + of cpuIa64: defineSymbol("itanium") + of cpuAmd64: defineSymbol("x8664") else: discard case targetOS - of osDOS: - DefineSymbol("msdos") + of osDos: + defineSymbol("msdos") of osWindows: - DefineSymbol("mswindows") - DefineSymbol("win32") - of osLinux, osMorphOS, osSkyOS, osIrix, osPalmOS, osQNX, osAtari, osAix, + defineSymbol("mswindows") + defineSymbol("win32") + of osLinux, osMorphos, osSkyos, osIrix, osPalmos, osQnx, osAtari, osAix, osHaiku: # these are all 'unix-like' - DefineSymbol("unix") - DefineSymbol("posix") + defineSymbol("unix") + defineSymbol("posix") of osSolaris: - DefineSymbol("sunos") - DefineSymbol("unix") - DefineSymbol("posix") - of osNetBSD, osFreeBSD, osOpenBSD: - DefineSymbol("unix") - DefineSymbol("bsd") - DefineSymbol("posix") - of osMacOS: - DefineSymbol("macintosh") - of osMacOSX: - DefineSymbol("macintosh") - DefineSymbol("unix") - DefineSymbol("posix") + defineSymbol("sunos") + defineSymbol("unix") + defineSymbol("posix") + of osNetbsd, osFreebsd, osOpenbsd: + defineSymbol("unix") + defineSymbol("bsd") + defineSymbol("posix") + of osMacos: + defineSymbol("macintosh") + of osMacosx: + defineSymbol("macintosh") + defineSymbol("unix") + defineSymbol("posix") else: discard - DefineSymbol("cpu" & $cpu[targetCPU].bit) - DefineSymbol(normalize(endianToStr[cpu[targetCPU].endian])) - DefineSymbol(cpu[targetCPU].name) - DefineSymbol(platform.os[targetOS].name) + defineSymbol("cpu" & $CPU[targetCPU].bit) + defineSymbol(normalize(EndianToStr[CPU[targetCPU].endian])) + defineSymbol(CPU[targetCPU].name) + defineSymbol(platform.OS[targetOS].name) if platform.OS[targetOS].props.contains(ospLacksThreadVars): - DefineSymbol("emulatedthreadvars") + defineSymbol("emulatedthreadvars") diff --git a/compiler/crc.nim b/compiler/crc.nim index a3b181e20..ae1df3ff1 100644 --- a/compiler/crc.nim +++ b/compiler/crc.nim @@ -18,8 +18,8 @@ const InitAdler32* = int32(1) proc updateCrc32*(val: int8, crc: TCrc32): TCrc32 {.inline.} -proc updateCrc32*(val: Char, crc: TCrc32): TCrc32 {.inline.} -proc crcFromBuf*(buf: Pointer, length: int): TCrc32 +proc updateCrc32*(val: char, crc: TCrc32): TCrc32 {.inline.} +proc crcFromBuf*(buf: pointer, length: int): TCrc32 proc strCrc32*(s: string): TCrc32 proc crcFromFile*(filename: string): TCrc32 proc updateAdler32*(adler: int32, buf: pointer, length: int): int32 @@ -75,10 +75,10 @@ const 755167117] proc updateCrc32(val: int8, crc: TCrc32): TCrc32 = - result = TCrc32(crc32Table[(int(crc) xor (int(val) and 0x000000FF)) and + result = TCrc32(crc32table[(int(crc) xor (int(val) and 0x000000FF)) and 0x000000FF]) xor (crc shr TCrc32(8)) -proc updateCrc32(val: Char, crc: TCrc32): TCrc32 = +proc updateCrc32(val: char, crc: TCrc32): TCrc32 = result = updateCrc32(toU8(ord(val)), crc) proc strCrc32(s: string): TCrc32 = @@ -93,7 +93,7 @@ type TByteArray = array[0..10000000, int8] PByteArray = ref TByteArray -proc crcFromBuf(buf: Pointer, length: int): TCrc32 = +proc crcFromBuf(buf: pointer, length: int): TCrc32 = var p = cast[PByteArray](buf) result = InitCrc32 for i in countup(0, length - 1): result = updateCrc32(p[i], result) @@ -102,11 +102,11 @@ proc crcFromFile(filename: string): TCrc32 = const bufSize = 8000 # don't use 8K for the memory allocator! var - bin: tfile + bin: TFile result = InitCrc32 if not open(bin, filename): return # not equal if file does not exist - var buf = alloc(BufSize) + var buf = alloc(bufSize) var p = cast[PByteArray](buf) while true: var readBytes = readBuffer(bin, buf, bufSize) diff --git a/compiler/depends.nim b/compiler/depends.nim index 1468cbdb9..5b02275c6 100644 --- a/compiler/depends.nim +++ b/compiler/depends.nim @@ -43,7 +43,7 @@ proc addDotDependency(c: PPassContext, n: PNode): PNode = proc generateDot(project: string) = writeRope(ropef("digraph $1 {$n$2}$n", [ - toRope(changeFileExt(extractFileName(project), "")), gDotGraph]), + toRope(changeFileExt(extractFilename(project), "")), gDotGraph]), changeFileExt(project, "dot")) proc myOpen(module: PSym): PPassContext = diff --git a/compiler/docgen.nim b/compiler/docgen.nim index d44018a2b..343f415b3 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -40,33 +40,33 @@ proc compilerMsgHandler(filename: string, line, col: int, of mwRedefinitionOfLabel: k = warnRedefinitionOfLabel of mwUnknownSubstitution: k = warnUnknownSubstitutionX of mwUnsupportedLanguage: k = warnLanguageXNotSupported - GlobalError(newLineInfo(filename, line, col), k, arg) + globalError(newLineInfo(filename, line, col), k, arg) proc parseRst(text, filename: string, line, column: int, hasToc: var bool, rstOptions: TRstParseOptions): PRstNode = result = rstParse(text, filename, line, column, hasToc, rstOptions, - options.FindFile, compilerMsgHandler) + options.findFile, compilerMsgHandler) proc newDocumentor*(filename: string, config: PStringTable): PDoc = new(result) - initRstGenerator(result[], (if gCmd != cmdRst2Tex: outHtml else: outLatex), + initRstGenerator(result[], (if gCmd != cmdRst2tex: outHtml else: outLatex), options.gConfigVars, filename, {roSupportRawDirective}, - options.FindFile, compilerMsgHandler) + options.findFile, compilerMsgHandler) result.id = 100 -proc dispA(dest: var PRope, xml, tex: string, args: openarray[PRope]) = - if gCmd != cmdRst2Tex: appf(dest, xml, args) +proc dispA(dest: var PRope, xml, tex: string, args: openArray[PRope]) = + if gCmd != cmdRst2tex: appf(dest, xml, args) else: appf(dest, tex, args) -proc getVarIdx(varnames: openarray[string], id: string): int = +proc getVarIdx(varnames: openArray[string], id: string): int = for i in countup(0, high(varnames)): if cmpIgnoreStyle(varnames[i], id) == 0: return i result = -1 -proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openarray[string], - varvalues: openarray[PRope]): PRope = +proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openArray[string], + varvalues: openArray[PRope]): PRope = var i = 0 var L = len(frmt) result = nil @@ -85,7 +85,7 @@ proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openarray[string], of '0'..'9': var j = 0 while true: - j = (j * 10) + Ord(frmt[i]) - ord('0') + j = (j * 10) + ord(frmt[i]) - ord('0') inc(i) if (i > L + 0 - 1) or not (frmt[i] in {'0'..'9'}): break if j > high(varvalues) + 1: internalError("ropeFormatNamedVars") @@ -112,7 +112,7 @@ proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openarray[string], var idx = getVarIdx(varnames, id) if idx >= 0: app(result, varvalues[idx]) else: rawMessage(errUnkownSubstitionVar, id) - else: InternalError("ropeFormatNamedVars") + else: internalError("ropeFormatNamedVars") var start = i while i < L: if frmt[i] != '$': inc(i) @@ -124,7 +124,7 @@ proc genComment(d: PDoc, n: PNode): string = var dummyHasToc: bool if n.comment != nil and startsWith(n.comment, "##"): renderRstToOut(d[], parseRst(n.comment, toFilename(n.info), - toLineNumber(n.info), toColumn(n.info), + toLinenumber(n.info), toColumn(n.info), dummyHasToc, d.options + {roSkipPounds}), result) proc genRecComment(d: PDoc, n: PNode): PRope = @@ -152,7 +152,7 @@ proc extractDocComment*(s: PSym, d: PDoc = nil): string = if not d.isNil: var dummyHasToc: bool renderRstToOut(d[], parseRst(n.comment, toFilename(n.info), - toLineNumber(n.info), toColumn(n.info), + toLinenumber(n.info), toColumn(n.info), dummyHasToc, d.options + {roSkipPounds}), result) else: @@ -272,7 +272,7 @@ proc genJSONItem(d: PDoc, n, nameNode: PNode, k: TSymKind): PJsonNode = result["code"] = %r.buf proc checkForFalse(n: PNode): bool = - result = n.kind == nkIdent and IdentEq(n.ident, "false") + result = n.kind == nkIdent and identEq(n.ident, "false") proc traceDeps(d: PDoc, n: PNode) = const k = skModule @@ -313,7 +313,7 @@ proc generateDoc*(d: PDoc, n: PNode) = of nkImportStmt: for i in 0 .. sonsLen(n)-1: traceDeps(d, n.sons[i]) of nkFromStmt, nkImportExceptStmt: traceDeps(d, n.sons[0]) - else: nil + else: discard proc generateJson(d: PDoc, n: PNode, jArray: PJsonNode = nil): PJsonNode = case n.kind @@ -355,7 +355,7 @@ proc generateJson(d: PDoc, n: PNode, jArray: PJsonNode = nil): PJsonNode = # generate documentation for the first branch only: if not checkForFalse(n.sons[0].sons[0]) and jArray != nil: discard generateJson(d, lastSon(n.sons[0]), jArray) - else: nil + else: discard proc genSection(d: PDoc, kind: TSymKind) = const sectionNames: array[skModule..skTemplate, string] = [ @@ -408,7 +408,7 @@ proc genOutFile(d: PDoc): PRope = proc generateIndex*(d: PDoc) = if optGenIndex in gGlobalOptions: writeIndexFile(d[], splitFile(options.outFile).dir / - splitFile(d.filename).name & indexExt) + splitFile(d.filename).name & IndexExt) proc writeOutput*(d: PDoc, filename, outExt: string, useWarning = false) = var content = genOutFile(d) @@ -417,7 +417,7 @@ proc writeOutput*(d: PDoc, filename, outExt: string, useWarning = false) = else: writeRope(content, getOutFile(filename, outExt), useWarning) -proc CommandDoc*() = +proc commandDoc*() = var ast = parseFile(gProjectMainIdx) if ast == nil: return var d = newDocumentor(gProjectFull, options.gConfigVars) @@ -426,7 +426,7 @@ proc CommandDoc*() = writeOutput(d, gProjectFull, HtmlExt) generateIndex(d) -proc CommandRstAux(filename, outExt: string) = +proc commandRstAux(filename, outExt: string) = var filen = addFileExt(filename, "txt") var d = newDocumentor(filen, options.gConfigVars) var rst = parseRst(readFile(filen), filen, 0, 1, d.hasToc, @@ -439,14 +439,14 @@ proc CommandRstAux(filename, outExt: string) = writeOutput(d, filename, outExt) generateIndex(d) -proc CommandRst2Html*() = - CommandRstAux(gProjectFull, HtmlExt) +proc commandRst2Html*() = + commandRstAux(gProjectFull, HtmlExt) -proc CommandRst2TeX*() = +proc commandRst2TeX*() = splitter = "\\-" - CommandRstAux(gProjectFull, TexExt) + commandRstAux(gProjectFull, TexExt) -proc CommandJSON*() = +proc commandJSON*() = var ast = parseFile(gProjectMainIdx) if ast == nil: return var d = newDocumentor(gProjectFull, options.gConfigVars) @@ -460,7 +460,7 @@ proc CommandJSON*() = echo getOutFile(gProjectFull, JsonExt) writeRope(content, getOutFile(gProjectFull, JsonExt), useWarning = false) -proc CommandBuildIndex*() = +proc commandBuildIndex*() = var content = mergeIndexes(gProjectFull).toRope let code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title", diff --git a/compiler/evalffi.nim b/compiler/evalffi.nim index 21a131996..74f0663f3 100644 --- a/compiler/evalffi.nim +++ b/compiler/evalffi.nim @@ -9,7 +9,7 @@ ## This file implements the FFI part of the evaluator for Nimrod code. -import ast, astalgo, ropes, types, options, tables, dynlib, libffi, msgs +import ast, astalgo, ropes, types, options, tables, dynlib, libffi, msgs, os when defined(windows): const libcDll = "msvcrt.dll" @@ -20,7 +20,11 @@ type TDllCache = tables.TTable[string, TLibHandle] var gDllCache = initTable[string, TLibHandle]() - gExeHandle = LoadLib() + +when defined(windows): + var gExeHandle = loadLib(os.getAppFilename()) +else: + var gExeHandle = loadLib() proc getDll(cache: var TDllCache; dll: string; info: TLineInfo): pointer = result = cache[dll] @@ -28,15 +32,17 @@ proc getDll(cache: var TDllCache; dll: string; info: TLineInfo): pointer = var libs: seq[string] = @[] libCandidates(dll, libs) for c in libs: - result = LoadLib(c) + result = loadLib(c) if not result.isNil: break if result.isNil: - GlobalError(info, "cannot load: " & dll) + globalError(info, "cannot load: " & dll) cache[dll] = result const nkPtrLit = nkIntLit # hopefully we can get rid of this hack soon +var myerrno {.importc: "errno", header: "<errno.h>".}: cint ## error variable + proc importcSymbol*(sym: PSym): PNode = let name = ropeToStr(sym.loc.r) @@ -47,10 +53,11 @@ proc importcSymbol*(sym: PSym): PNode = of "stdin": result.intVal = cast[TAddress](system.stdin) of "stdout": result.intVal = cast[TAddress](system.stdout) of "stderr": result.intVal = cast[TAddress](system.stderr) + of "vmErrnoWrapper": result.intVal = cast[TAddress](myerrno) else: let lib = sym.annex if lib != nil and lib.path.kind notin {nkStrLit..nkTripleStrLit}: - GlobalError(sym.info, "dynlib needs to be a string lit for the REPL") + globalError(sym.info, "dynlib needs to be a string lit for the REPL") var theAddr: pointer if lib.isNil and not gExehandle.isNil: # first try this exe itself: @@ -58,10 +65,12 @@ proc importcSymbol*(sym: PSym): PNode = # then try libc: if theAddr.isNil: let dllhandle = gDllCache.getDll(libcDll, sym.info) - theAddr = dllhandle.checkedSymAddr(name) - else: - let dllhandle = gDllCache.getDll(lib.path.strVal, sym.info) - theAddr = dllhandle.checkedSymAddr(name) + theAddr = dllhandle.symAddr(name) + elif not lib.isNil: + let dllhandle = gDllCache.getDll(if lib.kind == libHeader: libcDll + else: lib.path.strVal, sym.info) + theAddr = dllhandle.symAddr(name) + if theAddr.isNil: globalError(sym.info, "cannot import: " & sym.name.s) result.intVal = cast[TAddress](theAddr) proc mapType(t: ast.PType): ptr libffi.TType = @@ -78,7 +87,7 @@ proc mapType(t: ast.PType): ptr libffi.TType = of tyFloat, tyFloat64: result = addr libffi.type_double of tyFloat32: result = addr libffi.type_float of tyVar, tyPointer, tyPtr, tyRef, tyCString, tySequence, tyString, tyExpr, - tyStmt, tyTypeDesc, tyProc, tyArray, tyArrayConstr, tyNil: + tyStmt, tyTypeDesc, tyProc, tyArray, tyArrayConstr, tyStatic, tyNil: result = addr libffi.type_pointer of tyDistinct: result = mapType(t.sons[0]) @@ -139,7 +148,7 @@ proc getField(n: PNode; position: int): PSym = else: internalError(n.info, "getField(record case branch)") of nkSym: if n.sym.position == position: result = n.sym - else: nil + else: discard proc packObject(x: PNode, typ: PType, res: pointer) = InternalAssert x.kind in {nkObjConstr, nkPar} @@ -192,7 +201,7 @@ proc pack(v: PNode, typ: PType, res: pointer) = of tyPointer, tyProc, tyCString, tyString: if v.kind == nkNilLit: # nothing to do since the memory is 0 initialized anyway - nil + discard elif v.kind == nkPtrLit: awr(pointer, cast[pointer](v.intVal)) elif v.kind in {nkStrLit..nkTripleStrLit}: @@ -202,7 +211,7 @@ proc pack(v: PNode, typ: PType, res: pointer) = of tyPtr, tyRef, tyVar: if v.kind == nkNilLit: # nothing to do since the memory is 0 initialized anyway - nil + discard elif v.kind == nkPtrLit: awr(pointer, cast[pointer](v.intVal)) else: @@ -220,7 +229,7 @@ proc pack(v: PNode, typ: PType, res: pointer) = of tyObject, tyTuple: packObject(v, typ, res) of tyNil: - nil + discard of tyDistinct, tyGenericInst: pack(v, typ.sons[0], res) else: @@ -241,7 +250,7 @@ proc unpackObjectAdd(x: pointer, n, result: PNode) = pair.sons[1] = unpack(x +! n.sym.offset, n.sym.typ, nil) #echo "offset: ", n.sym.name.s, " ", n.sym.offset result.add pair - else: nil + else: discard proc unpackObject(x: pointer, typ: PType, n: PNode): PNode = # compute the field's offsets: @@ -441,3 +450,46 @@ proc callForeignFunction*(call: PNode): PNode = for i in 1 .. call.len-1: call.sons[i] = unpack(args[i-1], typ.sons[i], call[i]) dealloc args[i-1] + +proc callForeignFunction*(fn: PNode, fntyp: PType, + args: var TNodeSeq, start, len: int, + info: TLineInfo): PNode = + internalAssert fn.kind == nkPtrLit + + var cif: TCif + var sig: TParamList + for i in 0..len-1: + var aTyp = args[i+start].typ + if aTyp.isNil: + internalAssert i+1 < fntyp.len + aTyp = fntyp.sons[i+1] + args[i+start].typ = aTyp + sig[i] = mapType(aTyp) + if sig[i].isNil: globalError(info, "cannot map FFI type") + + if prep_cif(cif, mapCallConv(fntyp.callConv, info), cuint(len), + mapType(fntyp.sons[0]), sig) != OK: + globalError(info, "error in FFI call") + + var cargs: TArgList + let fn = cast[pointer](fn.intVal) + for i in 0 .. len-1: + let t = args[i+start].typ + cargs[i] = alloc0(packSize(args[i+start], t)) + pack(args[i+start], t, cargs[i]) + let retVal = if isEmptyType(fntyp.sons[0]): pointer(nil) + else: alloc(fntyp.sons[0].getSize.int) + + libffi.call(cif, fn, retVal, cargs) + + if retVal.isNil: + result = emptyNode + else: + result = unpack(retVal, fntyp.sons[0], nil) + result.info = info + + if retVal != nil: dealloc retVal + for i in 0 .. len-1: + let t = args[i+start].typ + args[i+start] = unpack(cargs[i], t, args[i+start]) + dealloc cargs[i] diff --git a/compiler/evals.nim b/compiler/evals.nim index b4ea973e8..151adf690 100644 --- a/compiler/evals.nim +++ b/compiler/evals.nim @@ -91,6 +91,7 @@ proc evalMacroCall*(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode proc raiseCannotEval(c: PEvalContext, info: TLineInfo): PNode = + if defined(debug) and gVerbosity >= 3: writeStackTrace() result = newNodeI(nkExceptBranch, info) # creating a nkExceptBranch without sons # means that it could not be evaluated @@ -263,8 +264,8 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode = result = newNodeIT(nkUIntLit, info, t) of tyFloat..tyFloat128: result = newNodeIt(nkFloatLit, info, t) - of tyVar, tyPointer, tyPtr, tyRef, tyCString, tySequence, tyString, tyExpr, - tyStmt, tyTypeDesc, tyProc: + of tyVar, tyPointer, tyPtr, tyRef, tyCString, tySequence, tyString, tyExpr, + tyStmt, tyTypeDesc, tyStatic, tyProc: result = newNodeIT(nkNilLit, info, t) of tyObject: result = newNodeIT(nkPar, info, t) @@ -358,7 +359,7 @@ proc evalVar(c: PEvalContext, n: PNode): PNode = proc aliasNeeded(n: PNode, flags: TEvalFlags): bool = result = efLValue in flags or n.typ == nil or - n.typ.kind in {tyExpr, tyStmt, tyTypeDesc} + n.typ.kind in {tyExpr, tyStatic, tyStmt, tyTypeDesc} proc evalVariable(c: PStackFrame, sym: PSym, flags: TEvalFlags): PNode = # We need to return a node to the actual value, @@ -905,17 +906,15 @@ proc evalParseStmt(c: PEvalContext, n: PNode): PNode = result = parseString(code.getStrValue, code.info.toFilename, code.info.line.int) #result.typ = newType(tyStmt, c.module) - -proc evalTypeTrait*(trait, operand: PNode, context: PSym): PNode = - InternalAssert operand.kind == nkSym - let typ = operand.sym.typ.skipTypes({tyTypeDesc}) +proc evalTypeTrait*(trait, operand: PNode, context: PSym): PNode = + let typ = operand.typ.skipTypes({tyTypeDesc}) case trait.sym.name.s.normalize of "name": result = newStrNode(nkStrLit, typ.typeToString(preferName)) result.typ = newType(tyString, context) result.info = trait.info - of "arity": + of "arity": result = newIntNode(nkIntLit, typ.n.len-1) result.typ = newType(tyInt, context) result.info = trait.info @@ -1329,7 +1328,7 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode = if gNestedEvals <= 0: stackTrace(c, n.info, errTooManyIterations) case n.kind of nkSym: result = evalSym(c, n, flags) - of nkType..nkNilLit: + of nkType..nkNilLit, nkTypeOfExpr: # nkStrLit is VERY common in the traces, so we should avoid # the 'copyNode' here. result = n #.copyNode diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index 05be0e9d3..78cdbb45f 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2012 Andreas Rumpf +# (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -16,9 +16,14 @@ import type TemplCtx {.pure, final.} = object owner, genSymOwner: PSym + instLines: bool # use the instantiation lines numbers mapping: TIdTable # every gensym'ed symbol needs to be mapped to some # new symbol +proc copyNode(ctx: TemplCtx, a, b: PNode): PNode = + result = copyNode(a) + if ctx.instLines: result.info = b.info + proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) = case templ.kind of nkSym: @@ -31,49 +36,23 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) = else: result.add copyTree(x) else: - InternalAssert sfGenSym in s.flags - var x = PSym(IdTableGet(c.mapping, s)) + internalAssert sfGenSym in s.flags + var x = PSym(idTableGet(c.mapping, s)) if x == nil: x = copySym(s, false) x.owner = c.genSymOwner - IdTablePut(c.mapping, s, x) - result.add newSymNode(x, templ.info) + idTablePut(c.mapping, s, x) + result.add newSymNode(x, if c.instLines: actual.info else: templ.info) else: - result.add copyNode(templ) + result.add copyNode(c, templ, actual) of nkNone..nkIdent, nkType..nkNilLit: # atom - result.add copyNode(templ) + result.add copyNode(c, templ, actual) else: - var res = copyNode(templ) + var res = copyNode(c, templ, actual) for i in countup(0, sonsLen(templ) - 1): evalTemplateAux(templ.sons[i], actual, c, res) result.add res -when false: - proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx): PNode = - case templ.kind - of nkSym: - var s = templ.sym - if s.owner.id == c.owner.id: - if s.kind == skParam: - result = copyTree(actual.sons[s.position]) - else: - InternalAssert sfGenSym in s.flags - var x = PSym(IdTableGet(c.mapping, s)) - if x == nil: - x = copySym(s, false) - x.owner = c.genSymOwner - IdTablePut(c.mapping, s, x) - result = newSymNode(x, templ.info) - else: - result = copyNode(templ) - of nkNone..nkIdent, nkType..nkNilLit: # atom - result = copyNode(templ) - else: - result = copyNode(templ) - newSons(result, sonsLen(templ)) - for i in countup(0, sonsLen(templ) - 1): - result.sons[i] = evalTemplateAux(templ.sons[i], actual, c) - proc evalTemplateArgs(n: PNode, s: PSym): PNode = # if the template has zero arguments, it can be called without ``()`` # `n` is then a nkSym or something similar @@ -83,13 +62,13 @@ proc evalTemplateArgs(n: PNode, s: PSym): PNode = a = sonsLen(n) else: a = 0 var f = s.typ.sonsLen - if a > f: GlobalError(n.info, errWrongNumberOfArguments) + if a > f: globalError(n.info, errWrongNumberOfArguments) result = newNodeI(nkArgList, n.info) for i in countup(1, f - 1): var arg = if i < a: n.sons[i] else: copyTree(s.typ.n.sons[i].sym.ast) if arg == nil or arg.kind == nkEmpty: - LocalError(n.info, errWrongNumberOfArguments) + localError(n.info, errWrongNumberOfArguments) addSon(result, arg) var evalTemplateCounter* = 0 @@ -98,7 +77,7 @@ var evalTemplateCounter* = 0 proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym): PNode = inc(evalTemplateCounter) if evalTemplateCounter > 100: - GlobalError(n.info, errTemplateInstantiationTooNested) + globalError(n.info, errTemplateInstantiationTooNested) result = n # replace each param by the corresponding node: @@ -114,11 +93,13 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym): PNode = evalTemplateAux(body, args, ctx, result) if result.len == 1: result = result.sons[0] else: - GlobalError(result.info, errIllFormedAstX, + globalError(result.info, errIllFormedAstX, renderTree(result, {renderNoComments})) else: result = copyNode(body) - #evalTemplateAux(body, args, ctx, result) + ctx.instLines = body.kind notin {nkStmtList, nkStmtListExpr, + nkBlockStmt, nkBlockExpr} + if ctx.instLines: result.info = n.info for i in countup(0, safeLen(body) - 1): evalTemplateAux(body.sons[i], args, ctx, result) diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index bbbbbfb8e..12761f1d4 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -324,7 +324,7 @@ var compileOptions: string = "" ccompilerpath: string = "" -proc NameToCC*(name: string): TSystemCC = +proc nameToCC*(name: string): TSystemCC = for i in countup(succ(ccNone), high(TSystemCC)): if cmpIgnoreStyle(name, CC[i].name) == 0: return i @@ -335,8 +335,8 @@ proc getConfigVar(c: TSystemCC, suffix: string): string = # for niminst support if (platform.hostOS != targetOS or platform.hostCPU != targetCPU) and optCompileOnly notin gGlobalOptions: - let fullCCname = platform.cpu[targetCPU].name & '.' & - platform.os[targetOS].name & '.' & + let fullCCname = platform.CPU[targetCPU].name & '.' & + platform.OS[targetOS].name & '.' & CC[c].name & suffix result = getConfigVar(fullCCname) if result.len == 0: @@ -346,13 +346,13 @@ proc getConfigVar(c: TSystemCC, suffix: string): string = result = getConfigVar(CC[c].name & suffix) proc setCC*(ccname: string) = - ccompiler = nameToCC(ccname) - if ccompiler == ccNone: rawMessage(errUnknownCcompiler, ccname) - compileOptions = getConfigVar(ccompiler, ".options.always") - linkOptions = getConfigVar(ccompiler, ".options.linker") - ccompilerpath = getConfigVar(ccompiler, ".path") + cCompiler = nameToCC(ccname) + if cCompiler == ccNone: rawMessage(errUnknownCcompiler, ccname) + compileOptions = getConfigVar(cCompiler, ".options.always") + linkOptions = getConfigVar(cCompiler, ".options.linker") + ccompilerpath = getConfigVar(cCompiler, ".path") for i in countup(low(CC), high(CC)): undefSymbol(CC[i].name) - defineSymbol(CC[ccompiler].name) + defineSymbol(CC[cCompiler].name) proc addOpt(dest: var string, src: string) = if len(dest) == 0 or dest[len(dest)-1] != ' ': add(dest, " ") @@ -368,20 +368,20 @@ proc addCompileOption*(option: string) = proc initVars*() = # we need to define the symbol here, because ``CC`` may have never been set! for i in countup(low(CC), high(CC)): undefSymbol(CC[i].name) - defineSymbol(CC[ccompiler].name) + defineSymbol(CC[cCompiler].name) if gCmd == cmdCompileToCpp: cExt = ".cpp" elif gCmd == cmdCompileToOC: cExt = ".m" - addCompileOption(getConfigVar(ccompiler, ".options.always")) - addLinkOption(getConfigVar(ccompiler, ".options.linker")) - if len(ccompilerPath) == 0: - ccompilerpath = getConfigVar(ccompiler, ".path") + addCompileOption(getConfigVar(cCompiler, ".options.always")) + addLinkOption(getConfigVar(cCompiler, ".options.linker")) + if len(ccompilerpath) == 0: + ccompilerpath = getConfigVar(cCompiler, ".path") proc completeCFilePath*(cfile: string, createSubDir: bool = true): string = result = completeGeneratedFilePath(cfile, createSubDir) proc toObjFile*(filenameWithoutExt: string): string = # Object file for compilation - result = changeFileExt(filenameWithoutExt, cc[ccompiler].objExt) + result = changeFileExt(filenameWithoutExt, CC[cCompiler].objExt) proc addFileToCompile*(filename: string) = appendStr(toCompile, filename) @@ -400,28 +400,28 @@ proc addFileToLink*(filename: string) = # BUGFIX: was ``appendStr`` proc execExternalProgram*(cmd: string) = - if optListCmd in gGlobalOptions or gVerbosity > 0: MsgWriteln(cmd) + if optListCmd in gGlobalOptions or gVerbosity > 0: msgWriteln(cmd) if execCmd(cmd) != 0: rawMessage(errExecutionOfProgramFailed, "") proc generateScript(projectFile: string, script: PRope) = let (dir, name, ext) = splitFile(projectFile) - WriteRope(script, dir / addFileExt("compile_" & name, - platform.os[targetOS].scriptExt)) + writeRope(script, dir / addFileExt("compile_" & name, + platform.OS[targetOS].scriptExt)) proc getOptSpeed(c: TSystemCC): string = result = getConfigVar(c, ".options.speed") if result == "": - result = cc[c].optSpeed # use default settings from this file + result = CC[c].optSpeed # use default settings from this file proc getDebug(c: TSystemCC): string = result = getConfigVar(c, ".options.debug") if result == "": - result = cc[c].debug # use default settings from this file + result = CC[c].debug # use default settings from this file proc getOptSize(c: TSystemCC): string = result = getConfigVar(c, ".options.size") if result == "": - result = cc[c].optSize # use default settings from this file + result = CC[c].optSize # use default settings from this file proc noAbsolutePaths: bool {.inline.} = # We used to check current OS != specified OS, but this makes no sense @@ -436,78 +436,78 @@ const var fileCounter: int -proc add(s: var string, many: openarray[string]) = +proc add(s: var string, many: openArray[string]) = s.add many.join -proc CFileSpecificOptions(cfilename: string): string = +proc cFileSpecificOptions(cfilename: string): string = result = compileOptions var trunk = splitFile(cfilename).name if optCDebug in gGlobalOptions: var key = trunk & ".debug" if existsConfigVar(key): addOpt(result, getConfigVar(key)) - else: addOpt(result, getDebug(ccompiler)) + else: addOpt(result, getDebug(cCompiler)) if optOptimizeSpeed in gOptions: var key = trunk & ".speed" if existsConfigVar(key): addOpt(result, getConfigVar(key)) - else: addOpt(result, getOptSpeed(ccompiler)) + else: addOpt(result, getOptSpeed(cCompiler)) elif optOptimizeSize in gOptions: var key = trunk & ".size" if existsConfigVar(key): addOpt(result, getConfigVar(key)) - else: addOpt(result, getOptSize(ccompiler)) + else: addOpt(result, getOptSize(cCompiler)) var key = trunk & ".always" if existsConfigVar(key): addOpt(result, getConfigVar(key)) proc getCompileOptions: string = - result = CFileSpecificOptions("__dummy__") + result = cFileSpecificOptions("__dummy__") proc getLinkOptions: string = result = linkOptions for linkedLib in items(cLinkedLibs): - result.add(cc[ccompiler].linkLibCmd % linkedLib.quoteShell) + result.add(CC[cCompiler].linkLibCmd % linkedLib.quoteShell) for libDir in items(cLibs): - result.add([cc[ccompiler].linkDirCmd, libDir.quoteShell]) + result.add([CC[cCompiler].linkDirCmd, libDir.quoteShell]) proc needsExeExt(): bool {.inline.} = result = (optGenScript in gGlobalOptions and targetOS == osWindows) or (platform.hostOS == osWindows) proc getCompileCFileCmd*(cfilename: string, isExternal = false): string = - var c = ccompiler - var options = CFileSpecificOptions(cfilename) + var c = cCompiler + var options = cFileSpecificOptions(cfilename) var exe = getConfigVar(c, ".exe") - if exe.len == 0: exe = cc[c].compilerExe + if exe.len == 0: exe = CC[c].compilerExe if needsExeExt(): exe = addFileExt(exe, "exe") if optGenDynLib in gGlobalOptions and ospNeedsPIC in platform.OS[targetOS].props: - add(options, ' ' & cc[c].pic) + add(options, ' ' & CC[c].pic) var includeCmd, compilePattern: string if not noAbsolutePaths(): # compute include paths: - includeCmd = cc[c].includeCmd & quoteShell(libpath) + includeCmd = CC[c].includeCmd & quoteShell(libpath) for includeDir in items(cIncludes): - includeCmd.add([cc[c].includeCmd, includeDir.quoteShell]) + includeCmd.add([CC[c].includeCmd, includeDir.quoteShell]) - compilePattern = JoinPath(ccompilerpath, exe) + compilePattern = joinPath(ccompilerpath, exe) else: includeCmd = "" - compilePattern = cc[c].compilerExe + compilePattern = CC[c].compilerExe - var cfile = if noAbsolutePaths(): extractFileName(cfilename) + var cfile = if noAbsolutePaths(): extractFilename(cfilename) else: cfilename var objfile = if not isExternal or noAbsolutePaths(): toObjFile(cfile) else: completeCFilePath(toObjFile(cfile)) - cfile = quoteShell(AddFileExt(cfile, cExt)) + cfile = quoteShell(addFileExt(cfile, cExt)) objfile = quoteShell(objfile) result = quoteShell(compilePattern % [ "file", cfile, "objfile", objfile, "options", options, "include", includeCmd, "nimrod", getPrefixDir(), "lib", libpath]) add(result, ' ') - addf(result, cc[c].compileTmpl, [ + addf(result, CC[c].compileTmpl, [ "file", cfile, "objfile", objfile, "options", options, "include", includeCmd, "nimrod", quoteShell(getPrefixDir()), @@ -517,7 +517,7 @@ proc footprint(filename: string): TCrc32 = result = crcFromFile(filename) >< platform.OS[targetOS].name >< platform.CPU[targetCPU].name >< - extccomp.CC[extccomp.ccompiler].name >< + extccomp.CC[extccomp.cCompiler].name >< getCompileCFileCmd(filename, true) proc externalFileChanged(filename: string): bool = @@ -541,7 +541,7 @@ proc addExternalFileToCompile*(filename: string) = if optForceFullMake in gGlobalOptions or externalFileChanged(filename): appendStr(externalToCompile, filename) -proc CompileCFile(list: TLinkedList, script: var PRope, cmds: var TStringSeq, +proc compileCFile(list: TLinkedList, script: var PRope, cmds: var TStringSeq, isExternal: bool) = var it = PStrEntry(list.head) while it != nil: @@ -554,18 +554,18 @@ proc CompileCFile(list: TLinkedList, script: var PRope, cmds: var TStringSeq, app(script, tnl) it = PStrEntry(it.next) -proc CallCCompiler*(projectfile: string) = +proc callCCompiler*(projectfile: string) = var linkCmd, buildgui, builddll: string if gGlobalOptions * {optCompileOnly, optGenScript} == {optCompileOnly}: return # speed up that call if only compiling and no script shall be # generated fileCounter = 0 - var c = ccompiler + var c = cCompiler var script: PRope = nil var cmds: TStringSeq = @[] - CompileCFile(toCompile, script, cmds, false) - CompileCFile(externalToCompile, script, cmds, true) + compileCFile(toCompile, script, cmds, false) + compileCFile(externalToCompile, script, cmds, true) if optCompileOnly notin gGlobalOptions: if gNumberOfProcessors == 0: gNumberOfProcessors = countProcessors() var res = 0 @@ -591,40 +591,40 @@ proc CallCCompiler*(projectfile: string) = let objFile = if noAbsolutePaths(): it.data.extractFilename else: it.data add(objfiles, ' ') add(objfiles, quoteShell( - addFileExt(objFile, cc[ccompiler].objExt))) + addFileExt(objFile, CC[cCompiler].objExt))) it = PStrEntry(it.next) if optGenStaticLib in gGlobalOptions: - linkcmd = cc[c].buildLib % ["libfile", (libNameTmpl() % gProjectName), + linkCmd = CC[c].buildLib % ["libfile", (libNameTmpl() % gProjectName), "objfiles", objfiles] if optCompileOnly notin gGlobalOptions: execExternalProgram(linkCmd) else: var linkerExe = getConfigVar(c, ".linkerexe") - if len(linkerExe) == 0: linkerExe = cc[c].linkerExe + if len(linkerExe) == 0: linkerExe = CC[c].linkerExe if needsExeExt(): linkerExe = addFileExt(linkerExe, "exe") if noAbsolutePaths(): linkCmd = quoteShell(linkerExe) - else: linkCmd = quoteShell(JoinPath(ccompilerpath, linkerExe)) - if optGenGuiApp in gGlobalOptions: buildGui = cc[c].buildGui - else: buildGui = "" + else: linkCmd = quoteShell(joinPath(ccompilerpath, linkerExe)) + if optGenGuiApp in gGlobalOptions: buildgui = CC[c].buildGui + else: buildgui = "" var exefile: string if optGenDynLib in gGlobalOptions: - exefile = platform.os[targetOS].dllFrmt % splitFile(projectFile).name - buildDll = cc[c].buildDll + exefile = platform.OS[targetOS].dllFrmt % splitFile(projectfile).name + builddll = CC[c].buildDll else: - exefile = splitFile(projectFile).name & platform.os[targetOS].exeExt - buildDll = "" + exefile = splitFile(projectfile).name & platform.OS[targetOS].exeExt + builddll = "" if options.outFile.len > 0: exefile = options.outFile.expandTilde if not noAbsolutePaths(): - if not exeFile.isAbsolute(): - exefile = joinPath(splitFile(projectFile).dir, exefile) + if not exefile.isAbsolute(): + exefile = joinPath(splitFile(projectfile).dir, exefile) exefile = quoteShell(exefile) let linkOptions = getLinkOptions() linkCmd = quoteShell(linkCmd % ["builddll", builddll, "buildgui", buildgui, "options", linkOptions, "objfiles", objfiles, "exefile", exefile, "nimrod", getPrefixDir(), "lib", libpath]) linkCmd.add ' ' - addf(linkCmd, cc[c].linkTmpl, ["builddll", builddll, + addf(linkCmd, CC[c].linkTmpl, ["builddll", builddll, "buildgui", buildgui, "options", linkOptions, "objfiles", objfiles, "exefile", exefile, "nimrod", quoteShell(getPrefixDir()), @@ -635,12 +635,12 @@ proc CallCCompiler*(projectfile: string) = if optGenScript in gGlobalOptions: app(script, linkCmd) app(script, tnl) - generateScript(projectFile, script) + generateScript(projectfile, script) proc genMappingFiles(list: TLinkedList): PRope = var it = PStrEntry(list.head) while it != nil: - appf(result, "--file:r\"$1\"$N", [toRope(AddFileExt(it.data, cExt))]) + appf(result, "--file:r\"$1\"$N", [toRope(addFileExt(it.data, cExt))]) it = PStrEntry(it.next) proc writeMapping*(gSymbolMapping: PRope) = @@ -658,5 +658,5 @@ proc writeMapping*(gSymbolMapping: PRope) = app(code, strutils.escape(libpath)) appf(code, "\n[Symbols]$n$1", [gSymbolMapping]) - WriteRope(code, joinPath(gProjectPath, "mapping.txt")) + writeRope(code, joinPath(gProjectPath, "mapping.txt")) diff --git a/compiler/filter_tmpl.nim b/compiler/filter_tmpl.nim index d16639d08..806754122 100644 --- a/compiler/filter_tmpl.nim +++ b/compiler/filter_tmpl.nim @@ -27,7 +27,7 @@ type indent, emitPar: int x: string # the current input line outp: PLLStream # the ouput will be parsed by pnimsyn - subsChar, NimDirective: Char + subsChar, nimDirective: char emit, conc, toStr: string curly, bracket, par: int pendingExprLine: bool @@ -37,11 +37,11 @@ const PatternChars = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '.', '_'} proc newLine(p: var TTmplParser) = - LLStreamWrite(p.outp, repeatChar(p.emitPar, ')')) + llStreamWrite(p.outp, repeatChar(p.emitPar, ')')) p.emitPar = 0 - if p.info.line > int16(1): LLStreamWrite(p.outp, "\n") + if p.info.line > int16(1): llStreamWrite(p.outp, "\n") if p.pendingExprLine: - LLStreamWrite(p.outp, repeatChar(2)) + llStreamWrite(p.outp, repeatChar(2)) p.pendingExprLine = false proc scanPar(p: var TTmplParser, d: int) = @@ -67,9 +67,9 @@ proc parseLine(p: var TTmplParser) = keyw: string j = 0 while p.x[j] == ' ': inc(j) - if (p.x[0] == p.NimDirective) and (p.x[0 + 1] == '!'): + if (p.x[0] == p.nimDirective) and (p.x[0 + 1] == '!'): newLine(p) - elif (p.x[j] == p.NimDirective): + elif (p.x[j] == p.nimDirective): newLine(p) inc(j) while p.x[j] == ' ': inc(j) @@ -87,26 +87,26 @@ proc parseLine(p: var TTmplParser) = dec(p.indent, 2) else: p.info.col = int16(j) - LocalError(p.info, errXNotAllowedHere, "end") - LLStreamWrite(p.outp, repeatChar(p.indent)) - LLStreamWrite(p.outp, "#end") + localError(p.info, errXNotAllowedHere, "end") + llStreamWrite(p.outp, repeatChar(p.indent)) + llStreamWrite(p.outp, "#end") of wIf, wWhen, wTry, wWhile, wFor, wBlock, wCase, wProc, wIterator, wConverter, wMacro, wTemplate, wMethod: - LLStreamWrite(p.outp, repeatChar(p.indent)) - LLStreamWrite(p.outp, substr(p.x, d)) + llStreamWrite(p.outp, repeatChar(p.indent)) + llStreamWrite(p.outp, substr(p.x, d)) inc(p.indent, 2) of wElif, wOf, wElse, wExcept, wFinally: - LLStreamWrite(p.outp, repeatChar(p.indent - 2)) - LLStreamWrite(p.outp, substr(p.x, d)) + llStreamWrite(p.outp, repeatChar(p.indent - 2)) + llStreamWrite(p.outp, substr(p.x, d)) of wLet, wVar, wConst, wType: - LLStreamWrite(p.outp, repeatChar(p.indent)) - LLStreamWrite(p.outp, substr(p.x, d)) + llStreamWrite(p.outp, repeatChar(p.indent)) + llStreamWrite(p.outp, substr(p.x, d)) if not p.x.contains({':', '='}): # no inline element --> treat as block: inc(p.indent, 2) else: - LLStreamWrite(p.outp, repeatChar(p.indent)) - LLStreamWrite(p.outp, substr(p.x, d)) + llStreamWrite(p.outp, repeatChar(p.indent)) + llStreamWrite(p.outp, substr(p.x, d)) p.state = psDirective else: # data line @@ -118,15 +118,15 @@ proc parseLine(p: var TTmplParser) = case p.state of psTempl: # next line of string literal: - LLStreamWrite(p.outp, p.conc) - LLStreamWrite(p.outp, "\n") - LLStreamWrite(p.outp, repeatChar(p.indent + 2)) - LLStreamWrite(p.outp, "\"") + llStreamWrite(p.outp, p.conc) + llStreamWrite(p.outp, "\n") + llStreamWrite(p.outp, repeatChar(p.indent + 2)) + llStreamWrite(p.outp, "\"") of psDirective: newLine(p) - LLStreamWrite(p.outp, repeatChar(p.indent)) - LLStreamWrite(p.outp, p.emit) - LLStreamWrite(p.outp, "(\"") + llStreamWrite(p.outp, repeatChar(p.indent)) + llStreamWrite(p.outp, p.emit) + llStreamWrite(p.outp, "(\"") inc(p.emitPar) p.state = psTempl while true: @@ -134,17 +134,17 @@ proc parseLine(p: var TTmplParser) = of '\0': break of '\x01'..'\x1F', '\x80'..'\xFF': - LLStreamWrite(p.outp, "\\x") - LLStreamWrite(p.outp, toHex(ord(p.x[j]), 2)) + llStreamWrite(p.outp, "\\x") + llStreamWrite(p.outp, toHex(ord(p.x[j]), 2)) inc(j) of '\\': - LLStreamWrite(p.outp, "\\\\") + llStreamWrite(p.outp, "\\\\") inc(j) of '\'': - LLStreamWrite(p.outp, "\\\'") + llStreamWrite(p.outp, "\\\'") inc(j) of '\"': - LLStreamWrite(p.outp, "\\\"") + llStreamWrite(p.outp, "\\\"") inc(j) else: if p.x[j] == p.subsChar: @@ -153,59 +153,59 @@ proc parseLine(p: var TTmplParser) = case p.x[j] of '{': p.info.col = int16(j) - LLStreamWrite(p.outp, '\"') - LLStreamWrite(p.outp, p.conc) - LLStreamWrite(p.outp, p.toStr) - LLStreamWrite(p.outp, '(') + llStreamWrite(p.outp, '\"') + llStreamWrite(p.outp, p.conc) + llStreamWrite(p.outp, p.toStr) + llStreamWrite(p.outp, '(') inc(j) curly = 0 while true: case p.x[j] of '\0': - LocalError(p.info, errXExpected, "}") + localError(p.info, errXExpected, "}") break of '{': inc(j) inc(curly) - LLStreamWrite(p.outp, '{') + llStreamWrite(p.outp, '{') of '}': inc(j) if curly == 0: break if curly > 0: dec(curly) - LLStreamWrite(p.outp, '}') + llStreamWrite(p.outp, '}') else: - LLStreamWrite(p.outp, p.x[j]) + llStreamWrite(p.outp, p.x[j]) inc(j) - LLStreamWrite(p.outp, ')') - LLStreamWrite(p.outp, p.conc) - LLStreamWrite(p.outp, '\"') + llStreamWrite(p.outp, ')') + llStreamWrite(p.outp, p.conc) + llStreamWrite(p.outp, '\"') of 'a'..'z', 'A'..'Z', '\x80'..'\xFF': - LLStreamWrite(p.outp, '\"') - LLStreamWrite(p.outp, p.conc) - LLStreamWrite(p.outp, p.toStr) - LLStreamWrite(p.outp, '(') + llStreamWrite(p.outp, '\"') + llStreamWrite(p.outp, p.conc) + llStreamWrite(p.outp, p.toStr) + llStreamWrite(p.outp, '(') while p.x[j] in PatternChars: - LLStreamWrite(p.outp, p.x[j]) + llStreamWrite(p.outp, p.x[j]) inc(j) - LLStreamWrite(p.outp, ')') - LLStreamWrite(p.outp, p.conc) - LLStreamWrite(p.outp, '\"') + llStreamWrite(p.outp, ')') + llStreamWrite(p.outp, p.conc) + llStreamWrite(p.outp, '\"') else: if p.x[j] == p.subsChar: - LLStreamWrite(p.outp, p.subsChar) + llStreamWrite(p.outp, p.subsChar) inc(j) else: p.info.col = int16(j) - LocalError(p.info, errInvalidExpression, "$") + localError(p.info, errInvalidExpression, "$") else: - LLStreamWrite(p.outp, p.x[j]) + llStreamWrite(p.outp, p.x[j]) inc(j) - LLStreamWrite(p.outp, "\\n\"") + llStreamWrite(p.outp, "\\n\"") proc filterTmpl(stdin: PLLStream, filename: string, call: PNode): PLLStream = var p: TTmplParser p.info = newLineInfo(filename, 0, 0) - p.outp = LLStreamOpen("") + p.outp = llStreamOpen("") p.inp = stdin p.subsChar = charArg(call, "subschar", 1, '$') p.nimDirective = charArg(call, "metachar", 2, '#') @@ -213,9 +213,9 @@ proc filterTmpl(stdin: PLLStream, filename: string, call: PNode): PLLStream = p.conc = strArg(call, "conc", 4, " & ") p.toStr = strArg(call, "tostring", 5, "$") p.x = newStringOfCap(120) - while LLStreamReadLine(p.inp, p.x): + while llStreamReadLine(p.inp, p.x): p.info.line = p.info.line + int16(1) parseLine(p) newLine(p) result = p.outp - LLStreamClose(p.inp) + llStreamClose(p.inp) diff --git a/compiler/filters.nim b/compiler/filters.nim index 19da11bca..ce0ffd196 100644 --- a/compiler/filters.nim +++ b/compiler/filters.nim @@ -16,13 +16,13 @@ import proc filterReplace*(stdin: PLLStream, filename: string, call: PNode): PLLStream proc filterStrip*(stdin: PLLStream, filename: string, call: PNode): PLLStream # helpers to retrieve arguments: -proc charArg*(n: PNode, name: string, pos: int, default: Char): Char +proc charArg*(n: PNode, name: string, pos: int, default: char): char proc strArg*(n: PNode, name: string, pos: int, default: string): string proc boolArg*(n: PNode, name: string, pos: int, default: bool): bool # implementation proc invalidPragma(n: PNode) = - LocalError(n.info, errXNotAllowedHere, renderTree(n, {renderNoComments})) + localError(n.info, errXNotAllowedHere, renderTree(n, {renderNoComments})) proc getArg(n: PNode, name: string, pos: int): PNode = result = nil @@ -30,12 +30,12 @@ proc getArg(n: PNode, name: string, pos: int): PNode = for i in countup(1, sonsLen(n) - 1): if n.sons[i].kind == nkExprEqExpr: if n.sons[i].sons[0].kind != nkIdent: invalidPragma(n) - if IdentEq(n.sons[i].sons[0].ident, name): + if identEq(n.sons[i].sons[0].ident, name): return n.sons[i].sons[1] elif i == pos: return n.sons[i] -proc charArg(n: PNode, name: string, pos: int, default: Char): Char = +proc charArg(n: PNode, name: string, pos: int, default: char): char = var x = getArg(n, name, pos) if x == nil: result = default elif x.kind == nkCharLit: result = chr(int(x.intVal)) @@ -50,30 +50,30 @@ proc strArg(n: PNode, name: string, pos: int, default: string): string = proc boolArg(n: PNode, name: string, pos: int, default: bool): bool = var x = getArg(n, name, pos) if x == nil: result = default - elif (x.kind == nkIdent) and IdentEq(x.ident, "true"): result = true - elif (x.kind == nkIdent) and IdentEq(x.ident, "false"): result = false + elif (x.kind == nkIdent) and identEq(x.ident, "true"): result = true + elif (x.kind == nkIdent) and identEq(x.ident, "false"): result = false else: invalidPragma(n) proc filterStrip(stdin: PLLStream, filename: string, call: PNode): PLLStream = var pattern = strArg(call, "startswith", 1, "") var leading = boolArg(call, "leading", 2, true) var trailing = boolArg(call, "trailing", 3, true) - result = LLStreamOpen("") + result = llStreamOpen("") var line = newStringOfCap(80) - while LLStreamReadLine(stdin, line): + while llStreamReadLine(stdin, line): var stripped = strip(line, leading, trailing) if (len(pattern) == 0) or startsWith(stripped, pattern): - LLStreamWriteln(result, stripped) + llStreamWriteln(result, stripped) else: - LLStreamWriteln(result, line) - LLStreamClose(stdin) + llStreamWriteln(result, line) + llStreamClose(stdin) proc filterReplace(stdin: PLLStream, filename: string, call: PNode): PLLStream = var sub = strArg(call, "sub", 1, "") if len(sub) == 0: invalidPragma(call) var by = strArg(call, "by", 2, "") - result = LLStreamOpen("") + result = llStreamOpen("") var line = newStringOfCap(80) - while LLStreamReadLine(stdin, line): - LLStreamWriteln(result, replace(line, sub, by)) - LLStreamClose(stdin) + while llStreamReadLine(stdin, line): + llStreamWriteln(result, replace(line, sub, by)) + llStreamClose(stdin) diff --git a/compiler/guards.nim b/compiler/guards.nim index 8d271fa6d..3d27c85c9 100644 --- a/compiler/guards.nim +++ b/compiler/guards.nim @@ -251,10 +251,10 @@ proc invalidateFacts*(m: var TModel, n: PNode) = proc valuesUnequal(a, b: PNode): bool = if a.isValue and b.isValue: - result = not SameValue(a, b) + result = not sameValue(a, b) proc pred(n: PNode): PNode = - if n.kind in {nkCharLit..nkUInt64Lit} and n.intVal != low(biggestInt): + if n.kind in {nkCharLit..nkUInt64Lit} and n.intVal != low(BiggestInt): result = copyNode(n) dec result.intVal else: @@ -366,7 +366,7 @@ proc impliesIsNil(fact, eq: PNode): TImplication = else: discard proc impliesGe(fact, x, c: PNode): TImplication = - InternalAssert isLocation(x) + internalAssert isLocation(x) case fact.sons[0].sym.magic of someEq: if sameTree(fact.sons[1], x): @@ -484,7 +484,7 @@ proc factImplies(fact, prop: PNode): TImplication = if a == b: return ~a return impUnknown else: - InternalError(fact.info, "invalid fact") + internalError(fact.info, "invalid fact") of mAnd: result = factImplies(fact.sons[1], prop) if result != impUnknown: return result @@ -575,4 +575,4 @@ proc checkFieldAccess*(m: TModel, n: PNode) = for i in 1..n.len-1: let check = buildProperFieldCheck(n.sons[0], n.sons[i]) if m.doesImply(check) != impYes: - Message(n.info, warnProveField, renderTree(n.sons[0])); break + message(n.info, warnProveField, renderTree(n.sons[0])); break diff --git a/compiler/hlo.nim b/compiler/hlo.nim index 1492ed76f..e3f80ad36 100644 --- a/compiler/hlo.nim +++ b/compiler/hlo.nim @@ -12,7 +12,7 @@ proc hlo(c: PContext, n: PNode): PNode proc evalPattern(c: PContext, n, orig: PNode): PNode = - InternalAssert n.kind == nkCall and n.sons[0].kind == nkSym + internalAssert n.kind == nkCall and n.sons[0].kind == nkSym # we need to ensure that the resulting AST is semchecked. However, it's # aweful to semcheck before macro invocation, so we don't and treat # templates and macros as immediate in this context. @@ -28,7 +28,7 @@ proc evalPattern(c: PContext, n, orig: PNode): PNode = else: result = semDirectOp(c, n, {}) if optHints in gOptions and hintPattern in gNotes: - Message(orig.info, hintPattern, rule & " --> '" & + message(orig.info, hintPattern, rule & " --> '" & renderTree(result, {renderNoComments}) & "'") proc applyPatterns(c: PContext, n: PNode): PNode = @@ -45,7 +45,7 @@ proc applyPatterns(c: PContext, n: PNode): PNode = # better be safe than sorry, so check evalTemplateCounter too: inc(evalTemplateCounter) if evalTemplateCounter > 100: - GlobalError(n.info, errTemplateInstantiationTooNested) + globalError(n.info, errTemplateInstantiationTooNested) # deactivate this pattern: c.patterns[i] = nil if x.kind == nkStmtList: diff --git a/compiler/idents.nim b/compiler/idents.nim index 1e6f9d2fd..ec903826a 100644 --- a/compiler/idents.nim +++ b/compiler/idents.nim @@ -102,7 +102,7 @@ proc getIdent*(identifier: string): PIdent = proc getIdent*(identifier: string, h: THash): PIdent = result = getIdent(cstring(identifier), len(identifier), h) -proc IdentEq*(id: PIdent, name: string): bool = +proc identEq*(id: PIdent, name: string): bool = result = id.id == getIdent(name).id var idAnon* = getIdent":anonymous" diff --git a/compiler/idgen.nim b/compiler/idgen.nim index fbf450c90..c4f5f2a9e 100644 --- a/compiler/idgen.nim +++ b/compiler/idgen.nim @@ -22,9 +22,9 @@ when debugIds: var usedIds = InitIntSet() proc registerID*(id: PIdObj) = - when debugIDs: - if id.id == -1 or ContainsOrIncl(usedIds, id.id): - InternalError("ID already used: " & $id.id) + when debugIds: + if id.id == -1 or containsOrIncl(usedIds, id.id): + internalError("ID already used: " & $id.id) proc getID*(): int {.inline.} = result = gFrontEndId @@ -37,8 +37,8 @@ proc backendId*(): int {.inline.} = proc setId*(id: int) {.inline.} = gFrontEndId = max(gFrontEndId, id + 1) -proc IDsynchronizationPoint*(idRange: int) = - gFrontEndId = (gFrontEndId div IdRange + 1) * IdRange + 1 +proc idSynchronizationPoint*(idRange: int) = + gFrontEndId = (gFrontEndId div idRange + 1) * idRange + 1 proc toGid(f: string): string = # we used to use ``f.addFileExt("gid")`` (aka ``$project.gid``), but this @@ -49,7 +49,7 @@ proc toGid(f: string): string = proc saveMaxIds*(project: string) = var f = open(project.toGid, fmWrite) f.writeln($gFrontEndId) - f.writeln($gBackEndId) + f.writeln($gBackendId) f.close() proc loadMaxIds*(project: string) = @@ -61,5 +61,5 @@ proc loadMaxIds*(project: string) = if f.readLine(line): var backEndId = parseInt(line) gFrontEndId = max(gFrontEndId, frontEndId) - gBackEndId = max(gBackEndId, backEndId) + gBackendId = max(gBackendId, backEndId) f.close() diff --git a/compiler/importer.nim b/compiler/importer.nim index 8b854bcc6..078a90c98 100644 --- a/compiler/importer.nim +++ b/compiler/importer.nim @@ -22,7 +22,7 @@ proc getModuleName*(n: PNode): string = # The proc won't perform any checks that the path is actually valid case n.kind of nkStrLit, nkRStrLit, nkTripleStrLit: - result = UnixToNativePath(n.strVal) + result = unixToNativePath(n.strVal) of nkIdent: result = n.ident.s of nkSym: @@ -50,7 +50,7 @@ proc checkModuleName*(n: PNode): int32 = let modulename = n.getModuleName let fullPath = findModule(modulename, n.info.toFullPath) if fullPath.len == 0: - LocalError(n.info, errCannotOpenFile, modulename) + localError(n.info, errCannotOpenFile, modulename) result = InvalidFileIDX else: result = fullPath.fileInfoIdx @@ -59,32 +59,32 @@ proc rawImportSymbol(c: PContext, s: PSym) = # This does not handle stubs, because otherwise loading on demand would be # pointless in practice. So importing stubs is fine here! # check if we have already a symbol of the same name: - var check = StrTableGet(c.importTable.symbols, s.name) + var check = strTableGet(c.importTable.symbols, s.name) if check != nil and check.id != s.id: if s.kind notin OverloadableSyms: # s and check need to be qualified: - Incl(c.AmbiguousSymbols, s.id) - Incl(c.AmbiguousSymbols, check.id) + incl(c.ambiguousSymbols, s.id) + incl(c.ambiguousSymbols, check.id) # thanks to 'export' feature, it could be we import the same symbol from # multiple sources, so we need to call 'StrTableAdd' here: - StrTableAdd(c.importTable.symbols, s) + strTableAdd(c.importTable.symbols, s) if s.kind == skType: var etyp = s.typ if etyp.kind in {tyBool, tyEnum} and sfPure notin s.flags: for j in countup(0, sonsLen(etyp.n) - 1): var e = etyp.n.sons[j].sym - if e.Kind != skEnumField: - InternalError(s.info, "rawImportSymbol") + if e.kind != skEnumField: + internalError(s.info, "rawImportSymbol") # BUGFIX: because of aliases for enums the symbol may already # have been put into the symbol table # BUGFIX: but only iff they are the same symbols! var it: TIdentIter - check = InitIdentIter(it, c.importTable.symbols, e.name) + check = initIdentIter(it, c.importTable.symbols, e.name) while check != nil: if check.id == e.id: e = nil break - check = NextIdentIter(it, c.importTable.symbols) + check = nextIdentIter(it, c.importTable.symbols) if e != nil: rawImportSymbol(c, e) else: @@ -94,36 +94,36 @@ proc rawImportSymbol(c: PContext, s: PSym) = proc importSymbol(c: PContext, n: PNode, fromMod: PSym) = let ident = lookups.considerAcc(n) - let s = StrTableGet(fromMod.tab, ident) + let s = strTableGet(fromMod.tab, ident) if s == nil: - LocalError(n.info, errUndeclaredIdentifier, ident.s) + localError(n.info, errUndeclaredIdentifier, ident.s) else: if s.kind == skStub: loadStub(s) - if s.Kind notin ExportableSymKinds: - InternalError(n.info, "importSymbol: 2") + if s.kind notin ExportableSymKinds: + internalError(n.info, "importSymbol: 2") # for an enumeration we have to add all identifiers - case s.Kind + case s.kind of skProc, skMethod, skIterator, skMacro, skTemplate, skConverter: # for a overloadable syms add all overloaded routines var it: TIdentIter - var e = InitIdentIter(it, fromMod.tab, s.name) + var e = initIdentIter(it, fromMod.tab, s.name) while e != nil: - if e.name.id != s.Name.id: InternalError(n.info, "importSymbol: 3") + if e.name.id != s.name.id: internalError(n.info, "importSymbol: 3") rawImportSymbol(c, e) - e = NextIdentIter(it, fromMod.tab) + e = nextIdentIter(it, fromMod.tab) else: rawImportSymbol(c, s) proc importAllSymbolsExcept(c: PContext, fromMod: PSym, exceptSet: TIntSet) = var i: TTabIter - var s = InitTabIter(i, fromMod.tab) + var s = initTabIter(i, fromMod.tab) while s != nil: if s.kind != skModule: if s.kind != skEnumField: - if s.Kind notin ExportableSymKinds: - InternalError(s.info, "importAllSymbols: " & $s.kind) + if s.kind notin ExportableSymKinds: + internalError(s.info, "importAllSymbols: " & $s.kind) if exceptSet.empty or s.name.id notin exceptSet: rawImportSymbol(c, s) - s = NextIter(i, fromMod.tab) + s = nextIter(i, fromMod.tab) proc importAllSymbols*(c: PContext, fromMod: PSym) = var exceptSet: TIntSet @@ -160,7 +160,7 @@ proc myImportModule(c: PContext, n: PNode): PSym = if f != InvalidFileIDX: result = importModuleAs(n, gImportModule(c.module, f)) if sfDeprecated in result.flags: - Message(n.info, warnDeprecated, result.name.s) + message(n.info, warnDeprecated, result.name.s) proc evalImport(c: PContext, n: PNode): PNode = result = n diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index a3c88824d..dd06b0235 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2013 Andreas Rumpf +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -64,7 +64,7 @@ type options: TOptions module: BModule g: PGlobals - BeforeRetNeeded: bool + beforeRetNeeded: bool target: TTarget # duplicated here for faster dispatching unique: int # for temp identifier generation blocks: seq[TBlock] @@ -111,7 +111,7 @@ proc mapType(typ: PType): TJSTypeKind = let t = skipTypes(typ, abstractInst) case t.kind of tyVar, tyRef, tyPtr: - if skipTypes(t.sons[0], abstractInst).kind in mappedToObject: + if skipTypes(t.sons[0], abstractInst).kind in MappedToObject: result = etyObject else: result = etyBaseIndex @@ -129,8 +129,9 @@ proc mapType(typ: PType): TJSTypeKind = tyVarargs: result = etyObject of tyNil: result = etyNull - of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvokation, tyNone, - tyForward, tyEmpty, tyExpr, tyStmt, tyTypeDesc, tyTypeClasses: + of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvokation, + tyNone, tyFromExpr, tyForward, tyEmpty, + tyExpr, tyStmt, tyStatic, tyTypeDesc, tyTypeClasses: result = etyNone of tyProc: result = etyProc of tyCString: result = etyString @@ -175,7 +176,7 @@ proc useMagic(p: PProc, name: string) = # we used to exclude the system module from this check, but for DLL # generation support this sloppyness leads to hard to detect bugs, so # we're picky here for the system module too: - if p.prc != nil: GlobalError(p.prc.info, errSystemNeeds, name) + if p.prc != nil: globalError(p.prc.info, errSystemNeeds, name) else: rawMessage(errSystemNeeds, name) proc isSimpleExpr(n: PNode): bool = @@ -240,7 +241,7 @@ proc genOr(p: PProc, a, b: PNode, r: var TCompRes) = type TMagicFrmt = array[0..3, string] - TMagicOps = array[mAddi..mStrToStr, TMagicFrmt] + TMagicOps = array[mAddI..mStrToStr, TMagicFrmt] const # magic checked op; magic unchecked op; checked op; unchecked op jsOps: TMagicOps = [ @@ -485,14 +486,14 @@ proc arith(p: PProc, n: PNode, r: var TCompRes, op: TMagic) = proc genLineDir(p: PProc, n: PNode) = let line = toLinenumber(n.info) - if optLineDir in p.Options: + if optLineDir in p.options: appf(p.body, "// line $2 \"$1\"$n" | "-- line $2 \"$1\"$n", [toRope(toFilename(n.info)), toRope(line)]) - if {optStackTrace, optEndb} * p.Options == {optStackTrace, optEndb} and + if {optStackTrace, optEndb} * p.options == {optStackTrace, optEndb} and ((p.prc == nil) or sfPure notin p.prc.flags): useMagic(p, "endb") appf(p.body, "endb($1);$n", [toRope(line)]) - elif ({optLineTrace, optStackTrace} * p.Options == + elif ({optLineTrace, optStackTrace} * p.options == {optLineTrace, optStackTrace}) and ((p.prc == nil) or not (sfPure in p.prc.flags)): appf(p.body, "F.line = $1;$n", [toRope(line)]) @@ -504,7 +505,7 @@ proc genWhileStmt(p: PProc, n: PNode) = genLineDir(p, n) inc(p.unique) var length = len(p.blocks) - setlen(p.blocks, length + 1) + setLen(p.blocks, length + 1) p.blocks[length].id = -p.unique p.blocks[length].isLoop = true let labl = p.unique.toRope @@ -514,7 +515,7 @@ proc genWhileStmt(p: PProc, n: PNode) = [cond.res, labl]) genStmt(p, n.sons[1]) appf(p.body, "}$n" | "end ::L$#::$n", [labl]) - setlen(p.blocks, length) + setLen(p.blocks, length) proc moveInto(p: PProc, src: var TCompRes, dest: TCompRes) = if src.kind != resNone: @@ -555,7 +556,7 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) = "var $1 = {prev: excHandler, exc: null};$nexcHandler = $1;$n" | "local $1 = pcall(", [safePoint]) - if optStackTrace in p.Options: app(p.body, "framePtr = F;" & tnl) + if optStackTrace in p.options: app(p.body, "framePtr = F;" & tnl) appf(p.body, "try {$n" | "function()$n") var length = sonsLen(n) var a: TCompRes @@ -579,7 +580,7 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) = useMagic(p, "isObj") for j in countup(0, blen - 2): if n.sons[i].sons[j].kind != nkType: - InternalError(n.info, "genTryStmt") + internalError(n.info, "genTryStmt") if orExpr != nil: app(orExpr, "||" | " or ") appf(orExpr, "isObj($1.exc.m_type, $2)", [safePoint, genTypeInfo(p, n.sons[i].sons[j].typ)]) @@ -641,13 +642,13 @@ proc genCaseJS(p: PProc, n: PNode, r: var TCompRes) = while v.intVal <= e.sons[1].intVal: gen(p, v, cond) appf(p.body, "case $1: ", [cond.rdLoc]) - Inc(v.intVal) + inc(v.intVal) else: if stringSwitch: case e.kind of nkStrLit..nkTripleStrLit: appf(p.body, "case $1: ", [makeJSString(e.strVal)]) - else: InternalError(e.info, "jsgen.genCaseStmt: 2") + else: internalError(e.info, "jsgen.genCaseStmt: 2") else: gen(p, e, cond) appf(p.body, "case $1: ", [cond.rdLoc]) @@ -694,7 +695,7 @@ proc genCaseLua(p: PProc, n: PNode, r: var TCompRes) = case e.kind of nkStrLit..nkTripleStrLit: appf(p.body, "eqStr($1, $2)", [tmp, makeJSString(e.strVal)]) - else: InternalError(e.info, "jsgen.genCaseStmt: 2") + else: internalError(e.info, "jsgen.genCaseStmt: 2") else: gen(p, e, cond) appf(p.body, "$1 == $2", [tmp, cond.rdLoc]) @@ -713,17 +714,17 @@ proc genBlock(p: PProc, n: PNode, r: var TCompRes) = let idx = len(p.blocks) if n.sons[0].kind != nkEmpty: # named block? - if (n.sons[0].kind != nkSym): InternalError(n.info, "genBlock") + if (n.sons[0].kind != nkSym): internalError(n.info, "genBlock") var sym = n.sons[0].sym sym.loc.k = locOther sym.loc.a = idx - setlen(p.blocks, idx + 1) + setLen(p.blocks, idx + 1) p.blocks[idx].id = - p.unique # negative because it isn't used yet let labl = p.unique appf(p.body, "L$1: do {$n" | "", labl.toRope) gen(p, n.sons[1], r) appf(p.body, "} while(false);$n" | "$n::L$#::$n", labl.toRope) - setlen(p.blocks, idx) + setLen(p.blocks, idx) proc genBreakStmt(p: PProc, n: PNode) = var idx: int @@ -739,7 +740,7 @@ proc genBreakStmt(p: PProc, n: PNode) = idx = len(p.blocks) - 1 while idx >= 0 and not p.blocks[idx].isLoop: dec idx if idx < 0 or not p.blocks[idx].isLoop: - InternalError(n.info, "no loop to break") + internalError(n.info, "no loop to break") p.blocks[idx].id = abs(p.blocks[idx].id) # label is used appf(p.body, "break L$1;$n" | "goto ::L$1::;$n", [toRope(p.blocks[idx].id)]) @@ -747,10 +748,10 @@ proc genAsmStmt(p: PProc, n: PNode) = genLineDir(p, n) assert(n.kind == nkAsmStmt) for i in countup(0, sonsLen(n) - 1): - case n.sons[i].Kind + case n.sons[i].kind of nkStrLit..nkTripleStrLit: app(p.body, n.sons[i].strVal) of nkSym: app(p.body, mangleName(n.sons[i].sym)) - else: InternalError(n.sons[i].info, "jsgen: genAsmStmt()") + else: internalError(n.sons[i].info, "jsgen: genAsmStmt()") proc genIf(p: PProc, n: PNode, r: var TCompRes) = var cond, stmt: TCompRes @@ -851,7 +852,7 @@ proc getFieldPosition(f: PNode): int = case f.kind of nkIntLit..nkUInt64Lit: result = int(f.intVal) of nkSym: result = f.sym.position - else: InternalError(f.info, "genFieldPosition") + else: internalError(f.info, "genFieldPosition") proc genFieldAddr(p: PProc, n: PNode, r: var TCompRes) = var a: TCompRes @@ -861,11 +862,11 @@ proc genFieldAddr(p: PProc, n: PNode, r: var TCompRes) = if skipTypes(b.sons[0].typ, abstractVarRange).kind == tyTuple: r.res = makeJSString("Field" & $getFieldPosition(b.sons[1])) else: - if b.sons[1].kind != nkSym: InternalError(b.sons[1].info, "genFieldAddr") + if b.sons[1].kind != nkSym: internalError(b.sons[1].info, "genFieldAddr") var f = b.sons[1].sym if f.loc.r == nil: f.loc.r = mangleName(f) r.res = makeJSString(ropeToStr(f.loc.r)) - InternalAssert a.typ != etyBaseIndex + internalAssert a.typ != etyBaseIndex r.address = a.res r.kind = resExpr @@ -875,7 +876,7 @@ proc genFieldAccess(p: PProc, n: PNode, r: var TCompRes) = if skipTypes(n.sons[0].typ, abstractVarRange).kind == tyTuple: r.res = ropef("$1.Field$2", [r.res, getFieldPosition(n.sons[1]).toRope]) else: - if n.sons[1].kind != nkSym: InternalError(n.sons[1].info, "genFieldAddr") + if n.sons[1].kind != nkSym: internalError(n.sons[1].info, "genFieldAddr") var f = n.sons[1].sym if f.loc.r == nil: f.loc.r = mangleName(f) r.res = ropef("$1.$2", [r.res, f.loc.r]) @@ -890,14 +891,14 @@ proc genCheckedFieldAccess(p: PProc, n: PNode, r: var TCompRes) = proc genArrayAddr(p: PProc, n: PNode, r: var TCompRes) = var a, b: TCompRes - first: biggestInt + first: BiggestInt r.typ = etyBaseIndex gen(p, n.sons[0], a) gen(p, n.sons[1], b) - InternalAssert a.typ != etyBaseIndex and b.typ != etyBaseIndex + internalAssert a.typ != etyBaseIndex and b.typ != etyBaseIndex r.address = a.res var typ = skipTypes(n.sons[0].typ, abstractPtrs) - if typ.kind in {tyArray, tyArrayConstr}: first = FirstOrd(typ.sons[0]) + if typ.kind in {tyArray, tyArrayConstr}: first = firstOrd(typ.sons[0]) else: first = 0 if optBoundsCheck in p.options and not isConstExpr(n.sons[1]): useMagic(p, "chckIndx") @@ -918,9 +919,9 @@ proc genArrayAccess(p: PProc, n: PNode, r: var TCompRes) = genArrayAddr(p, n, r) of tyTuple: genFieldAddr(p, n, r) - else: InternalError(n.info, "expr(nkBracketExpr, " & $ty.kind & ')') + else: internalError(n.info, "expr(nkBracketExpr, " & $ty.kind & ')') r.typ = etyNone - if r.res == nil: InternalError(n.info, "genArrayAccess") + if r.res == nil: internalError(n.info, "genArrayAccess") r.res = ropef("$1[$2]", [r.address, r.res]) r.address = nil r.kind = resExpr @@ -929,7 +930,7 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) = case n.sons[0].kind of nkSym: let s = n.sons[0].sym - if s.loc.r == nil: InternalError(n.info, "genAddr: 3") + if s.loc.r == nil: internalError(n.info, "genAddr: 3") case s.kind of skVar, skLet, skResult: r.kind = resExpr @@ -948,8 +949,8 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) = r.address = s.loc.r r.res = toRope("0") else: - InternalError(n.info, "genAddr: 4") - else: InternalError(n.info, "genAddr: 2") + internalError(n.info, "genAddr: 4") + else: internalError(n.info, "genAddr: 2") of nkCheckedFieldExpr: genCheckedFieldAddr(p, n, r) of nkDotExpr: @@ -963,15 +964,15 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) = genArrayAddr(p, n, r) of tyTuple: genFieldAddr(p, n, r) - else: InternalError(n.info, "expr(nkBracketExpr, " & $ty.kind & ')') - else: InternalError(n.info, "genAddr") + else: internalError(n.info, "expr(nkBracketExpr, " & $ty.kind & ')') + else: internalError(n.info, "genAddr") proc genSym(p: PProc, n: PNode, r: var TCompRes) = var s = n.sym case s.kind of skVar, skLet, skParam, skTemp, skResult: if s.loc.r == nil: - InternalError(n.info, "symbol has no generated name: " & s.name.s) + internalError(n.info, "symbol has no generated name: " & s.name.s) var k = mapType(s.typ) if k == etyBaseIndex: r.typ = etyBaseIndex @@ -988,7 +989,7 @@ proc genSym(p: PProc, n: PNode, r: var TCompRes) = of skConst: genConstant(p, s) if s.loc.r == nil: - InternalError(n.info, "symbol has no generated name: " & s.name.s) + internalError(n.info, "symbol has no generated name: " & s.name.s) r.res = s.loc.r of skProc, skConverter, skMethod: discard mangleName(s) @@ -1010,7 +1011,7 @@ proc genSym(p: PProc, n: PNode, r: var TCompRes) = else: app(p.g.code, newp) else: if s.loc.r == nil: - InternalError(n.info, "symbol has no generated name: " & s.name.s) + internalError(n.info, "symbol has no generated name: " & s.name.s) r.res = s.loc.r r.kind = resVal @@ -1020,7 +1021,7 @@ proc genDeref(p: PProc, n: PNode, r: var TCompRes) = else: var a: TCompRes gen(p, n.sons[0], a) - if a.typ != etyBaseIndex: InternalError(n.info, "genDeref") + if a.typ != etyBaseIndex: internalError(n.info, "genDeref") r.res = ropef("$1[$2]", [a.address, a.res]) proc genArg(p: PProc, n: PNode, r: var TCompRes) = @@ -1051,7 +1052,7 @@ proc genInfixCall(p: PProc, n: PNode, r: var TCompRes) = gen(p, n.sons[1], r) if r.typ == etyBaseIndex: if r.address == nil: - GlobalError(n.info, "cannot invoke with infix syntax") + globalError(n.info, "cannot invoke with infix syntax") r.res = ropef("$1[$2]", [r.address, r.res]) r.address = nil r.typ = etyNone @@ -1093,7 +1094,7 @@ proc createRecordVarAux(p: PProc, rec: PNode, c: var int): PRope = app(result, ": ") app(result, createVar(p, rec.sym.typ, false)) inc(c) - else: InternalError(rec.info, "createRecordVarAux") + else: internalError(rec.info, "createRecordVarAux") proc createVar(p: PProc, typ: PType, indirect: bool): PRope = var t = skipTypes(typ, abstractInst) @@ -1125,7 +1126,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): PRope = app(result, "]") of tyTuple: result = toRope("{") - for i in 0.. <t.sonslen: + for i in 0.. <t.sonsLen: if i > 0: app(result, ", ") appf(result, "Field$1: $2" | "Field$# = $#", i.toRope, createVar(p, t.sons[i], false)) @@ -1173,7 +1174,7 @@ proc genVarInit(p: PProc, v: PSym, n: PNode) = useMagic(p, "NimCopy") s = ropef("NimCopy($1, $2)", [a.res, genTypeInfo(p, n.typ)]) of etyBaseIndex: - if (a.typ != etyBaseIndex): InternalError(n.info, "genVarInit") + if (a.typ != etyBaseIndex): internalError(n.info, "genVarInit") if {sfAddrTaken, sfGlobal} * v.flags != {}: appf(p.body, "var $1 = [$2, $3];$n" | "local $1 = {$2, $3};$n", [v.loc.r, a.address, a.res]) @@ -1227,7 +1228,7 @@ proc genOrd(p: PProc, n: PNode, r: var TCompRes) = case skipTypes(n.sons[1].typ, abstractVar).kind of tyEnum, tyInt..tyInt64, tyChar: gen(p, n.sons[1], r) of tyBool: unaryExpr(p, n, r, "", "($1 ? 1:0)" | "toBool($#)") - else: InternalError(n.info, "genOrd") + else: internalError(n.info, "genOrd") proc genConStrStr(p: PProc, n: PNode, r: var TCompRes) = var a: TCompRes @@ -1293,20 +1294,20 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) = case op of mOr: genOr(p, n.sons[1], n.sons[2], r) of mAnd: genAnd(p, n.sons[1], n.sons[2], r) - of mAddi..mStrToStr: arith(p, n, r, op) + of mAddI..mStrToStr: arith(p, n, r, op) of mRepr: genRepr(p, n, r) of mSwap: genSwap(p, n) of mUnaryLt: # XXX: range checking? - if not (optOverflowCheck in p.Options): unaryExpr(p, n, r, "", "$1 - 1") + if not (optOverflowCheck in p.options): unaryExpr(p, n, r, "", "$1 - 1") else: unaryExpr(p, n, r, "subInt", "subInt($1, 1)") of mPred: # XXX: range checking? - if not (optOverflowCheck in p.Options): binaryExpr(p, n, r, "", "$1 - $2") + if not (optOverflowCheck in p.options): binaryExpr(p, n, r, "", "$1 - $2") else: binaryExpr(p, n, r, "subInt", "subInt($1, $2)") of mSucc: # XXX: range checking? - if not (optOverflowCheck in p.Options): binaryExpr(p, n, r, "", "$1 - $2") + if not (optOverflowCheck in p.options): binaryExpr(p, n, r, "", "$1 - $2") else: binaryExpr(p, n, r, "addInt", "addInt($1, $2)") of mAppendStrCh: binaryExpr(p, n, r, "addChar", "addChar($1, $2)") of mAppendStrStr: @@ -1335,10 +1336,10 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) = else: unaryExpr(p, n, r, "", "($1.length-1)") of mInc: - if not (optOverflowCheck in p.Options): binaryExpr(p, n, r, "", "$1 += $2") + if not (optOverflowCheck in p.options): binaryExpr(p, n, r, "", "$1 += $2") else: binaryExpr(p, n, r, "addInt", "$1 = addInt($1, $2)") of ast.mDec: - if not (optOverflowCheck in p.Options): binaryExpr(p, n, r, "", "$1 -= $2") + if not (optOverflowCheck in p.options): binaryExpr(p, n, r, "", "$1 -= $2") else: binaryExpr(p, n, r, "subInt", "$1 = subInt($1, $2)") of mSetLengthStr: binaryExpr(p, n, r, "", "$1.length = ($2)-1") of mSetLengthSeq: binaryExpr(p, n, r, "", "$1.length = $2") @@ -1416,7 +1417,7 @@ proc genObjConstr(p: PProc, n: PNode, r: var TCompRes) = for i in countup(1, sonsLen(n) - 1): if i > 0: app(r.res, ", ") var it = n.sons[i] - InternalAssert it.kind == nkExprColonExpr + internalAssert it.kind == nkExprColonExpr gen(p, it.sons[1], a) var f = it.sons[0].sym if f.loc.r == nil: f.loc.r = mangleName(f) @@ -1451,7 +1452,7 @@ proc convStrToCStr(p: PProc, n: PNode, r: var TCompRes) = gen(p, n.sons[0].sons[0], r) else: gen(p, n.sons[0], r) - if r.res == nil: InternalError(n.info, "convStrToCStr") + if r.res == nil: internalError(n.info, "convStrToCStr") useMagic(p, "toJSStr") r.res = ropef("toJSStr($1)", [r.res]) r.kind = resExpr @@ -1463,14 +1464,14 @@ proc convCStrToStr(p: PProc, n: PNode, r: var TCompRes) = gen(p, n.sons[0].sons[0], r) else: gen(p, n.sons[0], r) - if r.res == nil: InternalError(n.info, "convCStrToStr") + if r.res == nil: internalError(n.info, "convCStrToStr") useMagic(p, "cstrToNimstr") r.res = ropef("cstrToNimstr($1)", [r.res]) r.kind = resExpr proc genReturnStmt(p: PProc, n: PNode) = - if p.procDef == nil: InternalError(n.info, "genReturnStmt") - p.BeforeRetNeeded = true + if p.procDef == nil: internalError(n.info, "genReturnStmt") + p.beforeRetNeeded = true if (n.sons[0].kind != nkEmpty): genStmt(p, n.sons[0]) else: @@ -1564,7 +1565,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) = elif f == 0.5 * f: if f > 0.0: r.res = toRope"Infinity" else: r.res = toRope"-Infinity" - else: r.res = toRope(f.ToStrMaxPrecision) + else: r.res = toRope(f.toStrMaxPrecision) of nkCallKinds: if (n.sons[0].kind == nkSym) and (n.sons[0].sym.magic != mNone): genMagic(p, n, r) @@ -1640,7 +1641,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) = r.res = nil of nkGotoState, nkState: internalError(n.info, "first class iterators not implemented") - else: InternalError(n.info, "gen: unknown node type: " & $n.kind) + else: internalError(n.info, "gen: unknown node type: " & $n.kind) var globals: PGlobals @@ -1651,11 +1652,11 @@ proc newModule(module: PSym): BModule = proc genHeader(): PRope = result = ropef("/* Generated by the Nimrod Compiler v$1 */$n" & - "/* (c) 2013 Andreas Rumpf */$n$n" & + "/* (c) 2014 Andreas Rumpf */$n$n" & "$nvar Globals = this;$n" & "var framePtr = null;$n" & "var excHandler = null;$n", - [toRope(versionAsString)]) + [toRope(VersionAsString)]) proc genModule(p: PProc, n: PNode) = if optStackTrace in p.options: @@ -1671,7 +1672,7 @@ proc myProcess(b: PPassContext, n: PNode): PNode = if passes.skipCodegen(n): return n result = n var m = BModule(b) - if m.module == nil: InternalError(n.info, "myProcess") + if m.module == nil: internalError(n.info, "myProcess") var p = newProc(globals, m, nil, m.module.options) genModule(p, n) app(p.g.code, p.locals) @@ -1702,7 +1703,7 @@ proc myClose(b: PPassContext, n: PNode): PNode = discard writeRopeIfNotEqual(con(genHeader(), code), outfile) proc myOpenCached(s: PSym, rd: PRodReader): PPassContext = - InternalError("symbol files are not possible with the JS code generator") + internalError("symbol files are not possible with the JS code generator") result = nil proc myOpen(s: PSym): PPassContext = diff --git a/compiler/jstypes.nim b/compiler/jstypes.nim index 0be1e99dc..6d14076e1 100644 --- a/compiler/jstypes.nim +++ b/compiler/jstypes.nim @@ -37,7 +37,7 @@ proc genObjectFields(p: PProc, typ: PType, n: PNode): PRope = [mangleName(field), s, makeJSString(field.name.s)]) of nkRecCase: length = sonsLen(n) - if (n.sons[0].kind != nkSym): InternalError(n.info, "genObjectFields") + if (n.sons[0].kind != nkSym): internalError(n.info, "genObjectFields") field = n.sons[0].sym s = genTypeInfo(p, field.typ) for i in countup(1, length - 1): @@ -98,7 +98,7 @@ proc genEnumInfo(p: PProc, typ: PType, name: PRope) = let length = sonsLen(typ.n) var s: PRope = nil for i in countup(0, length - 1): - if (typ.n.sons[i].kind != nkSym): InternalError(typ.n.info, "genEnumInfo") + if (typ.n.sons[i].kind != nkSym): internalError(typ.n.info, "genEnumInfo") let field = typ.n.sons[i].sym if i > 0: app(s, ", " & tnl) let extName = if field.ast == nil: field.name.s else: field.ast.strVal @@ -119,7 +119,7 @@ proc genTypeInfo(p: PProc, typ: PType): PRope = var t = typ if t.kind == tyGenericInst: t = lastSon(t) result = ropef("NTI$1", [toRope(t.id)]) - if ContainsOrIncl(p.g.TypeInfoGenerated, t.id): return + if containsOrIncl(p.g.typeInfoGenerated, t.id): return case t.kind of tyDistinct: result = genTypeInfo(p, typ.sons[0]) @@ -145,4 +145,4 @@ proc genTypeInfo(p: PProc, typ: PType): PRope = of tyEnum: genEnumInfo(p, t, result) of tyObject: genObjectInfo(p, t, result) of tyTuple: genTupleInfo(p, t, result) - else: InternalError("genTypeInfo(" & $t.kind & ')') + else: internalError("genTypeInfo(" & $t.kind & ')') diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index 96eb3a5f4..9e42210c0 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -207,7 +207,9 @@ proc newCall(a, b: PSym): PNode = proc addHiddenParam(routine: PSym, param: PSym) = var params = routine.ast.sons[paramsPos] - param.position = params.len + # -1 is correct here as param.position is 0 based but we have at position 0 + # some nkEffect node: + param.position = params.len-1 addSon(params, newSymNode(param)) incl(routine.typ.flags, tfCapturesEnv) #echo "produced environment: ", param.id, " for ", routine.name.s @@ -224,7 +226,7 @@ proc isInnerProc(s, outerProc: PSym): bool {.inline.} = #s.typ.callConv == ccClosure proc addClosureParam(i: PInnerContext, e: PEnv) = - var cp = newSym(skParam, getIdent(paramname), i.fn, i.fn.info) + var cp = newSym(skParam, getIdent(paramName), i.fn, i.fn.info) incl(cp.flags, sfFromGeneric) cp.typ = newType(tyRef, i.fn) rawAddSon(cp.typ, e.tup) @@ -234,8 +236,8 @@ proc addClosureParam(i: PInnerContext, e: PEnv) = proc dummyClosureParam(o: POuterContext, i: PInnerContext) = var e = o.currentEnv - if IdTableGet(o.lambdasToEnv, i.fn) == nil: - IdTablePut(o.lambdasToEnv, i.fn, e) + if idTableGet(o.lambdasToEnv, i.fn) == nil: + idTablePut(o.lambdasToEnv, i.fn, e) if i.closureParam == nil: addClosureParam(i, e) proc illegalCapture(s: PSym): bool {.inline.} = @@ -247,13 +249,13 @@ proc captureVar(o: POuterContext, i: PInnerContext, local: PSym, info: TLineInfo) = # for inlined variables the owner is still wrong, so it can happen that it's # not a captured variable at all ... *sigh* - var it = PEnv(IdTableGet(o.localsToEnv, local)) + var it = PEnv(idTableGet(o.localsToEnv, local)) if it == nil: return if illegalCapture(local) or o.fn.id != local.owner.id or i.fn.typ.callConv notin {ccClosure, ccDefault}: # Currently captures are restricted to a single level of nesting: - LocalError(info, errIllegalCaptureX, local.name.s) + localError(info, errIllegalCaptureX, local.name.s) i.fn.typ.callConv = ccClosure #echo "captureVar ", i.fn.name.s, i.fn.id, " ", local.name.s, local.id @@ -261,11 +263,11 @@ proc captureVar(o: POuterContext, i: PInnerContext, local: PSym, # we need to remember which inner most closure belongs to this lambda: var e = o.currentEnv - if IdTableGet(o.lambdasToEnv, i.fn) == nil: - IdTablePut(o.lambdasToEnv, i.fn, e) + if idTableGet(o.lambdasToEnv, i.fn) == nil: + idTablePut(o.lambdasToEnv, i.fn, e) # variable already captured: - if IdNodeTableGet(i.localsToAccess, local) != nil: return + if idNodeTableGet(i.localsToAccess, local) != nil: return if i.closureParam == nil: addClosureParam(i, e) # check which environment `local` belongs to: @@ -279,7 +281,7 @@ proc captureVar(o: POuterContext, i: PInnerContext, local: PSym, access = indirectAccess(access, addDep(e, it, i.fn), info) access = indirectAccess(access, local, info) incl(o.capturedVars, local.id) - IdNodeTablePut(i.localsToAccess, local, access) + idNodeTablePut(i.localsToAccess, local, access) proc interestingVar(s: PSym): bool {.inline.} = result = s.kind in {skVar, skLet, skTemp, skForVar, skParam, skResult} and @@ -307,11 +309,11 @@ proc gatherVars(o: POuterContext, i: PInnerContext, n: PNode) = elif isInnerProc(s, o.fn) and tfCapturesEnv in s.typ.flags and s != i.fn: # call to some other inner proc; we need to track the dependencies for # this: - let env = PEnv(IdTableGet(o.lambdasToEnv, i.fn)) - if env == nil: InternalError(n.info, "no environment computed") + let env = PEnv(idTableGet(o.lambdasToEnv, i.fn)) + if env == nil: internalError(n.info, "no environment computed") if o.currentEnv != env: discard addDep(o.currentEnv, env, i.fn) - InternalError(n.info, "too complex environment handling required") + internalError(n.info, "too complex environment handling required") of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit: nil else: for k in countup(0, sonsLen(n) - 1): @@ -363,7 +365,7 @@ proc transformInnerProc(o: POuterContext, i: PInnerContext, n: PNode): PNode = result = makeClosure(s, i.closureParam, n.info) else: # captured symbol? - result = IdNodeTableGet(i.localsToAccess, n.sym) + result = idNodeTableGet(i.localsToAccess, n.sym) of nkLambdaKinds: result = transformInnerProc(o, i, n.sons[namePos]) of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef, @@ -423,18 +425,18 @@ proc searchForInnerProcs(o: POuterContext, n: PNode) = if it.kind == nkCommentStmt: nil elif it.kind == nkIdentDefs: var L = sonsLen(it) - if it.sons[0].kind != nkSym: InternalError(it.info, "transformOuter") + if it.sons[0].kind != nkSym: internalError(it.info, "transformOuter") #echo "set: ", it.sons[0].sym.name.s, " ", o.currentBlock == nil - IdTablePut(o.localsToEnv, it.sons[0].sym, o.currentEnv) + idTablePut(o.localsToEnv, it.sons[0].sym, o.currentEnv) searchForInnerProcs(o, it.sons[L-1]) elif it.kind == nkVarTuple: var L = sonsLen(it) for j in countup(0, L-3): #echo "set: ", it.sons[j].sym.name.s, " ", o.currentBlock == nil - IdTablePut(o.localsToEnv, it.sons[j].sym, o.currentEnv) + idTablePut(o.localsToEnv, it.sons[j].sym, o.currentEnv) searchForInnerProcs(o, it.sons[L-1]) else: - InternalError(it.info, "transformOuter") + internalError(it.info, "transformOuter") of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef, nkIteratorDef: # don't recurse here: @@ -488,7 +490,7 @@ proc generateClosureCreation(o: POuterContext, scope: PEnv): PNode = # maybe later: (sfByCopy in local.flags) # add ``env.param = param`` result.add(newAsgnStmt(fieldAccess, newSymNode(local), env.info)) - IdNodeTablePut(o.localsToAccess, local, fieldAccess) + idNodeTablePut(o.localsToAccess, local, fieldAccess) # add support for 'up' references: for e, field in items(scope.deps): # add ``env.up = env2`` @@ -501,7 +503,7 @@ proc transformOuterProc(o: POuterContext, n: PNode): PNode = of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit: nil of nkSym: var local = n.sym - var closure = PEnv(IdTableGet(o.lambdasToEnv, local)) + var closure = PEnv(idTableGet(o.lambdasToEnv, local)) if closure != nil: # we need to replace the lambda with '(lambda, env)': let a = closure.closure @@ -519,7 +521,7 @@ proc transformOuterProc(o: POuterContext, n: PNode): PNode = return makeClosure(local, x, n.info) if not contains(o.capturedVars, local.id): return - var env = PEnv(IdTableGet(o.localsToEnv, local)) + var env = PEnv(idTableGet(o.localsToEnv, local)) if env == nil: return var scope = env.attachedNode assert scope.kind == nkStmtList @@ -529,7 +531,7 @@ proc transformOuterProc(o: POuterContext, n: PNode): PNode = # change 'local' to 'closure.local', unless it's a 'byCopy' variable: # if sfByCopy notin local.flags: - result = IdNodeTableGet(o.localsToAccess, local) + result = idNodeTableGet(o.localsToAccess, local) assert result != nil, "cannot find: " & local.name.s # else it is captured by copy and this means that 'outer' should continue # to access the local as a local. @@ -549,6 +551,8 @@ proc transformOuterProc(o: POuterContext, n: PNode): PNode = if x != nil: n.sons[i] = x proc liftLambdas*(fn: PSym, body: PNode): PNode = + # XXX gCmd == cmdCompileToJS does not suffice! The compiletime stuff needs + # the transformation even when compiling to JS ... if body.kind == nkEmpty or gCmd == cmdCompileToJS: # ignore forward declaration: result = body @@ -560,13 +564,13 @@ proc liftLambdas*(fn: PSym, body: PNode): PNode = let params = fn.typ.n for i in 1.. <params.len: if params.sons[i].kind != nkSym: - InternalError(params.info, "liftLambdas: strange params") + internalError(params.info, "liftLambdas: strange params") let param = params.sons[i].sym - IdTablePut(o.localsToEnv, param, o.currentEnv) + idTablePut(o.localsToEnv, param, o.currentEnv) # put the 'result' into the environment so it can be captured: let ast = fn.ast if resultPos < sonsLen(ast) and ast.sons[resultPos].kind == nkSym: - IdTablePut(o.localsToEnv, ast.sons[resultPos].sym, o.currentEnv) + idTablePut(o.localsToEnv, ast.sons[resultPos].sym, o.currentEnv) searchForInnerProcs(o, body) discard transformOuterProc(o, body) result = ex @@ -675,7 +679,7 @@ proc liftIterator*(iter: PSym, body: PNode): PNode = c.tup = newType(tyTuple, iter) c.tup.n = newNodeI(nkRecList, iter.info) - var cp = newSym(skParam, getIdent(paramname), iter, iter.info) + var cp = newSym(skParam, getIdent(paramName), iter, iter.info) incl(cp.flags, sfFromGeneric) cp.typ = newType(tyRef, iter) rawAddSon(cp.typ, c.tup) @@ -754,7 +758,7 @@ proc liftForLoop*(body: PNode): PNode = ... """ var L = body.len - InternalAssert body.kind == nkForStmt and body[L-2].kind in nkCallKinds + internalAssert body.kind == nkForStmt and body[L-2].kind in nkCallKinds var call = body[L-2] result = newNodeI(nkStmtList, body.info) @@ -789,7 +793,7 @@ proc liftForLoop*(body: PNode): PNode = addSon(vpart, body[i]) addSon(vpart, ast.emptyNode) # no explicit type - if not env.isnil: + if not env.isNil: call.sons[0] = makeClosure(call.sons[0].sym, env, body.info) addSon(vpart, call) addSon(v2, vpart) diff --git a/compiler/lexer.nim b/compiler/lexer.nim index 82bfa0ad4..93aea7f61 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -41,11 +41,12 @@ type tkGeneric, tkIf, tkImport, tkIn, tkInclude, tkInterface, tkIs, tkIsnot, tkIterator, tkLambda, tkLet, - tkMacro, tkMethod, tkMixin, tkUsing, tkMod, tkNil, tkNot, tkNotin, + tkMacro, tkMethod, tkMixin, tkMod, tkNil, tkNot, tkNotin, tkObject, tkOf, tkOr, tkOut, tkProc, tkPtr, tkRaise, tkRef, tkReturn, tkShared, tkShl, tkShr, tkStatic, tkTemplate, - tkTry, tkTuple, tkType, tkVar, tkWhen, tkWhile, tkWith, tkWithout, tkXor, + tkTry, tkTuple, tkType, tkUsing, + tkVar, tkWhen, tkWhile, tkWith, tkWithout, tkXor, tkYield, # end of keywords tkIntLit, tkInt8Lit, tkInt16Lit, tkInt32Lit, tkInt64Lit, tkUIntLit, tkUInt8Lit, tkUInt16Lit, tkUInt32Lit, tkUInt64Lit, @@ -75,12 +76,13 @@ const "finally", "for", "from", "generic", "if", "import", "in", "include", "interface", "is", "isnot", "iterator", "lambda", "let", - "macro", "method", "mixin", "using", "mod", + "macro", "method", "mixin", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc", "ptr", "raise", "ref", "return", "shared", "shl", "shr", "static", "template", - "try", "tuple", "type", "var", "when", "while", "with", "without", "xor", + "try", "tuple", "type", "using", + "var", "when", "while", "with", "without", "xor", "yield", "tkIntLit", "tkInt8Lit", "tkInt16Lit", "tkInt32Lit", "tkInt64Lit", "tkUIntLit", "tkUInt8Lit", "tkUInt16Lit", "tkUInt32Lit", "tkUInt64Lit", @@ -130,11 +132,11 @@ proc getLineInfo*(L: TLexer, tok: TToken): TLineInfo {.inline.} = newLineInfo(L.fileIdx, tok.line, tok.col) proc closeLexer*(lex: var TLexer) -proc PrintTok*(tok: TToken) +proc printTok*(tok: TToken) proc tokToStr*(tok: TToken): string proc openLexer*(lex: var TLexer, filename: string, inputstream: PLLStream) = - OpenLexer(lex, filename.fileInfoIdx, inputStream) + openLexer(lex, filename.fileInfoIdx, inputstream) proc lexMessage*(L: TLexer, msg: TMsgKind, arg = "") @@ -158,19 +160,19 @@ proc tokToStr*(tok: TToken): string = of tkFloatLit..tkFloat64Lit: result = $tok.fNumber of tkInvalid, tkStrLit..tkCharLit, tkComment: result = tok.literal of tkParLe..tkColon, tkEof, tkAccent: - result = tokTypeToStr[tok.tokType] + result = TokTypeToStr[tok.tokType] else: if tok.ident != nil: result = tok.ident.s else: - InternalError("tokToStr") + internalError("tokToStr") result = "" proc prettyTok*(tok: TToken): string = - if IsKeyword(tok.tokType): result = "keyword " & tok.ident.s + if isKeyword(tok.tokType): result = "keyword " & tok.ident.s else: result = tokToStr(tok) -proc PrintTok*(tok: TToken) = +proc printTok*(tok: TToken) = write(stdout, TokTypeToStr[tok.tokType]) write(stdout, " ") writeln(stdout, tokToStr(tok)) @@ -178,18 +180,18 @@ proc PrintTok*(tok: TToken) = var dummyIdent: PIdent proc initToken*(L: var TToken) = - L.TokType = tkInvalid + L.tokType = tkInvalid L.iNumber = 0 - L.Indent = 0 + L.indent = 0 L.literal = "" L.fNumber = 0.0 L.base = base10 L.ident = dummyIdent proc fillToken(L: var TToken) = - L.TokType = tkInvalid + L.tokType = tkInvalid L.iNumber = 0 - L.Indent = 0 + L.indent = 0 setLen(L.literal, 0) L.fNumber = 0.0 L.base = base10 @@ -197,26 +199,26 @@ proc fillToken(L: var TToken) = proc openLexer(lex: var TLexer, fileIdx: int32, inputstream: PLLStream) = openBaseLexer(lex, inputstream) - lex.fileIdx = fileIdx + lex.fileIdx = fileidx lex.indentAhead = - 1 - inc(lex.Linenumber, inputstream.lineOffset) + inc(lex.lineNumber, inputstream.lineOffset) proc closeLexer(lex: var TLexer) = - inc(gLinesCompiled, lex.LineNumber) + inc(gLinesCompiled, lex.lineNumber) closeBaseLexer(lex) proc getColumn(L: TLexer): int = - result = getColNumber(L, L.bufPos) + result = getColNumber(L, L.bufpos) proc getLineInfo(L: TLexer): TLineInfo = - result = newLineInfo(L.fileIdx, L.linenumber, getColNumber(L, L.bufpos)) + result = newLineInfo(L.fileIdx, L.lineNumber, getColNumber(L, L.bufpos)) proc lexMessage(L: TLexer, msg: TMsgKind, arg = "") = - msgs.Message(getLineInfo(L), msg, arg) + msgs.message(getLineInfo(L), msg, arg) proc lexMessagePos(L: var TLexer, msg: TMsgKind, pos: int, arg = "") = - var info = newLineInfo(L.fileIdx, L.linenumber, pos - L.lineStart) - msgs.Message(info, msg, arg) + var info = newLineInfo(L.fileIdx, L.lineNumber, pos - L.lineStart) + msgs.message(info, msg, arg) proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: TCharSet) = var pos = L.bufpos # use registers for pos, buf @@ -224,7 +226,7 @@ proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: TCharSet) = while true: if buf[pos] in chars: add(tok.literal, buf[pos]) - Inc(pos) + inc(pos) else: break if buf[pos] == '_': @@ -232,11 +234,11 @@ proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: TCharSet) = lexMessage(L, errInvalidToken, "_") break add(tok.literal, '_') - Inc(pos) - L.bufPos = pos + inc(pos) + L.bufpos = pos -proc matchTwoChars(L: TLexer, first: Char, second: TCharSet): bool = - result = (L.buf[L.bufpos] == first) and (L.buf[L.bufpos + 1] in Second) +proc matchTwoChars(L: TLexer, first: char, second: TCharSet): bool = + result = (L.buf[L.bufpos] == first) and (L.buf[L.bufpos + 1] in second) proc isFloatLiteral(s: string): bool = for i in countup(0, len(s) - 1): @@ -244,10 +246,10 @@ proc isFloatLiteral(s: string): bool = return true result = false -proc GetNumber(L: var TLexer): TToken = +proc getNumber(L: var TLexer): TToken = var pos, endpos: int - xi: biggestInt + xi: BiggestInt # get the base: result.tokType = tkIntLit # int literal until we know better result.literal = "" @@ -388,25 +390,25 @@ proc GetNumber(L: var TLexer): TToken = xi = `shl`(xi, 4) or (ord(L.buf[pos]) - ord('A') + 10) inc(pos) else: break - else: InternalError(getLineInfo(L), "getNumber") + else: internalError(getLineInfo(L), "getNumber") case result.tokType of tkIntLit, tkInt64Lit: result.iNumber = xi - of tkInt8Lit: result.iNumber = biggestInt(int8(toU8(int(xi)))) - of tkInt16Lit: result.iNumber = biggestInt(toU16(int(xi))) - of tkInt32Lit: result.iNumber = biggestInt(toU32(xi)) + of tkInt8Lit: result.iNumber = BiggestInt(int8(toU8(int(xi)))) + of tkInt16Lit: result.iNumber = BiggestInt(toU16(int(xi))) + of tkInt32Lit: result.iNumber = BiggestInt(toU32(xi)) of tkUIntLit, tkUInt64Lit: result.iNumber = xi - of tkUInt8Lit: result.iNumber = biggestInt(int8(toU8(int(xi)))) - of tkUInt16Lit: result.iNumber = biggestInt(toU16(int(xi))) - of tkUInt32Lit: result.iNumber = biggestInt(toU32(xi)) + of tkUInt8Lit: result.iNumber = BiggestInt(int8(toU8(int(xi)))) + of tkUInt16Lit: result.iNumber = BiggestInt(toU16(int(xi))) + of tkUInt32Lit: result.iNumber = BiggestInt(toU32(xi)) of tkFloat32Lit: result.fNumber = (cast[PFloat32](addr(xi)))[] # note: this code is endian neutral! # XXX: Test this on big endian machine! of tkFloat64Lit: result.fNumber = (cast[PFloat64](addr(xi)))[] - else: InternalError(getLineInfo(L), "getNumber") + else: internalError(getLineInfo(L), "getNumber") elif isFloatLiteral(result.literal) or (result.tokType == tkFloat32Lit) or (result.tokType == tkFloat64Lit): - result.fnumber = parseFloat(result.literal) + result.fNumber = parseFloat(result.literal) if result.tokType == tkIntLit: result.tokType = tkFloatLit else: result.iNumber = parseBiggestInt(result.literal) @@ -443,51 +445,51 @@ proc getEscapedChar(L: var TLexer, tok: var TToken) = inc(L.bufpos) # skip '\' case L.buf[L.bufpos] of 'n', 'N': - if tok.toktype == tkCharLit: lexMessage(L, errNnotAllowedInCharacter) + if tok.tokType == tkCharLit: lexMessage(L, errNnotAllowedInCharacter) add(tok.literal, tnl) - Inc(L.bufpos) + inc(L.bufpos) of 'r', 'R', 'c', 'C': add(tok.literal, CR) - Inc(L.bufpos) + inc(L.bufpos) of 'l', 'L': add(tok.literal, LF) - Inc(L.bufpos) + inc(L.bufpos) of 'f', 'F': add(tok.literal, FF) inc(L.bufpos) of 'e', 'E': add(tok.literal, ESC) - Inc(L.bufpos) + inc(L.bufpos) of 'a', 'A': add(tok.literal, BEL) - Inc(L.bufpos) + inc(L.bufpos) of 'b', 'B': add(tok.literal, BACKSPACE) - Inc(L.bufpos) + inc(L.bufpos) of 'v', 'V': add(tok.literal, VT) - Inc(L.bufpos) + inc(L.bufpos) of 't', 'T': add(tok.literal, Tabulator) - Inc(L.bufpos) + inc(L.bufpos) of '\'', '\"': add(tok.literal, L.buf[L.bufpos]) - Inc(L.bufpos) + inc(L.bufpos) of '\\': add(tok.literal, '\\') - Inc(L.bufpos) + inc(L.bufpos) of 'x', 'X': inc(L.bufpos) var xi = 0 handleHexChar(L, xi) handleHexChar(L, xi) - add(tok.literal, Chr(xi)) + add(tok.literal, chr(xi)) of '0'..'9': if matchTwoChars(L, '0', {'0'..'9'}): lexMessage(L, warnOctalEscape) var xi = 0 handleDecChars(L, xi) - if (xi <= 255): add(tok.literal, Chr(xi)) + if (xi <= 255): add(tok.literal, chr(xi)) else: lexMessage(L, errInvalidCharacterConstant) else: lexMessage(L, errInvalidCharacterConstant) @@ -497,7 +499,7 @@ proc newString(s: cstring, len: int): string = for i in 0 .. <len: result[i] = s[i] -proc HandleCRLF(L: var TLexer, pos: int): int = +proc handleCRLF(L: var TLexer, pos: int): int = template registerLine = let col = L.getColNumber(pos) @@ -512,21 +514,21 @@ proc HandleCRLF(L: var TLexer, pos: int): int = case L.buf[pos] of CR: registerLine() - result = nimlexbase.HandleCR(L, pos) + result = nimlexbase.handleCR(L, pos) of LF: registerLine() - result = nimlexbase.HandleLF(L, pos) + result = nimlexbase.handleLF(L, pos) else: result = pos proc getString(L: var TLexer, tok: var TToken, rawMode: bool) = - var pos = L.bufPos + 1 # skip " + var pos = L.bufpos + 1 # skip " var buf = L.buf # put `buf` in a register - var line = L.linenumber # save linenumber for better error message + var line = L.lineNumber # save linenumber for better error message if buf[pos] == '\"' and buf[pos+1] == '\"': tok.tokType = tkTripleStrLit # long string literal: inc(pos, 2) # skip "" # skip leading newline: - pos = HandleCRLF(L, pos) + pos = handleCRLF(L, pos) buf = L.buf while true: case buf[pos] @@ -536,20 +538,20 @@ proc getString(L: var TLexer, tok: var TToken, rawMode: bool) = L.bufpos = pos + 3 # skip the three """ break add(tok.literal, '\"') - Inc(pos) + inc(pos) of CR, LF: - pos = HandleCRLF(L, pos) + pos = handleCRLF(L, pos) buf = L.buf add(tok.literal, tnl) of nimlexbase.EndOfFile: - var line2 = L.linenumber - L.LineNumber = line + var line2 = L.lineNumber + L.lineNumber = line lexMessagePos(L, errClosingTripleQuoteExpected, L.lineStart) - L.LineNumber = line2 + L.lineNumber = line2 break else: add(tok.literal, buf[pos]) - Inc(pos) + inc(pos) else: # ordinary string literal if rawMode: tok.tokType = tkRStrLit @@ -567,23 +569,23 @@ proc getString(L: var TLexer, tok: var TToken, rawMode: bool) = lexMessage(L, errClosingQuoteExpected) break elif (c == '\\') and not rawMode: - L.bufPos = pos + L.bufpos = pos getEscapedChar(L, tok) - pos = L.bufPos + pos = L.bufpos else: add(tok.literal, c) - Inc(pos) + inc(pos) L.bufpos = pos proc getCharacter(L: var TLexer, tok: var TToken) = - Inc(L.bufpos) # skip ' + inc(L.bufpos) # skip ' var c = L.buf[L.bufpos] case c - of '\0'..Pred(' '), '\'': lexMessage(L, errInvalidCharacterConstant) + of '\0'..pred(' '), '\'': lexMessage(L, errInvalidCharacterConstant) of '\\': getEscapedChar(L, tok) else: tok.literal = $c - Inc(L.bufpos) + inc(L.bufpos) if L.buf[L.bufpos] != '\'': lexMessage(L, errMissingFinalQuote) inc(L.bufpos) # skip ' @@ -604,7 +606,7 @@ proc getSymbol(L: var TLexer, tok: var TToken) = lexMessage(L, errInvalidToken, "_") break else: break - Inc(pos) + inc(pos) h = !$h tok.ident = getIdent(addr(L.buf[L.bufpos]), pos - L.bufpos, h) L.bufpos = pos @@ -629,8 +631,8 @@ proc getOperator(L: var TLexer, tok: var TToken) = while true: var c = buf[pos] if c notin OpChars: break - h = h !& Ord(c) - Inc(pos) + h = h !& ord(c) + inc(pos) endOperator(L, tok, pos, h) proc scanComment(L: var TLexer, tok: var TToken) = @@ -678,17 +680,17 @@ proc skip(L: var TLexer, tok: var TToken) = while true: case buf[pos] of ' ': - Inc(pos) + inc(pos) of Tabulator: lexMessagePos(L, errTabulatorsAreNotAllowed, pos) inc(pos) of CR, LF: - pos = HandleCRLF(L, pos) + pos = handleCRLF(L, pos) buf = L.buf var indent = 0 while buf[pos] == ' ': - Inc(pos) - Inc(indent) + inc(pos) + inc(indent) if buf[pos] > ' ': tok.indent = indent break @@ -705,7 +707,7 @@ proc rawGetTok(L: var TLexer, tok: var TToken) = tok.indent = -1 skip(L, tok) var c = L.buf[L.bufpos] - tok.line = L.linenumber + tok.line = L.lineNumber tok.col = getColNumber(L, L.bufpos) if c in SymStartChars - {'r', 'R', 'l'}: getSymbol(L, tok) @@ -722,8 +724,8 @@ proc rawGetTok(L: var TLexer, tok: var TToken) = else: getOperator(L, tok) of ',': - tok.toktype = tkComma - Inc(L.bufpos) + tok.tokType = tkComma + inc(L.bufpos) of 'l': # if we parsed exactly one character and its a small L (l), this # is treated as a warning because it may be confused with the number 1 @@ -731,59 +733,59 @@ proc rawGetTok(L: var TLexer, tok: var TToken) = lexMessage(L, warnSmallLshouldNotBeUsed) getSymbol(L, tok) of 'r', 'R': - if L.buf[L.bufPos + 1] == '\"': - Inc(L.bufPos) + if L.buf[L.bufpos + 1] == '\"': + inc(L.bufpos) getString(L, tok, true) else: getSymbol(L, tok) of '(': - Inc(L.bufpos) - if L.buf[L.bufPos] == '.' and L.buf[L.bufPos+1] != '.': - tok.toktype = tkParDotLe - Inc(L.bufpos) + inc(L.bufpos) + if L.buf[L.bufpos] == '.' and L.buf[L.bufpos+1] != '.': + tok.tokType = tkParDotLe + inc(L.bufpos) else: - tok.toktype = tkParLe + tok.tokType = tkParLe of ')': - tok.toktype = tkParRi - Inc(L.bufpos) + tok.tokType = tkParRi + inc(L.bufpos) of '[': - Inc(L.bufpos) - if L.buf[L.bufPos] == '.' and L.buf[L.bufPos+1] != '.': - tok.toktype = tkBracketDotLe - Inc(L.bufpos) + inc(L.bufpos) + if L.buf[L.bufpos] == '.' and L.buf[L.bufpos+1] != '.': + tok.tokType = tkBracketDotLe + inc(L.bufpos) else: - tok.toktype = tkBracketLe + tok.tokType = tkBracketLe of ']': - tok.toktype = tkBracketRi - Inc(L.bufpos) + tok.tokType = tkBracketRi + inc(L.bufpos) of '.': - if L.buf[L.bufPos+1] == ']': + if L.buf[L.bufpos+1] == ']': tok.tokType = tkBracketDotRi - Inc(L.bufpos, 2) - elif L.buf[L.bufPos+1] == '}': + inc(L.bufpos, 2) + elif L.buf[L.bufpos+1] == '}': tok.tokType = tkCurlyDotRi - Inc(L.bufpos, 2) - elif L.buf[L.bufPos+1] == ')': + inc(L.bufpos, 2) + elif L.buf[L.bufpos+1] == ')': tok.tokType = tkParDotRi - Inc(L.bufpos, 2) + inc(L.bufpos, 2) else: getOperator(L, tok) of '{': - Inc(L.bufpos) - if L.buf[L.bufPos] == '.' and L.buf[L.bufPos+1] != '.': - tok.toktype = tkCurlyDotLe - Inc(L.bufpos) + inc(L.bufpos) + if L.buf[L.bufpos] == '.' and L.buf[L.bufpos+1] != '.': + tok.tokType = tkCurlyDotLe + inc(L.bufpos) else: - tok.toktype = tkCurlyLe + tok.tokType = tkCurlyLe of '}': - tok.toktype = tkCurlyRi - Inc(L.bufpos) + tok.tokType = tkCurlyRi + inc(L.bufpos) of ';': - tok.toktype = tkSemiColon - Inc(L.bufpos) + tok.tokType = tkSemiColon + inc(L.bufpos) of '`': tok.tokType = tkAccent - Inc(L.bufpos) + inc(L.bufpos) of '\"': # check for extended raw string literal: var rawMode = L.bufpos > 0 and L.buf[L.bufpos-1] in SymChars @@ -802,12 +804,12 @@ proc rawGetTok(L: var TLexer, tok: var TToken) = if c in OpChars: getOperator(L, tok) elif c == nimlexbase.EndOfFile: - tok.toktype = tkEof + tok.tokType = tkEof tok.indent = 0 else: tok.literal = $c tok.tokType = tkInvalid lexMessage(L, errInvalidToken, c & " (\\" & $(ord(c)) & ')') - Inc(L.bufpos) + inc(L.bufpos) dummyIdent = getIdent("") diff --git a/compiler/lists.nim b/compiler/lists.nim index 22b1a183a..dd4f5d6be 100644 --- a/compiler/lists.nim +++ b/compiler/lists.nim @@ -20,17 +20,17 @@ type PStrEntry* = ref TStrEntry TLinkedList* = object # for the "find" operation: head*, tail*: PListEntry - Counter*: int + counter*: int - TCompareProc* = proc (entry: PListEntry, closure: Pointer): bool {.nimcall.} + TCompareProc* = proc (entry: PListEntry, closure: pointer): bool {.nimcall.} -proc InitLinkedList*(list: var TLinkedList) = - list.Counter = 0 +proc initLinkedList*(list: var TLinkedList) = + list.counter = 0 list.head = nil list.tail = nil -proc Append*(list: var TLinkedList, entry: PListEntry) = - Inc(list.counter) +proc append*(list: var TLinkedList, entry: PListEntry) = + inc(list.counter) entry.next = nil entry.prev = list.tail if list.tail != nil: @@ -39,7 +39,7 @@ proc Append*(list: var TLinkedList, entry: PListEntry) = list.tail = entry if list.head == nil: list.head = entry -proc Contains*(list: TLinkedList, data: string): bool = +proc contains*(list: TLinkedList, data: string): bool = var it = list.head while it != nil: if PStrEntry(it).data == data: @@ -50,15 +50,15 @@ proc newStrEntry(data: string): PStrEntry = new(result) result.data = data -proc AppendStr*(list: var TLinkedList, data: string) = +proc appendStr*(list: var TLinkedList, data: string) = append(list, newStrEntry(data)) -proc IncludeStr*(list: var TLinkedList, data: string): bool = - if Contains(list, data): return true - AppendStr(list, data) # else: add to list +proc includeStr*(list: var TLinkedList, data: string): bool = + if contains(list, data): return true + appendStr(list, data) # else: add to list -proc Prepend*(list: var TLinkedList, entry: PListEntry) = - Inc(list.counter) +proc prepend*(list: var TLinkedList, entry: PListEntry) = + inc(list.counter) entry.prev = nil entry.next = list.head if list.head != nil: @@ -67,22 +67,22 @@ proc Prepend*(list: var TLinkedList, entry: PListEntry) = list.head = entry if list.tail == nil: list.tail = entry -proc PrependStr*(list: var TLinkedList, data: string) = +proc prependStr*(list: var TLinkedList, data: string) = prepend(list, newStrEntry(data)) -proc InsertBefore*(list: var TLinkedList, pos, entry: PListEntry) = +proc insertBefore*(list: var TLinkedList, pos, entry: PListEntry) = assert(pos != nil) if pos == list.head: prepend(list, entry) else: - Inc(list.counter) + inc(list.counter) entry.next = pos entry.prev = pos.prev if pos.prev != nil: pos.prev.next = entry pos.prev = entry -proc Remove*(list: var TLinkedList, entry: PListEntry) = - Dec(list.counter) +proc remove*(list: var TLinkedList, entry: PListEntry) = + dec(list.counter) if entry == list.tail: list.tail = entry.prev if entry == list.head: @@ -103,14 +103,14 @@ proc bringToFront*(list: var TLinkedList, entry: PListEntry) = entry.next = list.head list.head = entry -proc ExcludeStr*(list: var TLinkedList, data: string) = +proc excludeStr*(list: var TLinkedList, data: string) = var it = list.head while it != nil: let nxt = it.next if PStrEntry(it).data == data: remove(list, it) it = nxt -proc Find*(list: TLinkedList, fn: TCompareProc, closure: Pointer): PListEntry = +proc find*(list: TLinkedList, fn: TCompareProc, closure: pointer): PListEntry = result = list.head while result != nil: if fn(result, closure): return diff --git a/compiler/llstream.nim b/compiler/llstream.nim index 8ccf24b99..510880ffd 100644 --- a/compiler/llstream.nim +++ b/compiler/llstream.nim @@ -23,63 +23,63 @@ type llsStdIn # stream encapsulates stdin TLLStream* = object of TObject kind*: TLLStreamKind # accessible for low-level access (lexbase uses this) - f*: tfile + f*: TFile s*: string rd*, wr*: int # for string streams lineOffset*: int # for fake stdin line numbers PLLStream* = ref TLLStream -proc LLStreamOpen*(data: string): PLLStream -proc LLStreamOpen*(f: var tfile): PLLStream -proc LLStreamOpen*(filename: string, mode: TFileMode): PLLStream -proc LLStreamOpen*(): PLLStream -proc LLStreamOpenStdIn*(): PLLStream -proc LLStreamClose*(s: PLLStream) -proc LLStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int -proc LLStreamReadLine*(s: PLLStream, line: var string): bool -proc LLStreamReadAll*(s: PLLStream): string -proc LLStreamWrite*(s: PLLStream, data: string) -proc LLStreamWrite*(s: PLLStream, data: Char) -proc LLStreamWrite*(s: PLLStream, buf: pointer, buflen: int) -proc LLStreamWriteln*(s: PLLStream, data: string) +proc llStreamOpen*(data: string): PLLStream +proc llStreamOpen*(f: var TFile): PLLStream +proc llStreamOpen*(filename: string, mode: TFileMode): PLLStream +proc llStreamOpen*(): PLLStream +proc llStreamOpenStdIn*(): PLLStream +proc llStreamClose*(s: PLLStream) +proc llStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int +proc llStreamReadLine*(s: PLLStream, line: var string): bool +proc llStreamReadAll*(s: PLLStream): string +proc llStreamWrite*(s: PLLStream, data: string) +proc llStreamWrite*(s: PLLStream, data: char) +proc llStreamWrite*(s: PLLStream, buf: pointer, buflen: int) +proc llStreamWriteln*(s: PLLStream, data: string) # implementation -proc LLStreamOpen(data: string): PLLStream = +proc llStreamOpen(data: string): PLLStream = new(result) result.s = data result.kind = llsString -proc LLStreamOpen(f: var tfile): PLLStream = +proc llStreamOpen(f: var TFile): PLLStream = new(result) result.f = f result.kind = llsFile -proc LLStreamOpen(filename: string, mode: TFileMode): PLLStream = +proc llStreamOpen(filename: string, mode: TFileMode): PLLStream = new(result) result.kind = llsFile if not open(result.f, filename, mode): result = nil -proc LLStreamOpen(): PLLStream = +proc llStreamOpen(): PLLStream = new(result) result.kind = llsNone -proc LLStreamOpenStdIn(): PLLStream = +proc llStreamOpenStdIn(): PLLStream = new(result) result.kind = llsStdIn result.s = "" result.lineOffset = -1 -proc LLStreamClose(s: PLLStream) = +proc llStreamClose(s: PLLStream) = case s.kind of llsNone, llsString, llsStdIn: - nil + discard of llsFile: close(s.f) -when not defined(ReadLineFromStdin): +when not defined(readLineFromStdin): # fallback implementation: - proc ReadLineFromStdin(prompt: string, line: var string): bool = + proc readLineFromStdin(prompt: string, line: var string): bool = stdout.write(prompt) result = readLine(stdin, line) @@ -99,7 +99,7 @@ proc endsWithOpr*(x: string): bool = result = x.endsWith(LineContinuationOprs) proc continueLine(line: string, inTripleString: bool): bool {.inline.} = - result = inTriplestring or + result = inTripleString or line[0] == ' ' or line.endsWith(LineContinuationOprs+AdditionalLineContinuationOprs) @@ -111,12 +111,12 @@ proc countTriples(s: string): int = inc i, 2 inc i -proc LLreadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int = +proc llReadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int = s.s = "" s.rd = 0 var line = newStringOfCap(120) var triples = 0 - while ReadLineFromStdin(if s.s.len == 0: ">>> " else: "... ", line): + while readLineFromStdin(if s.s.len == 0: ">>> " else: "... ", line): add(s.s, line) add(s.s, "\n") inc triples, countTriples(line) @@ -127,7 +127,7 @@ proc LLreadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int = copyMem(buf, addr(s.s[s.rd]), result) inc(s.rd, result) -proc LLStreamRead(s: PLLStream, buf: pointer, bufLen: int): int = +proc llStreamRead(s: PLLStream, buf: pointer, bufLen: int): int = case s.kind of llsNone: result = 0 @@ -139,9 +139,9 @@ proc LLStreamRead(s: PLLStream, buf: pointer, bufLen: int): int = of llsFile: result = readBuffer(s.f, buf, bufLen) of llsStdIn: - result = LLreadFromStdin(s, buf, bufLen) + result = llReadFromStdin(s, buf, bufLen) -proc LLStreamReadLine(s: PLLStream, line: var string): bool = +proc llStreamReadLine(s: PLLStream, line: var string): bool = setLen(line, 0) case s.kind of llsNone: @@ -165,25 +165,25 @@ proc LLStreamReadLine(s: PLLStream, line: var string): bool = of llsStdIn: result = readLine(stdin, line) -proc LLStreamWrite(s: PLLStream, data: string) = +proc llStreamWrite(s: PLLStream, data: string) = case s.kind of llsNone, llsStdIn: - nil + discard of llsString: add(s.s, data) inc(s.wr, len(data)) of llsFile: write(s.f, data) -proc LLStreamWriteln(s: PLLStream, data: string) = - LLStreamWrite(s, data) - LLStreamWrite(s, "\n") +proc llStreamWriteln(s: PLLStream, data: string) = + llStreamWrite(s, data) + llStreamWrite(s, "\n") -proc LLStreamWrite(s: PLLStream, data: Char) = +proc llStreamWrite(s: PLLStream, data: char) = var c: char case s.kind of llsNone, llsStdIn: - nil + discard of llsString: add(s.s, data) inc(s.wr) @@ -191,22 +191,21 @@ proc LLStreamWrite(s: PLLStream, data: Char) = c = data discard writeBuffer(s.f, addr(c), sizeof(c)) -proc LLStreamWrite(s: PLLStream, buf: pointer, buflen: int) = +proc llStreamWrite(s: PLLStream, buf: pointer, buflen: int) = case s.kind of llsNone, llsStdIn: - nil + discard of llsString: - if bufLen > 0: - setlen(s.s, len(s.s) + bufLen) - copyMem(addr(s.s[0 + s.wr]), buf, bufLen) - inc(s.wr, bufLen) + if buflen > 0: + setLen(s.s, len(s.s) + buflen) + copyMem(addr(s.s[0 + s.wr]), buf, buflen) + inc(s.wr, buflen) of llsFile: - discard writeBuffer(s.f, buf, bufLen) + discard writeBuffer(s.f, buf, buflen) -proc LLStreamReadAll(s: PLLStream): string = +proc llStreamReadAll(s: PLLStream): string = const bufSize = 2048 - var bytes, i: int case s.kind of llsNone, llsStdIn: result = "" @@ -216,10 +215,10 @@ proc LLStreamReadAll(s: PLLStream): string = s.rd = len(s.s) of llsFile: result = newString(bufSize) - bytes = readBuffer(s.f, addr(result[0]), bufSize) - i = bytes + var bytes = readBuffer(s.f, addr(result[0]), bufSize) + var i = bytes while bytes == bufSize: - setlen(result, i + bufSize) + setLen(result, i + bufSize) bytes = readBuffer(s.f, addr(result[i + 0]), bufSize) inc(i, bytes) - setlen(result, i) + setLen(result, i) diff --git a/compiler/lookups.nim b/compiler/lookups.nim index e1ec9e14b..57c420d3b 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -21,7 +21,7 @@ proc considerAcc*(n: PNode): PIdent = of nkSym: result = n.sym.name of nkAccQuoted: case n.len - of 0: GlobalError(n.info, errIdentifierExpected, renderTree(n)) + of 0: globalError(n.info, errIdentifierExpected, renderTree(n)) of 1: result = considerAcc(n.sons[0]) else: var id = "" @@ -30,16 +30,16 @@ proc considerAcc*(n: PNode): PIdent = case x.kind of nkIdent: id.add(x.ident.s) of nkSym: id.add(x.sym.name.s) - else: GlobalError(n.info, errIdentifierExpected, renderTree(n)) + else: globalError(n.info, errIdentifierExpected, renderTree(n)) result = getIdent(id) else: - GlobalError(n.info, errIdentifierExpected, renderTree(n)) + globalError(n.info, errIdentifierExpected, renderTree(n)) template addSym*(scope: PScope, s: PSym) = - StrTableAdd(scope.symbols, s) + strTableAdd(scope.symbols, s) proc addUniqueSym*(scope: PScope, s: PSym): TResult = - if StrTableIncl(scope.symbols, s): + if strTableIncl(scope.symbols, s): result = Failure else: result = Success @@ -64,17 +64,17 @@ iterator walkScopes*(scope: PScope): PScope = current = current.parent proc localSearchInScope*(c: PContext, s: PIdent): PSym = - result = StrTableGet(c.currentScope.symbols, s) + result = strTableGet(c.currentScope.symbols, s) proc searchInScopes*(c: PContext, s: PIdent): PSym = for scope in walkScopes(c.currentScope): - result = StrTableGet(scope.symbols, s) + result = strTableGet(scope.symbols, s) if result != nil: return result = nil proc searchInScopes*(c: PContext, s: PIdent, filter: TSymKinds): PSym = for scope in walkScopes(c.currentScope): - result = StrTableGet(scope.symbols, s) + result = strTableGet(scope.symbols, s) if result != nil and result.kind in filter: return result = nil @@ -114,65 +114,65 @@ proc getSymRepr*(s: PSym): string = proc ensureNoMissingOrUnusedSymbols(scope: PScope) = # check if all symbols have been used and defined: var it: TTabIter - var s = InitTabIter(it, scope.symbols) + var s = initTabIter(it, scope.symbols) var missingImpls = 0 while s != nil: if sfForward in s.flags: # too many 'implementation of X' errors are annoying # and slow 'suggest' down: if missingImpls == 0: - LocalError(s.info, errImplOfXexpected, getSymRepr(s)) + localError(s.info, errImplOfXexpected, getSymRepr(s)) inc missingImpls elif {sfUsed, sfExported} * s.flags == {} and optHints in s.options: # BUGFIX: check options in s! if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam}: - Message(s.info, hintXDeclaredButNotUsed, getSymRepr(s)) - s = NextIter(it, scope.symbols) + message(s.info, hintXDeclaredButNotUsed, getSymRepr(s)) + s = nextIter(it, scope.symbols) -proc WrongRedefinition*(info: TLineInfo, s: string) = +proc wrongRedefinition*(info: TLineInfo, s: string) = if gCmd != cmdInteractive: localError(info, errAttemptToRedefine, s) proc addDecl*(c: PContext, sym: PSym) = if c.currentScope.addUniqueSym(sym) == Failure: - WrongRedefinition(sym.info, sym.Name.s) + wrongRedefinition(sym.info, sym.name.s) proc addPrelimDecl*(c: PContext, sym: PSym) = discard c.currentScope.addUniqueSym(sym) proc addDeclAt*(scope: PScope, sym: PSym) = if scope.addUniqueSym(sym) == Failure: - WrongRedefinition(sym.info, sym.Name.s) + wrongRedefinition(sym.info, sym.name.s) -proc AddInterfaceDeclAux(c: PContext, sym: PSym) = +proc addInterfaceDeclAux(c: PContext, sym: PSym) = if sfExported in sym.flags: # add to interface: - if c.module != nil: StrTableAdd(c.module.tab, sym) - else: InternalError(sym.info, "AddInterfaceDeclAux") + if c.module != nil: strTableAdd(c.module.tab, sym) + else: internalError(sym.info, "AddInterfaceDeclAux") proc addInterfaceDeclAt*(c: PContext, scope: PScope, sym: PSym) = addDeclAt(scope, sym) - AddInterfaceDeclAux(c, sym) + addInterfaceDeclAux(c, sym) proc addOverloadableSymAt*(scope: PScope, fn: PSym) = if fn.kind notin OverloadableSyms: - InternalError(fn.info, "addOverloadableSymAt") + internalError(fn.info, "addOverloadableSymAt") return - var check = StrTableGet(scope.symbols, fn.name) - if check != nil and check.Kind notin OverloadableSyms: - WrongRedefinition(fn.info, fn.Name.s) + var check = strTableGet(scope.symbols, fn.name) + if check != nil and check.kind notin OverloadableSyms: + wrongRedefinition(fn.info, fn.name.s) else: scope.addSym(fn) proc addInterfaceDecl*(c: PContext, sym: PSym) = # it adds the symbol to the interface if appropriate addDecl(c, sym) - AddInterfaceDeclAux(c, sym) + addInterfaceDeclAux(c, sym) proc addInterfaceOverloadableSymAt*(c: PContext, scope: PScope, sym: PSym) = # it adds the symbol to the interface if appropriate addOverloadableSymAt(scope, sym) - AddInterfaceDeclAux(c, sym) + addInterfaceDeclAux(c, sym) proc lookUp*(c: PContext, n: PNode): PSym = # Looks up a symbol. Generates an error in case of nil. @@ -180,7 +180,7 @@ proc lookUp*(c: PContext, n: PNode): PSym = of nkIdent: result = searchInScopes(c, n.ident) if result == nil: - LocalError(n.info, errUndeclaredIdentifier, n.ident.s) + localError(n.info, errUndeclaredIdentifier, n.ident.s) result = errorSym(c, n) of nkSym: result = n.sym @@ -188,34 +188,34 @@ proc lookUp*(c: PContext, n: PNode): PSym = var ident = considerAcc(n) result = searchInScopes(c, ident) if result == nil: - LocalError(n.info, errUndeclaredIdentifier, ident.s) + localError(n.info, errUndeclaredIdentifier, ident.s) result = errorSym(c, n) else: - InternalError(n.info, "lookUp") + internalError(n.info, "lookUp") return - if Contains(c.AmbiguousSymbols, result.id): - LocalError(n.info, errUseQualifier, result.name.s) + if contains(c.ambiguousSymbols, result.id): + localError(n.info, errUseQualifier, result.name.s) if result.kind == skStub: loadStub(result) type TLookupFlag* = enum checkAmbiguity, checkUndeclared -proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = +proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = case n.kind of nkIdent, nkAccQuoted: var ident = considerAcc(n) result = searchInScopes(c, ident) if result == nil and checkUndeclared in flags: - LocalError(n.info, errUndeclaredIdentifier, ident.s) + localError(n.info, errUndeclaredIdentifier, ident.s) result = errorSym(c, n) elif checkAmbiguity in flags and result != nil and - Contains(c.AmbiguousSymbols, result.id): - LocalError(n.info, errUseQualifier, ident.s) + contains(c.ambiguousSymbols, result.id): + localError(n.info, errUseQualifier, ident.s) of nkSym: result = n.sym - if checkAmbiguity in flags and Contains(c.AmbiguousSymbols, result.id): - LocalError(n.info, errUseQualifier, n.sym.name.s) + if checkAmbiguity in flags and contains(c.ambiguousSymbols, result.id): + localError(n.info, errUseQualifier, n.sym.name.s) of nkDotExpr: result = nil var m = qualifiedLookUp(c, n.sons[0], flags*{checkUndeclared}) @@ -227,28 +227,31 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = ident = considerAcc(n.sons[1]) if ident != nil: if m == c.module: - result = StrTableGet(c.topLevelScope.symbols, ident) + result = strTableGet(c.topLevelScope.symbols, ident) else: - result = StrTableGet(m.tab, ident) + result = strTableGet(m.tab, ident) if result == nil and checkUndeclared in flags: - LocalError(n.sons[1].info, errUndeclaredIdentifier, ident.s) + localError(n.sons[1].info, errUndeclaredIdentifier, ident.s) result = errorSym(c, n.sons[1]) - elif checkUndeclared in flags: - LocalError(n.sons[1].info, errIdentifierExpected, + elif n.sons[1].kind == nkSym: + result = n.sons[1].sym + elif checkUndeclared in flags and + n.sons[1].kind notin {nkOpenSymChoice, nkClosedSymChoice}: + localError(n.sons[1].info, errIdentifierExpected, renderTree(n.sons[1])) result = errorSym(c, n.sons[1]) else: result = nil if result != nil and result.kind == skStub: loadStub(result) -proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = +proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = case n.kind of nkIdent, nkAccQuoted: var ident = considerAcc(n) o.scope = c.currentScope o.mode = oimNoQualifier while true: - result = InitIdentIter(o.it, o.scope.symbols, ident) + result = initIdentIter(o.it, o.scope.symbols, ident) if result != nil: break else: @@ -269,12 +272,12 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = if ident != nil: if o.m == c.module: # a module may access its private members: - result = InitIdentIter(o.it, c.topLevelScope.symbols, ident) + result = initIdentIter(o.it, c.topLevelScope.symbols, ident) o.mode = oimSelfModule else: - result = InitIdentIter(o.it, o.m.tab, ident) + result = initIdentIter(o.it, o.m.tab, ident) else: - LocalError(n.sons[1].info, errIdentifierExpected, + localError(n.sons[1].info, errIdentifierExpected, renderTree(n.sons[1])) result = errorSym(c, n.sons[1]) of nkClosedSymChoice, nkOpenSymChoice: @@ -282,7 +285,7 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = result = n.sons[0].sym o.symChoiceIndex = 1 o.inSymChoice = initIntSet() - Incl(o.inSymChoice, result.id) + incl(o.inSymChoice, result.id) else: nil if result != nil and result.kind == skStub: loadStub(result) @@ -303,7 +306,7 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = while result == nil: o.scope = o.scope.parent if o.scope == nil: break - result = InitIdentIter(o.it, o.scope.symbols, o.it.name) + result = initIdentIter(o.it, o.scope.symbols, o.it.name) # BUGFIX: o.it.name <-> n.ident else: result = nil @@ -314,25 +317,25 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = of oimSymChoice: if o.symChoiceIndex < sonsLen(n): result = n.sons[o.symChoiceIndex].sym - Incl(o.inSymChoice, result.id) + incl(o.inSymChoice, result.id) inc o.symChoiceIndex elif n.kind == nkOpenSymChoice: # try 'local' symbols too for Koenig's lookup: o.mode = oimSymChoiceLocalLookup o.scope = c.currentScope - result = FirstIdentExcluding(o.it, o.scope.symbols, + result = firstIdentExcluding(o.it, o.scope.symbols, n.sons[0].sym.name, o.inSymChoice) while result == nil: o.scope = o.scope.parent if o.scope == nil: break - result = FirstIdentExcluding(o.it, o.scope.symbols, + result = firstIdentExcluding(o.it, o.scope.symbols, n.sons[0].sym.name, o.inSymChoice) of oimSymChoiceLocalLookup: result = nextIdentExcluding(o.it, o.scope.symbols, o.inSymChoice) while result == nil: o.scope = o.scope.parent if o.scope == nil: break - result = FirstIdentExcluding(o.it, o.scope.symbols, + result = firstIdentExcluding(o.it, o.scope.symbols, n.sons[0].sym.name, o.inSymChoice) if result != nil and result.kind == skStub: loadStub(result) diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim index 0c0b87222..b4f6e043d 100644 --- a/compiler/magicsys.nim +++ b/compiler/magicsys.nim @@ -12,14 +12,14 @@ import ast, astalgo, hashes, msgs, platform, nversion, times, idents, rodread -var SystemModule*: PSym +var systemModule*: PSym proc registerSysType*(t: PType) # magic symbols in the system module: proc getSysType*(kind: TTypeKind): PType proc getCompilerProc*(name: string): PSym proc registerCompilerProc*(s: PSym) -proc FinishSystem*(tab: TStrTable) +proc finishSystem*(tab: TStrTable) proc getSysSym*(name: string): PSym # implementation @@ -36,7 +36,7 @@ proc newSysType(kind: TTypeKind, size: int): PType = result.align = size proc getSysSym(name: string): PSym = - result = StrTableGet(systemModule.tab, getIdent(name)) + result = strTableGet(systemModule.tab, getIdent(name)) if result == nil: rawMessage(errSystemNeeds, name) result = newSym(skError, getIdent(name), systemModule, systemModule.info) @@ -46,11 +46,11 @@ proc getSysSym(name: string): PSym = proc getSysMagic*(name: string, m: TMagic): PSym = var ti: TIdentIter let id = getIdent(name) - result = InitIdentIter(ti, systemModule.tab, id) + result = initIdentIter(ti, systemModule.tab, id) while result != nil: if result.kind == skStub: loadStub(result) if result.magic == m: return result - result = NextIdentIter(ti, systemModule.tab) + result = nextIdentIter(ti, systemModule.tab) rawMessage(errSystemNeeds, name) result = newSym(skError, id, systemModule, systemModule.info) result.typ = newType(tyError, systemModule) @@ -79,14 +79,14 @@ proc getSysType(kind: TTypeKind): PType = of tyBool: result = sysTypeFromName("bool") of tyChar: result = sysTypeFromName("char") of tyString: result = sysTypeFromName("string") - of tyCstring: result = sysTypeFromName("cstring") + of tyCString: result = sysTypeFromName("cstring") of tyPointer: result = sysTypeFromName("pointer") of tyNil: result = newSysType(tyNil, ptrSize) - else: InternalError("request for typekind: " & $kind) + else: internalError("request for typekind: " & $kind) gSysTypes[kind] = result if result.kind != kind: - InternalError("wanted: " & $kind & " got: " & $result.kind) - if result == nil: InternalError("type not found: " & $kind) + internalError("wanted: " & $kind & " got: " & $result.kind) + if result == nil: internalError("type not found: " & $kind) var intTypeCache: array[-5..64, PType] @@ -126,7 +126,7 @@ proc skipIntLit*(t: PType): PType {.inline.} = return getSysType(t.kind) result = t -proc AddSonSkipIntLit*(father, son: PType) = +proc addSonSkipIntLit*(father, son: PType) = if isNil(father.sons): father.sons = @[] let s = son.skipIntLit add(father.sons, s) @@ -134,7 +134,7 @@ proc AddSonSkipIntLit*(father, son: PType) = proc setIntLitType*(result: PNode) = let i = result.intVal - case platform.IntSize + case platform.intSize of 8: result.typ = getIntLitType(result) of 4: if i >= low(int32) and i <= high(int32): @@ -158,13 +158,13 @@ proc setIntLitType*(result: PNode) = result.typ = getSysType(tyInt32) else: result.typ = getSysType(tyInt64) - else: InternalError(result.info, "invalid int size") + else: internalError(result.info, "invalid int size") proc getCompilerProc(name: string): PSym = var ident = getIdent(name, hashIgnoreStyle(name)) - result = StrTableGet(compilerprocs, ident) + result = strTableGet(compilerprocs, ident) if result == nil: - result = StrTableGet(rodCompilerProcs, ident) + result = strTableGet(rodCompilerprocs, ident) if result != nil: strTableAdd(compilerprocs, result) if result.kind == skStub: loadStub(result) @@ -172,7 +172,6 @@ proc getCompilerProc(name: string): PSym = proc registerCompilerProc(s: PSym) = strTableAdd(compilerprocs, s) -proc FinishSystem(tab: TStrTable) = nil - -initStrTable(compilerprocs) +proc finishSystem(tab: TStrTable) = discard +initStrTable(compilerprocs) diff --git a/compiler/main.nim b/compiler/main.nim index 9ffe99454..cdea7b5ca 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2013 Andreas Rumpf +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -14,16 +14,16 @@ import os, condsyms, rodread, rodwrite, times, wordrecg, sem, semdata, idents, passes, docgen, extccomp, cgen, jsgen, json, nversion, - platform, nimconf, importer, passaux, depends, evals, types, idgen, + platform, nimconf, importer, passaux, depends, vm, vmdef, types, idgen, tables, docgen2, service, parser, modules, ccgutils, sigmatch, ropes, lists, pretty -from magicsys import SystemModule, resetSysTypes +from magicsys import systemModule, resetSysTypes const - has_LLVM_Backend = false + hasLLVM_Backend = false -when has_LLVM_Backend: +when hasLLVM_Backend: import llvmgen proc rodPass = @@ -37,22 +37,22 @@ proc semanticPasses = registerPass verbosePass registerPass semPass -proc CommandGenDepend = +proc commandGenDepend = semanticPasses() - registerPass(genDependPass) + registerPass(gendependPass) registerPass(cleanupPass) compileProject() generateDot(gProjectFull) execExternalProgram("dot -Tpng -o" & changeFileExt(gProjectFull, "png") & ' ' & changeFileExt(gProjectFull, "dot")) -proc CommandCheck = +proc commandCheck = msgs.gErrorMax = high(int) # do not stop after first error semanticPasses() # use an empty backend for semantic checking only rodPass() compileProject() -proc CommandDoc2 = +proc commandDoc2 = msgs.gErrorMax = high(int) # do not stop after first error semanticPasses() registerPass(docgen2Pass) @@ -60,7 +60,7 @@ proc CommandDoc2 = compileProject() finishDoc2Pass(gProjectName) -proc CommandCompileToC = +proc commandCompileToC = semanticPasses() registerPass(cgenPass) rodPass() @@ -73,7 +73,7 @@ proc CommandCompileToC = compileProject() cgenWriteModules() if gCmd != cmdRun: - extccomp.CallCCompiler(changeFileExt(gProjectFull, "")) + extccomp.callCCompiler(changeFileExt(gProjectFull, "")) if isServing: # caas will keep track only of the compilation commands @@ -111,45 +111,45 @@ proc CommandCompileToC = ccgutils.resetCaches() GC_fullCollect() -when has_LLVM_Backend: - proc CommandCompileToLLVM = +when hasLLVM_Backend: + proc commandCompileToLLVM = semanticPasses() registerPass(llvmgen.llvmgenPass()) rodPass() #registerPass(cleanupPass()) compileProject() -proc CommandCompileToJS = +proc commandCompileToJS = #incl(gGlobalOptions, optSafeCode) setTarget(osJS, cpuJS) #initDefines() - DefineSymbol("nimrod") # 'nimrod' is always defined - DefineSymbol("ecmascript") # For backward compatibility - DefineSymbol("js") + defineSymbol("nimrod") # 'nimrod' is always defined + defineSymbol("ecmascript") # For backward compatibility + defineSymbol("js") semanticPasses() - registerPass(jsgenPass) + registerPass(JSgenPass) compileProject() -proc InteractivePasses = +proc interactivePasses = #incl(gGlobalOptions, optSafeCode) #setTarget(osNimrodVM, cpuNimrodVM) initDefines() - DefineSymbol("nimrodvm") + defineSymbol("nimrodvm") when hasFFI: DefineSymbol("nimffi") registerPass(verbosePass) registerPass(semPass) registerPass(evalPass) -proc CommandInteractive = +proc commandInteractive = msgs.gErrorMax = high(int) # do not stop after first error - InteractivePasses() + interactivePasses() compileSystemModule() if commandArgs.len > 0: - discard CompileModule(fileInfoIdx(gProjectFull), {}) + discard compileModule(fileInfoIdx(gProjectFull), {}) else: var m = makeStdinModule() incl(m.flags, sfMainModule) - processModule(m, LLStreamOpenStdIn(), nil) + processModule(m, llStreamOpenStdIn(), nil) const evalPasses = [verbosePass, semPass, evalPass] @@ -157,28 +157,28 @@ proc evalNim(nodes: PNode, module: PSym) = carryPasses(nodes, module, evalPasses) proc commandEval(exp: string) = - if SystemModule == nil: - InteractivePasses() + if systemModule == nil: + interactivePasses() compileSystemModule() var echoExp = "echo \"eval\\t\", " & "repr(" & exp & ")" evalNim(echoExp.parseString, makeStdinModule()) -proc CommandPrettyOld = +proc commandPrettyOld = var projectFile = addFileExt(mainCommandArg(), NimExt) var module = parseFile(projectFile.fileInfoIdx) if module != nil: renderModule(module, getOutFile(mainCommandArg(), "pretty." & NimExt)) -proc CommandPretty = +proc commandPretty = msgs.gErrorMax = high(int) # do not stop after first error semanticPasses() registerPass(prettyPass) compileProject() pretty.overwriteFiles() -proc CommandScan = - var f = addFileExt(mainCommandArg(), nimExt) - var stream = LLStreamOpen(f, fmRead) +proc commandScan = + var f = addFileExt(mainCommandArg(), NimExt) + var stream = llStreamOpen(f, fmRead) if stream != nil: var L: TLexer @@ -187,20 +187,20 @@ proc CommandScan = openLexer(L, f, stream) while true: rawGetTok(L, tok) - PrintTok(tok) + printTok(tok) if tok.tokType == tkEof: break - CloseLexer(L) + closeLexer(L) else: rawMessage(errCannotOpenFile, f) -proc CommandSuggest = +proc commandSuggest = if isServing: # XXX: hacky work-around ahead # Currently, it's possible to issue a idetools command, before # issuing the first compile command. This will leave the compiler # cache in a state where "no recompilation is necessary", but the # cgen pass was never executed at all. - CommandCompileToC() + commandCompileToC() if gDirtyBufferIdx != 0: discard compileModule(gDirtyBufferIdx, {sfDirty}) resetModule(gDirtyBufferIdx) @@ -219,21 +219,21 @@ proc CommandSuggest = proc wantMainModule = if gProjectFull.len == 0: if optMainModule.len == 0: - Fatal(gCmdLineInfo, errCommandExpectsFilename) + fatal(gCmdLineInfo, errCommandExpectsFilename) else: gProjectName = optMainModule gProjectFull = gProjectPath / gProjectName - gProjectMainIdx = addFileExt(gProjectFull, nimExt).fileInfoIdx + gProjectMainIdx = addFileExt(gProjectFull, NimExt).fileInfoIdx proc requireMainModuleOption = if optMainModule.len == 0: - Fatal(gCmdLineInfo, errMainModuleMustBeSpecified) + fatal(gCmdLineInfo, errMainModuleMustBeSpecified) else: gProjectName = optMainModule gProjectFull = gProjectPath / gProjectName - gProjectMainIdx = addFileExt(gProjectFull, nimExt).fileInfoIdx + gProjectMainIdx = addFileExt(gProjectFull, NimExt).fileInfoIdx proc resetMemory = resetCompilationLists() @@ -286,7 +286,7 @@ const SimiluateCaasMemReset = false PrintRopeCacheStats = false -proc MainCommand* = +proc mainCommand* = when SimiluateCaasMemReset: gGlobalOptions.incl(optCaasEnabled) @@ -297,7 +297,7 @@ proc MainCommand* = if gProjectFull.len != 0: # current path is always looked first for modules prependStr(searchPaths, gProjectPath) - setID(100) + setId(100) passes.gIncludeFile = includeModule passes.gImportModule = importModule case command.normalize @@ -305,20 +305,20 @@ proc MainCommand* = # compile means compileToC currently gCmd = cmdCompileToC wantMainModule() - CommandCompileToC() + commandCompileToC() of "cpp", "compiletocpp": extccomp.cExt = ".cpp" gCmd = cmdCompileToCpp if cCompiler == ccGcc: setCC("gpp") wantMainModule() - DefineSymbol("cpp") - CommandCompileToC() + defineSymbol("cpp") + commandCompileToC() of "objc", "compiletooc": extccomp.cExt = ".m" gCmd = cmdCompileToOC wantMainModule() - DefineSymbol("objc") - CommandCompileToC() + defineSymbol("objc") + commandCompileToC() of "run": gCmd = cmdRun wantMainModule() @@ -330,63 +330,63 @@ proc MainCommand* = of "js", "compiletojs": gCmd = cmdCompileToJS wantMainModule() - CommandCompileToJS() + commandCompileToJS() of "compiletollvm": gCmd = cmdCompileToLLVM wantMainModule() - when has_LLVM_Backend: + when hasLLVM_Backend: CommandCompileToLLVM() else: rawMessage(errInvalidCommandX, command) of "pretty": gCmd = cmdPretty wantMainModule() - CommandPretty() + commandPretty() of "doc": gCmd = cmdDoc - LoadConfigs(DocConfig) + loadConfigs(DocConfig) wantMainModule() - CommandDoc() + commandDoc() of "doc2": gCmd = cmdDoc - LoadConfigs(DocConfig) + loadConfigs(DocConfig) wantMainModule() - DefineSymbol("nimdoc") - CommandDoc2() + defineSymbol("nimdoc") + commandDoc2() of "rst2html": gCmd = cmdRst2html - LoadConfigs(DocConfig) + loadConfigs(DocConfig) wantMainModule() - CommandRst2Html() + commandRst2Html() of "rst2tex": gCmd = cmdRst2tex - LoadConfigs(DocTexConfig) + loadConfigs(DocTexConfig) wantMainModule() - CommandRst2TeX() + commandRst2TeX() of "jsondoc": gCmd = cmdDoc - LoadConfigs(DocConfig) + loadConfigs(DocConfig) wantMainModule() - DefineSymbol("nimdoc") - CommandJSON() + defineSymbol("nimdoc") + commandJSON() of "buildindex": gCmd = cmdDoc - LoadConfigs(DocConfig) - CommandBuildIndex() + loadConfigs(DocConfig) + commandBuildIndex() of "gendepend": gCmd = cmdGenDepend wantMainModule() - CommandGenDepend() + commandGenDepend() of "dump": - gcmd = cmdDump - if getconfigvar("dump.format") == "json": + gCmd = cmdDump + if getConfigVar("dump.format") == "json": requireMainModuleOption() var definedSymbols = newJArray() for s in definedSymbolNames(): definedSymbols.elems.add(%s) var libpaths = newJArray() - for dir in itersearchpath(searchpaths): libpaths.elems.add(%dir) + for dir in iterSearchPath(searchPaths): libpaths.elems.add(%dir) var dumpdata = % [ (key: "version", val: %VersionAsString), @@ -395,17 +395,17 @@ proc MainCommand* = (key: "lib_paths", val: libpaths) ] - outWriteLn($dumpdata) + outWriteln($dumpdata) else: - outWriteLn("-- list of currently defined symbols --") - for s in definedSymbolNames(): outWriteLn(s) - outWriteLn("-- end of list --") + outWriteln("-- list of currently defined symbols --") + for s in definedSymbolNames(): outWriteln(s) + outWriteln("-- end of list --") - for it in iterSearchPath(searchpaths): msgWriteLn(it) + for it in iterSearchPath(searchPaths): msgWriteln(it) of "check": gCmd = cmdCheck wantMainModule() - CommandCheck() + commandCheck() of "parse": gCmd = cmdParse wantMainModule() @@ -413,11 +413,11 @@ proc MainCommand* = of "scan": gCmd = cmdScan wantMainModule() - CommandScan() - MsgWriteln("Beware: Indentation tokens depend on the parser\'s state!") + commandScan() + msgWriteln("Beware: Indentation tokens depend on the parser\'s state!") of "i": gCmd = cmdInteractive - CommandInteractive() + commandInteractive() of "e": # XXX: temporary command for easier testing commandEval(mainCommandArg()) @@ -429,12 +429,12 @@ proc MainCommand* = commandEval(gEvalExpr) else: wantMainModule() - CommandSuggest() + commandSuggest() of "serve": isServing = true gGlobalOptions.incl(optCaasEnabled) msgs.gErrorMax = high(int) # do not stop after first error - serve(MainCommand) + serve(mainCommand) else: rawMessage(errInvalidCommandX, command) diff --git a/compiler/modules.nim b/compiler/modules.nim index ef6af3d69..6a1491682 100644 --- a/compiler/modules.nim +++ b/compiler/modules.nim @@ -41,7 +41,7 @@ template crc(x: PSym): expr = gMemCacheData[x.position].crc proc crcChanged(fileIdx: int32): bool = - InternalAssert fileIdx >= 0 and fileIdx < gMemCacheData.len + internalAssert fileIdx >= 0 and fileIdx < gMemCacheData.len template updateStatus = gMemCacheData[fileIdx].crcStatus = if result: crcHasChanged @@ -68,7 +68,7 @@ proc doCRC(fileIdx: int32) = # echo "FIRST CRC: ", fileIdx.ToFilename gMemCacheData[fileIdx].crc = crcFromFile(fileIdx.toFilename) -proc addDep(x: Psym, dep: int32) = +proc addDep(x: PSym, dep: int32) = growCache gMemCacheData, dep gMemCacheData[x.position].deps.safeAdd(dep) @@ -130,7 +130,7 @@ proc newModule(fileIdx: int32): PSym = incl(result.flags, sfUsed) initStrTable(result.tab) - StrTableAdd(result.tab, result) # a module knows itself + strTableAdd(result.tab, result) # a module knows itself proc compileModule*(fileIdx: int32, flags: TSymFlags): PSym = result = getModule(fileIdx) @@ -144,7 +144,7 @@ proc compileModule*(fileIdx: int32, flags: TSymFlags): PSym = if gCmd in {cmdCompileToC, cmdCompileToCpp, cmdCheck, cmdIdeTools}: rd = handleSymbolFile(result) if result.id < 0: - InternalError("handleSymbolFile should have set the module\'s ID") + internalError("handleSymbolFile should have set the module\'s ID") return else: result.id = getID() @@ -155,7 +155,7 @@ proc compileModule*(fileIdx: int32, flags: TSymFlags): PSym = doCRC fileIdx else: if checkDepMem(fileIdx) == Yes: - result = CompileModule(fileIdx, flags) + result = compileModule(fileIdx, flags) else: result = gCompiledModules[fileIdx] @@ -164,14 +164,14 @@ proc importModule*(s: PSym, fileIdx: int32): PSym {.procvar.} = result = compileModule(fileIdx, {}) if optCaasEnabled in gGlobalOptions: addDep(s, fileIdx) if sfSystemModule in result.flags: - LocalError(result.info, errAttemptToRedefine, result.Name.s) + localError(result.info, errAttemptToRedefine, result.name.s) proc includeModule*(s: PSym, fileIdx: int32): PNode {.procvar.} = result = syntaxes.parseFile(fileIdx) if optCaasEnabled in gGlobalOptions: growCache gMemCacheData, fileIdx addDep(s, fileIdx) - doCrc(fileIdx) + doCRC(fileIdx) proc `==^`(a, b: string): bool = try: @@ -180,17 +180,17 @@ proc `==^`(a, b: string): bool = result = false proc compileSystemModule* = - if magicsys.SystemModule == nil: - SystemFileIdx = fileInfoIdx(options.libpath/"system.nim") - discard CompileModule(SystemFileIdx, {sfSystemModule}) + if magicsys.systemModule == nil: + systemFileIdx = fileInfoIdx(options.libpath/"system.nim") + discard compileModule(systemFileIdx, {sfSystemModule}) -proc CompileProject*(projectFile = gProjectMainIdx) = +proc compileProject*(projectFile = gProjectMainIdx) = let systemFileIdx = fileInfoIdx(options.libpath / "system.nim") - if projectFile == SystemFileIdx: - discard CompileModule(projectFile, {sfMainModule, sfSystemModule}) + if projectFile == systemFileIdx: + discard compileModule(projectFile, {sfMainModule, sfSystemModule}) else: compileSystemModule() - discard CompileModule(projectFile, {sfMainModule}) + discard compileModule(projectFile, {sfMainModule}) var stdinModule: PSym proc makeStdinModule*(): PSym = diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 895ba71f3..d7944a182 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -93,6 +93,7 @@ type errNewSectionExpected, errWhitespaceExpected, errXisNoValidIndexFile, errCannotRenderX, errVarVarTypeNotAllowed, errInstantiateXExplicitely, errOnlyACallOpCanBeDelegator, errUsingNoSymbol, + errDestructorNotGenericEnough, errXExpectsTwoArguments, errXExpectsObjectTypes, errXcanNeverBeOfThisSubtype, errTooManyIterations, @@ -322,6 +323,8 @@ const errInstantiateXExplicitely: "instantiate '$1' explicitely", errOnlyACallOpCanBeDelegator: "only a call operator can be a delegator", errUsingNoSymbol: "'$1' is not a variable, constant or a proc name", + errDestructorNotGenericEnough: "Destructor signarue is too specific. " & + "A destructor must be associated will all instantiations of a generic type", errXExpectsTwoArguments: "\'$1\' expects two arguments", errXExpectsObjectTypes: "\'$1\' expects object types", errXcanNeverBeOfThisSubtype: "\'$1\' can never be of this subtype", @@ -445,7 +448,7 @@ type TErrorOutputs* = set[TErrorOutput] ERecoverableError* = object of EInvalidValue - ESuggestDone* = object of EBase + ESuggestDone* = object of E_Base const InvalidFileIDX* = int32(-1) @@ -453,9 +456,9 @@ const var filenameToIndexTbl = initTable[string, int32]() fileInfos*: seq[TFileInfo] = @[] - SystemFileIdx*: int32 + systemFileIdx*: int32 -proc toCChar*(c: Char): string = +proc toCChar*(c: char): string = case c of '\0'..'\x1F', '\x80'..'\xFF': result = '\\' & toOctal(c) of '\'', '\"', '\\': result = '\\' & c @@ -474,7 +477,7 @@ proc makeCString*(s: string): PRope = add(res, '\"') add(res, tnl) app(result, toRope(res)) # reset: - setlen(res, 1) + setLen(res, 1) res[0] = '\"' add(res, toCChar(s[i])) add(res, '\"') @@ -545,14 +548,14 @@ var when useCaas: var stdoutSocket*: TSocket -proc UnknownLineInfo*(): TLineInfo = +proc unknownLineInfo*(): TLineInfo = result.line = int16(-1) result.col = int16(-1) result.fileIndex = -1 var msgContext: seq[TLineInfo] = @[] - lastError = UnknownLineInfo() + lastError = unknownLineInfo() bufferedMsgs*: seq[string] errorOutputs* = {eStdOut, eStdErr} @@ -560,20 +563,20 @@ var proc clearBufferedMsgs* = bufferedMsgs = nil -proc SuggestWriteln*(s: string) = +proc suggestWriteln*(s: string) = if eStdOut in errorOutputs: when useCaas: - if isNil(stdoutSocket): Writeln(stdout, s) + if isNil(stdoutSocket): writeln(stdout, s) else: - Writeln(stdout, s) + writeln(stdout, s) stdoutSocket.send(s & "\c\L") else: - Writeln(stdout, s) + writeln(stdout, s) if eInMemory in errorOutputs: bufferedMsgs.safeAdd(s) -proc SuggestQuit*() = +proc suggestQuit*() = if not isServing: quit(0) elif isWorkingWithDirtyBuffer: @@ -601,12 +604,12 @@ proc pushInfoContext*(info: TLineInfo) = msgContext.add(info) proc popInfoContext*() = - setlen(msgContext, len(msgContext) - 1) + setLen(msgContext, len(msgContext) - 1) proc getInfoContext*(index: int): TLineInfo = let L = msgContext.len let i = if index < 0: L + index else: index - if i >=% L: result = UnknownLineInfo() + if i >=% L: result = unknownLineInfo() else: result = msgContext[i] proc toFilename*(fileIdx: int32): string = @@ -643,6 +646,8 @@ proc toFileLine*(info: TLineInfo): string {.inline.} = proc toFileLineCol*(info: TLineInfo): string {.inline.} = result = info.toFilename & "(" & $info.line & "," & $info.col & ")" +template `$`*(info: TLineInfo): expr = toFileLineCol(info) + proc `??`* (info: TLineInfo, filename: string): bool = # only for debugging purposes result = filename in info.toFilename @@ -656,18 +661,18 @@ proc addCheckpoint*(info: TLineInfo) = proc addCheckpoint*(filename: string, line: int) = addCheckpoint(newLineInfo(filename, line, - 1)) -proc OutWriteln*(s: string) = +proc outWriteln*(s: string) = ## Writes to stdout. Always. - if eStdOut in errorOutputs: Writeln(stdout, s) + if eStdOut in errorOutputs: writeln(stdout, s) -proc MsgWriteln*(s: string) = +proc msgWriteln*(s: string) = ## Writes to stdout. If --stdout option is given, writes to stderr instead. if gCmd == cmdIdeTools and optCDebug notin gGlobalOptions: return if optStdout in gGlobalOptions: - if eStdErr in errorOutputs: Writeln(stderr, s) + if eStdErr in errorOutputs: writeln(stderr, s) else: - if eStdOut in errorOutputs: Writeln(stdout, s) + if eStdOut in errorOutputs: writeln(stdout, s) if eInMemory in errorOutputs: bufferedMsgs.safeAdd(s) @@ -675,9 +680,9 @@ proc coordToStr(coord: int): string = if coord == -1: result = "???" else: result = $coord -proc MsgKindToString*(kind: TMsgKind): string = +proc msgKindToString*(kind: TMsgKind): string = # later versions may provide translated error messages - result = msgKindToStr[kind] + result = MsgKindToStr[kind] proc getMessageStr(msg: TMsgKind, arg: string): string = result = msgKindToString(msg) % [arg] @@ -699,23 +704,20 @@ type TErrorHandling = enum doNothing, doAbort, doRaise proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) = - template maybeTrace = - if defined(debug) or gVerbosity >= 3: + template quit = + if defined(debug) or gVerbosity >= 3 or msg == errInternal: writeStackTrace() + quit 1 - if msg == errInternal: - writeStackTrace() # we always want a stack trace here if msg >= fatalMin and msg <= fatalMax: - maybeTrace() - quit(1) + quit() if msg >= errMin and msg <= errMax: - maybeTrace() inc(gErrorCounter) options.gExitcode = 1'i8 if gErrorCounter >= gErrorMax: - quit(1) + quit() elif eh == doAbort and gCmd != cmdIdeTools: - quit(1) + quit() elif eh == doRaise: raiseRecoverableError(s) @@ -723,34 +725,34 @@ proc `==`*(a, b: TLineInfo): bool = result = a.line == b.line and a.fileIndex == b.fileIndex proc writeContext(lastinfo: TLineInfo) = - var info = lastInfo + var info = lastinfo for i in countup(0, len(msgContext) - 1): - if msgContext[i] != lastInfo and msgContext[i] != info: - MsgWriteln(posContextFormat % [toMsgFilename(msgContext[i]), + if msgContext[i] != lastinfo and msgContext[i] != info: + msgWriteln(PosContextFormat % [toMsgFilename(msgContext[i]), coordToStr(msgContext[i].line), coordToStr(msgContext[i].col), getMessageStr(errInstantiationFrom, "")]) info = msgContext[i] -proc rawMessage*(msg: TMsgKind, args: openarray[string]) = +proc rawMessage*(msg: TMsgKind, args: openArray[string]) = var frmt: string case msg of errMin..errMax: writeContext(unknownLineInfo()) - frmt = rawErrorFormat + frmt = RawErrorFormat of warnMin..warnMax: if optWarns notin gOptions: return if msg notin gNotes: return writeContext(unknownLineInfo()) - frmt = rawWarningFormat + frmt = RawWarningFormat inc(gWarnCounter) of hintMin..hintMax: if optHints notin gOptions: return if msg notin gNotes: return - frmt = rawHintFormat + frmt = RawHintFormat inc(gHintCounter) let s = `%`(frmt, `%`(msgKindToString(msg), args)) - MsgWriteln(s) + msgWriteln(s) handleError(msg, doAbort, s) proc rawMessage*(msg: TMsgKind, arg: string) = @@ -758,8 +760,8 @@ proc rawMessage*(msg: TMsgKind, arg: string) = proc writeSurroundingSrc(info: TLineInfo) = const indent = " " - MsgWriteln(indent & info.sourceLine.ropeToStr) - MsgWriteln(indent & repeatChar(info.col, ' ') & '^') + msgWriteln(indent & info.sourceLine.ropeToStr) + msgWriteln(indent & repeatChar(info.col, ' ') & '^') proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string, eh: TErrorHandling) = @@ -768,7 +770,7 @@ proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string, case msg of errMin..errMax: writeContext(info) - frmt = posErrorFormat + frmt = PosErrorFormat # we try to filter error messages so that not two error message # in the same file and line are produced: #ignoreMsg = lastError == info and eh != doAbort @@ -776,54 +778,54 @@ proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string, of warnMin..warnMax: ignoreMsg = optWarns notin gOptions or msg notin gNotes if not ignoreMsg: writeContext(info) - frmt = posWarningFormat + frmt = PosWarningFormat inc(gWarnCounter) of hintMin..hintMax: ignoreMsg = optHints notin gOptions or msg notin gNotes - frmt = posHintFormat + frmt = PosHintFormat inc(gHintCounter) let s = frmt % [toMsgFilename(info), coordToStr(info.line), coordToStr(info.col), getMessageStr(msg, arg)] if not ignoreMsg: - MsgWriteln(s) + msgWriteln(s) if optPrintSurroundingSrc and msg in errMin..errMax: info.writeSurroundingSrc handleError(msg, eh, s) -proc Fatal*(info: TLineInfo, msg: TMsgKind, arg = "") = +proc fatal*(info: TLineInfo, msg: TMsgKind, arg = "") = liMessage(info, msg, arg, doAbort) -proc GlobalError*(info: TLineInfo, msg: TMsgKind, arg = "") = +proc globalError*(info: TLineInfo, msg: TMsgKind, arg = "") = liMessage(info, msg, arg, doRaise) -proc GlobalError*(info: TLineInfo, arg: string) = +proc globalError*(info: TLineInfo, arg: string) = liMessage(info, errGenerated, arg, doRaise) -proc LocalError*(info: TLineInfo, msg: TMsgKind, arg = "") = +proc localError*(info: TLineInfo, msg: TMsgKind, arg = "") = liMessage(info, msg, arg, doNothing) -proc LocalError*(info: TLineInfo, arg: string) = +proc localError*(info: TLineInfo, arg: string) = liMessage(info, errGenerated, arg, doNothing) -proc Message*(info: TLineInfo, msg: TMsgKind, arg = "") = +proc message*(info: TLineInfo, msg: TMsgKind, arg = "") = liMessage(info, msg, arg, doNothing) -proc InternalError*(info: TLineInfo, errMsg: string) = +proc internalError*(info: TLineInfo, errMsg: string) = if gCmd == cmdIdeTools: return writeContext(info) liMessage(info, errInternal, errMsg, doAbort) -proc InternalError*(errMsg: string) = +proc internalError*(errMsg: string) = if gCmd == cmdIdeTools: return - writeContext(UnknownLineInfo()) + writeContext(unknownLineInfo()) rawMessage(errInternal, errMsg) -template AssertNotNil*(e: expr): expr = - if e == nil: InternalError($InstantiationInfo()) +template assertNotNil*(e: expr): expr = + if e == nil: internalError($instantiationInfo()) e -template InternalAssert*(e: bool): stmt = - if not e: InternalError($InstantiationInfo()) +template internalAssert*(e: bool): stmt = + if not e: internalError($instantiationInfo()) proc addSourceLine*(fileIdx: int32, line: string) = fileInfos[fileIdx].lines.add line.toRope @@ -837,17 +839,17 @@ proc sourceLine*(i: TLineInfo): PRope = addSourceLine i.fileIndex, line.string except EIO: discard - InternalAssert i.fileIndex < fileInfos.len + internalAssert i.fileIndex < fileInfos.len # can happen if the error points to EOF: if i.line > fileInfos[i.fileIndex].lines.len: return nil result = fileInfos[i.fileIndex].lines[i.line-1] proc quotedFilename*(i: TLineInfo): PRope = - InternalAssert i.fileIndex >= 0 + internalAssert i.fileIndex >= 0 result = fileInfos[i.fileIndex].quotedName -ropes.ErrorHandler = proc (err: TRopesError, msg: string, useWarning: bool) = +ropes.errorHandler = proc (err: TRopesError, msg: string, useWarning: bool) = case err of rInvalidFormatStr: internalError("ropes: invalid format string: " & msg) diff --git a/compiler/nimconf.nim b/compiler/nimconf.nim index 7ec566a01..2bdfbe0b8 100644 --- a/compiler/nimconf.nim +++ b/compiler/nimconf.nim @@ -49,7 +49,7 @@ proc parseExpr(L: var TLexer, tok: var TToken): bool = var b = parseAndExpr(L, tok) result = result or b -proc EvalppIf(L: var TLexer, tok: var TToken): bool = +proc evalppIf(L: var TLexer, tok: var TToken): bool = ppGetTok(L, tok) # skip 'if' or 'elif' result = parseExpr(L, tok) if tok.tokType == tkColon: ppGetTok(L, tok) @@ -60,7 +60,7 @@ var condStack: seq[bool] = @[] proc doEnd(L: var TLexer, tok: var TToken) = if high(condStack) < 0: lexMessage(L, errTokenExpected, "@if") ppGetTok(L, tok) # skip 'end' - setlen(condStack, high(condStack)) + setLen(condStack, high(condStack)) type TJumpDest = enum @@ -75,18 +75,18 @@ proc doElse(L: var TLexer, tok: var TToken) = proc doElif(L: var TLexer, tok: var TToken) = if high(condStack) < 0: lexMessage(L, errTokenExpected, "@if") - var res = EvalppIf(L, tok) + var res = evalppIf(L, tok) if condStack[high(condStack)] or not res: jumpToDirective(L, tok, jdElseEndif) else: condStack[high(condStack)] = true proc jumpToDirective(L: var TLexer, tok: var TToken, dest: TJumpDest) = var nestedIfs = 0 - while True: + while true: if (tok.ident != nil) and (tok.ident.s == "@"): ppGetTok(L, tok) case whichKeyword(tok.ident) of wIf: - Inc(nestedIfs) + inc(nestedIfs) of wElse: if (dest == jdElseEndif) and (nestedIfs == 0): doElse(L, tok) @@ -99,7 +99,7 @@ proc jumpToDirective(L: var TLexer, tok: var TToken, dest: TJumpDest) = if nestedIfs == 0: doEnd(L, tok) break - if nestedIfs > 0: Dec(nestedIfs) + if nestedIfs > 0: dec(nestedIfs) else: nil ppGetTok(L, tok) @@ -112,8 +112,8 @@ proc parseDirective(L: var TLexer, tok: var TToken) = ppGetTok(L, tok) # skip @ case whichKeyword(tok.ident) of wIf: - setlen(condStack, len(condStack) + 1) - var res = EvalppIf(L, tok) + setLen(condStack, len(condStack) + 1) + var res = evalppIf(L, tok) condStack[high(condStack)] = res if not res: jumpToDirective(L, tok, jdElseEndif) of wElif: doElif(L, tok) @@ -121,7 +121,7 @@ proc parseDirective(L: var TLexer, tok: var TToken) = of wEnd: doEnd(L, tok) of wWrite: ppGetTok(L, tok) - msgs.MsgWriteln(tokToStr(tok)) + msgs.msgWriteln(tokToStr(tok)) ppGetTok(L, tok) else: case tok.ident.s.normalize @@ -135,13 +135,13 @@ proc parseDirective(L: var TLexer, tok: var TToken) = ppGetTok(L, tok) var key = tokToStr(tok) ppGetTok(L, tok) - os.putEnv(key, tokToStr(tok) & os.getenv(key)) + os.putEnv(key, tokToStr(tok) & os.getEnv(key)) ppGetTok(L, tok) of "appendenv": ppGetTok(L, tok) var key = tokToStr(tok) ppGetTok(L, tok) - os.putEnv(key, os.getenv(key) & tokToStr(tok)) + os.putEnv(key, os.getEnv(key) & tokToStr(tok)) ppGetTok(L, tok) else: lexMessage(L, errInvalidDirectiveX, tokToStr(tok)) @@ -196,7 +196,7 @@ proc readConfigFile(filename: string) = L: TLexer tok: TToken stream: PLLStream - stream = LLStreamOpen(filename, fmRead) + stream = llStreamOpen(filename, fmRead) if stream != nil: initToken(tok) openLexer(L, filename, stream) @@ -219,7 +219,7 @@ proc getSystemConfigPath(filename: string): string = if not existsFile(result): result = joinPath([p, "etc", filename]) if not existsFile(result): result = "/etc/" & filename -proc LoadConfigs*(cfg: string) = +proc loadConfigs*(cfg: string) = # set default value (can be overwritten): if libpath == "": # choose default libpath: diff --git a/compiler/nimlexbase.nim b/compiler/nimlexbase.nim index 6d45a825a..038573c35 100644 --- a/compiler/nimlexbase.nim +++ b/compiler/nimlexbase.nim @@ -42,7 +42,7 @@ type buf*: cstring bufLen*: int # length of buffer in characters stream*: PLLStream # we read from this stream - LineNumber*: int # the current line number + lineNumber*: int # the current line number # private data: sentinel*: int lineStart*: int # index of last line start in buffer @@ -54,11 +54,11 @@ proc openBaseLexer*(L: var TBaseLexer, inputstream: PLLStream, proc closeBaseLexer*(L: var TBaseLexer) proc getCurrentLine*(L: TBaseLexer, marker: bool = true): string proc getColNumber*(L: TBaseLexer, pos: int): int -proc HandleCR*(L: var TBaseLexer, pos: int): int +proc handleCR*(L: var TBaseLexer, pos: int): int # Call this if you scanned over CR in the buffer; it returns the # position to continue the scanning from. `pos` must be the position # of the CR. -proc HandleLF*(L: var TBaseLexer, pos: int): int +proc handleLF*(L: var TBaseLexer, pos: int): int # Call this if you scanned over LF in the buffer; it returns the the # position to continue the scanning from. `pos` must be the position # of the LF. @@ -69,9 +69,9 @@ const proc closeBaseLexer(L: var TBaseLexer) = dealloc(L.buf) - LLStreamClose(L.stream) + llStreamClose(L.stream) -proc FillBuffer(L: var TBaseLexer) = +proc fillBuffer(L: var TBaseLexer) = var charsRead, toCopy, s: int # all are in characters, # not bytes (in case this @@ -80,12 +80,12 @@ proc FillBuffer(L: var TBaseLexer) = # we know here that pos == L.sentinel, but not if this proc # is called the first time by initBaseLexer() assert(L.sentinel < L.bufLen) - toCopy = L.BufLen - L.sentinel - 1 + toCopy = L.bufLen - L.sentinel - 1 assert(toCopy >= 0) if toCopy > 0: - MoveMem(L.buf, addr(L.buf[L.sentinel + 1]), toCopy * chrSize) + moveMem(L.buf, addr(L.buf[L.sentinel + 1]), toCopy * chrSize) # "moveMem" handles overlapping regions - charsRead = LLStreamRead(L.stream, addr(L.buf[toCopy]), + charsRead = llStreamRead(L.stream, addr(L.buf[toCopy]), (L.sentinel + 1) * chrSize) div chrSize s = toCopy + charsRead if charsRead < L.sentinel + 1: @@ -96,7 +96,7 @@ proc FillBuffer(L: var TBaseLexer) = dec(s) # BUGFIX (valgrind) while true: assert(s < L.bufLen) - while (s >= 0) and not (L.buf[s] in NewLines): Dec(s) + while (s >= 0) and not (L.buf[s] in NewLines): dec(s) if s >= 0: # we found an appropriate character for a sentinel: L.sentinel = s @@ -104,11 +104,11 @@ proc FillBuffer(L: var TBaseLexer) = else: # rather than to give up here because the line is too long, # double the buffer's size and try again: - oldBufLen = L.BufLen - L.bufLen = L.BufLen * 2 + oldBufLen = L.bufLen + L.bufLen = L.bufLen * 2 L.buf = cast[cstring](realloc(L.buf, L.bufLen * chrSize)) - assert(L.bufLen - oldBuflen == oldBufLen) - charsRead = LLStreamRead(L.stream, addr(L.buf[oldBufLen]), + assert(L.bufLen - oldBufLen == oldBufLen) + charsRead = llStreamRead(L.stream, addr(L.buf[oldBufLen]), oldBufLen * chrSize) div chrSize if charsRead < oldBufLen: L.buf[oldBufLen + charsRead] = EndOfFile @@ -126,20 +126,20 @@ proc fillBaseLexer(L: var TBaseLexer, pos: int): int = result = 0 L.lineStart = result -proc HandleCR(L: var TBaseLexer, pos: int): int = +proc handleCR(L: var TBaseLexer, pos: int): int = assert(L.buf[pos] == CR) - inc(L.linenumber) + inc(L.lineNumber) result = fillBaseLexer(L, pos) if L.buf[result] == LF: result = fillBaseLexer(L, result) -proc HandleLF(L: var TBaseLexer, pos: int): int = +proc handleLF(L: var TBaseLexer, pos: int): int = assert(L.buf[pos] == LF) - inc(L.linenumber) + inc(L.lineNumber) result = fillBaseLexer(L, pos) #L.lastNL := result-1; // BUGFIX: was: result; -proc skip_UTF_8_BOM(L: var TBaseLexer) = - if (L.buf[0] == '\xEF') and (L.buf[1] == '\xBB') and (L.buf[2] == '\xBF'): +proc skipUTF8BOM(L: var TBaseLexer) = + if L.buf[0] == '\xEF' and L.buf[1] == '\xBB' and L.buf[2] == '\xBF': inc(L.bufpos, 3) inc(L.lineStart, 3) @@ -150,10 +150,10 @@ proc openBaseLexer(L: var TBaseLexer, inputstream: PLLStream, bufLen = 8192) = L.buf = cast[cstring](alloc(bufLen * chrSize)) L.sentinel = bufLen - 1 L.lineStart = 0 - L.linenumber = 1 # lines start at 1 + L.lineNumber = 1 # lines start at 1 L.stream = inputstream fillBuffer(L) - skip_UTF_8_BOM(L) + skipUTF8BOM(L) proc getColNumber(L: TBaseLexer, pos: int): int = result = abs(pos - L.lineStart) @@ -166,5 +166,4 @@ proc getCurrentLine(L: TBaseLexer, marker: bool = true): string = inc(i) result.add("\n") if marker: - result.add(RepeatChar(getColNumber(L, L.bufpos)) & '^' & "\n") - + result.add(repeatChar(getColNumber(L, L.bufpos)) & '^' & "\n") diff --git a/compiler/nimrod.nim b/compiler/nimrod.nim index 2bc94e3f8..38d440ade 100644 --- a/compiler/nimrod.nim +++ b/compiler/nimrod.nim @@ -31,12 +31,12 @@ proc prependCurDir(f: string): string = else: result = f -proc HandleCmdLine() = +proc handleCmdLine() = if paramCount() == 0: writeCommandLineUsage() else: # Process command line arguments: - ProcessCmdLine(passCmd1, "") + processCmdLine(passCmd1, "") if gProjectName != "": try: gProjectFull = canonicalizePath(gProjectName) @@ -47,12 +47,12 @@ proc HandleCmdLine() = gProjectName = p.name else: gProjectPath = getCurrentDir() - LoadConfigs(DefaultConfig) # load all config files + loadConfigs(DefaultConfig) # load all config files # now process command line arguments again, because some options in the # command line can overwite the config file's settings extccomp.initVars() - ProcessCmdLine(passCmd2, "") - MainCommand() + processCmdLine(passCmd2, "") + mainCommand() if gVerbosity >= 2: echo(GC_getStatistics()) #echo(GC_getStatistics()) if msgs.gErrorCounter == 0: @@ -71,7 +71,7 @@ proc HandleCmdLine() = binPath = options.outFile.prependCurDir else: # Figure out ourselves a valid binary name. - binPath = changeFileExt(gProjectFull, exeExt).prependCurDir + binPath = changeFileExt(gProjectFull, ExeExt).prependCurDir var ex = quoteShell(binPath) execExternalProgram(ex & ' ' & service.arguments) @@ -81,8 +81,8 @@ when defined(GC_setMaxPause): when compileOption("gc", "v2") or compileOption("gc", "refc"): # the new correct mark&sweet collector is too slow :-/ GC_disableMarkAndSweep() -condsyms.InitDefines() +condsyms.initDefines() when not defined(selftest): - HandleCmdLine() + handleCmdLine() quit(int8(msgs.gErrorCounter > 0)) diff --git a/compiler/nimrod.nimrod.cfg b/compiler/nimrod.nimrod.cfg index 9fa1b8cba..b2ae97686 100644 --- a/compiler/nimrod.nimrod.cfg +++ b/compiler/nimrod.nimrod.cfg @@ -13,3 +13,6 @@ path:"$lib/packages/docutils" define:booting import:testability +@if windows: + cincludes: "$lib/wrappers/libffi/common" +@end diff --git a/compiler/nimsets.nim b/compiler/nimsets.nim index 34f79e14b..d65618e0a 100644 --- a/compiler/nimsets.nim +++ b/compiler/nimsets.nim @@ -18,7 +18,7 @@ proc overlap*(a, b: PNode): bool proc inSet*(s: PNode, elem: PNode): bool proc someInSet*(s: PNode, a, b: PNode): bool proc emptyRange*(a, b: PNode): bool -proc SetHasRange*(s: PNode): bool +proc setHasRange*(s: PNode): bool # returns true if set contains a range (needed by the code generator) # these are used for constant folding: proc unionSets*(a, b: PNode): PNode @@ -32,7 +32,7 @@ proc cardSet*(s: PNode): BiggestInt proc inSet(s: PNode, elem: PNode): bool = if s.kind != nkCurly: - InternalError(s.info, "inSet") + internalError(s.info, "inSet") return false for i in countup(0, sonsLen(s) - 1): if s.sons[i].kind == nkRange: @@ -58,10 +58,10 @@ proc overlap(a, b: PNode): bool = else: result = sameValue(a, b) -proc SomeInSet(s: PNode, a, b: PNode): bool = +proc someInSet(s: PNode, a, b: PNode): bool = # checks if some element of a..b is in the set s if s.kind != nkCurly: - InternalError(s.info, "SomeInSet") + internalError(s.info, "SomeInSet") return false for i in countup(0, sonsLen(s) - 1): if s.sons[i].kind == nkRange: @@ -82,12 +82,12 @@ proc toBitSet(s: PNode, b: var TBitSet) = if s.sons[i].kind == nkRange: j = getOrdValue(s.sons[i].sons[0]) while j <= getOrdValue(s.sons[i].sons[1]): - BitSetIncl(b, j - first) + bitSetIncl(b, j - first) inc(j) else: - BitSetIncl(b, getOrdValue(s.sons[i]) - first) + bitSetIncl(b, getOrdValue(s.sons[i]) - first) -proc ToTreeSet(s: TBitSet, settype: PType, info: TLineInfo): PNode = +proc toTreeSet(s: TBitSet, settype: PType, info: TLineInfo): PNode = var a, b, e, first: BiggestInt # a, b are interval borders elemType: PType @@ -98,14 +98,14 @@ proc ToTreeSet(s: TBitSet, settype: PType, info: TLineInfo): PNode = result.typ = settype result.info = info e = 0 - while e < len(s) * elemSize: + while e < len(s) * ElemSize: if bitSetIn(s, e): a = e b = e while true: - Inc(b) - if (b >= len(s) * elemSize) or not bitSetIn(s, b): break - Dec(b) + inc(b) + if (b >= len(s) * ElemSize) or not bitSetIn(s, b): break + dec(b) if a == b: addSon(result, newIntTypeNode(nkIntLit, a + first, elemType)) else: @@ -115,7 +115,7 @@ proc ToTreeSet(s: TBitSet, settype: PType, info: TLineInfo): PNode = addSon(n, newIntTypeNode(nkIntLit, b + first, elemType)) addSon(result, n) e = b - Inc(e) + inc(e) template nodeSetOp(a, b: PNode, op: expr) {.dirty.} = var x, y: TBitSet @@ -124,10 +124,10 @@ template nodeSetOp(a, b: PNode, op: expr) {.dirty.} = op(x, y) result = toTreeSet(x, a.typ, a.info) -proc unionSets(a, b: PNode): PNode = nodeSetOp(a, b, BitSetUnion) -proc diffSets(a, b: PNode): PNode = nodeSetOp(a, b, BitSetDiff) -proc intersectSets(a, b: PNode): PNode = nodeSetOp(a, b, BitSetIntersect) -proc symdiffSets(a, b: PNode): PNode = nodeSetOp(a, b, BitSetSymDiff) +proc unionSets(a, b: PNode): PNode = nodeSetOp(a, b, bitSetUnion) +proc diffSets(a, b: PNode): PNode = nodeSetOp(a, b, bitSetDiff) +proc intersectSets(a, b: PNode): PNode = nodeSetOp(a, b, bitSetIntersect) +proc symdiffSets(a, b: PNode): PNode = nodeSetOp(a, b, bitSetSymDiff) proc containsSets(a, b: PNode): bool = var x, y: TBitSet @@ -156,11 +156,11 @@ proc cardSet(s: PNode): BiggestInt = result = result + getOrdValue(s.sons[i].sons[1]) - getOrdValue(s.sons[i].sons[0]) + 1 else: - Inc(result) + inc(result) -proc SetHasRange(s: PNode): bool = +proc setHasRange(s: PNode): bool = if s.kind != nkCurly: - InternalError(s.info, "SetHasRange") + internalError(s.info, "SetHasRange") return false for i in countup(0, sonsLen(s) - 1): if s.sons[i].kind == nkRange: diff --git a/compiler/options.nim b/compiler/options.nim index c62744485..4f642e626 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -143,7 +143,7 @@ const # additional configuration variables: var gConfigVars* = newStringTable(modeStyleInsensitive) - gDllOverrides = newStringtable(modeCaseInsensitive) + gDllOverrides = newStringTable(modeCaseInsensitive) libpath* = "" gProjectName* = "" # holds a name like 'nimrod' gProjectPath* = "" # holds a path like /home/alice/projects/nimrod/compiler/ @@ -159,8 +159,6 @@ var const oKeepVariableNames* = true -const oUseLateInstantiation* = false - proc mainCommandArg*: string = ## This is intended for commands like check or parse ## which will work on the main project file unless @@ -185,7 +183,7 @@ proc getOutFile*(filename, ext: string): string = proc getPrefixDir*(): string = ## gets the application directory - result = SplitPath(getAppDir()).head + result = splitPath(getAppDir()).head proc canonicalizePath*(path: string): string = result = path.expandFilename @@ -193,16 +191,16 @@ proc canonicalizePath*(path: string): string = proc shortenDir*(dir: string): string = ## returns the interesting part of a dir - var prefix = getPrefixDir() & dirSep + var prefix = getPrefixDir() & DirSep if startsWith(dir, prefix): return substr(dir, len(prefix)) - prefix = gProjectPath & dirSep + prefix = gProjectPath & DirSep if startsWith(dir, prefix): return substr(dir, len(prefix)) result = dir proc removeTrailingDirSep*(path: string): string = - if (len(path) > 0) and (path[len(path) - 1] == dirSep): + if (len(path) > 0) and (path[len(path) - 1] == DirSep): result = substr(path, 0, len(path) - 2) else: result = path @@ -214,9 +212,9 @@ proc getGeneratedPath: string = proc getPackageName*(path: string): string = var q = 1 var b = 0 - if path[len(path)-1] in {dirsep, altsep}: q = 2 + if path[len(path)-1] in {DirSep, AltSep}: q = 2 for i in countdown(len(path)-q, 0): - if path[i] in {dirsep, altsep}: + if path[i] in {DirSep, AltSep}: if b == 0: b = i else: let x = path.substr(i+1, b-1) @@ -255,15 +253,15 @@ proc completeGeneratedFilePath*(f: string, createSubDir: bool = true): string = result = joinPath(subdir, tail) #echo "completeGeneratedFilePath(", f, ") = ", result -iterator iterSearchPath*(SearchPaths: TLinkedList): string = - var it = PStrEntry(SearchPaths.head) +iterator iterSearchPath*(searchPaths: TLinkedList): string = + var it = PStrEntry(searchPaths.head) while it != nil: yield it.data - it = PStrEntry(it.Next) + it = PStrEntry(it.next) proc rawFindFile(f: string): string = - for it in iterSearchPath(SearchPaths): - result = JoinPath(it, f) + for it in iterSearchPath(searchPaths): + result = joinPath(it, f) if existsFile(result): return result.canonicalizePath result = "" @@ -271,14 +269,14 @@ proc rawFindFile(f: string): string = proc rawFindFile2(f: string): string = var it = PStrEntry(lazyPaths.head) while it != nil: - result = JoinPath(it.data, f) + result = joinPath(it.data, f) if existsFile(result): bringToFront(lazyPaths, it) return result.canonicalizePath - it = PStrEntry(it.Next) + it = PStrEntry(it.next) result = "" -proc FindFile*(f: string): string {.procvar.} = +proc findFile*(f: string): string {.procvar.} = result = f.rawFindFile if result.len == 0: result = f.toLower.rawFindFile @@ -289,11 +287,11 @@ proc FindFile*(f: string): string {.procvar.} = proc findModule*(modulename, currentModule: string): string = # returns path to module - let m = addFileExt(modulename, nimExt) + let m = addFileExt(modulename, NimExt) let currentPath = currentModule.splitFile.dir result = currentPath / m if not existsFile(result): - result = FindFile(m) + result = findFile(m) proc libCandidates*(s: string, dest: var seq[string]) = var le = strutils.find(s, '(') @@ -320,7 +318,7 @@ proc inclDynlibOverride*(lib: string) = proc isDynlibOverride*(lib: string): bool = result = gDllOverrides.hasKey(lib.canonDynlibName) -proc binaryStrSearch*(x: openarray[string], y: string): int = +proc binaryStrSearch*(x: openArray[string], y: string): int = var a = 0 var b = len(x) - 1 while a <= b: diff --git a/compiler/parampatterns.nim b/compiler/parampatterns.nim index 283f83906..e94068776 100644 --- a/compiler/parampatterns.nim +++ b/compiler/parampatterns.nim @@ -42,7 +42,7 @@ const MaxStackSize* = 64 ## max required stack size by the VM proc patternError(n: PNode) = - LocalError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments})) + localError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments})) proc add(code: var TPatternCode, op: TOpcode) {.inline.} = add(code, chr(ord(op))) @@ -97,14 +97,14 @@ proc compileConstraints(p: PNode, result: var TPatternCode) = of "nosideeffect": result.add(ppNoSideEffect) else: # check all symkinds: - InternalAssert int(high(TSymKind)) < 255 + internalAssert int(high(TSymKind)) < 255 for i in low(TSymKind)..high(TSymKind): if cmpIgnoreStyle(($i).substr(2), spec) == 0: result.add(ppSymKind) result.add(chr(i.ord)) return # check all nodekinds: - InternalAssert int(high(TNodeKind)) < 255 + internalAssert int(high(TNodeKind)) < 255 for i in low(TNodeKind)..high(TNodeKind): if cmpIgnoreStyle($i, spec) == 0: result.add(ppNodeKind) @@ -124,8 +124,8 @@ proc semNodeKindConstraints*(p: PNode): PNode = if p.len >= 2: for i in 1.. <p.len: compileConstraints(p.sons[i], result.strVal) - if result.strVal.len > maxStackSize-1: - InternalError(p.info, "parameter pattern too complex") + if result.strVal.len > MaxStackSize-1: + internalError(p.info, "parameter pattern too complex") else: patternError(p) result.strVal.add(ppEof) @@ -216,12 +216,12 @@ proc isAssignable*(owner: PSym, n: PNode): TAssignableResult = of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr: result = isAssignable(owner, n.sons[0]) else: - nil + discard proc matchNodeKinds*(p, n: PNode): bool = # matches the parameter constraint 'p' against the concrete AST 'n'. # Efficiency matters here. - var stack {.noinit.}: array[0..maxStackSize, bool] + var stack {.noinit.}: array[0..MaxStackSize, bool] # empty patterns are true: stack[0] = true var sp = 1 diff --git a/compiler/parser.nim b/compiler/parser.nim index fd51b04ec..e7a15c8ab 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -35,7 +35,7 @@ type lex*: TLexer # the lexer that is used for parsing tok*: TToken # the current token -proc ParseAll*(p: var TParser): PNode +proc parseAll*(p: var TParser): PNode proc openParser*(p: var TParser, filename: string, inputstream: PLLStream) proc closeParser*(p: var TParser) proc parseTopLevelStmt*(p: var TParser): PNode @@ -59,9 +59,9 @@ proc newFloatNodeP*(kind: TNodeKind, floatVal: BiggestFloat, p: TParser): PNode proc newStrNodeP*(kind: TNodeKind, strVal: string, p: TParser): PNode proc newIdentNodeP*(ident: PIdent, p: TParser): PNode proc expectIdentOrKeyw*(p: TParser) -proc ExpectIdent*(p: TParser) +proc expectIdent*(p: TParser) proc parLineInfo*(p: TParser): TLineInfo -proc Eat*(p: var TParser, TokType: TTokType) +proc eat*(p: var TParser, tokType: TTokType) proc skipInd*(p: var TParser) proc optPar*(p: var TParser) proc optInd*(p: var TParser, n: PNode) @@ -75,17 +75,17 @@ proc parseCase(p: var TParser): PNode proc getTok(p: var TParser) = rawGetTok(p.lex, p.tok) -proc OpenParser*(p: var TParser, fileIdx: int32, inputStream: PLLStream) = +proc openParser*(p: var TParser, fileIdx: int32, inputStream: PLLStream) = initToken(p.tok) - OpenLexer(p.lex, fileIdx, inputstream) + openLexer(p.lex, fileIdx, inputStream) getTok(p) # read the first token p.firstTok = true -proc OpenParser*(p: var TParser, filename: string, inputStream: PLLStream) = - openParser(p, filename.fileInfoIdx, inputStream) +proc openParser*(p: var TParser, filename: string, inputStream: PLLStream) = + openParser(p, filename.fileInfoIdx, inputstream) -proc CloseParser(p: var TParser) = - CloseLexer(p.lex) +proc closeParser(p: var TParser) = + closeLexer(p.lex) proc parMessage(p: TParser, msg: TMsgKind, arg: string = "") = lexMessage(p.lex, msg, arg) @@ -135,12 +135,12 @@ proc expectIdentOrKeyw(p: TParser) = if p.tok.tokType != tkSymbol and not isKeyword(p.tok.tokType): lexMessage(p.lex, errIdentifierExpected, prettyTok(p.tok)) -proc ExpectIdent(p: TParser) = +proc expectIdent(p: TParser) = if p.tok.tokType != tkSymbol: lexMessage(p.lex, errIdentifierExpected, prettyTok(p.tok)) -proc Eat(p: var TParser, TokType: TTokType) = - if p.tok.TokType == TokType: getTok(p) +proc eat(p: var TParser, tokType: TTokType) = + if p.tok.tokType == tokType: getTok(p) else: lexMessage(p.lex, errTokenExpected, TokTypeToStr[tokType]) proc parLineInfo(p: TParser): TLineInfo = @@ -185,10 +185,10 @@ proc relevantOprChar(ident: PIdent): char {.inline.} = if result == '\\' and L > 1: result = ident.s[1] -proc IsSigilLike(tok: TToken): bool {.inline.} = +proc isSigilLike(tok: TToken): bool {.inline.} = result = tok.tokType == tkOpr and relevantOprChar(tok.ident) == '@' -proc IsLeftAssociative(tok: TToken): bool {.inline.} = +proc isLeftAssociative(tok: TToken): bool {.inline.} = result = tok.tokType != tkOpr or relevantOprChar(tok.ident) != '^' proc getPrecedence(tok: TToken): int = @@ -211,7 +211,7 @@ proc getPrecedence(tok: TToken): int = of '?': result = 2 else: considerAsgn(2) of tkDiv, tkMod, tkShl, tkShr: result = 9 - of tkIn, tkNotIn, tkIs, tkIsNot, tkNot, tkOf, tkAs: result = 5 + of tkIn, tkNotin, tkIs, tkIsnot, tkNot, tkOf, tkAs: result = 5 of tkDotDot: result = 6 of tkAnd: result = 4 of tkOr, tkXor: result = 3 @@ -427,7 +427,7 @@ proc parseCast(p: var TParser): PNode = proc setBaseFlags(n: PNode, base: TNumericalBase) = case base - of base10: nil + of base10: discard of base2: incl(n.flags, nfBase2) of base8: incl(n.flags, nfBase8) of base16: incl(n.flags, nfBase16) @@ -455,7 +455,7 @@ proc simpleExpr(p: var TParser, mode = pmNormal): PNode proc semiStmtList(p: var TParser, result: PNode) = result.add(complexOrSimpleStmt(p)) - while p.tok.tokType == tkSemicolon: + while p.tok.tokType == tkSemiColon: getTok(p) optInd(p, result) result.add(complexOrSimpleStmt(p)) @@ -482,7 +482,7 @@ proc parsePar(p: var TParser): PNode = # XXX 'bind' used to be an expression, so we exclude it here; # tests/reject/tbind2 fails otherwise. semiStmtList(p, result) - elif p.tok.tokType == tkSemicolon: + elif p.tok.tokType == tkSemiColon: # '(;' enforces 'stmt' context: getTok(p) optInd(p, result) @@ -498,7 +498,7 @@ proc parsePar(p: var TParser): PNode = asgn.sons[0] = a asgn.sons[1] = b result.add(asgn) - elif p.tok.tokType == tkSemicolon: + elif p.tok.tokType == tkSemiColon: # stmt context: result.add(a) semiStmtList(p, result) @@ -672,7 +672,7 @@ proc simpleExprAux(p: var TParser, limit: int, mode: TPrimaryMode): PNode = let modeB = if mode == pmTypeDef: pmTypeDesc else: mode # the operator itself must not start on a new line: while opPrec >= limit and p.tok.indent < 0: - var leftAssoc = ord(IsLeftAssociative(p.tok)) + var leftAssoc = ord(isLeftAssociative(p.tok)) var a = newNodeP(nkInfix, p) var opNode = newIdentNodeP(p.tok.ident, p) # skip operator: getTok(p) @@ -798,7 +798,7 @@ proc parseTuple(p: var TParser, indentAllowed = false): PNode = while p.tok.tokType in {tkSymbol, tkAccent}: var a = parseIdentColonEquals(p, {}) addSon(result, a) - if p.tok.tokType notin {tkComma, tkSemicolon}: break + if p.tok.tokType notin {tkComma, tkSemiColon}: break getTok(p) skipComment(p, a) optPar(p) @@ -840,13 +840,13 @@ proc parseParamList(p: var TParser, retColon = true): PNode = parMessage(p, errTokenExpected, ")") break addSon(result, a) - if p.tok.tokType notin {tkComma, tkSemicolon}: break + if p.tok.tokType notin {tkComma, tkSemiColon}: break getTok(p) skipComment(p, a) optPar(p) eat(p, tkParRi) let hasRet = if retColon: p.tok.tokType == tkColon - else: p.tok.tokType == tkOpr and IdentEq(p.tok.ident, "->") + else: p.tok.tokType == tkOpr and identEq(p.tok.ident, "->") if hasRet and p.tok.indent < 0: getTok(p) optInd(p, result) @@ -941,7 +941,7 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode = #| / 'static' primary #| / 'bind' primary if isOperator(p.tok): - let isSigil = IsSigilLike(p.tok) + let isSigil = isSigilLike(p.tok) result = newNodeP(nkPrefix, p) var a = newIdentNodeP(p.tok.ident, p) addSon(result, a) @@ -965,14 +965,18 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode = of tkTuple: result = parseTuple(p, mode == pmTypeDef) of tkProc: result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}) of tkIterator: - if mode in {pmTypeDesc, pmTypeDef}: - result = parseProcExpr(p, false) - result.kind = nkIteratorTy + when true: + if mode in {pmTypeDesc, pmTypeDef}: + result = parseProcExpr(p, false) + result.kind = nkIteratorTy + else: + # no anon iterators for now: + parMessage(p, errExprExpected, p.tok) + getTok(p) # we must consume a token here to prevend endless loops! + result = ast.emptyNode else: - # no anon iterators for now: - parMessage(p, errExprExpected, p.tok) - getTok(p) # we must consume a token here to prevend endless loops! - result = ast.emptyNode + result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}) + result.kind = nkIteratorTy of tkEnum: if mode == pmTypeDef: result = parseEnum(p) @@ -995,9 +999,13 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode = getTokNoInd(p) addSon(result, primary(p, pmNormal)) of tkStatic: - result = newNodeP(nkStaticExpr, p) + let info = parLineInfo(p) getTokNoInd(p) - addSon(result, primary(p, pmNormal)) + let next = primary(p, pmNormal) + if next.kind == nkBracket and next.sonsLen == 1: + result = newNode(nkStaticTy, info, @[next.sons[0]]) + else: + result = newNode(nkStaticExpr, info, @[next]) of tkBind: result = newNodeP(nkBind, p) getTok(p) @@ -1060,7 +1068,7 @@ proc parseExprStmt(p: var TParser): PNode = result = makeCall(result) getTok(p) skipComment(p, result) - if p.tok.TokType notin {tkOf, tkElif, tkElse, tkExcept}: + if p.tok.tokType notin {tkOf, tkElif, tkElse, tkExcept}: let body = parseStmt(p) addSon(result, newProcNode(nkDo, body.info, body)) while sameInd(p): @@ -1378,7 +1386,7 @@ proc parseGenericParamList(p: var TParser): PNode = while p.tok.tokType in {tkSymbol, tkAccent}: var a = parseGenericParam(p) addSon(result, a) - if p.tok.tokType notin {tkComma, tkSemicolon}: break + if p.tok.tokType notin {tkComma, tkSemiColon}: break getTok(p) skipComment(p, a) optPar(p) @@ -1638,7 +1646,7 @@ proc parseTypeClass(p: var TParser): PNode = var args = newNode(nkArgList) addSon(result, args) addSon(args, p.parseTypeClassParam) - while p.tok.TokType == tkComma: + while p.tok.tokType == tkComma: getTok(p) addSon(args, p.parseTypeClassParam) if p.tok.tokType == tkCurlyDotLe and p.validInd: @@ -1810,7 +1818,7 @@ proc parseStmt(p: var TParser): PNode = while true: if p.tok.indent == p.currInd: nil - elif p.tok.tokType == tkSemicolon: + elif p.tok.tokType == tkSemiColon: getTok(p) if p.tok.indent < 0 or p.tok.indent == p.currInd: discard else: break @@ -1818,7 +1826,7 @@ proc parseStmt(p: var TParser): PNode = if p.tok.indent > p.currInd: parMessage(p, errInvalidIndentation) break - if p.tok.toktype in {tkCurlyRi, tkParRi, tkCurlyDotRi, tkBracketRi}: + if p.tok.tokType in {tkCurlyRi, tkParRi, tkCurlyDotRi, tkBracketRi}: # XXX this ensures tnamedparamanonproc still compiles; # deprecate this syntax later break @@ -1842,7 +1850,7 @@ proc parseStmt(p: var TParser): PNode = let a = simpleStmt(p) if a.kind == nkEmpty: parMessage(p, errExprExpected, p.tok) result.add(a) - if p.tok.tokType != tkSemicolon: break + if p.tok.tokType != tkSemiColon: break getTok(p) proc parseAll(p: var TParser): PNode = @@ -1862,11 +1870,11 @@ proc parseTopLevelStmt(p: var TParser): PNode = result = ast.emptyNode while true: if p.tok.indent != 0: - if p.firstTok and p.tok.indent < 0: nil + if p.firstTok and p.tok.indent < 0: discard else: parMessage(p, errInvalidIndentation) p.firstTok = false case p.tok.tokType - of tkSemicolon: + of tkSemiColon: getTok(p) if p.tok.indent <= 0: discard else: parMessage(p, errInvalidIndentation) @@ -1877,11 +1885,11 @@ proc parseTopLevelStmt(p: var TParser): PNode = break proc parseString(s: string, filename: string = "", line: int = 0): PNode = - var stream = LLStreamOpen(s) + var stream = llStreamOpen(s) stream.lineOffset = line var parser: TParser - OpenParser(parser, filename, stream) + openParser(parser, filename, stream) result = parser.parseAll - CloseParser(parser) + closeParser(parser) diff --git a/compiler/pas2nim/pas2nim.nim b/compiler/pas2nim/pas2nim.nim index ce5eb5c1a..d10028167 100644 --- a/compiler/pas2nim/pas2nim.nim +++ b/compiler/pas2nim/pas2nim.nim @@ -26,7 +26,7 @@ Options: """ proc main(infile, outfile: string, flags: set[TParserFlag]) = - var stream = LLStreamOpen(infile, fmRead) + var stream = llStreamOpen(infile, fmRead) if stream == nil: rawMessage(errCannotOpenFile, infile) var p: TParser openParser(p, infile, stream, flags) diff --git a/compiler/pas2nim/paslex.nim b/compiler/pas2nim/paslex.nim index 94e664832..67473e71f 100644 --- a/compiler/pas2nim/paslex.nim +++ b/compiler/pas2nim/paslex.nim @@ -78,7 +78,7 @@ type proc getTok*(L: var TLexer, tok: var TToken) -proc PrintTok*(tok: TToken) +proc printTok*(tok: TToken) proc `$`*(tok: TToken): string # implementation @@ -109,17 +109,17 @@ proc getLineInfo*(L: TLexer): TLineInfo = result = newLineInfo(L.filename, L.linenumber, getColNumber(L, L.bufpos)) proc lexMessage*(L: TLexer, msg: TMsgKind, arg = "") = - msgs.GlobalError(getLineInfo(L), msg, arg) + msgs.globalError(getLineInfo(L), msg, arg) proc lexMessagePos(L: var TLexer, msg: TMsgKind, pos: int, arg = "") = var info = newLineInfo(L.filename, L.linenumber, pos - L.lineStart) - msgs.GlobalError(info, msg, arg) + msgs.globalError(info, msg, arg) -proc TokKindToStr*(k: TTokKind): string = +proc tokKindToStr*(k: TTokKind): string = case k of pxEof: result = "[EOF]" of firstKeyword..lastKeyword: - result = keywords[ord(k)-ord(firstKeyword)] + result = Keywords[ord(k)-ord(firstKeyword)] of pxInvalid, pxComment, pxStrLit: result = "string literal" of pxCommand: result = "{@" of pxAmp: result = "{&" @@ -160,9 +160,9 @@ proc `$`(tok: TToken): string = of pxSymbol: result = tok.ident.s of pxIntLit, pxInt64Lit: result = $tok.iNumber of pxFloatLit: result = $tok.fNumber - else: result = TokKindToStr(tok.xkind) + else: result = tokKindToStr(tok.xkind) -proc PrintTok(tok: TToken) = +proc printTok(tok: TToken) = writeln(stdout, $tok) proc setKeyword(L: var TLexer, tok: var TToken) = @@ -177,12 +177,12 @@ proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: TCharSet) = while true: if buf[pos] in chars: add(tok.literal, buf[pos]) - Inc(pos) + inc(pos) else: break if buf[pos] == '_': add(tok.literal, '_') - Inc(pos) + inc(pos) L.bufPos = pos proc isFloatLiteral(s: string): bool = @@ -199,7 +199,7 @@ proc getNumber2(L: var TLexer, tok: var TToken) = inc(L.bufpos) return tok.base = base2 - var xi: biggestInt = 0 + var xi: BiggestInt = 0 var bits = 0 while true: case L.buf[pos] @@ -221,7 +221,7 @@ proc getNumber2(L: var TLexer, tok: var TToken) = proc getNumber16(L: var TLexer, tok: var TToken) = var pos = L.bufpos + 1 # skip $ tok.base = base16 - var xi: biggestInt = 0 + var xi: BiggestInt = 0 var bits = 0 while true: case L.buf[pos] @@ -261,7 +261,7 @@ proc getNumber10(L: var TLexer, tok: var TToken) = tok.fnumber = parseFloat(tok.literal) tok.xkind = pxFloatLit else: - tok.iNumber = ParseInt(tok.literal) + tok.iNumber = parseInt(tok.literal) if (tok.iNumber < low(int32)) or (tok.iNumber > high(int32)): tok.xkind = pxInt64Lit else: @@ -271,10 +271,10 @@ proc getNumber10(L: var TLexer, tok: var TToken) = except EOverflow: lexMessage(L, errNumberOutOfRange, tok.literal) -proc HandleCRLF(L: var TLexer, pos: int): int = +proc handleCRLF(L: var TLexer, pos: int): int = case L.buf[pos] - of CR: result = nimlexbase.HandleCR(L, pos) - of LF: result = nimlexbase.HandleLF(L, pos) + of CR: result = nimlexbase.handleCR(L, pos) + of LF: result = nimlexbase.handleLF(L, pos) else: result = pos proc getString(L: var TLexer, tok: var TToken) = @@ -319,7 +319,7 @@ proc getString(L: var TLexer, tok: var TToken) = xi = (xi * 10) + (ord(buf[pos]) - ord('0')) inc(pos) else: lexMessage(L, errInvalidCharacterConstant) - if (xi <= 255): add(tok.literal, Chr(xi)) + if (xi <= 255): add(tok.literal, chr(xi)) else: lexMessage(L, errInvalidCharacterConstant) else: break @@ -334,17 +334,17 @@ proc getSymbol(L: var TLexer, tok: var TToken) = var c = buf[pos] case c of 'a'..'z', '0'..'9', '\x80'..'\xFF': - h = h +% Ord(c) + h = h +% ord(c) h = h +% h shl 10 h = h xor (h shr 6) of 'A'..'Z': c = chr(ord(c) + (ord('a') - ord('A'))) # toLower() - h = h +% Ord(c) + h = h +% ord(c) h = h +% h shl 10 h = h xor (h shr 6) of '_': nil else: break - Inc(pos) + inc(pos) h = h +% h shl 3 h = h xor (h shr 11) h = h +% h shl 15 @@ -385,7 +385,7 @@ proc scanCurlyComment(L: var TLexer, tok: var TToken) = while true: case buf[pos] of CR, LF: - pos = HandleCRLF(L, pos) + pos = handleCRLF(L, pos) buf = L.buf add(tok.literal, "\n#") of '}': @@ -405,7 +405,7 @@ proc scanStarComment(L: var TLexer, tok: var TToken) = while true: case buf[pos] of CR, LF: - pos = HandleCRLF(L, pos) + pos = handleCRLF(L, pos) buf = L.buf add(tok.literal, "\n#") of '*': @@ -428,9 +428,9 @@ proc skip(L: var TLexer, tok: var TToken) = while true: case buf[pos] of ' ', Tabulator: - Inc(pos) # newline is special: + inc(pos) # newline is special: of CR, LF: - pos = HandleCRLF(L, pos) + pos = handleCRLF(L, pos) buf = L.buf else: break # EndOfFile also leaves the loop @@ -449,7 +449,7 @@ proc getTok(L: var TLexer, tok: var TToken) = case c of ';': tok.xkind = pxSemicolon - Inc(L.bufpos) + inc(L.bufpos) of '/': if L.buf[L.bufpos + 1] == '/': scanLineComment(L, tok) @@ -458,12 +458,12 @@ proc getTok(L: var TLexer, tok: var TToken) = inc(L.bufpos) of ',': tok.xkind = pxComma - Inc(L.bufpos) + inc(L.bufpos) of '(': - Inc(L.bufpos) + inc(L.bufpos) if (L.buf[L.bufPos] == '*'): if (L.buf[L.bufPos + 1] == '$'): - Inc(L.bufpos, 2) + inc(L.bufpos, 2) skip(L, tok) getSymbol(L, tok) tok.xkind = pxStarDirLe @@ -481,12 +481,12 @@ proc getTok(L: var TLexer, tok: var TToken) = tok.xkind = pxStar of ')': tok.xkind = pxParRi - Inc(L.bufpos) + inc(L.bufpos) of '[': - Inc(L.bufpos) + inc(L.bufpos) tok.xkind = pxBracketLe of ']': - Inc(L.bufpos) + inc(L.bufpos) tok.xkind = pxBracketRi of '.': inc(L.bufpos) @@ -496,21 +496,21 @@ proc getTok(L: var TLexer, tok: var TToken) = else: tok.xkind = pxDot of '{': - Inc(L.bufpos) + inc(L.bufpos) case L.buf[L.bufpos] of '$': - Inc(L.bufpos) + inc(L.bufpos) skip(L, tok) getSymbol(L, tok) tok.xkind = pxCurlyDirLe of '&': - Inc(L.bufpos) + inc(L.bufpos) tok.xkind = pxAmp of '%': - Inc(L.bufpos) + inc(L.bufpos) tok.xkind = pxPer of '@': - Inc(L.bufpos) + inc(L.bufpos) tok.xkind = pxCommand else: scanCurlyComment(L, tok) of '+': @@ -554,7 +554,7 @@ proc getTok(L: var TLexer, tok: var TToken) = inc(L.bufpos) of '}': tok.xkind = pxCurlyDirRi - Inc(L.bufpos) + inc(L.bufpos) of '\'', '#': getString(L, tok) of '$': @@ -567,4 +567,4 @@ proc getTok(L: var TLexer, tok: var TToken) = tok.literal = c & "" tok.xkind = pxInvalid lexMessage(L, errInvalidToken, c & " (\\" & $(ord(c)) & ')') - Inc(L.bufpos) + inc(L.bufpos) diff --git a/compiler/pas2nim/pasparse.nim b/compiler/pas2nim/pasparse.nim index 61d57dec3..928896338 100644 --- a/compiler/pas2nim/pasparse.nim +++ b/compiler/pas2nim/pasparse.nim @@ -57,7 +57,7 @@ const ["tbinaryfile", "tfile"], ["strstart", "0"], ["nl", "\"\\n\""], ["tostring", "$"]] -proc ParseUnit*(p: var TParser): PNode +proc parseUnit*(p: var TParser): PNode proc openParser*(p: var TParser, filename: string, inputStream: PLLStream, flags: set[TParserFlag] = {}) proc closeParser*(p: var TParser) @@ -67,20 +67,20 @@ proc fixRecordDef*(n: var PNode) # implementation -proc OpenParser(p: var TParser, filename: string, +proc openParser(p: var TParser, filename: string, inputStream: PLLStream, flags: set[TParserFlag] = {}) = - OpenLexer(p.lex, filename, inputStream) + openLexer(p.lex, filename, inputStream) initIdTable(p.repl) for i in countup(low(stdReplacements), high(stdReplacements)): - IdTablePut(p.repl, getIdent(stdReplacements[i][0]), + idTablePut(p.repl, getIdent(stdReplacements[i][0]), getIdent(stdReplacements[i][1])) if pfMoreReplacements in flags: for i in countup(low(nimReplacements), high(nimReplacements)): - IdTablePut(p.repl, getIdent(nimReplacements[i][0]), + idTablePut(p.repl, getIdent(nimReplacements[i][0]), getIdent(nimReplacements[i][1])) p.flags = flags -proc CloseParser(p: var TParser) = CloseLexer(p.lex) +proc closeParser(p: var TParser) = closeLexer(p.lex) proc getTok(p: var TParser) = getTok(p.lex, p.tok) proc parMessage(p: TParser, msg: TMsgKind, arg = "") = @@ -98,15 +98,15 @@ proc skipCom(p: var TParser, n: PNode) = parMessage(p, warnCommentXIgnored, p.tok.literal) getTok(p) -proc ExpectIdent(p: TParser) = +proc expectIdent(p: TParser) = if p.tok.xkind != pxSymbol: lexMessage(p.lex, errIdentifierExpected, $(p.tok)) -proc Eat(p: var TParser, xkind: TTokKind) = +proc eat(p: var TParser, xkind: TTokKind) = if p.tok.xkind == xkind: getTok(p) - else: lexMessage(p.lex, errTokenExpected, TokKindToStr(xkind)) + else: lexMessage(p.lex, errTokenExpected, tokKindToStr(xkind)) -proc Opt(p: var TParser, xkind: TTokKind) = +proc opt(p: var TParser, xkind: TTokKind) = if p.tok.xkind == xkind: getTok(p) proc newNodeP(kind: TNodeKind, p: TParser): PNode = @@ -131,7 +131,7 @@ proc newIdentNodeP(ident: PIdent, p: TParser): PNode = proc createIdentNodeP(ident: PIdent, p: TParser): PNode = result = newNodeP(nkIdent, p) - var x = PIdent(IdTableGet(p.repl, ident)) + var x = PIdent(idTableGet(p.repl, ident)) if x != nil: result.ident = x else: result.ident = ident @@ -170,7 +170,7 @@ proc parseCommand(p: var TParser, definition: PNode = nil): PNode = getTok(p) eat(p, pxCurlyDirRi) result = parseExpr(p) - if result.kind == nkEmpty: InternalError("emptyNode modified") + if result.kind == nkEmpty: internalError("emptyNode modified") result.kind = nkCurly elif p.tok.ident.id == getIdent("cast").id: getTok(p) @@ -251,7 +251,7 @@ proc bracketExprList(p: var TParser, first: PNode): PNode = getTok(p) break if p.tok.xkind == pxEof: - parMessage(p, errTokenExpected, TokKindToStr(pxBracketRi)) + parMessage(p, errTokenExpected, tokKindToStr(pxBracketRi)) break var a = rangeExpr(p) skipCom(p, a) @@ -281,7 +281,7 @@ proc exprListAux(p: var TParser, elemKind: TNodeKind, getTok(p) break if p.tok.xkind == pxEof: - parMessage(p, errTokenExpected, TokKindToStr(endtok)) + parMessage(p, errTokenExpected, tokKindToStr(endTok)) break var a = exprColonEqExpr(p, elemKind, sepTok) skipCom(p, a) @@ -319,7 +319,7 @@ proc qualifiedIdentListAux(p: var TParser, endTok: TTokKind, getTok(p) break if p.tok.xkind == pxEof: - parMessage(p, errTokenExpected, TokKindToStr(endtok)) + parMessage(p, errTokenExpected, tokKindToStr(endTok)) break var a = qualifiedIdent(p) skipCom(p, a) @@ -584,7 +584,7 @@ proc parseIncludeDir(p: var TParser): PNode = proc definedExprAux(p: var TParser): PNode = result = newNodeP(nkCall, p) addSon(result, newIdentNodeP(getIdent("defined"), p)) - ExpectIdent(p) + expectIdent(p) addSon(result, createIdentNodeP(p.tok.ident, p)) getTok(p) @@ -753,7 +753,7 @@ proc parseCase(p: var TParser): PNode = while (p.tok.xkind != pxEof) and (p.tok.xkind != pxColon): addSon(b, rangeExpr(p)) opt(p, pxComma) - skipcom(p, b) + skipCom(p, b) eat(p, pxColon) skipCom(p, b) addSon(b, parseStmt(p)) @@ -818,7 +818,7 @@ proc parseFor(p: var TParser): PNode = getTok(p) b = parseExpr(p) else: - parMessage(p, errTokenExpected, TokKindToStr(pxTo)) + parMessage(p, errTokenExpected, tokKindToStr(pxTo)) addSon(c, a) addSon(c, b) eat(p, pxDo) @@ -915,7 +915,7 @@ proc parseCallingConvention(p: var TParser): PNode = getTok(p) opt(p, pxSemicolon) else: - nil + discard proc parseRoutineSpecifiers(p: var TParser, noBody: var bool): PNode = var e: PNode @@ -1096,7 +1096,7 @@ proc parseRecordCase(p: var TParser): PNode = while (p.tok.xkind != pxEof) and (p.tok.xkind != pxColon): addSon(b, rangeExpr(p)) opt(p, pxComma) - skipcom(p, b) + skipCom(p, b) eat(p, pxColon) skipCom(p, b) c = newNodeP(nkRecList, p) @@ -1168,7 +1168,7 @@ proc addPragmaToIdent(ident: var PNode, pragma: PNode) = else: pragmasNode = ident.sons[1] if pragmasNode.kind != nkPragma: - InternalError(ident.info, "addPragmaToIdent") + internalError(ident.info, "addPragmaToIdent") addSon(pragmasNode, pragma) proc parseRecordBody(p: var TParser, result, definition: PNode) = @@ -1183,13 +1183,13 @@ proc parseRecordBody(p: var TParser, result, definition: PNode) = if definition != nil: addPragmaToIdent(definition.sons[0], newIdentNodeP(p.tok.ident, p)) else: - InternalError(result.info, "anonymous record is not supported") + internalError(result.info, "anonymous record is not supported") getTok(p) else: - InternalError(result.info, "parseRecordBody") + internalError(result.info, "parseRecordBody") of pxCommand: if definition != nil: addPragmaToIdent(definition.sons[0], parseCommand(p)) - else: InternalError(result.info, "anonymous record is not supported") + else: internalError(result.info, "anonymous record is not supported") else: nil opt(p, pxSemicolon) @@ -1223,7 +1223,7 @@ proc parseTypeDesc(p: var TParser, definition: PNode = nil): PNode = getTok(p) if p.tok.xkind == pxCommand: result = parseCommand(p) - if result.kind != nkTupleTy: InternalError(result.info, "parseTypeDesc") + if result.kind != nkTupleTy: internalError(result.info, "parseTypeDesc") parseRecordBody(p, result, definition) var a = lastSon(result) # embed nkRecList directly into nkTupleTy for i in countup(0, sonsLen(a) - 1): @@ -1237,7 +1237,7 @@ proc parseTypeDesc(p: var TParser, definition: PNode = nil): PNode = if definition != nil: addPragmaToIdent(definition.sons[0], newIdentNodeP(getIdent("final"), p)) else: - InternalError(result.info, "anonymous record is not supported") + internalError(result.info, "anonymous record is not supported") of pxObject: result = parseRecordOrObject(p, nkObjectTy, definition) of pxParLe: result = parseEnum(p) of pxArray: diff --git a/compiler/passaux.nim b/compiler/passaux.nim index 4a85c994c..79d11419b 100644 --- a/compiler/passaux.nim +++ b/compiler/passaux.nim @@ -19,12 +19,12 @@ proc verboseOpen(s: PSym): PPassContext = proc verboseProcess(context: PPassContext, n: PNode): PNode = result = n - if context != nil: InternalError("logpass: context is not nil") + if context != nil: internalError("logpass: context is not nil") if gVerbosity == 3: # system.nim deactivates all hints, for verbosity:3 we want the processing # messages nonetheless, so we activate them again unconditionally: incl(msgs.gNotes, hintProcessing) - Message(n.info, hintProcessing, $idgen.gBackendId) + message(n.info, hintProcessing, $idgen.gBackendId) const verbosePass* = makePass(open = verboseOpen, process = verboseProcess) @@ -34,7 +34,7 @@ proc cleanUp(c: PPassContext, n: PNode): PNode = if optDeadCodeElim in gGlobalOptions or n == nil: return case n.kind of nkStmtList: - for i in countup(0, sonsLen(n) - 1): discard cleanup(c, n.sons[i]) + for i in countup(0, sonsLen(n) - 1): discard cleanUp(c, n.sons[i]) of nkProcDef, nkMethodDef: if n.sons[namePos].kind == nkSym: var s = n.sons[namePos].sym diff --git a/compiler/passes.nim b/compiler/passes.nim index 8d228fe9a..3dc31e7ac 100644 --- a/compiler/passes.nim +++ b/compiler/passes.nim @@ -30,8 +30,8 @@ type TPass* = tuple[open: TPassOpen, openCached: TPassOpenCached, process: TPassProcess, close: TPassClose] - TPassData* = tuple[input: PNode, closeOutput: Pnode] - TPasses* = openarray[TPass] + TPassData* = tuple[input: PNode, closeOutput: PNode] + TPasses* = openArray[TPass] # a pass is a tuple of procedure vars ``TPass.close`` may produce additional # nodes. These are passed to the other close procedures. @@ -169,7 +169,7 @@ proc processModule(module: PSym, stream: PLLStream, rd: PRodReader) = openPasses(a, module) if stream == nil: let filename = fileIdx.toFullPath - s = LLStreamOpen(filename, fmRead) + s = llStreamOpen(filename, fmRead) if s == nil: rawMessage(errCannotOpenFile, filename) return @@ -195,7 +195,7 @@ proc processModule(module: PSym, stream: PLLStream, rd: PRodReader) = if s.kind != llsStdIn: break closePasses(a) # id synchronization point for more consistent code generation: - IDsynchronizationPoint(1000) + idSynchronizationPoint(1000) else: openPassesCached(a, module, rd) var n = loadInitSection(rd) diff --git a/compiler/patterns.nim b/compiler/patterns.nim index b7792100f..54f8d3af4 100644 --- a/compiler/patterns.nim +++ b/compiler/patterns.nim @@ -87,22 +87,22 @@ proc matchChoice(c: PPatternContext, p, n: PNode): bool = if matches(c, p.sons[i], n): return true proc bindOrCheck(c: PPatternContext, param: PSym, n: PNode): bool = - var pp = GetLazy(c, param) + var pp = getLazy(c, param) if pp != nil: # check if we got the same pattern (already unified): result = sameTrees(pp, n) #matches(c, pp, n) elif n.kind == nkArgList or checkTypes(c, param, n): - PutLazy(c, param, n) + putLazy(c, param, n) result = true proc gather(c: PPatternContext, param: PSym, n: PNode) = - var pp = GetLazy(c, param) + var pp = getLazy(c, param) if pp != nil and pp.kind == nkArgList: pp.add(n) else: pp = newNodeI(nkArgList, n.info, 1) pp.sons[0] = n - PutLazy(c, param, pp) + putLazy(c, param, pp) proc matchNested(c: PPatternContext, p, n: PNode, rpn: bool): bool = # match ``op * param`` or ``op *| param`` @@ -148,7 +148,7 @@ proc matches(c: PPatternContext, p, n: PNode): bool = of "*": result = matchNested(c, p, n, rpn=false) of "**": result = matchNested(c, p, n, rpn=true) of "~": result = not matches(c, p.sons[1], n) - else: InternalError(p.info, "invalid pattern") + else: internalError(p.info, "invalid pattern") # template {add(a, `&` * b)}(a: string{noalias}, b: varargs[string]) = # add(a, b) elif p.kind == nkCurlyExpr: @@ -256,7 +256,7 @@ proc applyRule*(c: PContext, s: PSym, n: PNode): PNode = args = newNodeI(nkArgList, n.info) for i in 1 .. < params.len: let param = params.sons[i].sym - let x = GetLazy(ctx, param) + let x = getLazy(ctx, param) # couldn't bind parameter: if isNil(x): return nil result.add(x) diff --git a/compiler/pbraces.nim b/compiler/pbraces.nim index a944fe0ab..ce6e0d9a9 100644 --- a/compiler/pbraces.nim +++ b/compiler/pbraces.nim @@ -10,7 +10,7 @@ import llstream, lexer, parser, idents, strutils, ast, msgs -proc ParseAll*(p: var TParser): PNode = +proc parseAll*(p: var TParser): PNode = result = nil proc parseTopLevelStmt*(p: var TParser): PNode = diff --git a/compiler/platform.nim b/compiler/platform.nim index 59091b690..2e78d4fc5 100644 --- a/compiler/platform.nim +++ b/compiler/platform.nim @@ -185,13 +185,13 @@ var targetCPU*, hostCPU*: TSystemCPU targetOS*, hostOS*: TSystemOS -proc NameToOS*(name: string): TSystemOS -proc NameToCPU*(name: string): TSystemCPU +proc nameToOS*(name: string): TSystemOS +proc nameToCPU*(name: string): TSystemCPU var - IntSize*: int + intSize*: int floatSize*: int - PtrSize*: int + ptrSize*: int tnl*: string # target newline proc setTarget*(o: TSystemOS, c: TSystemCPU) = @@ -200,18 +200,18 @@ proc setTarget*(o: TSystemOS, c: TSystemCPU) = #echo "new Target: OS: ", o, " CPU: ", c targetCPU = c targetOS = o - intSize = cpu[c].intSize div 8 - floatSize = cpu[c].floatSize div 8 - ptrSize = cpu[c].bit div 8 - tnl = os[o].newLine + intSize = CPU[c].intSize div 8 + floatSize = CPU[c].floatSize div 8 + ptrSize = CPU[c].bit div 8 + tnl = OS[o].newLine -proc NameToOS(name: string): TSystemOS = +proc nameToOS(name: string): TSystemOS = for i in countup(succ(osNone), high(TSystemOS)): if cmpIgnoreStyle(name, OS[i].name) == 0: return i result = osNone -proc NameToCPU(name: string): TSystemCPU = +proc nameToCPU(name: string): TSystemCPU = for i in countup(succ(cpuNone), high(TSystemCPU)): if cmpIgnoreStyle(name, CPU[i].name) == 0: return i diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 6f1e7af25..d9ed50cfe 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -20,49 +20,49 @@ const const procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, - wMagic, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, - wCompilerProc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, + wMagic, wNosideeffect, wSideeffect, wNoreturn, wDynlib, wHeader, + wCompilerproc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC, wNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl, - wGenSym, wInject, wRaises, wTags, wOperator, wDelegator} + wGensym, wInject, wRaises, wTags, wOperator, wDelegator} converterPragmas* = procPragmas methodPragmas* = procPragmas - templatePragmas* = {wImmediate, wDeprecated, wError, wGenSym, wInject, wDirty, + templatePragmas* = {wImmediate, wDeprecated, wError, wGensym, wInject, wDirty, wDelegator} macroPragmas* = {FirstCallConv..LastCallConv, wImmediate, wImportc, wExportc, - wNodecl, wMagic, wNosideEffect, wCompilerProc, wDeprecated, wExtern, - wImportcpp, wImportobjc, wError, wDiscardable, wGenSym, wInject, wDelegator} - iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideEffect, wSideEffect, + wNodecl, wMagic, wNosideeffect, wCompilerproc, wDeprecated, wExtern, + wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wDelegator} + iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideeffect, wSideeffect, wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern, - wImportcpp, wImportobjc, wError, wDiscardable, wGenSym, wInject, wRaises, + wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wRaises, wTags, wOperator} exprPragmas* = {wLine} stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, wLinedir, wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError, - wFatal, wDefine, wUndef, wCompile, wLink, wLinkSys, wPure, wPush, wPop, - wBreakpoint, wWatchpoint, wPassL, wPassC, wDeadCodeElim, wDeprecated, - wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll, + wFatal, wDefine, wUndef, wCompile, wLink, wLinksys, wPure, wPush, wPop, + wBreakpoint, wWatchPoint, wPassl, wPassc, wDeadCodeElim, wDeprecated, + wFloatchecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll, wLinearScanEnd, wPatterns, wEffects, wNoForward, wComputedGoto, wInjectStmt} lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, - wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, - wDeprecated, wExtern, wThread, wImportcpp, wImportobjc, wNoStackFrame, + wNosideeffect, wSideeffect, wNoreturn, wDynlib, wHeader, + wDeprecated, wExtern, wThread, wImportCpp, wImportObjC, wNoStackFrame, wRaises, wTags} typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl, - wPure, wHeader, wCompilerProc, wFinal, wSize, wExtern, wShallow, - wImportcpp, wImportobjc, wError, wIncompleteStruct, wByCopy, wByRef, - wInheritable, wGenSym, wInject, wRequiresInit} + wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow, + wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef, + wInheritable, wGensym, wInject, wRequiresInit} fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern, - wImportcpp, wImportobjc, wError} + wImportCpp, wImportObjC, wError} varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, - wMagic, wHeader, wDeprecated, wCompilerProc, wDynLib, wExtern, - wImportcpp, wImportobjc, wError, wNoInit, wCompileTime, wGlobal, - wGenSym, wInject, wCodegenDecl} + wMagic, wHeader, wDeprecated, wCompilerproc, wDynlib, wExtern, + wImportCpp, wImportObjC, wError, wNoInit, wCompileTime, wGlobal, + wGensym, wInject, wCodegenDecl} constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl, - wExtern, wImportcpp, wImportobjc, wError, wGenSym, wInject} + wExtern, wImportCpp, wImportObjC, wError, wGensym, wInject} letPragmas* = varPragmas - procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideEffect, + procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideeffect, wThread, wRaises, wTags} allRoutinePragmas* = procPragmas + iteratorPragmas + lambdaPragmas @@ -70,7 +70,7 @@ proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) # implementation proc invalidPragma(n: PNode) = - LocalError(n.info, errInvalidPragmaX, renderTree(n, {renderNoComments})) + localError(n.info, errInvalidPragmaX, renderTree(n, {renderNoComments})) proc pragmaAsm*(c: PContext, n: PNode): char = result = '\0' @@ -92,12 +92,12 @@ proc setExternName(s: PSym, extname: string) = # note that '{.importc.}' is transformed into '{.importc: "$1".}' s.loc.flags.incl(lfFullExternalName) -proc MakeExternImport(s: PSym, extname: string) = +proc makeExternImport(s: PSym, extname: string) = setExternName(s, extname) incl(s.flags, sfImportc) excl(s.flags, sfForward) -proc MakeExternExport(s: PSym, extname: string) = +proc makeExternExport(s: PSym, extname: string) = setExternName(s, extname) incl(s.flags, sfExportc) @@ -125,7 +125,7 @@ proc newEmptyStrNode(n: PNode): PNode {.noinline.} = proc getStrLitNode(c: PContext, n: PNode): PNode = if n.kind != nkExprColonExpr: - LocalError(n.info, errStringLiteralExpected) + localError(n.info, errStringLiteralExpected) # error correction: result = newEmptyStrNode(n) else: @@ -133,7 +133,7 @@ proc getStrLitNode(c: PContext, n: PNode): PNode = case n.sons[1].kind of nkStrLit, nkRStrLit, nkTripleStrLit: result = n.sons[1] else: - LocalError(n.info, errStringLiteralExpected) + localError(n.info, errStringLiteralExpected) # error correction: result = newEmptyStrNode(n) @@ -142,12 +142,12 @@ proc expectStrLit(c: PContext, n: PNode): string = proc expectIntLit(c: PContext, n: PNode): int = if n.kind != nkExprColonExpr: - LocalError(n.info, errIntLiteralExpected) + localError(n.info, errIntLiteralExpected) else: n.sons[1] = c.semConstExpr(c, n.sons[1]) case n.sons[1].kind of nkIntLit..nkInt64Lit: result = int(n.sons[1].intVal) - else: LocalError(n.info, errIntLiteralExpected) + else: localError(n.info, errIntLiteralExpected) proc getOptionalStr(c: PContext, n: PNode, defaultStr: string): string = if n.kind == nkExprColonExpr: result = expectStrLit(c, n) @@ -160,7 +160,7 @@ proc processMagic(c: PContext, n: PNode, s: PSym) = #if sfSystemModule notin c.module.flags: # liMessage(n.info, errMagicOnlyInSystem) if n.kind != nkExprColonExpr: - LocalError(n.info, errStringLiteralExpected) + localError(n.info, errStringLiteralExpected) return var v: string if n.sons[1].kind == nkIdent: v = n.sons[1].ident.s @@ -169,57 +169,57 @@ proc processMagic(c: PContext, n: PNode, s: PSym) = if substr($m, 1) == v: s.magic = m break - if s.magic == mNone: Message(n.info, warnUnknownMagic, v) + if s.magic == mNone: message(n.info, warnUnknownMagic, v) proc wordToCallConv(sw: TSpecialWord): TCallingConvention = # this assumes that the order of special words and calling conventions is # the same result = TCallingConvention(ord(ccDefault) + ord(sw) - ord(wNimcall)) -proc IsTurnedOn(c: PContext, n: PNode): bool = +proc isTurnedOn(c: PContext, n: PNode): bool = if n.kind == nkExprColonExpr: let x = c.semConstBoolExpr(c, n.sons[1]) n.sons[1] = x if x.kind == nkIntLit: return x.intVal != 0 - LocalError(n.info, errOnOrOffExpected) + localError(n.info, errOnOrOffExpected) proc onOff(c: PContext, n: PNode, op: TOptions) = - if IsTurnedOn(c, n): gOptions = gOptions + op + if isTurnedOn(c, n): gOptions = gOptions + op else: gOptions = gOptions - op proc pragmaDeadCodeElim(c: PContext, n: PNode) = - if IsTurnedOn(c, n): incl(c.module.flags, sfDeadCodeElim) + if isTurnedOn(c, n): incl(c.module.flags, sfDeadCodeElim) else: excl(c.module.flags, sfDeadCodeElim) proc pragmaNoForward(c: PContext, n: PNode) = - if IsTurnedOn(c, n): incl(c.module.flags, sfNoForward) + if isTurnedOn(c, n): incl(c.module.flags, sfNoForward) else: excl(c.module.flags, sfNoForward) proc processCallConv(c: PContext, n: PNode) = if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent): var sw = whichKeyword(n.sons[1].ident) case sw - of firstCallConv..lastCallConv: + of FirstCallConv..LastCallConv: POptionEntry(c.optionStack.tail).defaultCC = wordToCallConv(sw) - else: LocalError(n.info, errCallConvExpected) + else: localError(n.info, errCallConvExpected) else: - LocalError(n.info, errCallConvExpected) + localError(n.info, errCallConvExpected) proc getLib(c: PContext, kind: TLibKind, path: PNode): PLib = var it = PLib(c.libs.head) while it != nil: if it.kind == kind: - if trees.ExprStructuralEquivalent(it.path, path): return it + if trees.exprStructuralEquivalent(it.path, path): return it it = PLib(it.next) result = newLib(kind) result.path = path - Append(c.libs, result) + append(c.libs, result) if path.kind in {nkStrLit..nkTripleStrLit}: - result.isOverriden = options.isDynLibOverride(path.strVal) + result.isOverriden = options.isDynlibOverride(path.strVal) proc expectDynlibNode(c: PContext, n: PNode): PNode = if n.kind != nkExprColonExpr: - LocalError(n.info, errStringLiteralExpected) + localError(n.info, errStringLiteralExpected) # error correction: result = newEmptyStrNode(n) else: @@ -229,7 +229,7 @@ proc expectDynlibNode(c: PContext, n: PNode): PNode = if result.kind == nkSym and result.sym.kind == skConst: result = result.sym.ast # look it up if result.typ == nil or result.typ.kind notin {tyPointer, tyString, tyProc}: - LocalError(n.info, errStringLiteralExpected) + localError(n.info, errStringLiteralExpected) result = newEmptyStrNode(n) proc processDynLib(c: PContext, n: PNode, sym: PSym) = @@ -247,7 +247,7 @@ proc processDynLib(c: PContext, n: PNode, sym: PSym) = # since we'll be loading the dynlib symbols dynamically, we must use # a calling convention that doesn't introduce custom name mangling # cdecl is the default - the user can override this explicitly - if sym.kind in RoutineKinds and sym.typ != nil and + if sym.kind in routineKinds and sym.typ != nil and sym.typ.callConv == ccDefault: sym.typ.callConv = ccCDecl @@ -265,7 +265,7 @@ proc processNote(c: PContext, n: PNode) = of wWarning: var x = findStr(msgs.WarningsToStr, n.sons[0].sons[1].ident.s) if x >= 0: nk = TNoteKind(x + ord(warnMin)) - else: InvalidPragma(n); return + else: invalidPragma(n); return else: invalidPragma(n) return @@ -284,27 +284,27 @@ proc processOption(c: PContext, n: PNode): bool = else: var sw = whichKeyword(n.sons[0].ident) case sw - of wChecks: OnOff(c, n, checksOptions) - of wObjChecks: OnOff(c, n, {optObjCheck}) - of wFieldchecks: OnOff(c, n, {optFieldCheck}) - of wRangechecks: OnOff(c, n, {optRangeCheck}) - of wBoundchecks: OnOff(c, n, {optBoundsCheck}) - of wOverflowchecks: OnOff(c, n, {optOverflowCheck}) - of wNilchecks: OnOff(c, n, {optNilCheck}) - of wFloatChecks: OnOff(c, n, {optNanCheck, optInfCheck}) - of wNaNchecks: OnOff(c, n, {optNanCheck}) - of wInfChecks: OnOff(c, n, {optInfCheck}) - of wAssertions: OnOff(c, n, {optAssert}) - of wWarnings: OnOff(c, n, {optWarns}) - of wHints: OnOff(c, n, {optHints}) - of wCallConv: processCallConv(c, n) - of wLinedir: OnOff(c, n, {optLineDir}) - of wStacktrace: OnOff(c, n, {optStackTrace}) - of wLinetrace: OnOff(c, n, {optLineTrace}) - of wDebugger: OnOff(c, n, {optEndb}) - of wProfiler: OnOff(c, n, {optProfiler}) - of wByRef: OnOff(c, n, {optByRef}) - of wDynLib: processDynLib(c, n, nil) + of wChecks: onOff(c, n, ChecksOptions) + of wObjChecks: onOff(c, n, {optObjCheck}) + of wFieldChecks: onOff(c, n, {optFieldCheck}) + of wRangechecks: onOff(c, n, {optRangeCheck}) + of wBoundchecks: onOff(c, n, {optBoundsCheck}) + of wOverflowchecks: onOff(c, n, {optOverflowCheck}) + of wNilchecks: onOff(c, n, {optNilCheck}) + of wFloatchecks: onOff(c, n, {optNaNCheck, optInfCheck}) + of wNanChecks: onOff(c, n, {optNaNCheck}) + of wInfChecks: onOff(c, n, {optInfCheck}) + of wAssertions: onOff(c, n, {optAssert}) + of wWarnings: onOff(c, n, {optWarns}) + of wHints: onOff(c, n, {optHints}) + of wCallconv: processCallConv(c, n) + of wLinedir: onOff(c, n, {optLineDir}) + of wStacktrace: onOff(c, n, {optStackTrace}) + of wLinetrace: onOff(c, n, {optLineTrace}) + of wDebugger: onOff(c, n, {optEndb}) + of wProfiler: onOff(c, n, {optProfiler}) + of wByRef: onOff(c, n, {optByRef}) + of wDynlib: processDynLib(c, n, nil) of wOptimization: if n.sons[1].kind != nkIdent: invalidPragma(n) @@ -319,14 +319,14 @@ proc processOption(c: PContext, n: PNode): bool = of "none": excl(gOptions, optOptimizeSpeed) excl(gOptions, optOptimizeSize) - else: LocalError(n.info, errNoneSpeedOrSizeExpected) - of wImplicitStatic: OnOff(c, n, {optImplicitStatic}) - of wPatterns: OnOff(c, n, {optPatterns}) + else: localError(n.info, errNoneSpeedOrSizeExpected) + of wImplicitStatic: onOff(c, n, {optImplicitStatic}) + of wPatterns: onOff(c, n, {optPatterns}) else: result = true proc processPush(c: PContext, n: PNode, start: int) = if n.sons[start-1].kind == nkExprColonExpr: - LocalError(n.info, errGenerated, "':' after 'push' not supported") + localError(n.info, errGenerated, "':' after 'push' not supported") var x = newOptionEntry() var y = POptionEntry(c.optionStack.tail) x.options = gOptions @@ -344,7 +344,7 @@ proc processPush(c: PContext, n: PNode, start: int) = proc processPop(c: PContext, n: PNode) = if c.optionStack.counter <= 1: - LocalError(n.info, errAtPopWithoutPush) + localError(n.info, errAtPopWithoutPush) else: gOptions = POptionEntry(c.optionStack.tail).options gNotes = POptionEntry(c.optionStack.tail).notes @@ -352,15 +352,15 @@ proc processPop(c: PContext, n: PNode) = proc processDefine(c: PContext, n: PNode) = if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent): - DefineSymbol(n.sons[1].ident.s) - Message(n.info, warnDeprecated, "define") + defineSymbol(n.sons[1].ident.s) + message(n.info, warnDeprecated, "define") else: invalidPragma(n) proc processUndef(c: PContext, n: PNode) = if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent): - UndefSymbol(n.sons[1].ident.s) - Message(n.info, warnDeprecated, "undef") + undefSymbol(n.sons[1].ident.s) + message(n.info, warnDeprecated, "undef") else: invalidPragma(n) @@ -372,13 +372,13 @@ proc processCompile(c: PContext, n: PNode) = var s = expectStrLit(c, n) var found = findFile(s) if found == "": found = s - var trunc = ChangeFileExt(found, "") + var trunc = changeFileExt(found, "") extccomp.addExternalFileToCompile(found) extccomp.addFileToLink(completeCFilePath(trunc, false)) proc processCommonLink(c: PContext, n: PNode, feature: TLinkFeature) = var f = expectStrLit(c, n) - if splitFile(f).ext == "": f = addFileExt(f, cc[ccompiler].objExt) + if splitFile(f).ext == "": f = addFileExt(f, CC[cCompiler].objExt) var found = findFile(f) if found == "": found = f # use the default case feature @@ -387,16 +387,16 @@ proc processCommonLink(c: PContext, n: PNode, feature: TLinkFeature) = extccomp.addFileToLink(libpath / completeCFilePath(found, false)) else: internalError(n.info, "processCommonLink") -proc PragmaBreakpoint(c: PContext, n: PNode) = +proc pragmaBreakpoint(c: PContext, n: PNode) = discard getOptionalStr(c, n, "") -proc PragmaCheckpoint(c: PContext, n: PNode) = +proc pragmaCheckpoint(c: PContext, n: PNode) = # checkpoints can be used to debug the compiler; they are not documented var info = n.info inc(info.line) # next line is affected! msgs.addCheckpoint(info) -proc PragmaWatchpoint(c: PContext, n: PNode) = +proc pragmaWatchpoint(c: PContext, n: PNode) = if n.kind == nkExprColonExpr: n.sons[1] = c.semExpr(c, n.sons[1]) else: @@ -408,7 +408,7 @@ proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode = result = newNode(if n.kind == nkAsmStmt: nkAsmStmt else: nkArgList, n.info) var str = n.sons[1].strVal if str == "": - LocalError(n.info, errEmptyAsm) + localError(n.info, errEmptyAsm) return # now parse the string literal and substitute symbols: var a = 0 @@ -431,14 +431,14 @@ proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode = a = c + 1 else: illFormedAst(n) -proc PragmaEmit(c: PContext, n: PNode) = +proc pragmaEmit(c: PContext, n: PNode) = discard getStrLitNode(c, n) n.sons[1] = semAsmOrEmit(c, n, '`') proc noVal(n: PNode) = if n.kind == nkExprColonExpr: invalidPragma(n) -proc PragmaUnroll(c: PContext, n: PNode) = +proc pragmaUnroll(c: PContext, n: PNode) = if c.p.nestedLoopCounter <= 0: invalidPragma(n) elif n.kind == nkExprColonExpr: @@ -448,7 +448,7 @@ proc PragmaUnroll(c: PContext, n: PNode) = else: invalidPragma(n) -proc PragmaLine(c: PContext, n: PNode) = +proc pragmaLine(c: PContext, n: PNode) = if n.kind == nkExprColonExpr: n.sons[1] = c.semConstExpr(c, n.sons[1]) let a = n.sons[1] @@ -458,14 +458,14 @@ proc PragmaLine(c: PContext, n: PNode) = if x.kind == nkExprColonExpr: x = x.sons[1] if y.kind == nkExprColonExpr: y = y.sons[1] if x.kind != nkStrLit: - LocalError(n.info, errStringLiteralExpected) + localError(n.info, errStringLiteralExpected) elif y.kind != nkIntLit: - LocalError(n.info, errIntLiteralExpected) + localError(n.info, errIntLiteralExpected) else: n.info.fileIndex = msgs.fileInfoIdx(x.strVal) n.info.line = int16(y.intVal) else: - LocalError(n.info, errXExpected, "tuple") + localError(n.info, errXExpected, "tuple") else: # sensible default: n.info = getInfoContext(-1) @@ -476,11 +476,11 @@ proc processPragma(c: PContext, n: PNode, i: int) = elif it.sons[0].kind != nkIdent: invalidPragma(n) elif it.sons[1].kind != nkIdent: invalidPragma(n) - var userPragma = NewSym(skTemplate, it.sons[1].ident, nil, it.info) + var userPragma = newSym(skTemplate, it.sons[1].ident, nil, it.info) var body = newNodeI(nkPragma, n.info) for j in i+1 .. sonsLen(n)-1: addSon(body, n.sons[j]) userPragma.ast = body - StrTableAdd(c.userPragmas, userPragma) + strTableAdd(c.userPragmas, userPragma) proc pragmaRaisesOrTags(c: PContext, n: PNode) = proc processExc(c: PContext, x: PNode) = @@ -503,13 +503,13 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, var it = n.sons[i] var key = if it.kind == nkExprColonExpr: it.sons[0] else: it if key.kind == nkIdent: - var userPragma = StrTableGet(c.userPragmas, key.ident) + var userPragma = strTableGet(c.userPragmas, key.ident) if userPragma != nil: - inc c.InstCounter - if c.InstCounter > 100: - GlobalError(it.info, errRecursiveDependencyX, userPragma.name.s) + inc c.instCounter + if c.instCounter > 100: + globalError(it.info, errRecursiveDependencyX, userPragma.name.s) pragma(c, sym, userPragma.ast, validPragmas) - dec c.InstCounter + dec c.instCounter else: var k = whichKeyword(key.ident) if k in validPragmas: @@ -534,20 +534,20 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, of wAlign: if sym.typ == nil: invalidPragma(it) var align = expectIntLit(c, it) - if not IsPowerOfTwo(align) and align != 0: - LocalError(it.info, errPowerOfTwoExpected) + if not isPowerOfTwo(align) and align != 0: + localError(it.info, errPowerOfTwoExpected) else: sym.typ.align = align of wSize: if sym.typ == nil: invalidPragma(it) var size = expectIntLit(c, it) - if not IsPowerOfTwo(size) or size <= 0 or size > 8: - LocalError(it.info, errPowerOfTwoExpected) + if not isPowerOfTwo(size) or size <= 0 or size > 8: + localError(it.info, errPowerOfTwoExpected) else: sym.typ.size = size of wNodecl: noVal(it) - incl(sym.loc.Flags, lfNoDecl) + incl(sym.loc.flags, lfNoDecl) of wPure, wNoStackFrame: noVal(it) if sym != nil: incl(sym.flags, sfPure) @@ -566,20 +566,20 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, of wCompileTime: noVal(it) incl(sym.flags, sfCompileTime) - incl(sym.loc.Flags, lfNoDecl) + incl(sym.loc.flags, lfNoDecl) of wGlobal: noVal(it) incl(sym.flags, sfGlobal) incl(sym.flags, sfPure) of wMerge: - noval(it) + noVal(it) incl(sym.flags, sfMerge) of wHeader: var lib = getLib(c, libHeader, getStrLitNode(c, it)) addToLib(lib, sym) incl(sym.flags, sfImportc) incl(sym.loc.flags, lfHeader) - incl(sym.loc.Flags, lfNoDecl) + incl(sym.loc.flags, lfNoDecl) # implies nodecl, because otherwise header would not make sense if sym.loc.r == nil: sym.loc.r = toRope(sym.name.s) of wDestructor: @@ -591,23 +591,23 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, noVal(it) incl(sym.flags, sfNoSideEffect) if sym.typ != nil: incl(sym.typ.flags, tfNoSideEffect) - of wSideEffect: + of wSideeffect: noVal(it) incl(sym.flags, sfSideEffect) - of wNoReturn: + of wNoreturn: noVal(it) incl(sym.flags, sfNoReturn) - of wDynLib: + of wDynlib: processDynLib(c, it, sym) - of wCompilerProc: + of wCompilerproc: noVal(it) # compilerproc may not get a string! makeExternExport(sym, "$1") incl(sym.flags, sfCompilerProc) incl(sym.flags, sfUsed) # suppress all those stupid warnings registerCompilerProc(sym) - of wProcvar: + of wProcVar: noVal(it) - incl(sym.flags, sfProcVar) + incl(sym.flags, sfProcvar) of wDeprecated: noVal(it) if sym != nil: incl(sym.flags, sfDeprecated) @@ -638,10 +638,10 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, of wThread: noVal(it) incl(sym.flags, sfThread) - incl(sym.flags, sfProcVar) + incl(sym.flags, sfProcvar) if sym.typ != nil: incl(sym.typ.flags, tfThread) - of wHint: Message(it.info, hintUser, expectStrLit(c, it)) - of wWarning: Message(it.info, warnUser, expectStrLit(c, it)) + of wHint: message(it.info, hintUser, expectStrLit(c, it)) + of wWarning: message(it.info, warnUser, expectStrLit(c, it)) of wError: if sym != nil and sym.isRoutine: # This is subtle but correct: the error *statement* is only @@ -651,17 +651,17 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, noVal(it) incl(sym.flags, sfError) else: - LocalError(it.info, errUser, expectStrLit(c, it)) - of wFatal: Fatal(it.info, errUser, expectStrLit(c, it)) + localError(it.info, errUser, expectStrLit(c, it)) + of wFatal: fatal(it.info, errUser, expectStrLit(c, it)) of wDefine: processDefine(c, it) of wUndef: processUndef(c, it) of wCompile: processCompile(c, it) of wLink: processCommonLink(c, it, linkNormal) - of wLinkSys: processCommonLink(c, it, linkSys) - of wPassL: extccomp.addLinkOption(expectStrLit(c, it)) - of wPassC: extccomp.addCompileOption(expectStrLit(c, it)) - of wBreakpoint: PragmaBreakpoint(c, it) - of wWatchpoint: PragmaWatchpoint(c, it) + of wLinksys: processCommonLink(c, it, linkSys) + of wPassl: extccomp.addLinkOption(expectStrLit(c, it)) + of wPassc: extccomp.addCompileOption(expectStrLit(c, it)) + of wBreakpoint: pragmaBreakpoint(c, it) + of wWatchPoint: pragmaWatchpoint(c, it) of wPush: processPush(c, n, i + 1) result = true @@ -679,18 +679,18 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, of wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, wLinedir, wStacktrace, wLinetrace, wOptimization, - wCallConv, - wDebugger, wProfiler, wFloatChecks, wNanChecks, wInfChecks, + wCallconv, + wDebugger, wProfiler, wFloatchecks, wNanChecks, wInfChecks, wPatterns: if processOption(c, it): # calling conventions (boring...): - LocalError(it.info, errOptionExpected) - of firstCallConv..lastCallConv: + localError(it.info, errOptionExpected) + of FirstCallConv..LastCallConv: assert(sym != nil) if sym.typ == nil: invalidPragma(it) else: sym.typ.callConv = wordToCallConv(k) - of wEmit: PragmaEmit(c, it) - of wUnroll: PragmaUnroll(c, it) + of wEmit: pragmaEmit(c, it) + of wUnroll: pragmaUnroll(c, it) of wLinearScanEnd, wComputedGoto: noVal(it) of wEffects: # is later processed in effect analysis: @@ -706,19 +706,19 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, of wByRef: noVal(it) if sym == nil or sym.typ == nil: - if processOption(c, it): LocalError(it.info, errOptionExpected) + if processOption(c, it): localError(it.info, errOptionExpected) else: incl(sym.typ.flags, tfByRef) of wByCopy: noVal(it) if sym.kind != skType or sym.typ == nil: invalidPragma(it) else: incl(sym.typ.flags, tfByCopy) - of wInject, wGenSym: + of wInject, wGensym: # We check for errors, but do nothing with these pragmas otherwise # as they are handled directly in 'evalTemplate'. noVal(it) if sym == nil: invalidPragma(it) - of wLine: PragmaLine(c, it) + of wLine: pragmaLine(c, it) of wRaises, wTags: pragmaRaisesOrTags(c, it) of wOperator: if sym == nil: invalidPragma(it) @@ -735,18 +735,18 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, proc implictPragmas*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) = if sym != nil and sym.kind != skModule: - var it = POptionEntry(c.optionstack.head) + var it = POptionEntry(c.optionStack.head) while it != nil: let o = it.otherPragmas if not o.isNil: for i in countup(0, sonsLen(o) - 1): if singlePragma(c, sym, o, i, validPragmas): - InternalError(n.info, "implicitPragmas") + internalError(n.info, "implicitPragmas") it = it.next.POptionEntry if lfExportLib in sym.loc.flags and sfExportc notin sym.flags: - LocalError(n.info, errDynlibRequiresExportc) - var lib = POptionEntry(c.optionstack.tail).dynlib + localError(n.info, errDynlibRequiresExportc) + var lib = POptionEntry(c.optionStack.tail).dynlib if {lfDynamicLib, lfHeader} * sym.loc.flags == {} and sfImportc in sym.flags and lib != nil: incl(sym.loc.flags, lfDynamicLib) diff --git a/compiler/pretty.nim b/compiler/pretty.nim index 5036a16a3..3a5bfe197 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -12,12 +12,12 @@ import strutils, os, options, ast, astalgo, msgs, ropes, idents, passes, - intsets, strtabs + intsets, strtabs, semdata const removeTP = false # when true, "nimrod pretty" converts TTyp to Typ. -type +type TGen = object of TPassContext module*: PSym PGen = ref TGen @@ -29,6 +29,7 @@ type var gSourceFiles: seq[TSourceFile] = @[] + gCheckExtern: bool rules: PStringTable proc loadFile(info: TLineInfo) = @@ -44,13 +45,20 @@ proc loadFile(info: TLineInfo) = gSourceFiles[i].lines.add(line) proc overwriteFiles*() = + let overWrite = options.getConfigVar("pretty.overwrite").normalize == "on" + let doStrip = options.getConfigVar("pretty.strip").normalize == "on" for i in 0 .. high(gSourceFiles): if not gSourceFiles[i].dirty: continue - let newFile = gSourceFiles[i].fullpath.changeFileExt(".pretty.nim") + let newFile = if overWrite: gSourceFiles[i].fullpath + else: gSourceFiles[i].fullpath.changeFileExt(".pretty.nim") try: var f = open(newFile, fmWrite) for line in gSourceFiles[i].lines: - f.writeln(line) + if doStrip: + f.write line.strip(leading = false, trailing = true) + else: + f.write line + f.write("\L") f.close except EIO: rawMessage(errCannotOpenFile, newFile) @@ -60,18 +68,25 @@ proc `=~`(s: string, a: openArray[string]): bool = if s.startsWith(x): return true proc beautifyName(s: string, k: TSymKind): string = + # minimal set of rules here for transition: + # GC_ is allowed + + let allUpper = allCharsInSet(s, {'A'..'Z', '0'..'9', '_'}) + if allUpper and k in {skConst, skEnumField, skType}: return s result = newStringOfCap(s.len) var i = 0 case k of skType, skGenericParam: - # skip leading 'T' + # Types should start with a capital unless builtins like 'int' etc.: when removeTP: if s[0] == 'T' and s[1] in {'A'..'Z'}: i = 1 if s =~ ["int", "uint", "cint", "cuint", "clong", "cstring", "string", "char", "byte", "bool", "openArray", "seq", "array", "void", "pointer", "float", "csize", "cdouble", "cchar", "cschar", - "cshort", "cu"]: + "cshort", "cu", "nil", "expr", "stmt", "typedesc", "auto", "any", + "range", "openarray", "varargs", "set", "cfloat" + ]: result.add s[i] else: result.add toUpper(s[i]) @@ -81,13 +96,19 @@ proc beautifyName(s: string, k: TSymKind): string = else: # as a special rule, don't transform 'L' to 'l' if s.len == 1 and s[0] == 'L': result.add 'L' + elif '_' in s: result.add(s[i]) else: result.add toLower(s[0]) inc i - let allUpper = allCharsInSet(s, {'A'..'Z', '0'..'9', '_'}) while i < s.len: if s[i] == '_': - inc i - result.add toUpper(s[i]) + if i > 0 and s[i-1] in {'A'..'Z'}: + # don't skip '_' as it's essential for e.g. 'GC_disable' + result.add('_') + inc i + result.add s[i] + else: + inc i + result.add toUpper(s[i]) elif allUpper: result.add toLower(s[i]) else: @@ -97,8 +118,7 @@ proc beautifyName(s: string, k: TSymKind): string = proc checkStyle*(info: TLineInfo, s: string, k: TSymKind) = let beau = beautifyName(s, k) if s != beau: - Message(info, errGenerated, - "name does not adhere to naming convention; should be: " & beau) + message(info, errGenerated, "name should be: " & beau) const Letters = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '_'} @@ -117,13 +137,90 @@ proc differ(line: string, a, b: int, x: string): bool = inc j return false -var cannotRename = initIntSet() +proc checkDef*(n: PNode; s: PSym) = + # operators stay as they are: + if s.kind in {skResult, skTemp} or s.name.s[0] notin Letters: return + if s.kind in {skType, skGenericParam} and sfAnon in s.flags: return -proc processSym(c: PPassContext, n: PNode): PNode = - result = n - var g = PGen(c) - case n.kind - of nkSym: + if {sfImportc, sfExportc} * s.flags == {} or gCheckExtern: + checkStyle(n.info, s.name.s, s.kind) + +proc checkDef(c: PGen; n: PNode) = + if n.kind != nkSym: return + checkDef(n, n.sym) + +proc checkUse*(n: PNode, s: PSym) = + if n.info.fileIndex < 0: return + # we simply convert it to what it looks like in the definition + # for consistency + + # operators stay as they are: + if s.kind in {skResult, skTemp} or s.name.s[0] notin Letters: return + if s.kind in {skType, skGenericParam} and sfAnon in s.flags: return + let newName = s.name.s + + loadFile(n.info) + + let line = gSourceFiles[n.info.fileIndex].lines[n.info.line-1] + var first = min(n.info.col.int, line.len) + if first < 0: return + #inc first, skipIgnoreCase(line, "proc ", first) + while first > 0 and line[first-1] in Letters: dec first + if first < 0: return + if line[first] == '`': inc first + + let last = first+identLen(line, first)-1 + if differ(line, first, last, newName): + # last-first+1 != newName.len or + var x = line.substr(0, first-1) & newName & line.substr(last+1) + when removeTP: + # the WinAPI module is full of 'TX = X' which after the substitution + # becomes 'X = X'. We remove those lines: + if x.match(peg"\s* {\ident} \s* '=' \s* y$1 ('#' .*)?"): + x = "" + + system.shallowCopy(gSourceFiles[n.info.fileIndex].lines[n.info.line-1], x) + gSourceFiles[n.info.fileIndex].dirty = true + +when false: + var cannotRename = initIntSet() + + proc beautifyName(s: string, k: TSymKind): string = + let allUpper = allCharsInSet(s, {'A'..'Z', '0'..'9', '_'}) + result = newStringOfCap(s.len) + var i = 0 + case k + of skType, skGenericParam: + # skip leading 'T' + when removeTP: + if s[0] == 'T' and s[1] in {'A'..'Z'}: + i = 1 + if s =~ ["int", "uint", "cint", "cuint", "clong", "cstring", "string", + "char", "byte", "bool", "openArray", "seq", "array", "void", + "pointer", "float", "csize", "cdouble", "cchar", "cschar", + "cshort", "cu"]: + result.add s[i] + else: + result.add toUpper(s[i]) + of skConst, skEnumField: + # for 'const' we keep how it's spelt; either upper case or lower case: + result.add s[0] + else: + # as a special rule, don't transform 'L' to 'l' + if s.len == 1 and s[0] == 'L': result.add 'L' + else: result.add toLower(s[0]) + inc i + while i < s.len: + if s[i] == '_': + inc i + result.add toUpper(s[i]) + elif allUpper: + result.add toLower(s[i]) + else: + result.add s[i] + inc i + + proc checkUse(c: PGen; n: PNode) = if n.info.fileIndex < 0: return let s = n.sym # operators stay as they are: @@ -138,10 +235,11 @@ proc processSym(c: PPassContext, n: PNode): PNode = loadFile(n.info) let line = gSourceFiles[n.info.fileIndex].lines[n.info.line-1] - var first = n.info.col.int + var first = min(n.info.col.int, line.len) if first < 0: return #inc first, skipIgnoreCase(line, "proc ", first) while first > 0 and line[first-1] in Letters: dec first + if first < 0: return if line[first] == '`': inc first if {sfImportc, sfExportc} * s.flags != {}: @@ -149,8 +247,8 @@ proc processSym(c: PPassContext, n: PNode): PNode = # name: if newName != s.name.s and newName != s.loc.r.ropeToStr and lfFullExternalName notin s.loc.flags: - Message(n.info, errGenerated, - "cannot rename $# to $# due to external name" % [s.name.s, newName]) + #Message(n.info, errGenerated, + # "cannot rename $# to $# due to external name" % [s.name.s, newName]) cannotRename.incl(s.id) return let last = first+identLen(line, first)-1 @@ -165,14 +263,50 @@ proc processSym(c: PPassContext, n: PNode): PNode = system.shallowCopy(gSourceFiles[n.info.fileIndex].lines[n.info.line-1], x) gSourceFiles[n.info.fileIndex].dirty = true + +proc check(c: PGen, n: PNode) = + case n.kind + of nkSym: checkUse(n, n.sym) + of nkBlockStmt, nkBlockExpr, nkBlockType: + checkDef(c, n[0]) + check(c, n.sons[1]) + of nkForStmt, nkParForStmt: + let L = n.len + for i in countup(0, L-3): + checkDef(c, n[i]) + check(c, n[L-2]) + check(c, n[L-1]) + of nkProcDef, nkLambdaKinds, nkMethodDef, nkIteratorDef, nkTemplateDef, + nkMacroDef, nkConverterDef: + checkDef(c, n[namePos]) + for i in namePos+1 .. <n.len: check(c, n.sons[i]) + of nkIdentDefs, nkVarTuple: + let a = n + checkMinSonsLen(a, 3) + let L = len(a) + for j in countup(0, L-3): checkDef(c, a.sons[j]) + check(c, a.sons[L-2]) + check(c, a.sons[L-1]) + of nkTypeSection, nkConstSection: + for i in countup(0, sonsLen(n) - 1): + let a = n.sons[i] + if a.kind == nkCommentStmt: continue + checkSonsLen(a, 3) + checkDef(c, a.sons[0]) + check(c, a.sons[1]) + check(c, a.sons[2]) else: - for i in 0 .. <n.safeLen: - discard processSym(c, n.sons[i]) + for i in 0 .. <n.safeLen: check(c, n.sons[i]) + +proc processSym(c: PPassContext, n: PNode): PNode = + result = n + check(PGen(c), n) proc myOpen(module: PSym): PPassContext = var g: PGen new(g) g.module = module + gCheckExtern = options.getConfigVar("pretty.checkextern").normalize == "on" result = g if rules.isNil: rules = newStringTable(modeStyleInsensitive) diff --git a/compiler/procfind.nim b/compiler/procfind.nim index aefccd140..eb0cbca3f 100644 --- a/compiler/procfind.nim +++ b/compiler/procfind.nim @@ -17,52 +17,76 @@ proc equalGenericParams(procA, procB: PNode): bool = if sonsLen(procA) != sonsLen(procB): return for i in countup(0, sonsLen(procA) - 1): if procA.sons[i].kind != nkSym: - InternalError(procA.info, "equalGenericParams") + internalError(procA.info, "equalGenericParams") return if procB.sons[i].kind != nkSym: - InternalError(procB.info, "equalGenericParams") + internalError(procB.info, "equalGenericParams") return let a = procA.sons[i].sym let b = procB.sons[i].sym if a.name.id != b.name.id or - not sameTypeOrNil(a.typ, b.typ, {TypeDescExactMatch}): return + not sameTypeOrNil(a.typ, b.typ, {ExactTypeDescValues}): return if a.ast != nil and b.ast != nil: - if not ExprStructuralEquivalent(a.ast, b.ast): return + if not exprStructuralEquivalent(a.ast, b.ast): return result = true -proc SearchForProc*(c: PContext, scope: PScope, fn: PSym): PSym = +proc searchForProcOld*(c: PContext, scope: PScope, fn: PSym): PSym = # Searchs for a forward declaration or a "twin" symbol of fn # in the symbol table. If the parameter lists are exactly # the same the sym in the symbol table is returned, else nil. var it: TIdentIter - result = initIdentIter(it, scope.symbols, fn.Name) + result = initIdentIter(it, scope.symbols, fn.name) if isGenericRoutine(fn): # we simply check the AST; this is imprecise but nearly the best what # can be done; this doesn't work either though as type constraints are # not kept in the AST .. while result != nil: - if result.Kind == fn.kind and isGenericRoutine(result): + if result.kind == fn.kind and isGenericRoutine(result): let genR = result.ast.sons[genericParamsPos] let genF = fn.ast.sons[genericParamsPos] - if ExprStructuralEquivalent(genR, genF) and - ExprStructuralEquivalent(result.ast.sons[paramsPos], + if exprStructuralEquivalent(genR, genF) and + exprStructuralEquivalent(result.ast.sons[paramsPos], fn.ast.sons[paramsPos]) and equalGenericParams(genR, genF): return - result = NextIdentIter(it, scope.symbols) + result = nextIdentIter(it, scope.symbols) else: while result != nil: - if result.Kind == fn.kind and not isGenericRoutine(result): + if result.kind == fn.kind and not isGenericRoutine(result): case equalParams(result.typ.n, fn.typ.n) of paramsEqual: return of paramsIncompatible: - LocalError(fn.info, errNotOverloadable, fn.name.s) + localError(fn.info, errNotOverloadable, fn.name.s) return of paramsNotEqual: nil - result = NextIdentIter(it, scope.symbols) + result = nextIdentIter(it, scope.symbols) +proc searchForProcNew(c: PContext, scope: PScope, fn: PSym): PSym = + const flags = {ExactGenericParams, ExactTypeDescValues, + ExactConstraints, IgnoreCC} + + var it: TIdentIter + result = initIdentIter(it, scope.symbols, fn.name) + while result != nil: + if result.kind in skProcKinds and + sameType(result.typ, fn.typ, flags): return + + result = nextIdentIter(it, scope.symbols) + + return nil + +proc searchForProc*(c: PContext, scope: PScope, fn: PSym): PSym = + result = searchForProcNew(c, scope, fn) + when false: + let old = searchForProcOld(c, scope, fn) + if old != result: + echo "Mismatch in searchForProc: ", fn.info + debug fn.typ + debug if result != nil: result.typ else: nil + debug if old != nil: old.typ else: nil + when false: proc paramsFitBorrow(child, parent: PNode): bool = var length = sonsLen(child) @@ -77,7 +101,7 @@ when false: dcEqOrDistinctOf): return result = true - proc SearchForBorrowProc*(c: PContext, startScope: PScope, fn: PSym): PSym = + proc searchForBorrowProc*(c: PContext, startScope: PScope, fn: PSym): PSym = # Searchs for the fn in the symbol table. If the parameter lists are suitable # for borrowing the sym in the symbol table is returned, else nil. var it: TIdentIter diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 61babed66..6c7d9cae3 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -62,7 +62,7 @@ const MaxLineLen = 80 LineCommentColumn = 30 -proc InitSrcGen(g: var TSrcGen, renderFlags: TRenderFlags) = +proc initSrcGen(g: var TSrcGen, renderFlags: TRenderFlags) = g.comStack = @[] g.tokens = @[] g.indent = 0 @@ -76,7 +76,7 @@ proc InitSrcGen(g: var TSrcGen, renderFlags: TRenderFlags) = proc addTok(g: var TSrcGen, kind: TTokType, s: string) = var length = len(g.tokens) - setlen(g.tokens, length + 1) + setLen(g.tokens, length + 1) g.tokens[length].kind = kind g.tokens[length].length = int16(len(s)) add(g.buf, s) @@ -104,16 +104,16 @@ proc optNL(g: var TSrcGen) = optNL(g, g.indent) proc indentNL(g: var TSrcGen) = - inc(g.indent, indentWidth) + inc(g.indent, IndentWidth) g.pendingNL = g.indent g.lineLen = g.indent -proc Dedent(g: var TSrcGen) = - dec(g.indent, indentWidth) +proc dedent(g: var TSrcGen) = + dec(g.indent, IndentWidth) assert(g.indent >= 0) - if g.pendingNL > indentWidth: - Dec(g.pendingNL, indentWidth) - Dec(g.lineLen, indentWidth) + if g.pendingNL > IndentWidth: + dec(g.pendingNL, IndentWidth) + dec(g.lineLen, IndentWidth) proc put(g: var TSrcGen, kind: TTokType, s: string) = addPendingNL(g) @@ -127,7 +127,7 @@ proc putLong(g: var TSrcGen, kind: TTokType, s: string, lineLen: int) = addTok(g, kind, s) g.lineLen = lineLen -proc toNimChar(c: Char): string = +proc toNimChar(c: char): string = case c of '\0': result = "\\0" of '\x01'..'\x1F', '\x80'..'\xFF': result = "\\x" & strutils.toHex(ord(c), 2) @@ -241,14 +241,14 @@ proc containsNL(s: string): bool = proc pushCom(g: var TSrcGen, n: PNode) = var length = len(g.comStack) - setlen(g.comStack, length + 1) + setLen(g.comStack, length + 1) g.comStack[length] = n proc popAllComs(g: var TSrcGen) = - setlen(g.comStack, 0) + setLen(g.comStack, 0) proc popCom(g: var TSrcGen) = - setlen(g.comStack, len(g.comStack) - 1) + setLen(g.comStack, len(g.comStack) - 1) const Space = " " @@ -269,7 +269,7 @@ proc gcom(g: var TSrcGen, n: PNode) = if (g.pendingNL < 0) and (len(g.buf) > 0) and (g.lineLen < LineCommentColumn): var ml = maxLineLength(n.comment) - if ml + LineCommentColumn <= maxLineLen: + if ml + LineCommentColumn <= MaxLineLen: put(g, tkSpaces, repeatChar(LineCommentColumn - g.lineLen)) putComment(g, n.comment) #assert(g.comStack[high(g.comStack)] = n); @@ -278,7 +278,7 @@ proc gcoms(g: var TSrcGen) = popAllComs(g) proc lsub(n: PNode): int -proc litAux(n: PNode, x: biggestInt, size: int): string = +proc litAux(n: PNode, x: BiggestInt, size: int): string = proc skip(t: PType): PType = result = t while result.kind in {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal, @@ -295,7 +295,7 @@ proc litAux(n: PNode, x: biggestInt, size: int): string = elif nfBase16 in n.flags: result = "0x" & toHex(x, size * 2) else: result = $x -proc ulitAux(n: PNode, x: biggestInt, size: int): string = +proc ulitAux(n: PNode, x: BiggestInt, size: int): string = if nfBase2 in n.flags: result = "0b" & toBin(x, size * 8) elif nfBase8 in n.flags: result = "0o" & toOct(x, size * 3) elif nfBase16 in n.flags: result = "0x" & toHex(x, size * 2) @@ -341,7 +341,7 @@ proc atom(n: PNode): string = if (n.typ != nil) and (n.typ.sym != nil): result = n.typ.sym.name.s else: result = "[type node]" else: - InternalError("rnimsyn.atom " & $n.kind) + internalError("rnimsyn.atom " & $n.kind) result = "" proc lcomma(n: PNode, start: int = 0, theEnd: int = - 1): int = @@ -361,11 +361,11 @@ proc lsons(n: PNode, start: int = 0, theEnd: int = - 1): int = proc lsub(n: PNode): int = # computes the length of a tree if isNil(n): return 0 - if n.comment != nil: return maxLineLen + 1 + if n.comment != nil: return MaxLineLen + 1 case n.kind of nkEmpty: result = 0 of nkTripleStrLit: - if containsNL(n.strVal): result = maxLineLen + 1 + if containsNL(n.strVal): result = MaxLineLen + 1 else: result = len(atom(n)) of succ(nkEmpty)..pred(nkTripleStrLit), succ(nkTripleStrLit)..nkNilLit: result = len(atom(n)) @@ -425,7 +425,7 @@ proc lsub(n: PNode): int = of nkPtrTy: result = (if n.len > 0: lsub(n.sons[0])+1 else: 0) + len("ptr") of nkVarTy: result = (if n.len > 0: lsub(n.sons[0])+1 else: 0) + len("var") of nkDistinctTy: result = (if n.len > 0: lsub(n.sons[0])+1 else: 0) + - len("Distinct") + len("Distinct") of nkTypeDef: result = lsons(n) + 3 of nkOfInherit: result = lsub(n.sons[0]) + len("of_") of nkProcTy: result = lsons(n) + len("proc_") @@ -438,7 +438,7 @@ proc lsub(n: PNode): int = result = len("enum") of nkEnumFieldDef: result = lsons(n) + 3 of nkVarSection, nkLetSection: - if sonsLen(n) > 1: result = maxLineLen + 1 + if sonsLen(n) > 1: result = MaxLineLen + 1 else: result = lsons(n) + len("var_") of nkReturnStmt: result = lsub(n.sons[0]) + len("return_") of nkRaiseStmt: result = lsub(n.sons[0]) + len("raise_") @@ -459,10 +459,10 @@ proc lsub(n: PNode): int = if n.sons[0].kind != nkEmpty: result = result + lsub(n.sons[0]) + 2 of nkExceptBranch: result = lcomma(n, 0, -2) + lsub(lastSon(n)) + len("except_:_") - else: result = maxLineLen + 1 + else: result = MaxLineLen + 1 proc fits(g: TSrcGen, x: int): bool = - result = x + g.lineLen <= maxLineLen + result = x + g.lineLen <= MaxLineLen type TSubFlag = enum @@ -501,7 +501,7 @@ proc gcommaAux(g: var TSrcGen, n: PNode, ind: int, start: int = 0, for i in countup(start, sonsLen(n) + theEnd): var c = i < sonsLen(n) + theEnd var sublen = lsub(n.sons[i]) + ord(c) - if not fits(g, sublen) and (ind + sublen < maxLineLen): optNL(g, ind) + if not fits(g, sublen) and (ind + sublen < MaxLineLen): optNL(g, ind) let oldLen = g.tokens.len gsub(g, n.sons[i]) if c: @@ -515,21 +515,21 @@ proc gcomma(g: var TSrcGen, n: PNode, c: TContext, start: int = 0, theEnd: int = - 1) = var ind: int if rfInConstExpr in c.flags: - ind = g.indent + indentWidth + ind = g.indent + IndentWidth else: ind = g.lineLen - if ind > maxLineLen div 2: ind = g.indent + longIndentWid + if ind > MaxLineLen div 2: ind = g.indent + longIndentWid gcommaAux(g, n, ind, start, theEnd) proc gcomma(g: var TSrcGen, n: PNode, start: int = 0, theEnd: int = - 1) = var ind = g.lineLen - if ind > maxLineLen div 2: ind = g.indent + longIndentWid + if ind > MaxLineLen div 2: ind = g.indent + longIndentWid gcommaAux(g, n, ind, start, theEnd) proc gsemicolon(g: var TSrcGen, n: PNode, start: int = 0, theEnd: int = - 1) = var ind = g.lineLen - if ind > maxLineLen div 2: ind = g.indent + longIndentWid - gcommaAux(g, n, ind, start, theEnd, tkSemicolon) + if ind > MaxLineLen div 2: ind = g.indent + longIndentWid + gcommaAux(g, n, ind, start, theEnd, tkSemiColon) proc gsons(g: var TSrcGen, n: PNode, c: TContext, start: int = 0, theEnd: int = - 1) = @@ -552,13 +552,13 @@ proc longMode(n: PNode, start: int = 0, theEnd: int = - 1): bool = if not result: # check further for i in countup(start, sonsLen(n) + theEnd): - if (lsub(n.sons[i]) > maxLineLen): + if (lsub(n.sons[i]) > MaxLineLen): result = true break proc gstmts(g: var TSrcGen, n: PNode, c: TContext) = if n.kind == nkEmpty: return - if (n.kind == nkStmtList) or (n.kind == nkStmtListExpr): + if n.kind in {nkStmtList, nkStmtListExpr, nkStmtListType}: indentNL(g) for i in countup(0, sonsLen(n) - 1): optNL(g) @@ -577,7 +577,7 @@ proc gif(g: var TSrcGen, n: PNode) = gsub(g, n.sons[0].sons[0]) initContext(c) putWithSpace(g, tkColon, ":") - if longMode(n) or (lsub(n.sons[0].sons[1]) + g.lineLen > maxLineLen): + if longMode(n) or (lsub(n.sons[0].sons[1]) + g.lineLen > MaxLineLen): incl(c.flags, rfLongMode) gcoms(g) # a good place for comments gstmts(g, n.sons[0].sons[1], c) @@ -592,7 +592,7 @@ proc gwhile(g: var TSrcGen, n: PNode) = gsub(g, n.sons[0]) putWithSpace(g, tkColon, ":") initContext(c) - if longMode(n) or (lsub(n.sons[1]) + g.lineLen > maxLineLen): + if longMode(n) or (lsub(n.sons[1]) + g.lineLen > MaxLineLen): incl(c.flags, rfLongMode) gcoms(g) # a good place for comments gstmts(g, n.sons[1], c) @@ -601,7 +601,7 @@ proc gpattern(g: var TSrcGen, n: PNode) = var c: TContext put(g, tkCurlyLe, "{") initContext(c) - if longMode(n) or (lsub(n.sons[0]) + g.lineLen > maxLineLen): + if longMode(n) or (lsub(n.sons[0]) + g.lineLen > MaxLineLen): incl(c.flags, rfLongMode) gcoms(g) # a good place for comments gstmts(g, n.sons[0], c) @@ -612,7 +612,7 @@ proc gpragmaBlock(g: var TSrcGen, n: PNode) = gsub(g, n.sons[0]) putWithSpace(g, tkColon, ":") initContext(c) - if longMode(n) or (lsub(n.sons[1]) + g.lineLen > maxLineLen): + if longMode(n) or (lsub(n.sons[1]) + g.lineLen > MaxLineLen): incl(c.flags, rfLongMode) gcoms(g) # a good place for comments gstmts(g, n.sons[1], c) @@ -622,7 +622,7 @@ proc gtry(g: var TSrcGen, n: PNode) = put(g, tkTry, "try") putWithSpace(g, tkColon, ":") initContext(c) - if longMode(n) or (lsub(n.sons[0]) + g.lineLen > maxLineLen): + if longMode(n) or (lsub(n.sons[0]) + g.lineLen > MaxLineLen): incl(c.flags, rfLongMode) gcoms(g) # a good place for comments gstmts(g, n.sons[0], c) @@ -635,7 +635,7 @@ proc gfor(g: var TSrcGen, n: PNode) = initContext(c) if longMode(n) or (lsub(n.sons[length - 1]) + lsub(n.sons[length - 2]) + 6 + g.lineLen > - maxLineLen): + MaxLineLen): incl(c.flags, rfLongMode) gcomma(g, n, c, 0, - 3) put(g, tkSpaces, Space) @@ -650,7 +650,7 @@ proc gmacro(g: var TSrcGen, n: PNode) = initContext(c) gsub(g, n.sons[0]) putWithSpace(g, tkColon, ":") - if longMode(n) or (lsub(n.sons[1]) + g.lineLen > maxLineLen): + if longMode(n) or (lsub(n.sons[1]) + g.lineLen > MaxLineLen): incl(c.flags, rfLongMode) gcoms(g) gsons(g, n, c, 1) @@ -710,7 +710,7 @@ proc gblock(g: var TSrcGen, n: PNode) = else: put(g, tkBlock, "block") putWithSpace(g, tkColon, ":") - if longMode(n) or (lsub(n.sons[1]) + g.lineLen > maxLineLen): + if longMode(n) or (lsub(n.sons[1]) + g.lineLen > MaxLineLen): incl(c.flags, rfLongMode) gcoms(g) # XXX I don't get why this is needed here! gstmts should already handle this! @@ -723,7 +723,7 @@ proc gstaticStmt(g: var TSrcGen, n: PNode) = putWithSpace(g, tkStatic, "static") putWithSpace(g, tkColon, ":") initContext(c) - if longMode(n) or (lsub(n.sons[0]) + g.lineLen > maxLineLen): + if longMode(n) or (lsub(n.sons[0]) + g.lineLen > MaxLineLen): incl(c.flags, rfLongMode) gcoms(g) # a good place for comments gstmts(g, n.sons[0], c) @@ -817,7 +817,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = put(g, tkParRi, ")") of nkStaticExpr: put(g, tkStatic, "static") - put(g, tkSpaces, space) + put(g, tkSpaces, Space) gsub(g, n.sons[0]) of nkBracketExpr: gsub(g, n.sons[0]) @@ -834,7 +834,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = gcomma(g, n, 1) of nkCommand: gsub(g, n.sons[0]) - put(g, tkSpaces, space) + put(g, tkSpaces, Space) gcomma(g, n, 1) of nkExprEqExpr, nkAsgn, nkFastAsgn: gsub(g, n.sons[0]) @@ -941,7 +941,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = of nkPrefix: gsub(g, n.sons[0]) if n.len > 1: - put(g, tkSpaces, space) + put(g, tkSpaces, Space) if n.sons[1].kind == nkInfix: put(g, tkParLe, "(") gsub(g, n.sons[1]) @@ -1070,7 +1070,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = put(g, tkSpaces, Space) putWithSpace(g, tkEquals, "=") gsub(g, n.sons[1]) - of nkStmtList, nkStmtListExpr: gstmts(g, n, emptyContext) + of nkStmtList, nkStmtListExpr, nkStmtListType: gstmts(g, n, emptyContext) of nkIfStmt: putWithSpace(g, tkIf, "if") gif(g, n) @@ -1247,9 +1247,13 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = put(g, tkBracketLe, "[") gcomma(g, n) put(g, tkBracketRi, "]") + of nkMetaNode: + put(g, tkParLe, "(META|") + gsub(g, n.sons[0]) + put(g, tkParRi, ")") else: - #nkNone, nkMetaNode, nkExplicitTypeListCall: - InternalError(n.info, "rnimsyn.gsub(" & $n.kind & ')') + #nkNone, nkExplicitTypeListCall: + internalError(n.info, "rnimsyn.gsub(" & $n.kind & ')') proc renderTree(n: PNode, renderFlags: TRenderFlags = {}): string = var g: TSrcGen @@ -1260,7 +1264,7 @@ proc renderTree(n: PNode, renderFlags: TRenderFlags = {}): string = proc renderModule(n: PNode, filename: string, renderFlags: TRenderFlags = {}) = var - f: tfile + f: TFile g: TSrcGen initSrcGen(g, renderFlags) for i in countup(0, sonsLen(n) - 1): diff --git a/compiler/rodread.nim b/compiler/rodread.nim index 6e6b83260..7a35f0c84 100644 --- a/compiler/rodread.nim +++ b/compiler/rodread.nim @@ -184,7 +184,7 @@ proc skipNode(r: PRodReader) = if par == 0: break dec par of '(': inc par - else: nil + else: discard inc pos r.pos = pos+1 # skip ')' @@ -248,7 +248,7 @@ proc decodeNodeLazyBody(r: PRodReader, fInfo: TLineInfo, if r.s[r.pos] == ')': inc(r.pos) else: internalError(result.info, "decodeNode: ')' missing") else: - InternalError(fInfo, "decodeNode: '(' missing " & $r.pos) + internalError(fInfo, "decodeNode: '(' missing " & $r.pos) proc decodeNode(r: PRodReader, fInfo: TLineInfo): PNode = result = decodeNodeLazyBody(r, fInfo, nil) @@ -286,7 +286,7 @@ proc decodeLoc(r: PRodReader, loc: var TLoc, info: TLineInfo) = else: loc.a = 0 if r.s[r.pos] == '>': inc(r.pos) - else: InternalError(info, "decodeLoc " & r.s[r.pos]) + else: internalError(info, "decodeLoc " & r.s[r.pos]) proc decodeType(r: PRodReader, info: TLineInfo): PType = result = nil @@ -303,10 +303,10 @@ proc decodeType(r: PRodReader, info: TLineInfo): PType = setId(result.id) if debugIds: registerID(result) else: - InternalError(info, "decodeType: no id") + internalError(info, "decodeType: no id") # here this also avoids endless recursion for recursive type - IdTablePut(gTypeTable, result, result) - if r.s[r.pos] == '(': result.n = decodeNode(r, UnknownLineInfo()) + idTablePut(gTypeTable, result, result) + if r.s[r.pos] == '(': result.n = decodeNode(r, unknownLineInfo()) if r.s[r.pos] == '$': inc(r.pos) result.flags = cast[TTypeFlags](int32(decodeVInt(r.s, r.pos))) @@ -335,7 +335,7 @@ proc decodeType(r: PRodReader, info: TLineInfo): PType = if r.s[r.pos] == '(': inc(r.pos) if r.s[r.pos] == ')': inc(r.pos) - else: InternalError(info, "decodeType ^(" & r.s[r.pos]) + else: internalError(info, "decodeType ^(" & r.s[r.pos]) rawAddSon(result, nil) else: var d = decodeVInt(r.s, r.pos) @@ -347,10 +347,10 @@ proc decodeLib(r: PRodReader, info: TLineInfo): PLib = new(result) inc(r.pos) result.kind = TLibKind(decodeVInt(r.s, r.pos)) - if r.s[r.pos] != '|': InternalError("decodeLib: 1") + if r.s[r.pos] != '|': internalError("decodeLib: 1") inc(r.pos) result.name = toRope(decodeStr(r.s, r.pos)) - if r.s[r.pos] != '|': InternalError("decodeLib: 2") + if r.s[r.pos] != '|': internalError("decodeLib: 2") inc(r.pos) result.path = decodeNode(r, info) @@ -370,21 +370,21 @@ proc decodeSym(r: PRodReader, info: TLineInfo): PSym = id = decodeVInt(r.s, r.pos) setId(id) else: - InternalError(info, "decodeSym: no id") + internalError(info, "decodeSym: no id") if r.s[r.pos] == '&': inc(r.pos) ident = getIdent(decodeStr(r.s, r.pos)) else: - InternalError(info, "decodeSym: no ident") + internalError(info, "decodeSym: no ident") #echo "decoding: {", ident.s - result = PSym(IdTableGet(r.syms, id)) + result = PSym(idTableGet(r.syms, id)) if result == nil: new(result) result.id = id - IdTablePut(r.syms, result, result) + idTablePut(r.syms, result, result) if debugIds: registerID(result) elif result.id != id: - InternalError(info, "decodeSym: wrong id") + internalError(info, "decodeSym: wrong id") elif result.kind != skStub and not r.inViewMode: # we already loaded the symbol return @@ -427,7 +427,7 @@ proc decodeSym(r: PRodReader, info: TLineInfo): PSym = result.annex = decodeLib(r, info) if r.s[r.pos] == '#': inc(r.pos) - result.constraint = decodeNode(r, UnknownLineInfo()) + result.constraint = decodeNode(r, unknownLineInfo()) if r.s[r.pos] == '(': if result.kind in routineKinds: result.ast = decodeNodeLazyBody(r, result.info, result) @@ -455,10 +455,10 @@ proc skipSection(r: PRodReader) = elif c > 0: dec(c) of '\0': break # end of file - else: nil + else: discard inc(r.pos) else: - InternalError("skipSection " & $r.line) + internalError("skipSection " & $r.line) proc rdWord(r: PRodReader): string = result = "" @@ -472,11 +472,11 @@ proc newStub(r: PRodReader, name: string, id: int): PSym = result.id = id result.name = getIdent(name) result.position = r.readerIndex - setID(id) #MessageOut(result.name.s); + setId(id) #MessageOut(result.name.s); if debugIds: registerID(result) proc processInterf(r: PRodReader, module: PSym) = - if r.interfIdx == 0: InternalError("processInterf") + if r.interfIdx == 0: internalError("processInterf") r.pos = r.interfIdx while (r.s[r.pos] > '\x0A') and (r.s[r.pos] != ')'): var w = decodeStr(r.s, r.pos) @@ -485,23 +485,23 @@ proc processInterf(r: PRodReader, module: PSym) = inc(r.pos) # #10 var s = newStub(r, w, key) s.owner = module - StrTableAdd(module.tab, s) - IdTablePut(r.syms, s, s) + strTableAdd(module.tab, s) + idTablePut(r.syms, s, s) proc processCompilerProcs(r: PRodReader, module: PSym) = - if r.compilerProcsIdx == 0: InternalError("processCompilerProcs") + if r.compilerProcsIdx == 0: internalError("processCompilerProcs") r.pos = r.compilerProcsIdx while (r.s[r.pos] > '\x0A') and (r.s[r.pos] != ')'): var w = decodeStr(r.s, r.pos) inc(r.pos) var key = decodeVInt(r.s, r.pos) inc(r.pos) # #10 - var s = PSym(IdTableGet(r.syms, key)) + var s = PSym(idTableGet(r.syms, key)) if s == nil: s = newStub(r, w, key) s.owner = module - IdTablePut(r.syms, s, s) - StrTableAdd(rodCompilerProcs, s) + idTablePut(r.syms, s, s) + strTableAdd(rodCompilerprocs, s) proc processIndex(r: PRodReader; idx: var TIndex; outf: TFile = nil) = var key, val, tmp: int @@ -516,11 +516,11 @@ proc processIndex(r: PRodReader; idx: var TIndex; outf: TFile = nil) = else: key = idx.lastIdxKey + 1 val = tmp + idx.lastIdxVal - IITablePut(idx.tab, key, val) + iiTablePut(idx.tab, key, val) if not outf.isNil: outf.write(key, " ", val, "\n") idx.lastIdxKey = key idx.lastIdxVal = val - setID(key) # ensure that this id will not be used + setId(key) # ensure that this id will not be used if r.s[r.pos] == '\x0A': inc(r.pos) inc(r.line) @@ -558,7 +558,7 @@ proc processRodFile(r: PRodReader, crc: TCrc32) = of "ID": inc(r.pos) # skip ':' r.moduleID = decodeVInt(r.s, r.pos) - setID(r.moduleID) + setId(r.moduleID) of "ORIGFILE": inc(r.pos) r.origFile = decodeStr(r.s, r.pos) @@ -603,7 +603,7 @@ proc processRodFile(r: PRodReader, crc: TCrc32) = inc(r.pos) # skip ' ' inclCrc = decodeVInt(r.s, r.pos) if r.reason == rrNone: - if not ExistsFile(w) or (inclCrc != int(crcFromFile(w))): + if not existsFile(w) or (inclCrc != int(crcFromFile(w))): r.reason = rrInclDeps if r.s[r.pos] == '\x0A': inc(r.pos) @@ -639,7 +639,7 @@ proc processRodFile(r: PRodReader, crc: TCrc32) = r.initIdx = r.pos + 2 # "(\10" skipSection(r) else: - InternalError("invalid section: '" & section & + internalError("invalid section: '" & section & "' at " & $r.line & " in " & r.filename) #MsgWriteln("skipping section: " & section & # " at " & $r.line & " in " & r.filename) @@ -658,7 +658,7 @@ proc newRodReader(modfilename: string, crc: TCrc32, readerIndex: int): PRodReader = new(result) try: - result.memFile = memfiles.open(modfilename) + result.memfile = memfiles.open(modfilename) except EOS: return nil result.files = @[] @@ -670,13 +670,13 @@ proc newRodReader(modfilename: string, crc: TCrc32, r.line = 1 r.readerIndex = readerIndex r.filename = modfilename - InitIdTable(r.syms) + initIdTable(r.syms) # we terminate the file explicitely with ``\0``, so the cast to `cstring` # is safe: - r.s = cast[cstring](r.memFile.mem) + r.s = cast[cstring](r.memfile.mem) if startsWith(r.s, "NIM:"): - initIITable(r.index.tab) - initIITable(r.imports.tab) # looks like a ROD file + initIiTable(r.index.tab) + initIiTable(r.imports.tab) # looks like a ROD file inc(r.pos, 4) var version = "" while r.s[r.pos] notin {'\0', '\x0A'}: @@ -691,12 +691,12 @@ proc newRodReader(modfilename: string, crc: TCrc32, result = nil proc rrGetType(r: PRodReader, id: int, info: TLineInfo): PType = - result = PType(IdTableGet(gTypeTable, id)) + result = PType(idTableGet(gTypeTable, id)) if result == nil: # load the type: var oldPos = r.pos - var d = IITableGet(r.index.tab, id) - if d == invalidKey: InternalError(info, "rrGetType") + var d = iiTableGet(r.index.tab, id) + if d == InvalidKey: internalError(info, "rrGetType") r.pos = d + r.dataIdx result = decodeType(r, info) r.pos = oldPos @@ -715,7 +715,7 @@ var gMods*: TFileModuleMap = @[] proc decodeSymSafePos(rd: PRodReader, offset: int, info: TLineInfo): PSym = # all compiled modules - if rd.dataIdx == 0: InternalError(info, "dataIdx == 0") + if rd.dataIdx == 0: internalError(info, "dataIdx == 0") var oldPos = rd.pos rd.pos = offset + rd.dataIdx result = decodeSym(rd, info) @@ -725,8 +725,8 @@ proc findSomeWhere(id: int) = for i in countup(0, high(gMods)): var rd = gMods[i].rd if rd != nil: - var d = IITableGet(rd.index.tab, id) - if d != invalidKey: + var d = iiTableGet(rd.index.tab, id) + if d != InvalidKey: echo "found id ", id, " in ", gMods[i].filename proc getReader(moduleId: int): PRodReader = @@ -736,37 +736,37 @@ proc getReader(moduleId: int): PRodReader = # problems: for i in 0 .. <gMods.len: result = gMods[i].rd - if result != nil and result.moduleId == moduleId: return result + if result != nil and result.moduleID == moduleId: return result return nil proc rrGetSym(r: PRodReader, id: int, info: TLineInfo): PSym = - result = PSym(IdTableGet(r.syms, id)) + result = PSym(idTableGet(r.syms, id)) if result == nil: # load the symbol: - var d = IITableGet(r.index.tab, id) - if d == invalidKey: + var d = iiTableGet(r.index.tab, id) + if d == InvalidKey: # import from other module: - var moduleID = IiTableGet(r.imports.tab, id) + var moduleID = iiTableGet(r.imports.tab, id) if moduleID < 0: var x = "" encodeVInt(id, x) - InternalError(info, "missing from both indexes: +" & x) + internalError(info, "missing from both indexes: +" & x) var rd = getReader(moduleID) - d = IITableGet(rd.index.tab, id) - if d != invalidKey: + d = iiTableGet(rd.index.tab, id) + if d != InvalidKey: result = decodeSymSafePos(rd, d, info) else: var x = "" encodeVInt(id, x) when false: findSomeWhere(id) - InternalError(info, "rrGetSym: no reader found: +" & x) + internalError(info, "rrGetSym: no reader found: +" & x) else: # own symbol: result = decodeSymSafePos(r, d, info) if result != nil and result.kind == skStub: rawLoadStub(result) proc loadInitSection(r: PRodReader): PNode = - if r.initIdx == 0 or r.dataIdx == 0: InternalError("loadInitSection") + if r.initIdx == 0 or r.dataIdx == 0: internalError("loadInitSection") var oldPos = r.pos r.pos = r.initIdx result = newNode(nkStmtList) @@ -775,7 +775,7 @@ proc loadInitSection(r: PRodReader): PNode = inc(r.pos) # #10 var p = r.pos r.pos = d + r.dataIdx - addSon(result, decodeNode(r, UnknownLineInfo())) + addSon(result, decodeNode(r, unknownLineInfo())) r.pos = p r.pos = oldPos @@ -783,24 +783,24 @@ proc loadConverters(r: PRodReader) = # We have to ensure that no exported converter is a stub anymore, and the # import mechanism takes care of the rest. if r.convertersIdx == 0 or r.dataIdx == 0: - InternalError("importConverters") + internalError("importConverters") r.pos = r.convertersIdx while r.s[r.pos] > '\x0A': var d = decodeVInt(r.s, r.pos) - discard rrGetSym(r, d, UnknownLineInfo()) + discard rrGetSym(r, d, unknownLineInfo()) if r.s[r.pos] == ' ': inc(r.pos) proc loadMethods(r: PRodReader) = if r.methodsIdx == 0 or r.dataIdx == 0: - InternalError("loadMethods") + internalError("loadMethods") r.pos = r.methodsIdx while r.s[r.pos] > '\x0A': var d = decodeVInt(r.s, r.pos) - r.methods.add(rrGetSym(r, d, UnknownLineInfo())) + r.methods.add(rrGetSym(r, d, unknownLineInfo())) if r.s[r.pos] == ' ': inc(r.pos) -proc GetCRC*(fileIdx: int32): TCrc32 = - InternalAssert fileIdx >= 0 and fileIdx < gMods.len +proc getCRC*(fileIdx: int32): TCrc32 = + internalAssert fileIdx >= 0 and fileIdx < gMods.len if gMods[fileIdx].crcDone: return gMods[fileIdx].crc @@ -818,14 +818,14 @@ proc checkDep(fileIdx: int32): TReasonForRecompile = # reason has already been computed for this module: return gMods[fileIdx].reason let filename = fileIdx.toFilename - var crc = GetCRC(fileIdx) + var crc = getCRC(fileIdx) gMods[fileIdx].reason = rrNone # we need to set it here to avoid cycles result = rrNone var r: PRodReader = nil var rodfile = toGeneratedFile(filename.withPackageName, RodExt) r = newRodReader(rodfile, crc, fileIdx) if r == nil: - result = (if ExistsFile(rodfile): rrRodInvalid else: rrRodDoesNotExist) + result = (if existsFile(rodfile): rrRodInvalid else: rrRodDoesNotExist) else: processRodFile(r, crc) result = r.reason @@ -834,7 +834,7 @@ proc checkDep(fileIdx: int32): TReasonForRecompile = # NOTE: we need to process the entire module graph so that no ID will # be used twice! However, compilation speed does not suffer much from # this, since results are cached. - var res = checkDep(SystemFileIdx) + var res = checkDep(systemFileIdx) if res != rrNone: result = rrModDeps for i in countup(0, high(r.modDeps)): res = checkDep(r.modDeps[i]) @@ -845,7 +845,7 @@ proc checkDep(fileIdx: int32): TReasonForRecompile = rawMessage(hintProcessing, reasonToFrmt[result] % filename) if result != rrNone or optForceFullMake in gGlobalOptions: # recompilation is necessary: - if r != nil: memfiles.close(r.memFile) + if r != nil: memfiles.close(r.memfile) r = nil gMods[fileIdx].rd = r gMods[fileIdx].reason = result # now we know better @@ -858,11 +858,11 @@ proc handleSymbolFile(module: PSym): PRodReader = idgen.loadMaxIds(options.gProjectPath / options.gProjectName) discard checkDep(fileIdx) - if gMods[fileIdx].reason == rrEmpty: InternalError("handleSymbolFile") + if gMods[fileIdx].reason == rrEmpty: internalError("handleSymbolFile") result = gMods[fileIdx].rd if result != nil: module.id = result.moduleID - IdTablePut(result.syms, module, module) + idTablePut(result.syms, module, module) processInterf(result, module) processCompilerProcs(result, module) loadConverters(result) @@ -871,21 +871,21 @@ proc handleSymbolFile(module: PSym): PRodReader = module.id = getID() proc rawLoadStub(s: PSym) = - if s.kind != skStub: InternalError("loadStub") + if s.kind != skStub: internalError("loadStub") var rd = gMods[s.position].rd var theId = s.id # used for later check - var d = IITableGet(rd.index.tab, s.id) - if d == invalidKey: InternalError("loadStub: invalid key") - var rs = decodeSymSafePos(rd, d, UnknownLineInfo()) + var d = iiTableGet(rd.index.tab, s.id) + if d == InvalidKey: internalError("loadStub: invalid key") + var rs = decodeSymSafePos(rd, d, unknownLineInfo()) if rs != s: #echo "rs: ", toHex(cast[int](rs.position), int.sizeof * 2), # "\ns: ", toHex(cast[int](s.position), int.sizeof * 2) - InternalError(rs.info, "loadStub: wrong symbol") + internalError(rs.info, "loadStub: wrong symbol") elif rs.id != theId: - InternalError(rs.info, "loadStub: wrong ID") + internalError(rs.info, "loadStub: wrong ID") #MessageOut('loaded stub: ' + s.name.s); -proc LoadStub*(s: PSym) = +proc loadStub*(s: PSym) = ## loads the stub symbol `s`. # deactivate the GC here because we do a deep recursion and generate no @@ -912,8 +912,8 @@ proc getBody*(s: PSym): PNode = s.ast.sons[bodyPos] = result s.offset = 0 -InitIdTable(gTypeTable) -InitStrTable(rodCompilerProcs) +initIdTable(gTypeTable) +initStrTable(rodCompilerprocs) # viewer: proc writeNode(f: TFile; n: PNode) = @@ -1038,7 +1038,7 @@ proc viewFile(rodfile: string) = of "ID": inc(r.pos) # skip ':' r.moduleID = decodeVInt(r.s, r.pos) - setID(r.moduleID) + setId(r.moduleID) outf.writeln("ID:", $r.moduleID) of "ORIGFILE": inc(r.pos) @@ -1140,12 +1140,12 @@ proc viewFile(rodfile: string) = outf.write("DATA(\n") while r.s[r.pos] != ')': if r.s[r.pos] == '(': - outf.writeNode decodeNode(r, UnknownLineInfo()) + outf.writeNode decodeNode(r, unknownLineInfo()) outf.write("\n") elif r.s[r.pos] == '[': - outf.writeType decodeType(r, UnknownLineInfo()) + outf.writeType decodeType(r, unknownLineInfo()) else: - outf.writeSym decodeSym(r, UnknownLineInfo()) + outf.writeSym decodeSym(r, unknownLineInfo()) if r.s[r.pos] == '\x0A': inc(r.pos) inc(r.line) @@ -1166,7 +1166,7 @@ proc viewFile(rodfile: string) = if r.s[r.pos] == ')': inc r.pos outf.write("<not supported by viewer>)\n") else: - InternalError("invalid section: '" & section & + internalError("invalid section: '" & section & "' at " & $r.line & " in " & r.filename) skipSection(r) if r.s[r.pos] == '\x0A': diff --git a/compiler/rodutils.nim b/compiler/rodutils.nim index 0ee3b1ec4..4433ed4ab 100644 --- a/compiler/rodutils.nim +++ b/compiler/rodutils.nim @@ -12,7 +12,7 @@ import strutils proc c_sprintf(buf, frmt: cstring) {.importc: "sprintf", nodecl, varargs.} -proc ToStrMaxPrecision*(f: BiggestFloat): string = +proc toStrMaxPrecision*(f: BiggestFloat): string = if f != f: result = "NAN" elif f == 0.0: @@ -36,7 +36,7 @@ proc hexChar(c: char, xi: var int) = of '0'..'9': xi = (xi shl 4) or (ord(c) - ord('0')) of 'a'..'f': xi = (xi shl 4) or (ord(c) - ord('a') + 10) of 'A'..'F': xi = (xi shl 4) or (ord(c) - ord('A') + 10) - else: nil + else: discard proc decodeStr*(s: cstring, pos: var int): string = var i = pos @@ -119,7 +119,7 @@ template decodeIntImpl() = proc decodeVInt*(s: cstring, pos: var int): int = decodeIntImpl() -proc decodeVBiggestInt*(s: cstring, pos: var int): biggestInt = +proc decodeVBiggestInt*(s: cstring, pos: var int): BiggestInt = decodeIntImpl() iterator decodeVIntArray*(s: cstring): int = diff --git a/compiler/rodwrite.nim b/compiler/rodwrite.nim index 2e52aeaa7..c393ce1da 100644 --- a/compiler/rodwrite.nim +++ b/compiler/rodwrite.nim @@ -56,7 +56,7 @@ proc fileIdx(w: PRodWriter, filename: string): int = if w.files[i] == filename: return i result = len(w.files) - setlen(w.files, result + 1) + setLen(w.files, result + 1) w.files[result] = filename template filename*(w: PRodWriter): string = @@ -66,8 +66,8 @@ proc newRodWriter(crc: TCrc32, module: PSym): PRodWriter = new(result) result.sstack = @[] result.tstack = @[] - InitIITable(result.index.tab) - InitIITable(result.imports.tab) + initIiTable(result.index.tab) + initIiTable(result.imports.tab) result.index.r = "" result.imports.r = "" result.crc = crc @@ -101,12 +101,12 @@ proc addInclDep(w: PRodWriter, dep: string) = proc pushType(w: PRodWriter, t: PType) = # check so that the stack does not grow too large: - if IiTableGet(w.index.tab, t.id) == invalidKey: + if iiTableGet(w.index.tab, t.id) == InvalidKey: w.tstack.add(t) proc pushSym(w: PRodWriter, s: PSym) = # check so that the stack does not grow too large: - if IiTableGet(w.index.tab, s.id) == invalidKey: + if iiTableGet(w.index.tab, s.id) == InvalidKey: w.sstack.add(s) proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode, @@ -120,19 +120,19 @@ proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode, # we do not write comments for now # Line information takes easily 20% or more of the filesize! Therefore we # omit line information if it is the same as the father's line information: - if finfo.fileIndex != n.info.fileIndex: + if fInfo.fileIndex != n.info.fileIndex: result.add('?') encodeVInt(n.info.col, result) result.add(',') encodeVInt(n.info.line, result) result.add(',') encodeVInt(fileIdx(w, toFilename(n.info)), result) - elif finfo.line != n.info.line: + elif fInfo.line != n.info.line: result.add('?') encodeVInt(n.info.col, result) result.add(',') encodeVInt(n.info.line, result) - elif finfo.col != n.info.col: + elif fInfo.col != n.info.col: result.add('?') encodeVInt(n.info.col, result) # No need to output the file index, as this is the serialization of one @@ -190,7 +190,7 @@ proc encodeLoc(w: PRodWriter, loc: TLoc, result: var string) = if loc.a != 0: add(result, '?') encodeVInt(loc.a, result) - if oldlen + 1 == result.len: + if oldLen + 1 == result.len: # no data was necessary, so remove the '<' again: setLen(result, oldLen) else: @@ -202,7 +202,7 @@ proc encodeType(w: PRodWriter, t: PType, result: var string) = result.add("[]") return # we need no surrounding [] here because the type is in a line of its own - if t.kind == tyForward: InternalError("encodeType: tyForward") + if t.kind == tyForward: internalError("encodeType: tyForward") # for the new rodfile viewer we use a preceeding [ so that the data section # can easily be disambiguated: add(result, '[') @@ -210,7 +210,7 @@ proc encodeType(w: PRodWriter, t: PType, result: var string) = add(result, '+') encodeVInt(t.id, result) if t.n != nil: - encodeNode(w, UnknownLineInfo(), t.n, result) + encodeNode(w, unknownLineInfo(), t.n, result) if t.flags != {}: add(result, '$') encodeVInt(cast[int32](t.flags), result) @@ -292,7 +292,7 @@ proc encodeSym(w: PRodWriter, s: PSym, result: var string) = if s.annex != nil: encodeLib(w, s.annex, s.info, result) if s.constraint != nil: add(result, '#') - encodeNode(w, UnknownLineInfo(), s.constraint, result) + encodeNode(w, unknownLineInfo(), s.constraint, result) # lazy loading will soon reload the ast lazily, so the ast needs to be # the last entry of a symbol: if s.ast != nil: @@ -322,7 +322,7 @@ proc addToIndex(w: var TIndex, key, val: int) = add(w.r, rodNL) w.lastIdxKey = key w.lastIdxVal = val - IiTablePut(w.tab, key, val) + iiTablePut(w.tab, key, val) const debugWrittenIds = false @@ -336,9 +336,9 @@ proc symStack(w: PRodWriter): int = if sfForward in s.flags: w.sstack[result] = s inc result - elif IiTableGet(w.index.tab, s.id) == invalidKey: + elif iiTableGet(w.index.tab, s.id) == InvalidKey: var m = getModule(s) - if m == nil: InternalError("symStack: module nil: " & s.name.s) + if m == nil: internalError("symStack: module nil: " & s.name.s) if (m.id == w.module.id) or (sfFromGeneric in s.flags): # put definition in here var L = w.data.len @@ -364,7 +364,7 @@ proc symStack(w: PRodWriter): int = if s.kind == skMethod and sfDispatcher notin s.flags: if w.methods.len != 0: add(w.methods, ' ') encodeVInt(s.id, w.methods) - elif IiTableGet(w.imports.tab, s.id) == invalidKey: + elif iiTableGet(w.imports.tab, s.id) == InvalidKey: addToIndex(w.imports, s.id, m.id) when debugWrittenIds: if not Contains(debugWritten, s.id): @@ -374,7 +374,7 @@ proc symStack(w: PRodWriter): int = debug(m) InternalError("Symbol referred to but never written") inc(i) - setlen(w.sstack, result) + setLen(w.sstack, result) proc typeStack(w: PRodWriter): int = var i = 0 @@ -383,13 +383,13 @@ proc typeStack(w: PRodWriter): int = if t.kind == tyForward: w.tstack[result] = t inc result - elif IiTableGet(w.index.tab, t.id) == invalidKey: + elif iiTableGet(w.index.tab, t.id) == InvalidKey: var L = w.data.len addToIndex(w.index, t.id, L) encodeType(w, t, w.data) add(w.data, rodNL) inc(i) - setlen(w.tstack, result) + setLen(w.tstack, result) proc processStacks(w: PRodWriter, finalPass: bool) = var oldS = 0 @@ -401,7 +401,7 @@ proc processStacks(w: PRodWriter, finalPass: bool) = oldS = slen oldT = tlen if finalPass and (oldS != 0 or oldT != 0): - InternalError("could not serialize some forwarded symbols/types") + internalError("could not serialize some forwarded symbols/types") proc rawAddInterfaceSym(w: PRodWriter, s: PSym) = pushSym(w, s) @@ -416,7 +416,7 @@ proc addInterfaceSym(w: PRodWriter, s: PSym) = proc addStmt(w: PRodWriter, n: PNode) = encodeVInt(w.data.len, w.init) add(w.init, rodNL) - encodeNode(w, UnknownLineInfo(), n, w.data) + encodeNode(w, unknownLineInfo(), n, w.data) add(w.data, rodNL) processStacks(w, false) @@ -534,9 +534,9 @@ proc process(c: PPassContext, n: PNode): PNode = of nkProcDef, nkMethodDef, nkIteratorDef, nkConverterDef, nkTemplateDef, nkMacroDef: var s = n.sons[namePos].sym - if s == nil: InternalError(n.info, "rodwrite.process") + if s == nil: internalError(n.info, "rodwrite.process") if n.sons[bodyPos] == nil: - InternalError(n.info, "rodwrite.process: body is nil") + internalError(n.info, "rodwrite.process: body is nil") if n.sons[bodyPos].kind != nkEmpty or s.magic != mNone or sfForward notin s.flags: addInterfaceSym(w, s) @@ -549,7 +549,7 @@ proc process(c: PPassContext, n: PNode): PNode = for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue - if a.sons[0].kind != nkSym: InternalError(a.info, "rodwrite.process") + if a.sons[0].kind != nkSym: internalError(a.info, "rodwrite.process") var s = a.sons[0].sym addInterfaceSym(w, s) # this takes care of enum fields too @@ -576,8 +576,8 @@ proc process(c: PPassContext, n: PNode): PNode = nil proc myOpen(module: PSym): PPassContext = - if module.id < 0: InternalError("rodwrite: module ID not set") - var w = newRodWriter(module.fileIdx.GetCRC, module) + if module.id < 0: internalError("rodwrite: module ID not set") + var w = newRodWriter(module.fileIdx.getCRC, module) rawAddInterfaceSym(w, module) result = w diff --git a/compiler/ropes.nim b/compiler/ropes.nim index 707c29123..fcf5dd202 100644 --- a/compiler/ropes.nim +++ b/compiler/ropes.nim @@ -91,13 +91,13 @@ proc writeRopeIfNotEqual*(r: PRope, filename: string): bool proc ropeToStr*(p: PRope): string proc ropef*(frmt: TFormatStr, args: varargs[PRope]): PRope proc appf*(c: var PRope, frmt: TFormatStr, args: varargs[PRope]) -proc RopeEqualsFile*(r: PRope, f: string): bool +proc ropeEqualsFile*(r: PRope, f: string): bool # returns true if the rope r is the same as the contents of file f -proc RopeInvariant*(r: PRope): bool +proc ropeInvariant*(r: PRope): bool # exported for debugging # implementation -var ErrorHandler*: proc(err: TRopesError, msg: string, useWarning = false) +var errorHandler*: proc(err: TRopesError, msg: string, useWarning = false) # avoid dependency on msgs.nim proc ropeLen(a: PRope): int = @@ -126,7 +126,7 @@ proc resetRopeCache* = for i in low(cache)..high(cache): cache[i] = nil -proc RopeInvariant(r: PRope): bool = +proc ropeInvariant(r: PRope): bool = if r == nil: result = true else: @@ -157,14 +157,14 @@ proc toRope(s: string): PRope = result = nil else: result = insertInCache(s) - assert(RopeInvariant(result)) + assert(ropeInvariant(result)) -proc RopeSeqInsert(rs: var TRopeSeq, r: PRope, at: Natural) = +proc ropeSeqInsert(rs: var TRopeSeq, r: PRope, at: Natural) = var length = len(rs) if at > length: - setlen(rs, at + 1) + setLen(rs, at + 1) else: - setlen(rs, length + 1) # move old rope elements: + setLen(rs, length + 1) # move old rope elements: for i in countdown(length, at + 1): rs[i] = rs[i - 1] # this is correct, I used pen and paper to validate it rs[at] = r @@ -177,8 +177,8 @@ proc newRecRopeToStr(result: var string, resultLen: var int, r: PRope) = add(stack, it.right) it = it.left assert(it.data != nil) - CopyMem(addr(result[resultLen]), addr(it.data[0]), it.length) - Inc(resultLen, it.length) + copyMem(addr(result[resultLen]), addr(it.data[0]), it.length) + inc(resultLen, it.length) assert(resultLen <= len(result)) proc ropeToStr(p: PRope): string = @@ -227,13 +227,13 @@ proc writeRope*(f: TFile, c: PRope) = assert(it.data != nil) write(f, it.data) -proc WriteRope*(head: PRope, filename: string, useWarning = false) = - var f: tfile +proc writeRope*(head: PRope, filename: string, useWarning = false) = + var f: TFile if open(f, filename, fmWrite): - if head != nil: WriteRope(f, head) + if head != nil: writeRope(f, head) close(f) else: - ErrorHandler(rCannotOpenFile, filename, useWarning) + errorHandler(rCannotOpenFile, filename, useWarning) var rnl* = tnl.newRope @@ -258,12 +258,12 @@ proc ropef(frmt: TFormatStr, args: varargs[PRope]): PRope = of '0'..'9': var j = 0 while true: - j = (j * 10) + Ord(frmt[i]) - ord('0') + j = (j * 10) + ord(frmt[i]) - ord('0') inc(i) if (i > length + 0 - 1) or not (frmt[i] in {'0'..'9'}): break num = j if j > high(args) + 1: - ErrorHandler(rInvalidFormatStr, $(j)) + errorHandler(rInvalidFormatStr, $(j)) else: app(result, args[j - 1]) of 'n': @@ -273,22 +273,25 @@ proc ropef(frmt: TFormatStr, args: varargs[PRope]): PRope = app(result, rnl) inc(i) else: - ErrorHandler(rInvalidFormatStr, $(frmt[i])) + errorHandler(rInvalidFormatStr, $(frmt[i])) var start = i while i < length: if frmt[i] != '$': inc(i) else: break if i - 1 >= start: app(result, substr(frmt, start, i - 1)) - assert(RopeInvariant(result)) - -{.push stack_trace: off, line_trace: off.} -proc `~`*(r: expr[string]): PRope = - # this is the new optimized "to rope" operator - # the mnemonic is that `~` looks a bit like a rope :) - var r {.global.} = r.ropef - return r -{.pop.} + assert(ropeInvariant(result)) + +when true: + template `~`*(r: string): PRope = r.ropef +else: + {.push stack_trace: off, line_trace: off.} + proc `~`*(r: static[string]): PRope = + # this is the new optimized "to rope" operator + # the mnemonic is that `~` looks a bit like a rope :) + var r {.global.} = r.ropef + return r + {.pop.} proc appf(c: var PRope, frmt: TFormatStr, args: varargs[PRope]) = app(c, ropef(frmt, args)) @@ -296,10 +299,10 @@ proc appf(c: var PRope, frmt: TFormatStr, args: varargs[PRope]) = const bufSize = 1024 # 1 KB is reasonable -proc auxRopeEqualsFile(r: PRope, bin: var tfile, buf: Pointer): bool = +proc auxRopeEqualsFile(r: PRope, bin: var TFile, buf: pointer): bool = if r.data != nil: if r.length > bufSize: - ErrorHandler(rTokenTooLong, r.data) + errorHandler(rTokenTooLong, r.data) return var readBytes = readBuffer(bin, buf, r.length) result = readBytes == r.length and @@ -308,12 +311,12 @@ proc auxRopeEqualsFile(r: PRope, bin: var tfile, buf: Pointer): bool = result = auxRopeEqualsFile(r.left, bin, buf) if result: result = auxRopeEqualsFile(r.right, bin, buf) -proc RopeEqualsFile(r: PRope, f: string): bool = - var bin: tfile +proc ropeEqualsFile(r: PRope, f: string): bool = + var bin: TFile result = open(bin, f) if not result: return # not equal if file does not exist - var buf = alloc(BufSize) + var buf = alloc(bufSize) result = auxRopeEqualsFile(r, bin, buf) if result: result = readBuffer(bin, buf, bufSize) == 0 # really at the end of file? @@ -346,7 +349,7 @@ proc newCrcFromRopeAux(r: PRope, startVal: TCrc32): TCrc32 = inc(i) proc crcFromRope(r: PRope): TCrc32 = - result = newCrcFromRopeAux(r, initCrc32) + result = newCrcFromRopeAux(r, InitCrc32) proc writeRopeIfNotEqual(r: PRope, filename: string): bool = # returns true if overwritten diff --git a/compiler/saturate.nim b/compiler/saturate.nim index e0968843b..ed197bdd1 100644 --- a/compiler/saturate.nim +++ b/compiler/saturate.nim @@ -9,7 +9,7 @@ ## Saturated arithmetic routines. XXX Make part of the stdlib? -proc `|+|`*(a, b: biggestInt): biggestInt = +proc `|+|`*(a, b: BiggestInt): BiggestInt = ## saturated addition. result = a +% b if (result xor a) >= 0'i64 or (result xor b) >= 0'i64: @@ -19,7 +19,7 @@ proc `|+|`*(a, b: biggestInt): biggestInt = else: result = high(result) -proc `|-|`*(a, b: biggestInt): biggestInt = +proc `|-|`*(a, b: BiggestInt): BiggestInt = result = a -% b if (result xor a) >= 0'i64 or (result xor not b) >= 0'i64: return result @@ -28,14 +28,14 @@ proc `|-|`*(a, b: biggestInt): biggestInt = else: result = high(result) -proc `|abs|`*(a: biggestInt): biggestInt = +proc `|abs|`*(a: BiggestInt): BiggestInt = if a != low(a): if a >= 0: result = a else: result = -a else: result = low(a) -proc `|div|`*(a, b: biggestInt): biggestInt = +proc `|div|`*(a, b: BiggestInt): BiggestInt = # (0..5) div (0..4) == (0..5) div (1..4) == (0 div 4) .. (5 div 1) if b == 0'i64: # make the same as ``div 1``: @@ -45,13 +45,13 @@ proc `|div|`*(a, b: biggestInt): biggestInt = else: result = a div b -proc `|mod|`*(a, b: biggestInt): biggestInt = +proc `|mod|`*(a, b: BiggestInt): BiggestInt = if b == 0'i64: result = a else: result = a mod b -proc `|*|`*(a, b: biggestInt): biggestInt = +proc `|*|`*(a, b: BiggestInt): BiggestInt = var resAsFloat, floatProd: float64 result = a *% b diff --git a/compiler/sem.nim b/compiler/sem.nim index 3ace623bc..e89e32f4e 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -14,8 +14,8 @@ import wordrecg, ropes, msgs, os, condsyms, idents, renderer, types, platform, math, magicsys, parser, nversion, nimsets, semfold, importer, procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch, - semthreads, intsets, transf, evals, idgen, aliases, cgmeth, lambdalifting, - evaltempl, patterns, parampatterns, sempass2 + semthreads, intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting, + evaltempl, patterns, parampatterns, sempass2, pretty, semmacrosanity # implementation @@ -43,30 +43,30 @@ proc activate(c: PContext, n: PNode) proc semQuoteAst(c: PContext, n: PNode): PNode proc finishMethod(c: PContext, s: PSym) -proc IndexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode +proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode proc typeMismatch(n: PNode, formal, actual: PType) = if formal.kind != tyError and actual.kind != tyError: - LocalError(n.Info, errGenerated, msgKindToString(errTypeMismatch) & + localError(n.info, errGenerated, msgKindToString(errTypeMismatch) & typeToString(actual) & ") " & `%`(msgKindToString(errButExpectedX), [typeToString(formal)])) proc fitNode(c: PContext, formal: PType, arg: PNode): PNode = if arg.typ.isNil: - LocalError(arg.info, errExprXHasNoType, + localError(arg.info, errExprXHasNoType, renderTree(arg, {renderNoComments})) # error correction: result = copyNode(arg) result.typ = formal else: - result = IndexTypesMatch(c, formal, arg.typ, arg) + result = indexTypesMatch(c, formal, arg.typ, arg) if result == nil: typeMismatch(arg, formal, arg.typ) # error correction: - result = copyNode(arg) + result = copyTree(arg) result.typ = formal -var CommonTypeBegin = PType(kind: tyExpr) +var commonTypeBegin = PType(kind: tyExpr) proc commonType*(x, y: PType): PType = # new type relation that is used for array constructors, @@ -134,8 +134,8 @@ proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym = # like newSymS, but considers gensym'ed symbols if n.kind == nkSym: result = n.sym - InternalAssert sfGenSym in result.flags - InternalAssert result.kind == kind + internalAssert sfGenSym in result.flags + internalAssert result.kind == kind else: result = newSym(kind, considerAcc(n), getCurrOwner(), n.info) @@ -146,73 +146,108 @@ proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode, allowed: TSymFlags): PSym proc semStmtScope(c: PContext, n: PNode): PNode -proc ParamsTypeCheck(c: PContext, typ: PType) {.inline.} = +proc paramsTypeCheck(c: PContext, typ: PType) {.inline.} = if not typeAllowed(typ, skConst): - LocalError(typ.n.info, errXisNoType, typeToString(typ)) + localError(typ.n.info, errXisNoType, typeToString(typ)) proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym proc semTemplateExpr(c: PContext, n: PNode, s: PSym, semCheck = true): PNode proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode proc semWhen(c: PContext, n: PNode, semCheck: bool = true): PNode -proc IsOpImpl(c: PContext, n: PNode): PNode +proc isOpImpl(c: PContext, n: PNode): PNode proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, semCheck: bool = true): PNode +proc symFromType(t: PType, info: TLineInfo): PSym = + if t.sym != nil: return t.sym + result = newSym(skType, getIdent"AnonType", t.owner, info) + result.flags.incl sfAnon + result.typ = t + +proc symNodeFromType(c: PContext, t: PType, info: TLineInfo): PNode = + result = newSymNode(symFromType(t, info), info) + result.typ = makeTypeDesc(c, t) + when false: - proc symFromType(t: PType, info: TLineInfo): PSym = - if t.sym != nil: return t.sym - result = newSym(skType, getIdent"AnonType", t.owner, info) - result.flags.incl sfAnon - result.typ = t - - proc symNodeFromType(c: PContext, t: PType, info: TLineInfo): PNode = - result = newSymNode(symFromType(t, info), info) - result.typ = makeTypeDesc(c, t) - -proc createEvalContext(c: PContext, mode: TEvalMode): PEvalContext = - result = newEvalContext(c.module, mode) - result.getType = proc (n: PNode): PNode = - result = tryExpr(c, n) - if result == nil: - result = newSymNode(errorSym(c, n)) - elif result.typ == nil: - result = newSymNode(getSysSym"void") + proc createEvalContext(c: PContext, mode: TEvalMode): PEvalContext = + result = newEvalContext(c.module, mode) + result.getType = proc (n: PNode): PNode = + result = tryExpr(c, n) + if result == nil: + result = newSymNode(errorSym(c, n)) + elif result.typ == nil: + result = newSymNode(getSysSym"void") + else: + result.typ = makeTypeDesc(c, result.typ) + + result.handleIsOperator = proc (n: PNode): PNode = + result = isOpImpl(c, n) + +proc fixupTypeAfterEval(c: PContext, evaluated, eOrig: PNode): PNode = + # recompute the types as 'eval' isn't guaranteed to construct types nor + # that the types are sound: + when true: + if eOrig.typ.kind in {tyExpr, tyStmt, tyTypeDesc}: + result = semExprWithType(c, evaluated) else: - result.typ = makeTypeDesc(c, result.typ) + result = evaluated + semmacrosanity.annotateType(result, eOrig.typ) + else: + result = semExprWithType(c, evaluated) + #result = fitNode(c, e.typ, result) inlined with special case: + let arg = result + result = indexTypesMatch(c, eOrig.typ, arg.typ, arg) + if result == nil: + result = arg + # for 'tcnstseq' we support [] to become 'seq' + if eOrig.typ.skipTypes(abstractInst).kind == tySequence and + arg.typ.skipTypes(abstractInst).kind == tyArrayConstr: + arg.typ = eOrig.typ - result.handleIsOperator = proc (n: PNode): PNode = - result = IsOpImpl(c, n) +proc tryConstExpr(c: PContext, n: PNode): PNode = + var e = semExprWithType(c, n) + if e == nil: return + + result = getConstExpr(c.module, e) + if result != nil: return -proc evalConstExpr(c: PContext, module: PSym, e: PNode): PNode = - result = evalConstExprAux(c.createEvalContext(emConst), module, nil, e) + try: + result = evalConstExpr(c.module, e) + if result == nil or result.kind == nkEmpty: + return nil -proc evalStaticExpr(c: PContext, module: PSym, e: PNode, prc: PSym): PNode = - result = evalConstExprAux(c.createEvalContext(emStatic), module, prc, e) + result = fixupTypeAfterEval(c, result, e) + except: + return nil proc semConstExpr(c: PContext, n: PNode): PNode = var e = semExprWithType(c, n) if e == nil: - LocalError(n.info, errConstExprExpected) + localError(n.info, errConstExprExpected) return n result = getConstExpr(c.module, e) if result == nil: - result = evalConstExpr(c, c.module, e) + result = evalConstExpr(c.module, e) if result == nil or result.kind == nkEmpty: if e.info != n.info: pushInfoContext(n.info) - LocalError(e.info, errConstExprExpected) + localError(e.info, errConstExprExpected) popInfoContext() else: - LocalError(e.info, errConstExprExpected) + localError(e.info, errConstExprExpected) # error correction: result = e + else: + result = fixupTypeAfterEval(c, result, e) include hlo, seminst, semcall proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode = inc(evalTemplateCounter) if evalTemplateCounter > 100: - GlobalError(s.info, errTemplateInstantiationTooNested) + globalError(s.info, errTemplateInstantiationTooNested) + let oldFriend = c.friendModule + c.friendModule = s.owner.getModule result = n if s.typ.sons[0] == nil: @@ -236,17 +271,18 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode = result = fitNode(c, s.typ.sons[0], result) #GlobalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0])) dec(evalTemplateCounter) + c.friendModule = oldFriend proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, semCheck: bool = true): PNode = markUsed(n, sym) if sym == c.p.owner: - GlobalError(n.info, errRecursiveDependencyX, sym.name.s) + globalError(n.info, errRecursiveDependencyX, sym.name.s) - if c.evalContext == nil: - c.evalContext = c.createEvalContext(emStatic) + #if c.evalContext == nil: + # c.evalContext = c.createEvalContext(emStatic) - result = evalMacroCall(c.evalContext, n, nOrig, sym) + result = evalMacroCall(c.module, n, nOrig, sym) if semCheck: result = semAfterMacroCall(c, result, sym) proc forceBool(c: PContext, n: PNode): PNode = @@ -257,13 +293,21 @@ proc semConstBoolExpr(c: PContext, n: PNode): PNode = let nn = semExprWithType(c, n) result = fitNode(c, getSysType(tyBool), nn) if result == nil: - LocalError(n.info, errConstExprExpected) + localError(n.info, errConstExprExpected) return nn result = getConstExpr(c.module, result) if result == nil: - LocalError(n.info, errConstExprExpected) + localError(n.info, errConstExprExpected) result = nn +type + TSemGenericFlag = enum + withinBind, withinTypeDesc, withinMixin + TSemGenericFlags = set[TSemGenericFlag] + +proc semGenericStmt(c: PContext, n: PNode, flags: TSemGenericFlags, + ctx: var TIntSet): PNode + include semtypes, semtempl, semgnrc, semstmts, semexprs proc addCodeForGenerics(c: PContext, n: PNode) = @@ -271,17 +315,18 @@ proc addCodeForGenerics(c: PContext, n: PNode) = var prc = c.generics[i].inst.sym if prc.kind in {skProc, skMethod, skConverter} and prc.magic == mNone: if prc.ast == nil or prc.ast.sons[bodyPos] == nil: - InternalError(prc.info, "no code for " & prc.name.s) + internalError(prc.info, "no code for " & prc.name.s) else: addSon(n, prc.ast) c.lastGenericIdx = c.generics.len proc myOpen(module: PSym): PPassContext = var c = newContext(module) - if c.p != nil: InternalError(module.info, "sem.myOpen") + if c.p != nil: internalError(module.info, "sem.myOpen") c.semConstExpr = semConstExpr c.semExpr = semExpr c.semTryExpr = tryExpr + c.semTryConstExpr = tryConstExpr c.semOperand = semOperand c.semConstBoolExpr = semConstBoolExpr c.semOverloadedCall = semOverloadedCall @@ -291,10 +336,10 @@ proc myOpen(module: PSym): PPassContext = c.importTable = openScope(c) c.importTable.addSym(module) # a module knows itself if sfSystemModule in module.flags: - magicsys.SystemModule = module # set global variable! + magicsys.systemModule = module # set global variable! else: - c.importTable.addSym magicsys.SystemModule # import the "System" identifier - importAllSymbols(c, magicsys.SystemModule) + c.importTable.addSym magicsys.systemModule # import the "System" identifier + importAllSymbols(c, magicsys.systemModule) c.topLevelScope = openScope(c) result = c @@ -302,7 +347,7 @@ proc myOpenCached(module: PSym, rd: PRodReader): PPassContext = result = myOpen(module) for m in items(rd.methods): methodDef(m, true) -proc SemStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = +proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = result = semStmt(c, n) # BUGFIX: process newly generated generics here, not at the end! if c.lastGenericIdx < c.generics.len: @@ -317,7 +362,7 @@ proc SemStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = result = buildEchoStmt(c, result) result = transformStmt(c.module, result) -proc RecoverContext(c: PContext) = +proc recoverContext(c: PContext) = # clean up in case of a semantic error: We clean up the stacks, etc. This is # faster than wrapping every stack operation in a 'try finally' block and # requires far less code. @@ -329,15 +374,15 @@ proc myProcess(context: PPassContext, n: PNode): PNode = var c = PContext(context) # no need for an expensive 'try' if we stop after the first error anyway: if msgs.gErrorMax <= 1: - result = SemStmtAndGenerateGenerics(c, n) + result = semStmtAndGenerateGenerics(c, n) else: let oldContextLen = msgs.getInfoContextLen() - let oldInGenericInst = c.InGenericInst + let oldInGenericInst = c.inGenericInst try: - result = SemStmtAndGenerateGenerics(c, n) + result = semStmtAndGenerateGenerics(c, n) except ERecoverableError, ESuggestDone: - RecoverContext(c) - c.InGenericInst = oldInGenericInst + recoverContext(c) + c.inGenericInst = oldInGenericInst msgs.setInfoContextLen(oldContextLen) if getCurrentException() of ESuggestDone: result = nil else: result = ast.emptyNode @@ -346,7 +391,7 @@ proc myProcess(context: PPassContext, n: PNode): PNode = proc checkThreads(c: PContext) = if not needsGlobalAnalysis(): return for i in 0 .. c.threadEntries.len-1: - semthreads.AnalyseThreadProc(c.threadEntries[i]) + semthreads.analyseThreadProc(c.threadEntries[i]) proc myClose(context: PPassContext, n: PNode): PNode = var c = PContext(context) @@ -354,7 +399,7 @@ proc myClose(context: PPassContext, n: PNode): PNode = rawCloseScope(c) # imported symbols; don't check for unused ones! result = newNode(nkStmtList) if n != nil: - InternalError(n.info, "n is not nil") #result := n; + internalError(n.info, "n is not nil") #result := n; addCodeForGenerics(c, result) if c.module.ast != nil: result.add(c.module.ast) diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 9e9614796..5990f2e96 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -19,7 +19,7 @@ proc sameMethodDispatcher(a, b: PSym): bool = if aa.sym == bb.sym: result = true else: - nil + discard # generics have no dispatcher yet, so we need to compare the method # names; however, the names are equal anyway because otherwise we # wouldn't even consider them to be overloaded. But even this does @@ -47,14 +47,14 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode, var z: TCandidate if sym == nil: return - initCandidate(best, sym, initialBinding, symScope) - initCandidate(alt, sym, initialBinding, symScope) + initCandidate(c, best, sym, initialBinding, symScope) + initCandidate(c, alt, sym, initialBinding, symScope) best.state = csNoMatch while sym != nil: if sym.kind in filter: determineType(c, sym) - initCandidate(z, sym, initialBinding, o.lastOverloadScope) + initCandidate(c, z, sym, initialBinding, o.lastOverloadScope) z.calleeSym = sym matches(c, n, orig, z) if errors != nil: @@ -74,13 +74,13 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode, else: nil sym = nextOverloadIter(o, c, headSymbol) -proc NotFoundError*(c: PContext, n: PNode, errors: seq[string]) = +proc notFoundError*(c: PContext, n: PNode, errors: seq[string]) = # Gives a detailed error message; this is separated from semOverloadedCall, # as semOverlodedCall is already pretty slow (and we need this information # only in case of an error). - if c.InCompilesContext > 0: + if c.inCompilesContext > 0: # fail fast: - GlobalError(n.info, errTypeMismatch, "") + globalError(n.info, errTypeMismatch, "") var result = msgKindToString(errTypeMismatch) add(result, describeArgs(c, n, 1 + ord(nfDelegate in n.flags))) add(result, ')') @@ -93,7 +93,7 @@ proc NotFoundError*(c: PContext, n: PNode, errors: seq[string]) = if candidates != "": add(result, "\n" & msgKindToString(errButExpected) & "\n" & candidates) - LocalError(n.Info, errGenerated, result) + localError(n.info, errGenerated, result) proc gatherUsedSyms(c: PContext, usedSyms: var seq[PNode]) = for scope in walkScopes(c.currentScope): @@ -139,7 +139,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode, let overloadsState = result.state if overloadsState != csMatch: if nfDelegate in n.flags: - InternalAssert f.kind == nkIdent + internalAssert f.kind == nkIdent let calleeName = newStrNode(nkStrLit, f.ident.s) calleeName.info = n.info @@ -150,26 +150,26 @@ proc resolveOverloads(c: PContext, n, orig: PNode, pickBest(callOp) if overloadsState == csEmpty and result.state == csEmpty: - LocalError(n.info, errUndeclaredIdentifier, considerAcc(f).s) + localError(n.info, errUndeclaredIdentifier, considerAcc(f).s) return elif result.state != csMatch: if nfExprCall in n.flags: - LocalError(n.info, errExprXCannotBeCalled, + localError(n.info, errExprXCannotBeCalled, renderTree(n, {renderNoComments})) else: errors = @[] pickBest(f) - NotFoundError(c, n, errors) + notFoundError(c, n, errors) return if alt.state == csMatch and cmpCandidates(result, alt) == 0 and not sameMethodDispatcher(result.calleeSym, alt.calleeSym): - InternalAssert result.state == csMatch + internalAssert result.state == csMatch #writeMatches(result) #writeMatches(alt) if c.inCompilesContext > 0: # quick error message for performance of 'compiles' built-in: - GlobalError(n.Info, errGenerated, "ambiguous call") + globalError(n.info, errGenerated, "ambiguous call") elif gErrorCounter == 0: # don't cascade errors var args = "(" @@ -178,7 +178,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode, add(args, typeToString(n.sons[i].typ)) add(args, ")") - LocalError(n.Info, errGenerated, msgKindToString(errAmbiguousCallXYZ) % [ + localError(n.info, errGenerated, msgKindToString(errAmbiguousCallXYZ) % [ getProcHeader(result.calleeSym), getProcHeader(alt.calleeSym), args]) @@ -197,17 +197,17 @@ proc instGenericConvertersSons*(c: PContext, n: PNode, x: TCandidate) = for i in 1 .. <n.len: instGenericConvertersArg(c, n.sons[i], x) -proc IndexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode = +proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode = var m: TCandidate - initCandidate(m, f) - result = paramTypesMatch(c, m, f, a, arg, nil) + initCandidate(c, m, f) + result = paramTypesMatch(m, f, a, arg, nil) if m.genericConverter and result != nil: instGenericConvertersArg(c, result, m) -proc ConvertTo*(c: PContext, f: PType, n: PNode): PNode = +proc convertTo*(c: PContext, f: PType, n: PNode): PNode = var m: TCandidate - initCandidate(m, f) - result = paramTypesMatch(c, m, f, n.typ, n, nil) + initCandidate(c, m, f) + result = paramTypesMatch(m, f, n.typ, n, nil) if m.genericConverter and result != nil: instGenericConvertersArg(c, result, m) @@ -225,7 +225,7 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode = result = x.call result.sons[0] = newSymNode(finalCallee, result.sons[0].info) result.typ = finalCallee.typ.sons[0] - if ContainsGenericType(result.typ): result.typ = errorType(c) + if containsGenericType(result.typ): result.typ = errorType(c) return result = x.call instGenericConvertersSons(c, result, x) @@ -239,13 +239,13 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode, # else: result = errorNode(c, n) proc explicitGenericInstError(n: PNode): PNode = - LocalError(n.info, errCannotInstantiateX, renderTree(n)) + localError(n.info, errCannotInstantiateX, renderTree(n)) result = n proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode = - var x: TCandidate - initCandidate(x, s, n) - var newInst = generateInstance(c, s, x.bindings, n.info) + var m: TCandidate + initCandidate(c, m, s, n) + var newInst = generateInstance(c, s, m.bindings, n.info) markUsed(n, s) result = newSymNode(newInst, n.info) @@ -260,7 +260,7 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = # number of generic type parameters: if safeLen(s.ast.sons[genericParamsPos]) != n.len-1: let expected = safeLen(s.ast.sons[genericParamsPos]) - LocalError(n.info, errGenerated, "cannot instantiate: " & renderTree(n) & + localError(n.info, errGenerated, "cannot instantiate: " & renderTree(n) & "; got " & $(n.len-1) & " type(s) but expected " & $expected) return n result = explicitGenericSym(c, n, s) @@ -283,7 +283,7 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = else: result = explicitGenericInstError(n) -proc SearchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym = +proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym = # Searchs for the fn in the symbol table. If the parameter lists are suitable # for borrowing the sym in the symbol table is returned, else nil. # New approach: generate fn(x, y, z) where x, y, z have the proper types diff --git a/compiler/semdata.nim b/compiler/semdata.nim index d02359d4c..980abb865 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -13,7 +13,7 @@ import strutils, lists, intsets, options, lexer, ast, astalgo, trees, treetab, wordrecg, ropes, msgs, platform, os, condsyms, idents, renderer, types, extccomp, math, - magicsys, nversion, nimsets, parser, times, passes, rodread, evals + magicsys, nversion, nimsets, parser, times, passes, rodread, vmdef type TOptionEntry* = object of lists.TListEntry # entries to put on a @@ -21,7 +21,7 @@ type options*: TOptions defaultCC*: TCallingConvention dynlib*: PLib - Notes*: TNoteKinds + notes*: TNoteKinds otherPragmas*: PNode # every pragma can be pushed POptionEntry* = ref TOptionEntry @@ -32,7 +32,7 @@ type resultSym*: PSym # the result symbol (if we are in a proc) nestedLoopCounter*: int # whether we are in a loop or not nestedBlockCounter*: int # whether we are in a block or not - InTryStmt*: int # whether we are in a try statement; works also + inTryStmt*: int # whether we are in a try statement; works also # in standalone ``except`` and ``finally`` next*: PProcCon # used for stacking procedure contexts @@ -55,16 +55,16 @@ type friendModule*: PSym # current friend module; may access private data; # this is used so that generic instantiations # can access private object fields - InstCounter*: int # to prevent endless instantiations + instCounter*: int # to prevent endless instantiations threadEntries*: TSymSeq # list of thread entries to check - AmbiguousSymbols*: TIntSet # ids of all ambiguous symbols (cannot + ambiguousSymbols*: TIntSet # ids of all ambiguous symbols (cannot # store this info in the syms themselves!) - InTypeClass*: int # > 0 if we are in a user-defined type class - InGenericContext*: int # > 0 if we are in a generic type - InUnrolledContext*: int # > 0 if we are unrolling a loop - InCompilesContext*: int # > 0 if we are in a ``compiles`` magic - InGenericInst*: int # > 0 if we are instantiating a generic + inTypeClass*: int # > 0 if we are in a user-defined type class + inGenericContext*: int # > 0 if we are in a generic type + inUnrolledContext*: int # > 0 if we are unrolling a loop + inCompilesContext*: int # > 0 if we are in a ``compiles`` magic + inGenericInst*: int # > 0 if we are instantiating a generic converters*: TSymSeq # sequence of converters patterns*: TSymSeq # sequence of pattern matchers optionStack*: TLinkedList @@ -75,6 +75,7 @@ type semExpr*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.} semTryExpr*: proc (c: PContext, n: PNode,flags: TExprFlags = {}, bufferErrors = false): PNode {.nimcall.} + semTryConstExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} semOperand*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.} semConstBoolExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # XXX bite the bullet semOverloadedCall*: proc (c: PContext, n, nOrig: PNode, @@ -83,7 +84,7 @@ type includedFiles*: TIntSet # used to detect recursive include files userPragmas*: TStrTable evalContext*: PEvalContext - UnknownIdents*: TIntSet # ids of all unknown identifiers to prevent + unknownIdents*: TIntSet # ids of all unknown identifiers to prevent # naming it multiple times generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile lastGenericIdx*: int # used for the generics stack @@ -114,8 +115,8 @@ proc scopeDepth*(c: PContext): int {.inline.} = # owner handling: proc getCurrOwner*(): PSym -proc PushOwner*(owner: PSym) -proc PopOwner*() +proc pushOwner*(owner: PSym) +proc popOwner*() # implementation var gOwners*: seq[PSym] = @[] @@ -128,20 +129,20 @@ proc getCurrOwner(): PSym = # BUGFIX: global array is needed! result = gOwners[high(gOwners)] -proc PushOwner(owner: PSym) = +proc pushOwner(owner: PSym) = add(gOwners, owner) -proc PopOwner() = +proc popOwner() = var length = len(gOwners) - if length > 0: setlen(gOwners, length - 1) - else: InternalError("popOwner") + if length > 0: setLen(gOwners, length - 1) + else: internalError("popOwner") proc lastOptionEntry(c: PContext): POptionEntry = result = POptionEntry(c.optionStack.tail) proc pushProcCon*(c: PContext, owner: PSym) {.inline.} = if owner == nil: - InternalError("owner is nil") + internalError("owner is nil") return var x: PProcCon new(x) @@ -160,7 +161,7 @@ proc newOptionEntry(): POptionEntry = proc newContext(module: PSym): PContext = new(result) - result.AmbiguousSymbols = initIntset() + result.ambiguousSymbols = initIntSet() initLinkedList(result.optionStack) initLinkedList(result.libs) append(result.optionStack, newOptionEntry()) @@ -172,13 +173,13 @@ proc newContext(module: PSym): PContext = result.includedFiles = initIntSet() initStrTable(result.userPragmas) result.generics = @[] - result.UnknownIdents = initIntSet() + result.unknownIdents = initIntSet() proc inclSym(sq: var TSymSeq, s: PSym) = var L = len(sq) for i in countup(0, L - 1): if sq[i].id == s.id: return - setlen(sq, L + 1) + setLen(sq, L + 1) sq[L] = s proc addConverter*(c: PContext, conv: PSym) = @@ -198,29 +199,55 @@ proc addToLib(lib: PLib, sym: PSym) = proc makePtrType(c: PContext, baseType: PType): PType = result = newTypeS(tyPtr, c) - addSonSkipIntLit(result, baseType.AssertNotNil) + addSonSkipIntLit(result, baseType.assertNotNil) proc makeVarType(c: PContext, baseType: PType): PType = result = newTypeS(tyVar, c) - addSonSkipIntLit(result, baseType.AssertNotNil) + addSonSkipIntLit(result, baseType.assertNotNil) proc makeTypeDesc*(c: PContext, typ: PType): PType = result = newTypeS(tyTypeDesc, c) - result.addSonSkipIntLit(typ.AssertNotNil) + result.addSonSkipIntLit(typ.assertNotNil) proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode = let typedesc = makeTypeDesc(c, typ) let sym = newSym(skType, idAnon, getCurrOwner(), info).linkTo(typedesc) return newSymNode(sym, info) -proc newTypeS(kind: TTypeKind, c: PContext): PType = - result = newType(kind, getCurrOwner()) +proc makeTypeFromExpr*(c: PContext, n: PNode): PType = + result = newTypeS(tyFromExpr, c) + result.n = n proc newTypeWithSons*(c: PContext, kind: TTypeKind, sons: seq[PType]): PType = result = newType(kind, getCurrOwner()) result.sons = sons +proc makeStaticExpr*(c: PContext, n: PNode): PNode = + result = newNodeI(nkStaticExpr, n.info) + result.sons = @[n] + result.typ = newTypeWithSons(c, tyStatic, @[n.typ]) + +proc makeAndType*(c: PContext, t1, t2: PType): PType = + result = newTypeS(tyAnd, c) + result.sons = @[t1, t2] + propagateToOwner(result, t1) + propagateToOwner(result, t2) + +proc makeOrType*(c: PContext, t1, t2: PType): PType = + result = newTypeS(tyOr, c) + result.sons = @[t1, t2] + propagateToOwner(result, t1) + propagateToOwner(result, t2) + +proc makeNotType*(c: PContext, t1: PType): PType = + result = newTypeS(tyNot, c) + result.sons = @[t1] + propagateToOwner(result, t1) + +proc newTypeS(kind: TTypeKind, c: PContext): PType = + result = newType(kind, getCurrOwner()) + proc errorType*(c: PContext): PType = ## creates a type representing an error state result = newTypeS(tyError, c) @@ -234,7 +261,7 @@ proc fillTypeS(dest: PType, kind: TTypeKind, c: PContext) = dest.owner = getCurrOwner() dest.size = - 1 -proc makeRangeType*(c: PContext; first, last: biggestInt; +proc makeRangeType*(c: PContext; first, last: BiggestInt; info: TLineInfo; intType = getSysType(tyInt)): PType = var n = newNodeI(nkRange, info) addSon(n, newIntTypeNode(nkIntLit, first, intType)) @@ -249,7 +276,7 @@ proc markIndirect*(c: PContext, s: PSym) {.inline.} = # XXX add to 'c' for global analysis proc illFormedAst*(n: PNode) = - GlobalError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments})) + globalError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments})) proc checkSonsLen*(n: PNode, length: int) = if sonsLen(n) != length: illFormedAst(n) diff --git a/compiler/semdestruct.nim b/compiler/semdestruct.nim index 797d8895e..9dbbf2940 100644 --- a/compiler/semdestruct.nim +++ b/compiler/semdestruct.nim @@ -9,26 +9,39 @@ ## This module implements destructors. +# included from sem.nim # special marker values that indicates that we are # 1) AnalyzingDestructor: currently analyzing the type for destructor # generation (needed for recursive types) # 2) DestructorIsTrivial: completed the analysis before and determined # that the type has a trivial destructor -var AnalyzingDestructor, DestructorIsTrivial: PSym -new(AnalyzingDestructor) -new(DestructorIsTrivial) +var analyzingDestructor, destructorIsTrivial: PSym +new(analyzingDestructor) +new(destructorIsTrivial) var destructorName = getIdent"destroy_" destructorParam = getIdent"this_" - destructorPragma = newIdentNode(getIdent"destructor", UnknownLineInfo()) + destructorPragma = newIdentNode(getIdent"destructor", unknownLineInfo()) rangeDestructorProc*: PSym -proc instantiateDestructor(c: PContext, typ: PType): bool +proc instantiateDestructor(c: PContext, typ: PType): PType proc doDestructorStuff(c: PContext, s: PSym, n: PNode) = - let t = s.typ.sons[1].skipTypes({tyVar}) + var t = s.typ.sons[1].skipTypes({tyVar}) + if t.kind == tyGenericInvokation: + for i in 1 .. <t.sonsLen: + if t.sons[i].kind != tyGenericParam: + localError(n.info, errDestructorNotGenericEnough) + return + t = t.base + elif t.kind == tyCompositeTypeClass: + t = t.base + if t.kind != tyGenericBody: + localError(n.info, errDestructorNotGenericEnough) + return + t.destructor = s # automatically insert calls to base classes' destructors if n.sons[bodyPos].kind != nkEmpty: @@ -36,15 +49,17 @@ proc doDestructorStuff(c: PContext, s: PSym, n: PNode) = # when inheriting directly from object # there will be a single nil son if t.sons[i] == nil: continue - if instantiateDestructor(c, t.sons[i]): + let destructableT = instantiateDestructor(c, t.sons[i]) + if destructableT != nil: n.sons[bodyPos].addSon(newNode(nkCall, t.sym.info, @[ - useSym(t.sons[i].destructor), + useSym(destructableT.destructor), n.sons[paramsPos][1][0]])) proc destroyField(c: PContext, field: PSym, holder: PNode): PNode = - if instantiateDestructor(c, field.typ): + let destructableT = instantiateDestructor(c, field.typ) + if destructableT != nil: result = newNode(nkCall, field.info, @[ - useSym(field.typ.destructor), + useSym(destructableT.destructor), newNode(nkDotExpr, field.info, @[holder, useSym(field)])]) proc destroyCase(c: PContext, n: PNode, holder: PNode): PNode = @@ -90,7 +105,7 @@ proc generateDestructor(c: PContext, t: PType): PNode = # Tposix_spawnattr if t.n == nil or t.n.sons == nil: return internalAssert t.n.kind == nkRecList - let destructedObj = newIdentNode(destructorParam, UnknownLineInfo()) + let destructedObj = newIdentNode(destructorParam, unknownLineInfo()) # call the destructods of all fields for s in countup(0, t.n.sons.len - 1): case t.n.sons[s].kind @@ -105,28 +120,37 @@ proc generateDestructor(c: PContext, t: PType): PNode = # base classes' destructors will be automatically called by # semProcAux for both auto-generated and user-defined destructors -proc instantiateDestructor(c: PContext, typ: PType): bool = - # returns true if the type already had a user-defined - # destructor or if the compiler generated a default - # member-wise one - var t = skipTypes(typ, {tyConst, tyMutable}) +proc instantiateDestructor(c: PContext, typ: PType): PType = + # returns nil if a variable of type `typ` doesn't require a + # destructor. Otherwise, returns the type, which holds the + # destructor that must be used for the varialbe. + # The destructor is either user-defined or automatically + # generated by the compiler in a member-wise fashion. + var t = skipTypes(typ, {tyConst, tyMutable}).skipGenericAlias + let typeHoldingUserDefinition = if t.kind == tyGenericInst: t.base + else: t - if t.destructor != nil: + if typeHoldingUserDefinition.destructor != nil: # XXX: This is not entirely correct for recursive types, but we need # it temporarily to hide the "destroy is already defined" problem - return t.destructor notin [AnalyzingDestructor, DestructorIsTrivial] + if typeHoldingUserDefinition.destructor notin + [analyzingDestructor, destructorIsTrivial]: + return typeHoldingUserDefinition + else: + return nil + t = t.skipTypes({tyGenericInst}) case t.kind of tySequence, tyArray, tyArrayConstr, tyOpenArray, tyVarargs: - if instantiateDestructor(c, t.sons[0]): + if instantiateDestructor(c, t.sons[0]) != nil: if rangeDestructorProc == nil: rangeDestructorProc = searchInScopes(c, getIdent"nimDestroyRange") t.destructor = rangeDestructorProc - return true + return t else: - return false + return nil of tyTuple, tyObject: - t.destructor = AnalyzingDestructor + t.destructor = analyzingDestructor let generated = generateDestructor(c, t) if generated != nil: internalAssert t.sym != nil @@ -139,21 +163,21 @@ proc instantiateDestructor(c: PContext, typ: PType): bool = emptyNode, newNode(nkIdentDefs, i, @[ newIdentNode(destructorParam, i), - useSym(t.sym), + symNodeFromType(c, makeVarType(c, t), t.sym.info), emptyNode]), ]), newNode(nkPragma, i, @[destructorPragma]), emptyNode, generated ]) - discard semProc(c, fullDef) - internalAssert t.destructor != nil - return true + let semantizedDef = semProc(c, fullDef) + t.destructor = semantizedDef[namePos].sym + return t else: - t.destructor = DestructorIsTrivial - return false + t.destructor = destructorIsTrivial + return nil else: - return false + return nil proc insertDestructors(c: PContext, varSection: PNode): tuple[outer, inner: PNode] = @@ -179,9 +203,11 @@ proc insertDestructors(c: PContext, varId = varSection[j][0] varTyp = varId.sym.typ info = varId.info - - if varTyp != nil and instantiateDestructor(c, varTyp) and - sfGlobal notin varId.sym.flags: + + if varTyp == nil or sfGlobal in varId.sym.flags: continue + let destructableT = instantiateDestructor(c, varTyp) + + if destructableT != nil: var tryStmt = newNodeI(nkTryStmt, info) if j < totalVars - 1: @@ -198,11 +224,11 @@ proc insertDestructors(c: PContext, else: result.inner = newNodeI(nkStmtList, info) tryStmt.addSon(result.inner) - + tryStmt.addSon( newNode(nkFinally, info, @[ semStmt(c, newNode(nkCall, info, @[ - useSym(varTyp.destructor), + useSym(destructableT.destructor), useSym(varId.sym)]))])) result.outer = newNodeI(nkStmtList, info) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 310aabc32..0d74db1ce 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -30,7 +30,7 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # XXX tyGenericInst here? if result.typ.kind == tyVar: result = newDeref(result) else: - LocalError(n.info, errExprXHasNoType, + localError(n.info, errExprXHasNoType, renderTree(result, {renderNoComments})) result.typ = errorType(c) @@ -40,9 +40,9 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # do not produce another redundant error message: #raiseRecoverableError("") result = errorNode(c, n) - if result.typ == nil or result.typ == EnforceVoidContext: + if result.typ == nil or result.typ == enforceVoidContext: # we cannot check for 'void' in macros ... - LocalError(n.info, errExprXHasNoType, + localError(n.info, errExprXHasNoType, renderTree(result, {renderNoComments})) result.typ = errorType(c) else: @@ -57,7 +57,7 @@ proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # do not produce another redundant error message: result = errorNode(c, n) if result.typ == nil: - LocalError(n.info, errExprXHasNoType, + localError(n.info, errExprXHasNoType, renderTree(result, {renderNoComments})) result.typ = errorType(c) else: @@ -102,7 +102,7 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = # if a proc accesses a global variable, it is not side effect free: if sfGlobal in s.flags: incl(c.p.owner.flags, sfSideEffect) - elif s.kind == skParam and s.typ.kind == tyExpr and s.typ.n != nil: + elif s.kind == skParam and s.typ.kind == tyStatic and s.typ.n != nil: # XXX see the hack in sigmatch.nim ... return s.typ.n result = newSymNode(s, n.info) @@ -111,13 +111,13 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = # var len = 0 # but won't be called # genericThatUsesLen(x) # marked as taking a closure? of skGenericParam: - if s.typ.kind == tyExpr: + if s.typ.kind == tyStatic: result = newSymNode(s, n.info) result.typ = s.typ elif s.ast != nil: result = semExpr(c, s.ast) else: - InternalError(n.info, "no default for") + internalError(n.info, "no default for") result = emptyNode of skType: markUsed(n, s) @@ -142,7 +142,7 @@ proc checkConversionBetweenObjects(castDest, src: PType): TConvStatus = const IntegralTypes = {tyBool, tyEnum, tyChar, tyInt..tyUInt64} -proc checkConvertible(castDest, src: PType): TConvStatus = +proc checkConvertible(c: PContext, castDest, src: PType): TConvStatus = result = convOK if sameType(castDest, src) and castDest.sym == src.sym: # don't annoy conversions that may be needed on another processor: @@ -151,19 +151,19 @@ proc checkConvertible(castDest, src: PType): TConvStatus = return var d = skipTypes(castDest, abstractVar) var s = skipTypes(src, abstractVar-{tyTypeDesc}) - while (d != nil) and (d.Kind in {tyPtr, tyRef}) and (d.Kind == s.Kind): + while (d != nil) and (d.kind in {tyPtr, tyRef}) and (d.kind == s.kind): d = base(d) s = base(s) if d == nil: result = convNotLegal - elif d.Kind == tyObject and s.Kind == tyObject: + elif d.kind == tyObject and s.kind == tyObject: result = checkConversionBetweenObjects(d, s) - elif (skipTypes(castDest, abstractVarRange).Kind in IntegralTypes) and - (skipTypes(src, abstractVarRange-{tyTypeDesc}).Kind in IntegralTypes): + elif (skipTypes(castDest, abstractVarRange).kind in IntegralTypes) and + (skipTypes(src, abstractVarRange-{tyTypeDesc}).kind in IntegralTypes): # accept conversion between integral types else: # we use d, s here to speed up that operation a bit: - case cmpTypes(d, s) + case cmpTypes(c, d, s) of isNone, isGeneric: if not compareTypes(castDest, src, dcEqIgnoreDistinct): result = convNotLegal @@ -175,7 +175,7 @@ proc isCastable(dst, src: PType): bool = # castableTypeKinds = {tyInt, tyPtr, tyRef, tyCstring, tyString, # tySequence, tyPointer, tyNil, tyOpenArray, # tyProc, tySet, tyEnum, tyBool, tyChar} - var ds, ss: biggestInt + var ds, ss: BiggestInt # this is very unrestrictive; cast is allowed if castDest.size >= src.size ds = computeSize(dst) ss = computeSize(src) @@ -193,7 +193,7 @@ proc isSymChoice(n: PNode): bool {.inline.} = proc semConv(c: PContext, n: PNode): PNode = if sonsLen(n) != 2: - LocalError(n.info, errConvNeedsOneArg) + localError(n.info, errConvNeedsOneArg) return n result = newNodeI(nkConv, n.info) result.typ = semTypeNode(c, n.sons[0], nil).skipTypes({tyGenericInst}) @@ -202,18 +202,18 @@ proc semConv(c: PContext, n: PNode): PNode = var op = result.sons[1] if not isSymChoice(op): - let status = checkConvertible(result.typ, op.typ) + let status = checkConvertible(c, result.typ, op.typ) case status of convOK: nil of convNotNeedeed: - Message(n.info, hintConvFromXtoItselfNotNeeded, result.typ.typeToString) + message(n.info, hintConvFromXtoItselfNotNeeded, result.typ.typeToString) of convNotLegal: - LocalError(n.info, errGenerated, MsgKindToString(errIllegalConvFromXtoY)% + localError(n.info, errGenerated, msgKindToString(errIllegalConvFromXtoY)% [op.typ.typeToString, result.typ.typeToString]) else: for i in countup(0, sonsLen(op) - 1): let it = op.sons[i] - let status = checkConvertible(result.typ, it.typ) + let status = checkConvertible(c, result.typ, it.typ) if status == convOK: markUsed(n, it.sym) markIndirect(c, it.sym) @@ -228,19 +228,19 @@ proc semCast(c: PContext, n: PNode): PNode = result.typ = semTypeNode(c, n.sons[0], nil) addSon(result, copyTree(n.sons[0])) addSon(result, semExprWithType(c, n.sons[1])) - if not isCastable(result.typ, result.sons[1].Typ): - LocalError(result.info, errExprCannotBeCastedToX, - typeToString(result.Typ)) - + if not isCastable(result.typ, result.sons[1].typ): + localError(result.info, errExprCannotBeCastedToX, + typeToString(result.typ)) + proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode = const opToStr: array[mLow..mHigh, string] = ["low", "high"] if sonsLen(n) != 2: - LocalError(n.info, errXExpectsTypeOrValue, opToStr[m]) + localError(n.info, errXExpectsTypeOrValue, opToStr[m]) else: n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType}) - var typ = skipTypes(n.sons[1].typ, abstractVarRange) - case typ.Kind + var typ = skipTypes(n.sons[1].typ, abstractVarRange+{tyTypeDesc}) + case typ.kind of tySequence, tyString, tyOpenArray, tyVarargs: n.typ = getSysType(tyInt) of tyArrayConstr, tyArray: @@ -249,15 +249,17 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode = # do not skip the range! n.typ = n.sons[1].typ.skipTypes(abstractVar) of tyGenericParam: - # leave it for now, it will be resolved in semtypinst - n.typ = getSysType(tyInt) + # prepare this for resolving in semtypinst: + # we must use copyTree here in order to avoid creating a cycle + # that could easily turn into an infinite recursion in semtypinst + n.typ = makeTypeFromExpr(c, n.copyTree) else: - LocalError(n.info, errInvalidArgForX, opToStr[m]) + localError(n.info, errInvalidArgForX, opToStr[m]) result = n proc semSizeof(c: PContext, n: PNode): PNode = if sonsLen(n) != 2: - LocalError(n.info, errXExpectsTypeOrValue, "sizeof") + localError(n.info, errXExpectsTypeOrValue, "sizeof") else: n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType}) #restoreOldStyleType(n.sons[1]) @@ -276,9 +278,9 @@ proc semOf(c: PContext, n: PNode): PNode = let y = skipTypes(n.sons[2].typ, abstractPtrs-{tyTypeDesc}) if x.kind == tyTypeDesc or y.kind != tyTypeDesc: - LocalError(n.info, errXExpectsObjectTypes, "of") + localError(n.info, errXExpectsObjectTypes, "of") elif b.kind != tyObject or a.kind != tyObject: - LocalError(n.info, errXExpectsObjectTypes, "of") + localError(n.info, errXExpectsObjectTypes, "of") else: let diff = inheritanceDiff(a, b) # | returns: 0 iff `a` == `b` @@ -287,24 +289,24 @@ proc semOf(c: PContext, n: PNode): PNode = # | returns: `maxint` iff `a` and `b` are not compatible at all if diff <= 0: # optimize to true: - Message(n.info, hintConditionAlwaysTrue, renderTree(n)) + message(n.info, hintConditionAlwaysTrue, renderTree(n)) result = newIntNode(nkIntLit, 1) result.info = n.info result.typ = getSysType(tyBool) return result elif diff == high(int): - LocalError(n.info, errXcanNeverBeOfThisSubtype, typeToString(a)) + localError(n.info, errXcanNeverBeOfThisSubtype, typeToString(a)) else: - LocalError(n.info, errXExpectsTwoArguments, "of") + localError(n.info, errXExpectsTwoArguments, "of") n.typ = getSysType(tyBool) result = n proc isOpImpl(c: PContext, n: PNode): PNode = - InternalAssert n.sonsLen == 3 and - n[1].kind == nkSym and n[1].sym.kind == skType and + internalAssert n.sonsLen == 3 and + n[1].typ != nil and n[1].typ.kind == tyTypeDesc and n[2].kind in {nkStrLit..nkTripleStrLit, nkType} - let t1 = n[1].sym.typ.skipTypes({tyTypeDesc}) + let t1 = n[1].typ.skipTypes({tyTypeDesc}) if n[2].kind in {nkStrLit..nkTripleStrLit}: case n[2].strVal.normalize @@ -324,15 +326,15 @@ proc isOpImpl(c: PContext, n: PNode): PNode = case t2.kind of tyTypeClasses: var m: TCandidate - InitCandidate(m, t2) + initCandidate(c, m, t2) match = matchUserTypeClass(c, m, emptyNode, t2, t1) != nil of tyOrdinal: var m: TCandidate - InitCandidate(m, t2) + initCandidate(c, m, t2) match = isOrdinalType(t1) of tySequence, tyArray, tySet: var m: TCandidate - InitCandidate(m, t2) + initCandidate(c, m, t2) match = typeRel(m, t2, t1) != isNone else: match = sameType(t1, t2) @@ -343,7 +345,7 @@ proc isOpImpl(c: PContext, n: PNode): PNode = proc semIs(c: PContext, n: PNode): PNode = if sonsLen(n) != 3: - LocalError(n.info, errXExpectsTwoArguments, "is") + localError(n.info, errXExpectsTwoArguments, "is") result = n n.typ = getSysType(tyBool) @@ -394,7 +396,7 @@ proc changeType(n: PNode, newType: PType, check: bool) = changeType(n.sons[i], elemType(newType), check) of nkPar: if newType.kind != tyTuple: - InternalError(n.info, "changeType: no tuple type for constructor") + internalError(n.info, "changeType: no tuple type for constructor") elif newType.n == nil: nil elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr: for i in countup(0, sonsLen(n) - 1): @@ -419,7 +421,7 @@ proc changeType(n: PNode, newType: PType, check: bool) = if check: let value = n.intVal if value < firstOrd(newType) or value > lastOrd(newType): - LocalError(n.info, errGenerated, "cannot convert " & $value & + localError(n.info, errGenerated, "cannot convert " & $value & " to " & typeToString(newType)) else: nil n.typ = newType @@ -431,7 +433,7 @@ proc arrayConstrType(c: PContext, n: PNode): PType = rawAddSon(typ, newTypeS(tyEmpty, c)) # needs an empty basetype! else: var x = n.sons[0] - var lastIndex: biggestInt = sonsLen(n) - 1 + var lastIndex: BiggestInt = sonsLen(n) - 1 var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyOrdinal}) addSonSkipIntLit(typ, t) typ.sons[0] = makeRangeType(c, 0, sonsLen(n) - 1, n.info) @@ -445,7 +447,7 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = rawAddSon(result.typ, newTypeS(tyEmpty, c)) # needs an empty basetype! else: var x = n.sons[0] - var lastIndex: biggestInt = 0 + var lastIndex: BiggestInt = 0 var indexType = getSysType(tyInt) if x.kind == nkExprColonExpr and sonsLen(x) == 2: var idx = semConstExpr(c, x.sons[0]) @@ -582,7 +584,7 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) = skipTypes(t.sons[i], abstractInst-{tyTypeDesc}).kind == tyVar: if isAssignable(c, n.sons[i]) notin {arLValue, arLocalLValue}: if n.sons[i].kind != nkHiddenAddr: - LocalError(n.sons[i].info, errVarForOutParamNeeded) + localError(n.sons[i].info, errVarForOutParamNeeded) return for i in countup(1, sonsLen(n) - 1): if n.sons[i].kind == nkHiddenCallConv: @@ -640,25 +642,25 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode = call.add(a) #echo "NOW evaluating at compile time: ", call.renderTree if sfCompileTime in callee.flags: - result = evalStaticExpr(c, c.module, call, c.p.owner) + result = evalStaticExpr(c.module, call, c.p.owner) if result.isNil: - LocalError(n.info, errCannotInterpretNodeX, renderTree(call)) + localError(n.info, errCannotInterpretNodeX, renderTree(call)) else: - result = evalConstExpr(c, c.module, call) + result = evalConstExpr(c.module, call) if result.isNil: result = n #if result != n: # echo "SUCCESS evaluated at compile time: ", call.renderTree proc semStaticExpr(c: PContext, n: PNode): PNode = let a = semExpr(c, n.sons[0]) - result = evalStaticExpr(c, c.module, a, c.p.owner) + result = evalStaticExpr(c.module, a, c.p.owner) if result.isNil: - LocalError(n.info, errCannotInterpretNodeX, renderTree(n)) + localError(n.info, errCannotInterpretNodeX, renderTree(n)) result = emptyNode proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode, flags: TExprFlags): PNode = - if flags*{efInTypeOf, efWantIterator} != {}: + if flags*{efInTypeof, efWantIterator} != {}: # consider: 'for x in pReturningArray()' --> we don't want the restriction # to 'skIterator' anymore; skIterator is preferred in sigmatch already for # typeof support. @@ -668,16 +670,17 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode, else: result = semOverloadedCall(c, n, nOrig, {skProc, skMethod, skConverter, skMacro, skTemplate}) + if result != nil: if result.sons[0].kind != nkSym: - InternalError("semOverloadedCallAnalyseEffects") + internalError("semOverloadedCallAnalyseEffects") return let callee = result.sons[0].sym case callee.kind of skMacro, skTemplate: nil else: if (callee.kind == skIterator) and (callee.id == c.p.owner.id): - LocalError(n.info, errRecursiveDependencyX, callee.name.s) + localError(n.info, errRecursiveDependencyX, callee.name.s) if sfNoSideEffect notin callee.flags: if {sfImportc, sfSideEffect} * callee.flags != {}: incl(c.p.owner.flags, sfSideEffect) @@ -702,16 +705,16 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = semOpAux(c, n) var t: PType = nil if n.sons[0].typ != nil: - t = skipTypes(n.sons[0].typ, abstractInst-{tyTypedesc}) + t = skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc}) if t != nil and t.kind == tyProc: # This is a proc variable, apply normal overload resolution var m: TCandidate - initCandidate(m, t) + initCandidate(c, m, t) matches(c, n, nOrig, m) if m.state != csMatch: if c.inCompilesContext > 0: # speed up error generation: - GlobalError(n.Info, errTypeMismatch, "") + globalError(n.info, errTypeMismatch, "") return emptyNode else: var hasErrorType = false @@ -726,7 +729,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = if not hasErrorType: add(msg, ")\n" & msgKindToString(errButExpected) & "\n" & typeToString(n.sons[0].typ)) - LocalError(n.Info, errGenerated, msg) + localError(n.info, errGenerated, msg) return errorNode(c, n) result = nil else: @@ -771,7 +774,7 @@ proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags): PNode = analyseIfAddressTakenInCall(c, result) if callee.magic != mNone: result = magicsAfterOverloadResolution(c, result, flags) - if c.InTypeClass == 0: + if c.inTypeClass == 0: result = evalAtCompileTime(c, result) proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = @@ -780,6 +783,7 @@ proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = #semLazyOpAux(c, n) result = semOverloadedCallAnalyseEffects(c, n, nOrig, flags) if result != nil: result = afterCallActions(c, result, nOrig, flags) + else: result = errorNode(c, n) proc buildStringify(c: PContext, arg: PNode): PNode = if arg.typ != nil and @@ -800,7 +804,7 @@ proc semEcho(c: PContext, n: PNode): PNode = let t = arg.typ if (t == nil or t.skipTypes(abstractInst).kind != tyString) and arg.kind != nkEmpty: - LocalError(n.info, errGenerated, + localError(n.info, errGenerated, "implicitly invoked '$' does not return string") let t = n.sons[0].typ if tfNoSideEffect notin t.flags: incl(c.p.owner.flags, sfSideEffect) @@ -809,11 +813,11 @@ proc semEcho(c: PContext, n: PNode): PNode = proc buildEchoStmt(c: PContext, n: PNode): PNode = # we MUST not check 'n' for semantics again here! result = newNodeI(nkCall, n.info) - var e = StrTableGet(magicsys.systemModule.Tab, getIdent"echo") + var e = strTableGet(magicsys.systemModule.tab, getIdent"echo") if e != nil: addSon(result, newSymNode(e)) else: - LocalError(n.info, errSystemNeeds, "echo") + localError(n.info, errSystemNeeds, "echo") addSon(result, errorNode(c, n)) var arg = buildStringify(c, n) # problem is: implicit '$' is not checked for semantics yet. So we give up @@ -843,7 +847,7 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent, if result != nil: return of nkRecCase: checkMinSonsLen(r, 2) - if (r.sons[0].kind != nkSym): IllFormedAst(r) + if (r.sons[0].kind != nkSym): illFormedAst(r) result = lookupInRecordAndBuildCheck(c, n, r.sons[0], field, check) if result != nil: return var s = newNodeI(nkCurly, r.info) @@ -905,8 +909,9 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = # early exit for this; see tests/compile/tbindoverload.nim: if isSymChoice(n.sons[1]): return - var s = qualifiedLookup(c, n, {checkAmbiguity, checkUndeclared}) + var s = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared}) if s != nil: + markUsed(n.sons[1], s) return semSym(c, n, s, flags) n.sons[0] = semExprWithType(c, n.sons[0], flags+{efDetermineType}) @@ -937,7 +942,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = let tParam = tbody.sons[s] if tParam.sym.name == i: let rawTyp = ty.sons[s + 1] - if rawTyp.kind == tyExpr: + if rawTyp.kind == tyStatic: return rawTyp.n else: let foundTyp = makeTypeDesc(c, rawTyp) @@ -949,7 +954,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = return # XXX: This is probably not relevant any more # reset to prevent 'nil' bug: see "tests/reject/tenumitems.nim": - ty = n.sons[0].Typ + ty = n.sons[0].typ ty = skipTypes(ty, {tyGenericInst, tyVar, tyPtr, tyRef}) var check: PNode = nil @@ -963,10 +968,10 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = if f != nil: if fieldVisible(c, f): # is the access to a public field or in the same module or in a friend? + markUsed(n.sons[1], f) n.sons[0] = makeDeref(n.sons[0]) n.sons[1] = newSymNode(f) # we now have the correct field n.typ = f.typ - markUsed(n, f) if check == nil: result = n else: @@ -976,11 +981,11 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = elif ty.kind == tyTuple and ty.n != nil: f = getSymFromList(ty.n, i) if f != nil: + markUsed(n.sons[1], f) n.sons[0] = makeDeref(n.sons[0]) n.sons[1] = newSymNode(f) n.typ = f.typ result = n - markUsed(n, f) proc dotTransformation(c: PContext, n: PNode): PNode = if isSymChoice(n.sons[1]): @@ -1037,7 +1042,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = n.sons[i] = semExprWithType(c, n.sons[i], flags*{efInTypeof, efDetermineType}) var indexType = if arr.kind == tyArray: arr.sons[0] else: getSysType(tyInt) - var arg = IndexTypesMatch(c, indexType, n.sons[1].typ, n.sons[1]) + var arg = indexTypesMatch(c, indexType, n.sons[1].typ, n.sons[1]) if arg != nil: n.sons[1] = arg result = n @@ -1059,11 +1064,11 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = {tyInt..tyInt64}: var idx = getOrdValue(n.sons[1]) if idx >= 0 and idx < sonsLen(arr): n.typ = arr.sons[int(idx)] - else: LocalError(n.info, errInvalidIndexValueForTuple) + else: localError(n.info, errInvalidIndexValueForTuple) else: - LocalError(n.info, errIndexTypesDoNotMatch) + localError(n.info, errIndexTypesDoNotMatch) result = n - else: nil + else: discard proc semArrayAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = result = semSubscript(c, n, flags) @@ -1097,9 +1102,9 @@ proc takeImplicitAddr(c: PContext, n: PNode): PNode = var valid = isAssignable(c, n) if valid != arLValue: if valid == arLocalLValue: - LocalError(n.info, errXStackEscape, renderTree(n, {renderNoComments})) + localError(n.info, errXStackEscape, renderTree(n, {renderNoComments})) else: - LocalError(n.info, errExprHasNoAddress) + localError(n.info, errExprHasNoAddress) result = newNodeIT(nkHiddenAddr, n.info, makePtrType(c, n.typ)) result.add(n) @@ -1148,7 +1153,7 @@ proc semAsgn(c: PContext, n: PNode): PNode = # a = b # b no 'var T' means: a = addr(b) var le = a.typ if skipTypes(le, {tyGenericInst}).kind != tyVar and - IsAssignable(c, a) == arNone: + isAssignable(c, a) == arNone: # Direct assignment to a discriminant is allowed! localError(a.info, errXCannotBeAssignedTo, renderTree(a, {renderNoComments})) @@ -1160,10 +1165,10 @@ proc semAsgn(c: PContext, n: PNode): PNode = rhs = semExprWithType(c, n.sons[1], if lhsIsResult: {efAllowDestructor} else: {}) if lhsIsResult: - n.typ = EnforceVoidContext - if lhs.sym.typ.kind == tyGenericParam: - if matchTypeClass(lhs.typ, rhs.typ): - InternalAssert c.p.resultSym != nil + n.typ = enforceVoidContext + if lhs.sym.typ.isMetaType and lhs.sym.typ.kind != tyTypeDesc: + if cmpTypes(c, lhs.typ, rhs.typ) == isGeneric: + internalAssert c.p.resultSym != nil lhs.typ = rhs.typ c.p.resultSym.typ = rhs.typ c.p.owner.typ.sons[0] = rhs.typ @@ -1175,7 +1180,7 @@ proc semAsgn(c: PContext, n: PNode): PNode = asgnToResultVar(c, n, n.sons[0], n.sons[1]) result = n -proc SemReturn(c: PContext, n: PNode): PNode = +proc semReturn(c: PContext, n: PNode): PNode = result = n checkSonsLen(n, 1) if c.p.owner.kind in {skConverter, skMethod, skProc, skMacro} or @@ -1191,9 +1196,9 @@ proc SemReturn(c: PContext, n: PNode): PNode = if n[0][1].kind == nkSym and n[0][1].sym == c.p.resultSym: n.sons[0] = ast.emptyNode else: - LocalError(n.info, errNoReturnTypeDeclared) + localError(n.info, errNoReturnTypeDeclared) else: - LocalError(n.info, errXNotAllowedHere, "\'return\'") + localError(n.info, errXNotAllowedHere, "\'return\'") proc semProcBody(c: PContext, n: PNode): PNode = openScope(c) @@ -1222,7 +1227,7 @@ proc semProcBody(c: PContext, n: PNode): PNode = discardCheck(c, result) closeScope(c) -proc SemYieldVarResult(c: PContext, n: PNode, restype: PType) = +proc semYieldVarResult(c: PContext, n: PNode, restype: PType) = var t = skipTypes(restype, {tyGenericInst}) case t.kind of tyVar: @@ -1241,20 +1246,20 @@ proc SemYieldVarResult(c: PContext, n: PNode, restype: PType) = localError(n.sons[0].info, errXExpected, "tuple constructor") else: nil -proc SemYield(c: PContext, n: PNode): PNode = +proc semYield(c: PContext, n: PNode): PNode = result = n checkSonsLen(n, 1) if c.p.owner == nil or c.p.owner.kind != skIterator: - LocalError(n.info, errYieldNotAllowedHere) + localError(n.info, errYieldNotAllowedHere) elif c.p.inTryStmt > 0 and c.p.owner.typ.callConv != ccInline: - LocalError(n.info, errYieldNotAllowedInTryStmt) + localError(n.info, errYieldNotAllowedInTryStmt) elif n.sons[0].kind != nkEmpty: - n.sons[0] = SemExprWithType(c, n.sons[0]) # check for type compatibility: + n.sons[0] = semExprWithType(c, n.sons[0]) # check for type compatibility: var restype = c.p.owner.typ.sons[0] if restype != nil: n.sons[0] = fitNode(c, restype, n.sons[0]) - if n.sons[0].typ == nil: InternalError(n.info, "semYield") - SemYieldVarResult(c, n, restype) + if n.sons[0].typ == nil: internalError(n.info, "semYield") + semYieldVarResult(c, n, restype) else: localError(n.info, errCannotReturnExpr) elif c.p.owner.typ.sons[0] != nil: @@ -1266,37 +1271,37 @@ proc lookUpForDefined(c: PContext, i: PIdent, onlyCurrentScope: bool): PSym = else: result = searchInScopes(c, i) # no need for stub loading -proc LookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym = +proc lookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym = case n.kind of nkIdent: - result = LookupForDefined(c, n.ident, onlyCurrentScope) + result = lookUpForDefined(c, n.ident, onlyCurrentScope) of nkDotExpr: result = nil if onlyCurrentScope: return checkSonsLen(n, 2) - var m = LookupForDefined(c, n.sons[0], onlyCurrentScope) + var m = lookUpForDefined(c, n.sons[0], onlyCurrentScope) if (m != nil) and (m.kind == skModule): if (n.sons[1].kind == nkIdent): var ident = n.sons[1].ident if m == c.module: - result = StrTableGet(c.topLevelScope.symbols, ident) + result = strTableGet(c.topLevelScope.symbols, ident) else: - result = StrTableGet(m.tab, ident) + result = strTableGet(m.tab, ident) else: - LocalError(n.sons[1].info, errIdentifierExpected, "") + localError(n.sons[1].info, errIdentifierExpected, "") of nkAccQuoted: - result = lookupForDefined(c, considerAcc(n), onlyCurrentScope) + result = lookUpForDefined(c, considerAcc(n), onlyCurrentScope) of nkSym: result = n.sym else: - LocalError(n.info, errIdentifierExpected, renderTree(n)) + localError(n.info, errIdentifierExpected, renderTree(n)) result = nil proc semDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PNode = checkSonsLen(n, 2) # we replace this node by a 'true' or 'false' node: result = newIntNode(nkIntLit, 0) - if LookUpForDefined(c, n.sons[1], onlyCurrentScope) != nil: + if lookUpForDefined(c, n.sons[1], onlyCurrentScope) != nil: result.intVal = 1 elif not onlyCurrentScope and (n.sons[1].kind == nkIdent) and condsyms.isDefined(n.sons[1].ident): @@ -1313,18 +1318,18 @@ proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym = ## The argument to the proc should be nkCall(...) or similar ## Returns the macro/template symbol if isCallExpr(n): - var expandedSym = qualifiedLookup(c, n[0], {checkUndeclared}) + var expandedSym = qualifiedLookUp(c, n[0], {checkUndeclared}) if expandedSym == nil: - LocalError(n.info, errUndeclaredIdentifier, n[0].renderTree) + localError(n.info, errUndeclaredIdentifier, n[0].renderTree) return errorSym(c, n[0]) if expandedSym.kind notin {skMacro, skTemplate}: - LocalError(n.info, errXisNoMacroOrTemplate, expandedSym.name.s) + localError(n.info, errXisNoMacroOrTemplate, expandedSym.name.s) return errorSym(c, n[0]) result = expandedSym else: - LocalError(n.info, errXisNoMacroOrTemplate, n.renderTree) + localError(n.info, errXisNoMacroOrTemplate, n.renderTree) result = errorSym(c, n) proc expectString(c: PContext, n: PNode): string = @@ -1332,10 +1337,10 @@ proc expectString(c: PContext, n: PNode): string = if n.kind in nkStrKinds: return n.strVal else: - LocalError(n.info, errStringLiteralExpected) + localError(n.info, errStringLiteralExpected) proc getMagicSym(magic: TMagic): PSym = - result = newSym(skProc, getIdent($magic), GetCurrOwner(), gCodegenLineInfo) + result = newSym(skProc, getIdent($magic), getCurrOwner(), gCodegenLineInfo) result.magic = magic proc newAnonSym(kind: TSymKind, info: TLineInfo, @@ -1355,9 +1360,9 @@ proc semUsing(c: PContext, n: PNode): PNode = of skProcKinds: addDeclAt(c.currentScope, usedSym.sym) continue - else: nil + else: discard - LocalError(e.info, errUsingNoSymbol, e.renderTree) + localError(e.info, errUsingNoSymbol, e.renderTree) proc semExpandToAst(c: PContext, n: PNode): PNode = var macroCall = n[1] @@ -1371,7 +1376,7 @@ proc semExpandToAst(c: PContext, n: PNode): PNode = macroCall.sons[i] = semExprWithType(c, macroCall[i], {}) # Preserve the magic symbol in order to be handled in evals.nim - InternalAssert n.sons[0].sym.magic == mExpandToAst + internalAssert n.sons[0].sym.magic == mExpandToAst n.typ = getSysSym("PNimrodNode").typ # expandedSym.getReturnType result = n @@ -1408,7 +1413,7 @@ proc processQuotations(n: var PNode, op: string, processQuotations(n.sons[i], op, quotes, ids) proc semQuoteAst(c: PContext, n: PNode): PNode = - InternalAssert n.len == 2 or n.len == 3 + internalAssert n.len == 2 or n.len == 3 # We transform the do block into a template with a param for # each interpolation. We'll pass this template to getAst. var @@ -1421,7 +1426,7 @@ proc semQuoteAst(c: PContext, n: PNode): PNode = # this will store the generated param names if doBlk.kind != nkDo: - LocalError(n.info, errXExpected, "block") + localError(n.info, errXExpected, "block") processQuotations(doBlk.sons[bodyPos], op, quotes, ids) @@ -1445,7 +1450,7 @@ proc tryExpr(c: PContext, n: PNode, # watch out, hacks ahead: let oldErrorCount = msgs.gErrorCounter let oldErrorMax = msgs.gErrorMax - inc c.InCompilesContext + inc c.inCompilesContext # do not halt after first error: msgs.gErrorMax = high(int) @@ -1458,9 +1463,9 @@ proc tryExpr(c: PContext, n: PNode, errorOutputs = if bufferErrors: {eInMemory} else: {} let oldContextLen = msgs.getInfoContextLen() - let oldInGenericContext = c.InGenericContext - let oldInUnrolledContext = c.InUnrolledContext - let oldInGenericInst = c.InGenericInst + let oldInGenericContext = c.inGenericContext + let oldInUnrolledContext = c.inUnrolledContext + let oldInGenericInst = c.inGenericInst let oldProcCon = c.p c.generics = @[] try: @@ -1470,14 +1475,14 @@ proc tryExpr(c: PContext, n: PNode, nil # undo symbol table changes (as far as it's possible): c.generics = oldGenerics - c.InGenericContext = oldInGenericContext - c.InUnrolledContext = oldInUnrolledContext - c.InGenericInst = oldInGenericInst + c.inGenericContext = oldInGenericContext + c.inUnrolledContext = oldInUnrolledContext + c.inGenericInst = oldInGenericInst c.p = oldProcCon msgs.setInfoContextLen(oldContextLen) - setlen(gOwners, oldOwnerLen) + setLen(gOwners, oldOwnerLen) c.currentScope = oldScope - dec c.InCompilesContext + dec c.inCompilesContext errorOutputs = oldErrorOutputs msgs.gErrorCounter = oldErrorCount msgs.gErrorMax = oldErrorMax @@ -1555,7 +1560,7 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode = # The ``when`` statement implements the mechanism for platform dependent # code. Thus we try to ensure here consistent ID allocation after the # ``when`` statement. - IDsynchronizationPoint(200) + idSynchronizationPoint(200) proc semSetConstr(c: PContext, n: PNode): PNode = result = newNodeI(nkCurly, n.info) @@ -1584,7 +1589,7 @@ proc semSetConstr(c: PContext, n: PNode): PNode = if typ == nil: typ = skipTypes(n.sons[i].typ, {tyGenericInst, tyVar, tyOrdinal}) if not isOrdinalType(typ): - LocalError(n.info, errOrdinalTypeExpected) + localError(n.info, errOrdinalTypeExpected) typ = makeRangeType(c, 0, MaxSetElements - 1, n.info) elif lengthOrd(typ) > MaxSetElements: typ = makeRangeType(c, 0, MaxSetElements - 1, n.info) @@ -1641,11 +1646,11 @@ proc checkPar(n: PNode): TParKind = if result == paTupleFields: if (n.sons[i].kind != nkExprColonExpr) or not (n.sons[i].sons[0].kind in {nkSym, nkIdent}): - LocalError(n.sons[i].info, errNamedExprExpected) + localError(n.sons[i].info, errNamedExprExpected) return paNone else: if n.sons[i].kind == nkExprColonExpr: - LocalError(n.sons[i].info, errNamedExprNotAllowed) + localError(n.sons[i].info, errNamedExprNotAllowed) return paNone proc semTupleFieldsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = @@ -1660,7 +1665,7 @@ proc semTupleFieldsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = var id: PIdent if n.sons[i].sons[0].kind == nkIdent: id = n.sons[i].sons[0].ident else: id = n.sons[i].sons[0].sym.name - if ContainsOrIncl(ids, id.id): + if containsOrIncl(ids, id.id): localError(n.sons[i].info, errFieldInitTwice, id.s) n.sons[i].sons[1] = semExprWithType(c, n.sons[i].sons[1], flags*{efAllowDestructor}) @@ -1687,7 +1692,7 @@ proc checkInitialized(n: PNode, ids: TIntSet, info: TLineInfo) = for i in countup(0, sonsLen(n) - 1): checkInitialized(n.sons[i], ids, info) of nkRecCase: - if (n.sons[0].kind != nkSym): InternalError(info, "checkInitialized") + if (n.sons[0].kind != nkSym): internalError(info, "checkInitialized") checkInitialized(n.sons[0], ids, info) when false: # XXX we cannot check here, as we don't know the branch! @@ -1697,7 +1702,7 @@ proc checkInitialized(n: PNode, ids: TIntSet, info: TLineInfo) = else: internalError(info, "checkInitialized") of nkSym: if tfNeedsInit in n.sym.typ.flags and n.sym.name.id notin ids: - Message(info, errGenerated, "field not initialized: " & n.sym.name.s) + message(info, errGenerated, "field not initialized: " & n.sym.name.s) else: internalError(info, "checkInitialized") proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = @@ -1720,7 +1725,7 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = var id: PIdent if it.sons[0].kind == nkIdent: id = it.sons[0].ident else: id = it.sons[0].sym.name - if ContainsOrIncl(ids, id.id): + if containsOrIncl(ids, id.id): localError(it.info, errFieldInitTwice, id.s) var e = semExprWithType(c, it.sons[1], flags*{efAllowDestructor}) var @@ -1753,7 +1758,7 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = proc semBlock(c: PContext, n: PNode): PNode = result = n - Inc(c.p.nestedBlockCounter) + inc(c.p.nestedBlockCounter) checkSonsLen(n, 2) openScope(c) # BUGFIX: label is in the scope of block! if n.sons[0].kind != nkEmpty: @@ -1767,7 +1772,7 @@ proc semBlock(c: PContext, n: PNode): PNode = if isEmptyType(n.typ): n.kind = nkBlockStmt else: n.kind = nkBlockExpr closeScope(c) - Dec(c.p.nestedBlockCounter) + dec(c.p.nestedBlockCounter) proc buildCall(n: PNode): PNode = if n.kind == nkDotExpr and n.len == 2: @@ -1833,13 +1838,13 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = if result.kind == nkSym: markIndirect(c, result.sym) if isGenericRoutine(result.sym): - LocalError(n.info, errInstantiateXExplicitely, s.name.s) + localError(n.info, errInstantiateXExplicitely, s.name.s) of nkSym: # because of the changed symbol binding, this does not mean that we # don't have to check the symbol for semantics here again! result = semSym(c, n, n.sym, flags) of nkEmpty, nkNone, nkCommentStmt: - nil + discard of nkNilLit: result.typ = getSysType(tyNil) of nkIntLit: @@ -1880,9 +1885,9 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result.kind = nkCall result = semExpr(c, result, flags) of nkBind: - Message(n.info, warnDeprecated, "bind") + message(n.info, warnDeprecated, "bind") result = semExpr(c, n.sons[0], flags) - of nkTypeOfExpr, nkTupleTy, nkRefTy..nkEnumTy: + of nkTypeOfExpr, nkTupleTy, nkRefTy..nkEnumTy, nkStaticTy: var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc}) result.typ = makeTypeDesc(c, typ) #result = symNodeFromType(c, typ, n.info) @@ -1890,8 +1895,10 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # check if it is an expression macro: checkMinSonsLen(n, 1) let mode = if nfDelegate in n.flags: {} else: {checkUndeclared} - var s = qualifiedLookup(c, n.sons[0], mode) + var s = qualifiedLookUp(c, n.sons[0], mode) if s != nil: + if gCmd == cmdPretty and n.sons[0].kind == nkDotExpr: + pretty.checkUse(n.sons[0].sons[1], s) case s.kind of skMacro: if sfImmediate notin s.flags: @@ -1911,8 +1918,8 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = semConv(c, n) elif n.len == 1: result = semObjConstr(c, n, flags) - elif Contains(c.AmbiguousSymbols, s.id): - LocalError(n.info, errUseQualifier, s.name.s) + elif contains(c.ambiguousSymbols, s.id): + localError(n.info, errUseQualifier, s.name.s) elif s.magic == mNone: result = semDirectOp(c, n, flags) else: result = semMagic(c, n, s, flags) of skProc, skMethod, skConverter, skIterator: @@ -1936,12 +1943,14 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = semExpr(c, result, flags) of nkBracketExpr: checkMinSonsLen(n, 1) - var s = qualifiedLookup(c, n.sons[0], {checkUndeclared}) + var s = qualifiedLookUp(c, n.sons[0], {checkUndeclared}) if s != nil and s.kind in {skProc, skMethod, skConverter, skIterator}: # type parameters: partial generic specialization n.sons[0] = semSymGenericInstantiation(c, n.sons[0], s) result = explicitGenericInstantiation(c, n, s) - else: + elif s != nil and s.kind in {skType}: + result = symNodeFromType(c, semTypeNode(c, n, nil), n.info) + else: result = semArrayAccess(c, n, flags) of nkCurlyExpr: result = semExpr(c, buildOverloadedSubscripts(n, getIdent"{}"), flags) @@ -1964,7 +1973,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = checkSonsLen(n, 1) n.sons[0] = semExprWithType(c, n.sons[0]) if isAssignable(c, n.sons[0]) notin {arLValue, arLocalLValue}: - LocalError(n.info, errExprHasNoAddress) + localError(n.info, errExprHasNoAddress) n.typ = makePtrType(c, n.sons[0].typ) of nkHiddenAddr, nkHiddenDeref: checkSonsLen(n, 1) @@ -1993,7 +2002,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of nkVarSection: result = semVarOrLet(c, n, skVar) of nkLetSection: result = semVarOrLet(c, n, skLet) of nkConstSection: result = semConst(c, n) - of nkTypeSection: result = SemTypeSection(c, n) + of nkTypeSection: result = semTypeSection(c, n) of nkDiscardStmt: result = semDiscard(c, n) of nkWhileStmt: result = semWhile(c, n) of nkTryStmt: result = semTry(c, n) @@ -2012,25 +2021,25 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of nkMacroDef: result = semMacroDef(c, n) of nkTemplateDef: result = semTemplateDef(c, n) of nkImportStmt: - if not isTopLevel(c): LocalError(n.info, errXOnlyAtModuleScope, "import") + if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "import") result = evalImport(c, n) of nkImportExceptStmt: - if not isTopLevel(c): LocalError(n.info, errXOnlyAtModuleScope, "import") + if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "import") result = evalImportExcept(c, n) of nkFromStmt: - if not isTopLevel(c): LocalError(n.info, errXOnlyAtModuleScope, "from") + if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "from") result = evalFrom(c, n) of nkIncludeStmt: - if not isTopLevel(c): LocalError(n.info, errXOnlyAtModuleScope, "include") + if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "include") result = evalInclude(c, n) of nkExportStmt, nkExportExceptStmt: - if not isTopLevel(c): LocalError(n.info, errXOnlyAtModuleScope, "export") + if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "export") result = semExport(c, n) of nkPragmaBlock: result = semPragmaBlock(c, n) of nkStaticStmt: result = semStaticStmt(c, n) else: - LocalError(n.info, errInvalidExpressionX, + localError(n.info, errInvalidExpressionX, renderTree(n, {renderNoComments})) if result != nil: incl(result.flags, nfSem) diff --git a/compiler/semfold.nim b/compiler/semfold.nim index ca06ea1b6..1d03e6888 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -66,14 +66,14 @@ proc ordinalValToString*(a: PNode): string = of tyEnum: var n = t.n for i in countup(0, sonsLen(n) - 1): - if n.sons[i].kind != nkSym: InternalError(a.info, "ordinalValToString") + if n.sons[i].kind != nkSym: internalError(a.info, "ordinalValToString") var field = n.sons[i].sym if field.position == x: if field.ast == nil: return field.name.s else: return field.ast.strVal - InternalError(a.info, "no symbol for ordinal value: " & $x) + internalError(a.info, "no symbol for ordinal value: " & $x) else: result = $x @@ -92,7 +92,7 @@ proc pickIntRange(a, b: PType): PType = proc isIntRangeOrLit(t: PType): bool = result = isIntRange(t) or isIntLit(t) -proc pickMinInt(n: PNode): biggestInt = +proc pickMinInt(n: PNode): BiggestInt = if n.kind in {nkIntLit..nkUInt64Lit}: result = n.intVal elif isIntLit(n.typ): @@ -100,9 +100,9 @@ proc pickMinInt(n: PNode): biggestInt = elif isIntRange(n.typ): result = firstOrd(n.typ) else: - InternalError(n.info, "pickMinInt") + internalError(n.info, "pickMinInt") -proc pickMaxInt(n: PNode): biggestInt = +proc pickMaxInt(n: PNode): BiggestInt = if n.kind in {nkIntLit..nkUInt64Lit}: result = n.intVal elif isIntLit(n.typ): @@ -110,9 +110,9 @@ proc pickMaxInt(n: PNode): biggestInt = elif isIntRange(n.typ): result = lastOrd(n.typ) else: - InternalError(n.info, "pickMaxInt") + internalError(n.info, "pickMaxInt") -proc makeRange(typ: PType, first, last: biggestInt): PType = +proc makeRange(typ: PType, first, last: BiggestInt): PType = var n = newNode(nkRange) addSon(n, newIntNode(nkIntLit, min(first, last))) addSon(n, newIntNode(nkIntLit, max(first, last))) @@ -120,7 +120,7 @@ proc makeRange(typ: PType, first, last: biggestInt): PType = result.n = n addSonSkipIntLit(result, skipTypes(typ, {tyRange})) -proc makeRangeF(typ: PType, first, last: biggestFloat): PType = +proc makeRangeF(typ: PType, first, last: BiggestFloat): PType = var n = newNode(nkRange) addSon(n, newFloatNode(nkFloatLit, min(first.float, last.float))) addSon(n, newFloatNode(nkFloatLit, max(first.float, last.float))) @@ -229,6 +229,34 @@ discard """ mShrI, mShrI64, mAddF64, mSubF64, mMulF64, mDivF64, mMaxF64, mMinF64 """ +proc evalIs(n, a: PNode): PNode = + # XXX: This should use the standard isOpImpl + internalAssert a.kind == nkSym and a.sym.kind == skType + internalAssert n.sonsLen == 3 and + n[2].kind in {nkStrLit..nkTripleStrLit, nkType} + + let t1 = a.sym.typ + + if n[2].kind in {nkStrLit..nkTripleStrLit}: + case n[2].strVal.normalize + of "closure": + let t = skipTypes(t1, abstractRange) + result = newIntNode(nkIntLit, ord(t.kind == tyProc and + t.callConv == ccClosure and + tfIterator notin t.flags)) + of "iterator": + let t = skipTypes(t1, abstractRange) + result = newIntNode(nkIntLit, ord(t.kind == tyProc and + t.callConv == ccClosure and + tfIterator in t.flags)) + else: + # XXX semexprs.isOpImpl is slightly different and requires a context. yay. + let t2 = n[2].typ + var match = if t2.kind == tyTypeClass: true + else: sameType(t1, t2) + result = newIntNode(nkIntLit, ord(match)) + result.typ = n.typ + proc evalOp(m: TMagic, n, a, b, c: PNode): PNode = # b and c may be nil result = nil @@ -276,7 +304,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode = of tyInt32: result = newIntNodeT(int32(getInt(a)) shl int32(getInt(b)), n) of tyInt64, tyInt, tyUInt..tyUInt64: result = newIntNodeT(`shl`(getInt(a), getInt(b)), n) - else: InternalError(n.info, "constant folding for shl") + else: internalError(n.info, "constant folding for shl") of mShrI, mShrI64: case skipTypes(n.typ, abstractRange).kind of tyInt8: result = newIntNodeT(int8(getInt(a)) shr int8(getInt(b)), n) @@ -284,7 +312,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode = of tyInt32: result = newIntNodeT(int32(getInt(a)) shr int32(getInt(b)), n) of tyInt64, tyInt, tyUInt..tyUInt64: result = newIntNodeT(`shr`(getInt(a), getInt(b)), n) - else: InternalError(n.info, "constant folding for shr") + else: internalError(n.info, "constant folding for shr") of mDivI, mDivI64: result = newIntNodeT(getInt(a) div getInt(b), n) of mModI, mModI64: result = newIntNodeT(getInt(a) mod getInt(b), n) of mAddF64: result = newFloatNodeT(getFloat(a) + getFloat(b), n) @@ -327,10 +355,10 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode = of mMulU: result = newIntNodeT(`*%`(getInt(a), getInt(b)), n) of mModU: result = newIntNodeT(`%%`(getInt(a), getInt(b)), n) of mDivU: result = newIntNodeT(`/%`(getInt(a), getInt(b)), n) - of mLeSet: result = newIntNodeT(Ord(containsSets(a, b)), n) - of mEqSet: result = newIntNodeT(Ord(equalSets(a, b)), n) + of mLeSet: result = newIntNodeT(ord(containsSets(a, b)), n) + of mEqSet: result = newIntNodeT(ord(equalSets(a, b)), n) of mLtSet: - result = newIntNodeT(Ord(containsSets(a, b) and not equalSets(a, b)), n) + result = newIntNodeT(ord(containsSets(a, b) and not equalSets(a, b)), n) of mMulSet: result = nimsets.intersectSets(a, b) result.info = n.info @@ -344,7 +372,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode = result = nimsets.symdiffSets(a, b) result.info = n.info of mConStrStr: result = newStrNodeT(getStrOrChar(a) & getStrOrChar(b), n) - of mInSet: result = newIntNodeT(Ord(inSet(a, b)), n) + of mInSet: result = newIntNodeT(ord(inSet(a, b)), n) of mRepr: # BUGFIX: we cannot eval mRepr here for reasons that I forgot. of mIntToStr, mInt64ToStr: result = newStrNodeT($(getOrdValue(a)), n) @@ -363,19 +391,19 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode = result = copyTree(a) result.typ = n.typ of mCompileOption: - result = newIntNodeT(Ord(commands.testCompileOption(a.getStr, n.info)), n) + result = newIntNodeT(ord(commands.testCompileOption(a.getStr, n.info)), n) of mCompileOptionArg: - result = newIntNodeT(Ord( + result = newIntNodeT(ord( testCompileOptionArg(getStr(a), getStr(b), n.info)), n) of mNewString, mNewStringOfCap, mExit, mInc, ast.mDec, mEcho, mSwap, mAppendStrCh, mAppendStrStr, mAppendSeqElem, mSetLengthStr, mSetLengthSeq, mParseExprToAst, mParseStmtToAst, mExpandToAst, mTypeTrait, mNLen..mNError, mEqRef, mSlurp, mStaticExec, mNGenSym: - nil + discard of mRand: result = newIntNodeT(math.random(a.getInt.int), n) - else: InternalError(a.info, "evalOp(" & $m & ')') + else: internalError(a.info, "evalOp(" & $m & ')') proc getConstIfExpr(c: PSym, n: PNode): PNode = result = nil @@ -425,13 +453,13 @@ proc leValueConv(a, b: PNode): bool = case b.kind of nkCharLit..nkUInt64Lit: result = a.intVal <= b.intVal of nkFloatLit..nkFloat128Lit: result = a.intVal <= round(b.floatVal) - else: InternalError(a.info, "leValueConv") + else: internalError(a.info, "leValueConv") of nkFloatLit..nkFloat128Lit: case b.kind of nkFloatLit..nkFloat128Lit: result = a.floatVal <= b.floatVal of nkCharLit..nkUInt64Lit: result = a.floatVal <= toFloat(int(b.intVal)) - else: InternalError(a.info, "leValueConv") - else: InternalError(a.info, "leValueConv") + else: internalError(a.info, "leValueConv") + else: internalError(a.info, "leValueConv") proc magicCall(m: PSym, n: PNode): PNode = if sonsLen(n) <= 1: return @@ -446,8 +474,6 @@ proc magicCall(m: PSym, n: PNode): PNode = if sonsLen(n) > 3: c = getConstExpr(m, n.sons[3]) if c == nil: return - else: - b = nil result = evalOp(s.magic, n, a, b, c) proc getAppType(n: PNode): PNode = @@ -460,9 +486,9 @@ proc getAppType(n: PNode): PNode = else: result = newStrNodeT("console", n) -proc rangeCheck(n: PNode, value: biggestInt) = +proc rangeCheck(n: PNode, value: BiggestInt) = if value < firstOrd(n.typ) or value > lastOrd(n.typ): - LocalError(n.info, errGenerated, "cannot convert " & $value & + localError(n.info, errGenerated, "cannot convert " & $value & " to " & typeToString(n.typ)) proc foldConv*(n, a: PNode; check = false): PNode = @@ -485,7 +511,7 @@ proc foldConv*(n, a: PNode; check = false): PNode = result = a result.typ = n.typ of tyOpenArray, tyVarargs, tyProc: - nil + discard else: result = a result.typ = n.typ @@ -511,10 +537,10 @@ proc foldArrayAccess(m: PSym, n: PNode): PNode = result = x.sons[int(idx)] if result.kind == nkExprColonExpr: result = result.sons[1] else: - LocalError(n.info, errIndexOutOfBounds) + localError(n.info, errIndexOutOfBounds) of nkBracket, nkMetaNode: if (idx >= 0) and (idx < sonsLen(x)): result = x.sons[int(idx)] - else: LocalError(n.info, errIndexOutOfBounds) + else: localError(n.info, errIndexOutOfBounds) of nkStrLit..nkTripleStrLit: result = newNodeIT(nkCharLit, x.info, n.typ) if (idx >= 0) and (idx < len(x.strVal)): @@ -522,8 +548,8 @@ proc foldArrayAccess(m: PSym, n: PNode): PNode = elif idx == len(x.strVal): nil else: - LocalError(n.info, errIndexOutOfBounds) - else: nil + localError(n.info, errIndexOutOfBounds) + else: discard proc foldFieldAccess(m: PSym, n: PNode): PNode = # a real field access; proc calls have already been transformed @@ -587,12 +613,13 @@ proc getConstExpr(m: PSym, n: PNode): PNode = of skType: result = newSymNodeTypeDesc(s, n.info) of skGenericParam: - if s.typ.kind == tyExpr: - result = s.typ.n - result.typ = s.typ.sons[0] + if s.typ.kind == tyStatic: + if s.typ.n != nil: + result = s.typ.n + result.typ = s.typ.sons[0] else: result = newSymNodeTypeDesc(s, n.info) - else: nil + else: discard of nkCharLit..nkNilLit: result = copyNode(n) of nkIfExpr: @@ -604,11 +631,12 @@ proc getConstExpr(m: PSym, n: PNode): PNode = try: case s.magic of mNone: - return # XXX: if it has no sideEffect, it should be evaluated + # If it has no sideEffect, it should be evaluated. But not here. + return of mSizeOf: var a = n.sons[1] if computeSize(a.typ) < 0: - LocalError(a.info, errCannotEvalXBecauseIncompletelyDefined, + localError(a.info, errCannotEvalXBecauseIncompletelyDefined, "sizeof") result = nil elif skipTypes(a.typ, typedescInst).kind in @@ -644,12 +672,16 @@ proc getConstExpr(m: PSym, n: PNode): PNode = result = newStrNodeT(renderTree(n[1], {renderNoComments}), n) of mConStrStr: result = foldConStrStr(m, n) + of mIs: + let a = getConstExpr(m, n[1]) + if a != nil and a.kind == nkSym and a.sym.kind == skType: + result = evalIs(n, a) else: result = magicCall(m, n) except EOverflow: - LocalError(n.info, errOverOrUnderflow) + localError(n.info, errOverOrUnderflow) except EDivByZero: - LocalError(n.info, errConstantDivisionByZero) + localError(n.info, errConstantDivisionByZero) of nkAddr: var a = getConstExpr(m, n.sons[0]) if a != nil: @@ -705,7 +737,7 @@ proc getConstExpr(m: PSym, n: PNode): PNode = result = a # a <= x and x <= b result.typ = n.typ else: - LocalError(n.info, errGenerated, `%`( + localError(n.info, errGenerated, `%`( msgKindToString(errIllegalConvFromXtoY), [typeToString(n.sons[0].typ), typeToString(n.typ)])) of nkStringToCString, nkCStringToString: @@ -727,4 +759,4 @@ proc getConstExpr(m: PSym, n: PNode): PNode = of nkBracketExpr: result = foldArrayAccess(m, n) of nkDotExpr: result = foldFieldAccess(m, n) else: - nil + discard diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index d626d2eb2..89a167b96 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -17,11 +17,6 @@ # included from sem.nim -type - TSemGenericFlag = enum - withinBind, withinTypeDesc, withinMixin - TSemGenericFlags = set[TSemGenericFlag] - proc getIdentNode(n: PNode): PNode = case n.kind of nkPostfix: result = getIdentNode(n.sons[1]) @@ -31,8 +26,6 @@ proc getIdentNode(n: PNode): PNode = illFormedAst(n) result = n -proc semGenericStmt(c: PContext, n: PNode, flags: TSemGenericFlags, - ctx: var TIntSet): PNode proc semGenericStmtScope(c: PContext, n: PNode, flags: TSemGenericFlags, ctx: var TIntSet): PNode = @@ -73,7 +66,7 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym): PNode = result = n else: result = newSymNode(s, n.info) -proc Lookup(c: PContext, n: PNode, flags: TSemGenericFlags, +proc lookup(c: PContext, n: PNode, flags: TSemGenericFlags, ctx: var TIntSet): PNode = result = n let ident = considerAcc(n) @@ -96,10 +89,10 @@ proc semGenericStmt(c: PContext, n: PNode, if gCmd == cmdIdeTools: suggestStmt(c, n) case n.kind of nkIdent, nkAccQuoted: - result = Lookup(c, n, flags, ctx) + result = lookup(c, n, flags, ctx) of nkDotExpr: let luf = if withinMixin notin flags: {checkUndeclared} else: {} - var s = QualifiedLookUp(c, n, luf) + var s = qualifiedLookUp(c, n, luf) if s != nil: result = semGenericStmtSymbol(c, n, s) # XXX for example: ``result.add`` -- ``add`` needs to be looked up here... of nkEmpty, nkSym..nkNilLit: @@ -110,7 +103,7 @@ proc semGenericStmt(c: PContext, n: PNode, # not work. Copying the symbol does not work either because we're already # the owner of the symbol! What we need to do is to copy the symbol # in the generic instantiation process... - nil + discard of nkBind: result = semGenericStmt(c, n.sons[0], flags+{withinBind}, ctx) of nkMixinStmt: @@ -119,7 +112,7 @@ proc semGenericStmt(c: PContext, n: PNode, # check if it is an expression macro: checkMinSonsLen(n, 1) let fn = n.sons[0] - var s = qualifiedLookup(c, fn, {}) + var s = qualifiedLookUp(c, fn, {}) if s == nil and withinMixin notin flags and fn.kind in {nkIdent, nkAccQuoted} and considerAcc(fn).id notin ctx: localError(n.info, errUndeclaredIdentifier, fn.renderTree) @@ -219,7 +212,7 @@ proc semGenericStmt(c: PContext, n: PNode, for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue - if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): IllFormedAst(a) + if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): illFormedAst(a) checkMinSonsLen(a, 3) var L = sonsLen(a) a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, @@ -230,7 +223,7 @@ proc semGenericStmt(c: PContext, n: PNode, of nkGenericParams: for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] - if (a.kind != nkIdentDefs): IllFormedAst(a) + if (a.kind != nkIdentDefs): illFormedAst(a) checkMinSonsLen(a, 3) var L = sonsLen(a) a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, @@ -242,7 +235,7 @@ proc semGenericStmt(c: PContext, n: PNode, for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue - if (a.kind != nkConstDef): IllFormedAst(a) + if (a.kind != nkConstDef): illFormedAst(a) checkSonsLen(a, 3) addPrelimDecl(c, newSymS(skUnknown, getIdentNode(a.sons[0]), c)) a.sons[1] = semGenericStmt(c, a.sons[1], flags+{withinTypeDesc}, ctx) @@ -251,13 +244,13 @@ proc semGenericStmt(c: PContext, n: PNode, for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue - if (a.kind != nkTypeDef): IllFormedAst(a) + if (a.kind != nkTypeDef): illFormedAst(a) checkSonsLen(a, 3) addPrelimDecl(c, newSymS(skUnknown, getIdentNode(a.sons[0]), c)) for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue - if (a.kind != nkTypeDef): IllFormedAst(a) + if (a.kind != nkTypeDef): illFormedAst(a) checkSonsLen(a, 3) if a.sons[1].kind != nkEmpty: openScope(c) @@ -278,14 +271,14 @@ proc semGenericStmt(c: PContext, n: PNode, else: illFormedAst(n) addDecl(c, newSymS(skUnknown, getIdentNode(a.sons[i]), c)) of nkObjectTy, nkTupleTy: - nil + discard of nkFormalParams: checkMinSonsLen(n, 1) if n.sons[0].kind != nkEmpty: n.sons[0] = semGenericStmt(c, n.sons[0], flags+{withinTypeDesc}, ctx) for i in countup(1, sonsLen(n) - 1): var a = n.sons[i] - if (a.kind != nkIdentDefs): IllFormedAst(a) + if (a.kind != nkIdentDefs): illFormedAst(a) checkMinSonsLen(a, 3) var L = sonsLen(a) a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, @@ -311,7 +304,7 @@ proc semGenericStmt(c: PContext, n: PNode, else: body = n.sons[bodyPos] n.sons[bodyPos] = semGenericStmtScope(c, body, flags, ctx) closeScope(c) - of nkPragma, nkPragmaExpr: nil + of nkPragma, nkPragmaExpr: discard of nkExprColonExpr, nkExprEqExpr: checkMinSonsLen(n, 2) result.sons[1] = semGenericStmt(c, n.sons[1], flags, ctx) diff --git a/compiler/seminst.nim b/compiler/seminst.nim index d7d64fd54..8faf1d21a 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -13,28 +13,28 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable, entry: var TInstantiation) = if n.kind != nkGenericParams: - InternalError(n.info, "instantiateGenericParamList; no generic params") + internalError(n.info, "instantiateGenericParamList; no generic params") newSeq(entry.concreteTypes, n.len) for i in countup(0, n.len - 1): var a = n.sons[i] if a.kind != nkSym: - InternalError(a.info, "instantiateGenericParamList; no symbol") + internalError(a.info, "instantiateGenericParamList; no symbol") var q = a.sym - if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyExpr}+tyTypeClasses: + if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyStatic}+tyTypeClasses: continue var s = newSym(skType, q.name, getCurrOwner(), q.info) s.flags = s.flags + {sfUsed, sfFromGeneric} - var t = PType(IdTableGet(pt, q.typ)) + var t = PType(idTableGet(pt, q.typ)) if t == nil: if tfRetType in q.typ.flags: # keep the generic type and allow the return type to be bound # later by semAsgn in return type inference scenario t = q.typ else: - LocalError(a.info, errCannotInstantiateX, s.name.s) + localError(a.info, errCannotInstantiateX, s.name.s) t = errorType(c) elif t.kind == tyGenericParam: - InternalError(a.info, "instantiateGenericParamList: " & q.name.s) + internalError(a.info, "instantiateGenericParamList: " & q.name.s) elif t.kind == tyGenericInvokation: #t = instGenericContainer(c, a, t) t = generateTypeInstance(c, pt, a, t) @@ -47,10 +47,10 @@ proc sameInstantiation(a, b: TInstantiation): bool = if a.concreteTypes.len == b.concreteTypes.len: for i in 0..a.concreteTypes.high: if not compareTypes(a.concreteTypes[i], b.concreteTypes[i], - flags = {TypeDescExactMatch}): return + flags = {ExactTypeDescValues}): return result = true -proc GenericCacheGet(genericSym: Psym, entry: TInstantiation): PSym = +proc genericCacheGet(genericSym: PSym, entry: TInstantiation): PSym = if genericSym.procInstCache != nil: for inst in genericSym.procInstCache: if sameInstantiation(entry, inst[]): @@ -75,11 +75,11 @@ proc removeDefaultParamValues(n: PNode) = proc freshGenSyms(n: PNode, owner: PSym, symMap: var TIdTable) = # we need to create a fresh set of gensym'ed symbols: if n.kind == nkSym and sfGenSym in n.sym.flags: - var x = PSym(IdTableGet(symMap, n.sym)) + var x = PSym(idTableGet(symMap, n.sym)) if x == nil: x = copySym(n.sym, false) x.owner = owner - IdTablePut(symMap, n.sym, x) + idTablePut(symMap, n.sym, x) n.sym = x else: for i in 0 .. <safeLen(n): freshGenSyms(n.sons[i], owner, symMap) @@ -88,7 +88,7 @@ proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) proc instantiateBody(c: PContext, n: PNode, result: PSym) = if n.sons[bodyPos].kind != nkEmpty: - inc c.InGenericInst + inc c.inGenericInst # add it here, so that recursive generic procs are possible: addDecl(c, result) pushProcCon(c, result) @@ -101,7 +101,7 @@ proc instantiateBody(c: PContext, n: PNode, result: PSym) = maybeAddResult(c, result, n) var b = n.sons[bodyPos] var symMap: TIdTable - InitIdTable symMap + initIdTable symMap freshGenSyms(b, result, symMap) b = semProcBody(c, b) b = hloBody(c, b) @@ -109,7 +109,7 @@ proc instantiateBody(c: PContext, n: PNode, result: PSym) = #echo "code instantiated ", result.name.s excl(result.flags, sfForward) popProcCon(c) - dec c.InGenericInst + dec c.inGenericInst proc fixupInstantiatedSymbols(c: PContext, s: PSym) = for i in countup(0, c.generics.len - 1): @@ -126,147 +126,33 @@ proc fixupInstantiatedSymbols(c: PContext, s: PSym) = proc sideEffectsCheck(c: PContext, s: PSym) = if {sfNoSideEffect, sfSideEffect} * s.flags == {sfNoSideEffect, sfSideEffect}: - LocalError(s.info, errXhasSideEffects, s.name.s) + localError(s.info, errXhasSideEffects, s.name.s) elif sfThread in s.flags and semthreads.needsGlobalAnalysis() and s.ast.sons[genericParamsPos].kind == nkEmpty: c.threadEntries.add(s) -proc lateInstantiateGeneric(c: PContext, invocation: PType, info: TLineInfo): PType = - InternalAssert invocation.kind == tyGenericInvokation - - let cacheHit = searchInstTypes(invocation) - if cacheHit != nil: - result = cacheHit - else: - let s = invocation.sons[0].sym - let oldScope = c.currentScope - c.currentScope = s.typScope - openScope(c) - pushInfoContext(info) - for i in 0 .. <s.typ.n.sons.len: - let genericParam = s.typ.n[i].sym - let symKind = if genericParam.typ.kind == tyExpr: skConst - else: skType - - var boundSym = newSym(symKind, s.typ.n[i].sym.name, s, info) - boundSym.typ = invocation.sons[i+1].skipTypes({tyExpr}) - boundSym.ast = invocation.sons[i+1].n - addDecl(c, boundSym) - # XXX: copyTree would have been unnecessary here if semTypeNode - # didn't modify its input parameters. Currently, it does modify - # at least the record lists of the passed object and tuple types - var instantiated = semTypeNode(c, copyTree(s.ast[2]), nil) - popInfoContext() - closeScope(c) - c.currentScope = oldScope - if instantiated != nil: - result = invocation - result.kind = tyGenericInst - result.sons.add instantiated - cacheTypeInst result - -proc instGenericContainer(c: PContext, info: TLineInfo, header: PType): PType = - when oUseLateInstantiation: - lateInstantiateGeneric(c, header, info) - else: - var cl: TReplTypeVars - InitIdTable(cl.symMap) - InitIdTable(cl.typeMap) - cl.info = info - cl.c = c - result = ReplaceTypeVarsT(cl, header) +proc instGenericContainer(c: PContext, info: TLineInfo, header: PType, + allowMetaTypes = false): PType = + var cl: TReplTypeVars + initIdTable(cl.symMap) + initIdTable(cl.typeMap) + initIdTable(cl.localCache) + cl.info = info + cl.c = c + cl.allowMetaTypes = allowMetaTypes + result = replaceTypeVarsT(cl, header) proc instGenericContainer(c: PContext, n: PNode, header: PType): PType = result = instGenericContainer(c, n.info, header) -proc fixupProcType(c: PContext, genericType: PType, - inst: TInstantiation): PType = - # XXX: This is starting to look suspiciously like ReplaceTypeVarsT - # there are few apparent differences, but maybe the code could be - # moved over. - # * the code here uses the new genericSym.position property when - # doing lookups. - # * the handling of tyTypeDesc seems suspicious in ReplaceTypeVarsT - # typedesc params were previously handled in the second pass of - # semParamList - # * void (nkEmpty) params doesn't seem to be stripped in ReplaceTypeVarsT - result = genericType - if result == nil: return - - case genericType.kind - of tyGenericParam, tyTypeClasses: - result = inst.concreteTypes[genericType.sym.position] - of tyTypeDesc: - result = inst.concreteTypes[genericType.sym.position] - if tfUnresolved in genericType.flags: - result = result.sons[0] - of tyExpr: - result = inst.concreteTypes[genericType.sym.position] - of tyOpenArray, tyArray, tySet, tySequence, tyTuple, tyProc, - tyPtr, tyVar, tyRef, tyOrdinal, tyRange, tyVarargs: - if genericType.sons == nil: return - var head = 0 - for i in 0 .. <genericType.sons.len: - let origType = genericType.sons[i] - var changed = fixupProcType(c, origType, inst) - if changed != genericType.sons[i]: - var changed = changed.skipIntLit - if result == genericType: - # the first detected change initializes the result - result = copyType(genericType, genericType.owner, false) - if genericType.n != nil: - result.n = copyTree(genericType.n) - - # XXX: doh, we have to treat seq and arrays as special case - # because sometimes the `@` magic will be applied to an empty - # sequence having the type tySequence(tyEmpty) - if changed.kind == tyEmpty and - genericType.kind notin {tyArray, tySequence}: - if genericType.kind == tyProc and i == 0: - # return types of procs are overwritten with nil - changed = nil - else: - # otherwise, `empty` is just erased from the signature - result.sons[i..i] = [] - if result.n != nil: result.n.sons[i..i] = [] - continue - - result.sons[head] = changed - - if result.n != nil: - if result.n.kind == nkRecList: - for son in result.n.sons: - if son.typ == origType: - son.typ = changed - son.sym = copySym(son.sym, true) - son.sym.typ = changed - if result.n.kind == nkFormalParams: - if i != 0: - let origParam = result.n.sons[head].sym - var param = copySym(origParam) - param.typ = changed - param.ast = origParam.ast - result.n.sons[head] = newSymNode(param) - - # won't be advanced on empty (void) nodes - inc head - - of tyGenericInvokation: - result = newTypeWithSons(c, tyGenericInvokation, genericType.sons) - for i in 1 .. <genericType.sons.len: - result.sons[i] = fixupProcType(c, result.sons[i], inst) - result = instGenericContainer(c, getInfoContext(-1), result) - - else: nil - proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, info: TLineInfo): PSym = # no need to instantiate generic templates/macros: if fn.kind in {skTemplate, skMacro}: return fn - + # generates an instantiated proc - if c.InstCounter > 1000: InternalError(fn.ast.info, "nesting too deep") - inc(c.InstCounter) + if c.instCounter > 1000: internalError(fn.ast.info, "nesting too deep") + inc(c.instCounter) # careful! we copy the whole AST including the possibly nil body! var n = copyTree(fn.ast) # NOTE: for access of private fields within generics from a different module @@ -281,16 +167,15 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, result.ast = n pushOwner(result) openScope(c) - if n.sons[genericParamsPos].kind == nkEmpty: - InternalError(n.info, "generateInstance") + internalAssert n.sons[genericParamsPos].kind != nkEmpty n.sons[namePos] = newSymNode(result) pushInfoContext(info) var entry = TInstantiation.new entry.sym = result instantiateGenericParamList(c, n.sons[genericParamsPos], pt, entry[]) - result.typ = fixupProcType(c, fn.typ, entry[]) + result.typ = generateTypeInstance(c, pt, info, fn.typ) n.sons[genericParamsPos] = ast.emptyNode - var oldPrc = GenericCacheGet(fn, entry[]) + var oldPrc = genericCacheGet(fn, entry[]) if oldPrc == nil: fn.procInstCache.safeAdd(entry) c.generics.add(makeInstPair(fn, entry)) @@ -301,7 +186,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, if fn.kind != skTemplate: instantiateBody(c, n, result) sideEffectsCheck(c, result) - ParamsTypeCheck(c, result.typ) + paramsTypeCheck(c, result.typ) else: result = oldPrc popInfoContext() @@ -309,7 +194,5 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, popOwner() #c.currentScope = oldScope c.friendModule = oldFriend - dec(c.InstCounter) + dec(c.instCounter) if result.kind == skMethod: finishMethod(c, result) - - diff --git a/compiler/semmacrosanity.nim b/compiler/semmacrosanity.nim new file mode 100644 index 000000000..1bece95c2 --- /dev/null +++ b/compiler/semmacrosanity.nim @@ -0,0 +1,89 @@ +# +# +# The Nimrod Compiler +# (c) Copyright 2014 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## Implements type sanity checking for ASTs resulting from macros. Lots of +## room for improvement here. + +import ast, astalgo, msgs, types + +proc ithField(n: PNode, field: int): PSym = + result = nil + case n.kind + of nkRecList: + for i in countup(0, sonsLen(n) - 1): + result = ithField(n.sons[i], field-i) + if result != nil: return + of nkRecCase: + if n.sons[0].kind != nkSym: internalError(n.info, "ithField") + result = ithField(n.sons[0], field-1) + if result != nil: return + for i in countup(1, sonsLen(n) - 1): + case n.sons[i].kind + of nkOfBranch, nkElse: + result = ithField(lastSon(n.sons[i]), field-1) + if result != nil: return + else: internalError(n.info, "ithField(record case branch)") + of nkSym: + if field == 0: result = n.sym + else: discard + +proc annotateType*(n: PNode, t: PType) = + let x = t.skipTypes(abstractInst) + # Note: x can be unequal to t and we need to be careful to use 't' + # to not to skip tyGenericInst + case n.kind + of nkPar: + if x.kind == tyObject: + n.typ = t + for i in 0 .. <n.len: + let field = x.n.ithField(i) + if field.isNil: globalError n.info, "invalid field at index " & $i + else: annotateType(n.sons[i], field.typ) + elif x.kind == tyTuple: + n.typ = t + for i in 0 .. <n.len: + if i >= x.len: globalError n.info, "invalid field at index " & $i + else: annotateType(n.sons[i], x.sons[i]) + elif x.kind == tyProc and x.callConv == ccClosure: + n.typ = t + else: + globalError(n.info, "() must have an object or tuple type") + of nkBracket: + if x.kind in {tyArrayConstr, tyArray, tySequence, tyOpenarray}: + n.typ = t + for m in n: annotateType(m, x.elemType) + else: + globalError(n.info, "[] must have some form of array type") + of nkCurly: + if x.kind in {tySet}: + n.typ = t + for m in n: annotateType(m, x.elemType) + else: + globalError(n.info, "{} must have the set type") + of nkFloatLit..nkFloat128Lit: + if x.kind in {tyFloat..tyFloat128}: + n.typ = t + else: + globalError(n.info, "float literal must have some float type") + of nkCharLit..nkUInt64Lit: + if x.kind in {tyInt..tyUInt64, tyBool, tyChar, tyEnum}: + n.typ = t + else: + globalError(n.info, "integer literal must have some int type") + of nkStrLit..nkTripleStrLit: + if x.kind in {tyString, tyCString}: + n.typ = t + else: + globalError(n.info, "string literal must be of some string type") + of nkNilLit: + if x.kind in NilableTypes: + n.typ = t + else: + globalError(n.info, "nil literal must be of some pointer type") + else: discard diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 88567b10a..a1af94971 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -18,7 +18,7 @@ proc expectIntLit(c: PContext, n: PNode): int = let x = c.semConstExpr(c, n) case x.kind of nkIntLit..nkInt64Lit: result = int(x.intVal) - else: LocalError(n.info, errIntLiteralExpected) + else: localError(n.info, errIntLiteralExpected) proc semInstantiationInfo(c: PContext, n: PNode): PNode = result = newNodeIT(nkPar, n.info, n.typ) @@ -26,21 +26,34 @@ proc semInstantiationInfo(c: PContext, n: PNode): PNode = let useFullPaths = expectIntLit(c, n.sons[2]) let info = getInfoContext(idx) var filename = newNodeIT(nkStrLit, n.info, getSysType(tyString)) - filename.strVal = if useFullPaths != 0: info.toFullPath else: info.ToFilename + filename.strVal = if useFullPaths != 0: info.toFullPath else: info.toFilename var line = newNodeIT(nkIntLit, n.info, getSysType(tyInt)) - line.intVal = ToLinenumber(info) + line.intVal = toLinenumber(info) result.add(filename) result.add(line) + +proc evalTypeTrait(trait: PNode, operand: PType, context: PSym): PNode = + let typ = operand.skipTypes({tyTypeDesc}) + case trait.sym.name.s.normalize + of "name": + result = newStrNode(nkStrLit, typ.typeToString(preferName)) + result.typ = newType(tyString, context) + result.info = trait.info + of "arity": + result = newIntNode(nkIntLit, typ.n.len-1) + result.typ = newType(tyInt, context) + result.info = trait.info + else: + internalAssert false proc semTypeTraits(c: PContext, n: PNode): PNode = checkMinSonsLen(n, 2) - internalAssert n.sons[1].kind == nkSym - let typArg = n.sons[1].sym - if typArg.kind == skType or - (typArg.kind == skParam and typArg.typ.sonsLen > 0): + let t = n.sons[1].typ + internalAssert t != nil and t.kind == tyTypeDesc + if t.sonsLen > 0: # This is either a type known to sem or a typedesc # param to a regular proc (again, known at instantiation) - result = evalTypeTrait(n[0], n[1], GetCurrOwner()) + result = evalTypeTrait(n[0], t, GetCurrOwner()) else: # a typedesc variable, pass unmodified to evals result = n @@ -56,23 +69,23 @@ proc semBindSym(c: PContext, n: PNode): PNode = let sl = semConstExpr(c, n.sons[1]) if sl.kind notin {nkStrLit, nkRStrLit, nkTripleStrLit}: - LocalError(n.sons[1].info, errStringLiteralExpected) + localError(n.sons[1].info, errStringLiteralExpected) return errorNode(c, n) let isMixin = semConstExpr(c, n.sons[2]) if isMixin.kind != nkIntLit or isMixin.intVal < 0 or isMixin.intVal > high(TSymChoiceRule).int: - LocalError(n.sons[2].info, errConstExprExpected) + localError(n.sons[2].info, errConstExprExpected) return errorNode(c, n) let id = newIdentNode(getIdent(sl.strVal), n.info) - let s = QualifiedLookUp(c, id) + let s = qualifiedLookUp(c, id) if s != nil: # we need to mark all symbols: var sc = symChoice(c, id, s, TSymChoiceRule(isMixin.intVal)) result.add(sc) else: - LocalError(n.sons[1].info, errUndeclaredIdentifier, sl.strVal) + localError(n.sons[1].info, errUndeclaredIdentifier, sl.strVal) proc semLocals(c: PContext, n: PNode): PNode = var counter = 0 @@ -88,7 +101,7 @@ proc semLocals(c: PContext, n: PNode): PNode = #if it.owner != c.p.owner: return result if it.kind in skLocalVars and it.typ.skipTypes({tyGenericInst, tyVar}).kind notin - {tyVarargs, tyOpenArray, tyTypeDesc, tyExpr, tyStmt, tyEmpty}: + {tyVarargs, tyOpenArray, tyTypeDesc, tyStatic, tyExpr, tyStmt, tyEmpty}: var field = newSym(skField, it.name, getCurrOwner(), n.info) field.typ = it.typ.skipTypes({tyGenericInst, tyVar}) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 7dec557be..fb266ae3a 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -95,12 +95,12 @@ proc useVar(a: PEffects, n: PNode) = if s.id notin a.init: if {tfNeedsInit, tfNotNil} * s.typ.flags != {}: when true: - Message(n.info, warnProveInit, s.name.s) + message(n.info, warnProveInit, s.name.s) else: Message(n.info, errGenerated, "'$1' might not have been initialized" % s.name.s) else: - Message(n.info, warnUninit, s.name.s) + message(n.info, warnUninit, s.name.s) # prevent superfluous warnings about the same variable: a.init.add s.id @@ -162,8 +162,8 @@ proc mergeTags(a: PEffects, b, comesFrom: PNode) = for effect in items(b): addTag(a, effect, useLineInfo=comesFrom != nil) proc listEffects(a: PEffects) = - for e in items(a.exc): Message(e.info, hintUser, typeToString(e.typ)) - for e in items(a.tags): Message(e.info, hintUser, typeToString(e.typ)) + for e in items(a.exc): message(e.info, hintUser, typeToString(e.typ)) + for e in items(a.tags): message(e.info, hintUser, typeToString(e.typ)) proc catches(tracked: PEffects, e: PType) = let e = skipTypes(e, skipPtrs) @@ -305,21 +305,21 @@ proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) = if n.kind == nkAddr: # addr(x[]) can't be proven, but addr(x) can: if not containsNode(n, {nkDerefExpr, nkHiddenDeref}): return - elif n.kind == nkSym and n.sym.kind in RoutineKinds: + elif n.kind == nkSym and n.sym.kind in routineKinds: # 'p' is not nil obviously: return case impliesNotNil(tracked.guards, n) of impUnknown: - Message(n.info, errGenerated, + message(n.info, errGenerated, "cannot prove '$1' is not nil" % n.renderTree) of impNo: - Message(n.info, errGenerated, "'$1' is provably nil" % n.renderTree) + message(n.info, errGenerated, "'$1' is provably nil" % n.renderTree) of impYes: discard proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) = let op = n.typ if op != nil and op.kind == tyProc and n.kind != nkNilLit: - InternalAssert op.n.sons[0].kind == nkEffectList + internalAssert op.n.sons[0].kind == nkEffectList var effectList = op.n.sons[0] let s = n.skipConv if s.kind == nkSym and s.sym.kind in routineKinds: @@ -367,7 +367,7 @@ proc trackCase(tracked: PEffects, n: PNode) = for i in oldState.. <tracked.init.len: addToIntersection(inter, tracked.init[i]) - let exh = case skipTypes(n.sons[0].Typ, abstractVarRange-{tyTypeDesc}).Kind + let exh = case skipTypes(n.sons[0].typ, abstractVarRange-{tyTypeDesc}).kind of tyFloat..tyFloat128, tyString: lastSon(n).kind == nkElse else: @@ -549,7 +549,7 @@ proc checkRaisesSpec(spec, real: PNode, msg: string, hints: bool) = if hints: for s in 0 .. <spec.len: if not used.contains(s): - Message(spec[s].info, hintXDeclaredButNotUsed, renderTree(spec[s])) + message(spec[s].info, hintXDeclaredButNotUsed, renderTree(spec[s])) proc checkMethodEffects*(disp, branch: PSym) = ## checks for consistent effects for multi methods. @@ -568,13 +568,13 @@ proc checkMethodEffects*(disp, branch: PSym) = proc setEffectsForProcType*(t: PType, n: PNode) = var effects = t.n.sons[0] - InternalAssert t.kind == tyProc and effects.kind == nkEffectList + internalAssert t.kind == tyProc and effects.kind == nkEffectList let raisesSpec = effectSpec(n, wRaises) tagsSpec = effectSpec(n, wTags) if not isNil(raisesSpec) or not isNil(tagsSpec): - InternalAssert effects.len == 0 + internalAssert effects.len == 0 newSeq(effects.sons, effectListLen) if not isNil(raisesSpec): effects.sons[exceptionEffects] = raisesSpec @@ -583,7 +583,7 @@ proc setEffectsForProcType*(t: PType, n: PNode) = proc trackProc*(s: PSym, body: PNode) = var effects = s.typ.n.sons[0] - InternalAssert effects.kind == nkEffectList + internalAssert effects.kind == nkEffectList # effects already computed? if sfForward in s.flags: return if effects.len == effectListLen: return @@ -603,7 +603,7 @@ proc trackProc*(s: PSym, body: PNode) = s.kind in {skProc, skConverter, skMethod}: var res = s.ast.sons[resultPos].sym # get result symbol if res.id notin t.init: - Message(body.info, warnProveInit, "result") + message(body.info, warnProveInit, "result") let p = s.ast.sons[pragmasPos] let raisesSpec = effectSpec(p, wRaises) if not isNil(raisesSpec): @@ -618,4 +618,4 @@ proc trackProc*(s: PSym, body: PNode) = hints=off) # after the check, use the formal spec: effects.sons[tagEffects] = tagsSpec - \ No newline at end of file + diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index a1805fdec..f0007d01e 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -10,7 +10,7 @@ ## this module does the semantic checking of statements # included from sem.nim -var EnforceVoidContext = PType(kind: tyStmt) +var enforceVoidContext = PType(kind: tyStmt) proc semCommand(c: PContext, n: PNode): PNode = result = semExprNoType(c, n) @@ -58,10 +58,10 @@ proc semWhile(c: PContext, n: PNode): PNode = n.sons[1] = semStmt(c, n.sons[1]) dec(c.p.nestedLoopCounter) closeScope(c) - if n.sons[1].typ == EnforceVoidContext: - result.typ = EnforceVoidContext + if n.sons[1].typ == enforceVoidContext: + result.typ = enforceVoidContext -proc toCover(t: PType): biggestInt = +proc toCover(t: PType): BiggestInt = var t2 = skipTypes(t, abstractVarRange-{tyTypeDesc}) if t2.kind == tyEnum and enumHasHoles(t2): result = sonsLen(t2.n) @@ -70,9 +70,9 @@ proc toCover(t: PType): biggestInt = proc performProcvarCheck(c: PContext, n: PNode, s: PSym) = var smoduleId = getModule(s).id - if sfProcVar notin s.flags and s.typ.callConv == ccDefault and + if sfProcvar notin s.flags and s.typ.callConv == ccDefault and smoduleId != c.module.id and smoduleId != c.friendModule.id: - LocalError(n.info, errXCannotBePassedToProcVar, s.name.s) + localError(n.info, errXCannotBePassedToProcVar, s.name.s) proc semProcvarCheck(c: PContext, n: PNode) = let n = n.skipConv @@ -86,8 +86,8 @@ include semdestruct proc semDestructorCheck(c: PContext, n: PNode, flags: TExprFlags) {.inline.} = if efAllowDestructor notin flags and n.kind in nkCallKinds+{nkObjConstr}: - if instantiateDestructor(c, n.typ): - LocalError(n.info, errGenerated, + if instantiateDestructor(c, n.typ) != nil: + localError(n.info, errGenerated, "usage of a type with a destructor in a non destructible context") # This still breaks too many things: when false: @@ -117,7 +117,7 @@ const nkElse, nkStmtListExpr, nkTryStmt, nkFinally, nkExceptBranch, nkElifBranch, nkElifExpr, nkElseExpr, nkBlockStmt, nkBlockExpr} -proc ImplicitlyDiscardable(n: PNode): bool = +proc implicitlyDiscardable(n: PNode): bool = var n = n while n.kind in skipForDiscardable: n = n.lastSon result = isCallExpr(n) and n.sons[0].kind == nkSym and @@ -136,13 +136,13 @@ proc discardCheck(c: PContext, result: PNode) = if result.typ != nil and result.typ.kind notin {tyStmt, tyEmpty}: if result.kind == nkNilLit: result.typ = nil - elif ImplicitlyDiscardable(result): + elif implicitlyDiscardable(result): var n = result result.typ = nil while n.kind in skipForDiscardable: n = n.lastSon n.typ = nil - elif c.InTypeClass > 0 and result.typ.kind == tyBool: + elif c.inTypeClass > 0 and result.typ.kind == tyBool: let verdict = semConstExpr(c, result) if verdict.intVal == 0: localError(result.info, "type class predicate failed.") @@ -156,7 +156,7 @@ proc discardCheck(c: PContext, result: PNode) = proc semIf(c: PContext, n: PNode): PNode = result = n - var typ = CommonTypeBegin + var typ = commonTypeBegin var hasElse = false for i in countup(0, sonsLen(n) - 1): var it = n.sons[i] @@ -176,7 +176,7 @@ proc semIf(c: PContext, n: PNode): PNode = for it in n: discardCheck(c, it.lastSon) result.kind = nkIfStmt # propagate any enforced VoidContext: - if typ == EnforceVoidContext: result.typ = EnforceVoidContext + if typ == enforceVoidContext: result.typ = enforceVoidContext else: for it in n: let j = it.len-1 @@ -190,16 +190,16 @@ proc semCase(c: PContext, n: PNode): PNode = openScope(c) n.sons[0] = semExprWithType(c, n.sons[0]) var chckCovered = false - var covered: biggestint = 0 - var typ = CommonTypeBegin + var covered: BiggestInt = 0 + var typ = commonTypeBegin var hasElse = false - case skipTypes(n.sons[0].Typ, abstractVarRange-{tyTypeDesc}).Kind + case skipTypes(n.sons[0].typ, abstractVarRange-{tyTypeDesc}).kind of tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32: chckCovered = true of tyFloat..tyFloat128, tyString, tyError: - nil + discard else: - LocalError(n.info, errSelectorMustBeOfCertainTypes) + localError(n.info, errSelectorMustBeOfCertainTypes) return for i in countup(1, sonsLen(n) - 1): var x = n.sons[i] @@ -236,8 +236,8 @@ proc semCase(c: PContext, n: PNode): PNode = if isEmptyType(typ) or typ.kind == tyNil or not hasElse: for i in 1..n.len-1: discardCheck(c, n.sons[i].lastSon) # propagate any enforced VoidContext: - if typ == EnforceVoidContext: - result.typ = EnforceVoidContext + if typ == enforceVoidContext: + result.typ = enforceVoidContext else: for i in 1..n.len-1: var it = n.sons[i] @@ -249,7 +249,7 @@ proc semTry(c: PContext, n: PNode): PNode = result = n inc c.p.inTryStmt checkMinSonsLen(n, 2) - var typ = CommonTypeBegin + var typ = commonTypeBegin n.sons[0] = semExprBranchScope(c, n.sons[0]) typ = commonType(typ, n.sons[0].typ) var check = initIntSet() @@ -267,10 +267,10 @@ proc semTry(c: PContext, n: PNode): PNode = var typ = semTypeNode(c, a.sons[j], nil) if typ.kind == tyRef: typ = typ.sons[0] if typ.kind != tyObject: - LocalError(a.sons[j].info, errExprCannotBeRaised) + localError(a.sons[j].info, errExprCannotBeRaised) a.sons[j] = newNodeI(nkType, a.sons[j].info) a.sons[j].typ = typ - if ContainsOrIncl(check, typ.id): + if containsOrIncl(check, typ.id): localError(a.sons[j].info, errExceptionAlreadyHandled) elif a.kind != nkFinally: illFormedAst(n) @@ -281,8 +281,8 @@ proc semTry(c: PContext, n: PNode): PNode = if isEmptyType(typ) or typ.kind == tyNil: discardCheck(c, n.sons[0]) for i in 1..n.len-1: discardCheck(c, n.sons[i].lastSon) - if typ == EnforceVoidContext: - result.typ = EnforceVoidContext + if typ == enforceVoidContext: + result.typ = enforceVoidContext else: n.sons[0] = fitNode(c, typ, n.sons[0]) for i in 1..n.len-1: @@ -291,7 +291,7 @@ proc semTry(c: PContext, n: PNode): PNode = it.sons[j] = fitNode(c, typ, it.sons[j]) result.typ = typ -proc fitRemoveHiddenConv(c: PContext, typ: Ptype, n: PNode): PNode = +proc fitRemoveHiddenConv(c: PContext, typ: PType, n: PNode): PNode = result = fitNode(c, typ, n) if result.kind in {nkHiddenStdConv, nkHiddenSubConv}: changeType(result.sons[1], typ, check=true) @@ -302,7 +302,7 @@ proc fitRemoveHiddenConv(c: PContext, typ: Ptype, n: PNode): PNode = proc findShadowedVar(c: PContext, v: PSym): PSym = for scope in walkScopes(c.currentScope.parent): if scope == c.topLevelScope: break - let shadowed = StrTableGet(scope.symbols, v.name) + let shadowed = strTableGet(scope.symbols, v.name) if shadowed != nil and shadowed.kind in skLocalVars: return shadowed @@ -322,9 +322,9 @@ proc semIdentDef(c: PContext, n: PNode, kind: TSymKind): PSym = proc checkNilable(v: PSym) = if sfGlobal in v.flags and {tfNotNil, tfNeedsInit} * v.typ.flags != {}: if v.ast.isNil: - Message(v.info, warnProveInit, v.name.s) + message(v.info, warnProveInit, v.name.s) elif tfNotNil in v.typ.flags and tfNotNil notin v.ast.typ.flags: - Message(v.info, warnProveInit, v.name.s) + message(v.info, warnProveInit, v.name.s) proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = var b: PNode @@ -333,7 +333,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = var a = n.sons[i] if gCmd == cmdIdeTools: suggestStmt(c, a) if a.kind == nkCommentStmt: continue - if a.kind notin {nkIdentDefs, nkVarTuple, nkConstDef}: IllFormedAst(a) + if a.kind notin {nkIdentDefs, nkVarTuple, nkConstDef}: illFormedAst(a) checkMinSonsLen(a, 3) var length = sonsLen(a) var typ: PType @@ -350,12 +350,12 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = else: typ = skipIntLit(def.typ) else: def = ast.emptyNode - if symkind == skLet: LocalError(a.info, errLetNeedsInit) + if symkind == skLet: localError(a.info, errLetNeedsInit) # this can only happen for errornous var statements: if typ == nil: continue if not typeAllowed(typ, symkind): - LocalError(a.info, errXisNoType, typeToString(typ)) + localError(a.info, errXisNoType, typeToString(typ)) var tup = skipTypes(typ, {tyGenericInst}) if a.kind == nkVarTuple: if tup.kind != tyTuple: @@ -370,12 +370,12 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = addSon(result, b) elif tup.kind == tyTuple and def.kind == nkPar and a.kind == nkIdentDefs and a.len > 3: - Message(a.info, warnEachIdentIsTuple) + message(a.info, warnEachIdentIsTuple) for j in countup(0, length-3): var v = semIdentDef(c, a.sons[j], symkind) if sfGenSym notin v.flags: addInterfaceDecl(c, v) when oKeepVariableNames: - if c.InUnrolledContext > 0: v.flags.incl(sfShadowed) + if c.inUnrolledContext > 0: v.flags.incl(sfShadowed) else: let shadowed = findShadowedVar(c, v) if shadowed != nil: @@ -383,12 +383,12 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = # a shadowed variable is an error unless it appears on the right # side of the '=': if warnShadowIdent in gNotes and not identWithin(def, v.name): - Message(a.info, warnShadowIdent, v.name.s) + message(a.info, warnShadowIdent, v.name.s) if a.kind != nkVarTuple: if def != nil and def.kind != nkEmpty: # this is needed for the evaluation pass and for the guard checking: v.ast = def - if sfThread in v.flags: LocalError(def.info, errThreadvarCannotInit) + if sfThread in v.flags: localError(def.info, errThreadvarCannotInit) v.typ = typ b = newNodeI(nkIdentDefs, a.info) if importantComments(): @@ -410,7 +410,7 @@ proc semConst(c: PContext, n: PNode): PNode = var a = n.sons[i] if gCmd == cmdIdeTools: suggestStmt(c, a) if a.kind == nkCommentStmt: continue - if (a.kind != nkConstDef): IllFormedAst(a) + if (a.kind != nkConstDef): illFormedAst(a) checkSonsLen(a, 3) var v = semIdentDef(c, a.sons[0], skConst) var typ: PType = nil @@ -418,16 +418,18 @@ proc semConst(c: PContext, n: PNode): PNode = var def = semConstExpr(c, a.sons[2]) if def == nil: - LocalError(a.sons[2].info, errConstExprExpected) + localError(a.sons[2].info, errConstExprExpected) continue # check type compatibility between def.typ and typ: if typ != nil: def = fitRemoveHiddenConv(c, typ, def) else: typ = def.typ - if typ == nil: continue + if typ == nil: + localError(a.sons[2].info, errConstExprExpected) + continue if not typeAllowed(typ, skConst): - LocalError(a.info, errXisNoType, typeToString(typ)) + localError(a.info, errXisNoType, typeToString(typ)) continue v.typ = typ v.ast = def # no need to copy @@ -494,17 +496,17 @@ proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) = fc.field = typ.sym fc.replaceByFieldName = c.m == mFieldPairs openScope(c.c) - inc c.c.InUnrolledContext + inc c.c.inUnrolledContext let body = instFieldLoopBody(fc, lastSon(forLoop), forLoop) - father.add(SemStmt(c.c, body)) - dec c.c.InUnrolledContext + father.add(semStmt(c.c, body)) + dec c.c.inUnrolledContext closeScope(c.c) - of nkNilLit: nil + of nkNilLit: discard of nkRecCase: let L = forLoop.len let call = forLoop.sons[L-2] if call.len > 2: - LocalError(forLoop.info, errGenerated, + localError(forLoop.info, errGenerated, "parallel 'fields' iterator does not work for 'case' objects") return # iterate over the selector: @@ -533,9 +535,9 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode = # so that 'break' etc. work as expected, we produce # a 'while true: stmt; break' loop ... result = newNodeI(nkWhileStmt, n.info, 2) - var trueSymbol = StrTableGet(magicsys.systemModule.Tab, getIdent"true") + var trueSymbol = strTableGet(magicsys.systemModule.tab, getIdent"true") if trueSymbol == nil: - LocalError(n.info, errSystemNeeds, "true") + localError(n.info, errSystemNeeds, "true") trueSymbol = newSym(skUnknown, getIdent"true", getCurrOwner(), n.info) trueSymbol.typ = getSysType(tyBool) @@ -546,7 +548,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode = var length = sonsLen(n) var call = n.sons[length-2] if length-2 != sonsLen(call)-1 + ord(m==mFieldPairs): - LocalError(n.info, errWrongNumberOfVariables) + localError(n.info, errWrongNumberOfVariables) return result var tupleTypeA = skipTypes(call.sons[1].typ, abstractVar-{tyTypeDesc}) @@ -555,10 +557,10 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode = return result for i in 1..call.len-1: var tupleTypeB = skipTypes(call.sons[i].typ, abstractVar-{tyTypeDesc}) - if not SameType(tupleTypeA, tupleTypeB): + if not sameType(tupleTypeA, tupleTypeB): typeMismatch(call.sons[i], tupleTypeA, tupleTypeB) - Inc(c.p.nestedLoopCounter) + inc(c.p.nestedLoopCounter) if tupleTypeA.kind == tyTuple: var loopBody = n.sons[length-1] for i in 0..sonsLen(tupleTypeA)-1: @@ -568,16 +570,16 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode = fc.tupleIndex = i fc.replaceByFieldName = m == mFieldPairs var body = instFieldLoopBody(fc, loopBody, n) - inc c.InUnrolledContext - stmts.add(SemStmt(c, body)) - dec c.InUnrolledContext + inc c.inUnrolledContext + stmts.add(semStmt(c, body)) + dec c.inUnrolledContext closeScope(c) else: var fc: TFieldsCtx fc.m = m fc.c = c semForObjectFields(fc, tupleTypeA.n, n, stmts) - Dec(c.p.nestedLoopCounter) + dec(c.p.nestedLoopCounter) # for TR macros this 'while true: ...; break' loop is pretty bad, so # we avoid it now if we can: if hasSonWith(stmts, nkBreakStmt): @@ -593,7 +595,7 @@ proc addForVarDecl(c: PContext, v: PSym) = if shadowed != nil: # XXX should we do this here? #shadowed.flags.incl(sfShadowed) - Message(v.info, warnShadowIdent, v.name.s) + message(v.info, warnShadowIdent, v.name.s) addDecl(c, v) proc symForVar(c: PContext, n: PNode): PSym = @@ -617,9 +619,9 @@ proc semForVars(c: PContext, n: PNode): PNode = n.sons[0] = newSymNode(v) if sfGenSym notin v.flags: addForVarDecl(c, v) else: - LocalError(n.info, errWrongNumberOfVariables) + localError(n.info, errWrongNumberOfVariables) elif length-2 != sonsLen(iter): - LocalError(n.info, errWrongNumberOfVariables) + localError(n.info, errWrongNumberOfVariables) else: for i in countup(0, length - 3): var v = symForVar(c, n.sons[i]) @@ -627,9 +629,9 @@ proc semForVars(c: PContext, n: PNode): PNode = v.typ = iter.sons[i] n.sons[i] = newSymNode(v) if sfGenSym notin v.flags: addForVarDecl(c, v) - Inc(c.p.nestedLoopCounter) - n.sons[length-1] = SemStmt(c, n.sons[length-1]) - Dec(c.p.nestedLoopCounter) + inc(c.p.nestedLoopCounter) + n.sons[length-1] = semStmt(c, n.sons[length-1]) + dec(c.p.nestedLoopCounter) proc implicitIterator(c: PContext, it: string, arg: PNode): PNode = result = newNodeI(nkCall, arg.info) @@ -657,7 +659,7 @@ proc semFor(c: PContext, n: PNode): PNode = elif length == 4: n.sons[length-2] = implicitIterator(c, "pairs", n.sons[length-2]) else: - LocalError(n.sons[length-2].info, errIteratorExpected) + localError(n.sons[length-2].info, errIteratorExpected) result = semForVars(c, n) elif call.sons[0].sym.magic != mNone: if call.sons[0].sym.magic == mOmpParFor: @@ -668,8 +670,8 @@ proc semFor(c: PContext, n: PNode): PNode = else: result = semForVars(c, n) # propagate any enforced VoidContext: - if n.sons[length-1].typ == EnforceVoidContext: - result.typ = EnforceVoidContext + if n.sons[length-1].typ == enforceVoidContext: + result.typ = enforceVoidContext closeScope(c) proc semRaise(c: PContext, n: PNode): PNode = @@ -695,7 +697,7 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) = var a = n.sons[i] if gCmd == cmdIdeTools: suggestStmt(c, a) if a.kind == nkCommentStmt: continue - if a.kind != nkTypeDef: IllFormedAst(a) + if a.kind != nkTypeDef: illFormedAst(a) checkSonsLen(a, 3) var s = semIdentDef(c, a.sons[0], skType) s.typ = newTypeS(tyForward, c) @@ -710,12 +712,12 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue - if (a.kind != nkTypeDef): IllFormedAst(a) + if (a.kind != nkTypeDef): illFormedAst(a) checkSonsLen(a, 3) - if (a.sons[0].kind != nkSym): IllFormedAst(a) + if (a.sons[0].kind != nkSym): illFormedAst(a) var s = a.sons[0].sym if s.magic == mNone and a.sons[2].kind == nkEmpty: - LocalError(a.info, errImplOfXexpected, s.name.s) + localError(a.info, errImplOfXexpected, s.name.s) if s.magic != mNone: processMagicType(c, s) if a.sons[1].kind != nkEmpty: # We have a generic type declaration here. In generic types, @@ -738,16 +740,12 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = # like: mydata.seq rawAddSon(s.typ, newTypeS(tyEmpty, c)) s.ast = a - when oUseLateInstantiation: - var body: PType = nil - s.typScope = c.currentScope.parent - else: - inc c.InGenericContext - var body = semTypeNode(c, a.sons[2], nil) - dec c.InGenericContext - if body != nil: - body.sym = s - body.size = -1 # could not be computed properly + inc c.inGenericContext + var body = semTypeNode(c, a.sons[2], nil) + dec c.inGenericContext + if body != nil: + body.sym = s + body.size = -1 # could not be computed properly s.typ.sons[sonsLen(s.typ) - 1] = body popOwner() closeScope(c) @@ -768,7 +766,7 @@ proc typeSectionFinalPass(c: PContext, n: PNode) = for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue - if a.sons[0].kind != nkSym: IllFormedAst(a) + if a.sons[0].kind != nkSym: illFormedAst(a) var s = a.sons[0].sym # compute the type's size and check for illegal recursions: if a.sons[1].kind == nkEmpty: @@ -786,12 +784,12 @@ proc typeSectionFinalPass(c: PContext, n: PNode) = # give anonymous object a dummy symbol: var st = s.typ if st.kind == tyGenericBody: st = st.lastSon - InternalAssert st.kind in {tyPtr, tyRef} - InternalAssert st.sons[0].sym == nil + internalAssert st.kind in {tyPtr, tyRef} + internalAssert st.sons[0].sym == nil st.sons[0].sym = newSym(skType, getIdent(s.name.s & ":ObjectType"), getCurrOwner(), s.info) -proc SemTypeSection(c: PContext, n: PNode): PNode = +proc semTypeSection(c: PContext, n: PNode): PNode = typeSectionLeftSidePass(c, n) typeSectionRightSidePass(c, n) typeSectionFinalPass(c, n) @@ -810,12 +808,12 @@ proc addParams(c: PContext, n: PNode, kind: TSymKind) = proc semBorrow(c: PContext, n: PNode, s: PSym) = # search for the correct alias: - var b = SearchForBorrowProc(c, c.currentScope.parent, s) + var b = searchForBorrowProc(c, c.currentScope.parent, s) if b != nil: # store the alias: n.sons[bodyPos] = newSymNode(b) else: - LocalError(n.info, errNoSymbolToBorrowFromFound) + localError(n.info, errNoSymbolToBorrowFromFound) proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind) = if t != nil: @@ -853,7 +851,7 @@ proc semProcAnnotation(c: PContext, prc: PNode): PNode = prc.sons[namePos] = newIdentNode(idDelegator, prc.info) prc.sons[pragmasPos] = copyExcept(n, i) else: - LocalError(prc.info, errOnlyACallOpCanBeDelegator) + localError(prc.info, errOnlyACallOpCanBeDelegator) continue # we transform ``proc p {.m, rest.}`` into ``m(do: proc p {.rest.})`` and # let the semantic checker deal with it: @@ -885,8 +883,8 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode = illFormedAst(n) # process parameters: if n.sons[paramsPos].kind != nkEmpty: var gp = newNodeI(nkGenericParams, n.info) - semParamList(c, n.sons[ParamsPos], gp, s) - ParamsTypeCheck(c, s.typ) + semParamList(c, n.sons[paramsPos], gp, s) + paramsTypeCheck(c, s.typ) else: s.typ = newTypeS(tyProc, c) rawAddSon(s.typ, nil) @@ -895,7 +893,7 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode = s.options = gOptions if n.sons[bodyPos].kind != nkEmpty: if sfImportc in s.flags: - LocalError(n.sons[bodyPos].info, errImplOfXNotAllowed, s.name.s) + localError(n.sons[bodyPos].info, errImplOfXNotAllowed, s.name.s) #if efDetermineType notin flags: # XXX not good enough; see tnamedparamanonproc.nim pushProcCon(c, s) @@ -906,7 +904,7 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode = popProcCon(c) sideEffectsCheck(c, s) else: - LocalError(n.info, errImplOfXexpected, s.name.s) + localError(n.info, errImplOfXexpected, s.name.s) closeScope(c) # close scope for parameters popOwner() result.typ = s.typ @@ -937,7 +935,7 @@ type stepCompileBody proc isForwardDecl(s: PSym): bool = - InternalAssert s.kind == skProc + internalAssert s.kind == skProc result = s.ast[bodyPos].kind != nkEmpty proc semProcAux(c: PContext, n: PNode, kind: TSymKind, @@ -980,7 +978,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, gp = newNodeI(nkGenericParams, n.info) # process parameters: if n.sons[paramsPos].kind != nkEmpty: - semParamList(c, n.sons[ParamsPos], gp, s) + semParamList(c, n.sons[paramsPos], gp, s) if sonsLen(gp) > 0: if n.sons[genericParamsPos].kind == nkEmpty: # we have a list of implicit type parameters: @@ -994,7 +992,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, n.sons[patternPos] = semPattern(c, n.sons[patternPos]) if s.kind == skIterator: s.typ.flags.incl(tfIterator) - var proto = SearchForProc(c, s.scope, s) + var proto = searchForProc(c, s.scope, s) if proto == nil: s.typ.callConv = lastOptionEntry(c).defaultCC # add it here, so that recursive procs are possible: @@ -1011,9 +1009,9 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, implictPragmas(c, s, n, validPragmas) else: if n.sons[pragmasPos].kind != nkEmpty: - LocalError(n.sons[pragmasPos].info, errPragmaOnlyInHeaderOfProc) + localError(n.sons[pragmasPos].info, errPragmaOnlyInHeaderOfProc) if sfForward notin proto.flags: - WrongRedefinition(n.info, proto.name.s) + wrongRedefinition(n.info, proto.name.s) excl(proto.flags, sfForward) closeScope(c) # close scope with wrong parameter symbols openScope(c) # open scope for old (correct) parameter symbols @@ -1026,7 +1024,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, n.sons[genericParamsPos] = proto.ast.sons[genericParamsPos] n.sons[paramsPos] = proto.ast.sons[paramsPos] n.sons[pragmasPos] = proto.ast.sons[pragmasPos] - if n.sons[namePos].kind != nkSym: InternalError(n.info, "semProcAux") + if n.sons[namePos].kind != nkSym: internalError(n.info, "semProcAux") n.sons[namePos].sym = proto if importantComments() and not isNil(proto.ast.comment): n.comment = proto.ast.comment @@ -1035,12 +1033,16 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, pushOwner(s) s.options = gOptions if sfDestructor in s.flags: doDestructorStuff(c, s, n) - if n.sons[bodyPos].kind != nkEmpty: + if n.sons[bodyPos].kind != nkEmpty: # for DLL generation it is annoying to check for sfImportc! - if sfBorrow in s.flags: - LocalError(n.sons[bodyPos].info, errImplOfXNotAllowed, s.name.s) - if n.sons[genericParamsPos].kind == nkEmpty: - ParamsTypeCheck(c, s.typ) + if sfBorrow in s.flags: + localError(n.sons[bodyPos].info, errImplOfXNotAllowed, s.name.s) + let usePseudoGenerics = kind in {skMacro, skTemplate} + # Macros and Templates can have generic parameters, but they are + # only used for overload resolution (there is no instantiation of + # the symbol, so we must process the body now) + if n.sons[genericParamsPos].kind == nkEmpty or usePseudoGenerics: + if not usePseudoGenerics: paramsTypeCheck(c, s.typ) pushProcCon(c, s) maybeAddResult(c, s, n) if sfImportc notin s.flags: @@ -1050,17 +1052,17 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, # context as it may even be evaluated in 'system.compiles': n.sons[bodyPos] = transformBody(c.module, semBody, s) popProcCon(c) - else: + else: if s.typ.sons[0] != nil and kind != skIterator: addDecl(c, newSym(skUnknown, getIdent"result", nil, n.info)) var toBind = initIntSet() n.sons[bodyPos] = semGenericStmtScope(c, n.sons[bodyPos], {}, toBind) fixupInstantiatedSymbols(c, s) - if sfImportc in s.flags: + if sfImportc in s.flags: # so we just ignore the body after semantic checking for importc: n.sons[bodyPos] = ast.emptyNode else: - if proto != nil: LocalError(n.info, errImplOfXexpected, proto.name.s) + if proto != nil: localError(n.info, errImplOfXexpected, proto.name.s) if {sfImportc, sfBorrow} * s.flags == {} and s.magic == mNone: incl(s.flags, sfForward) elif sfBorrow in s.flags: semBorrow(c, n, s) @@ -1081,7 +1083,7 @@ proc semIterator(c: PContext, n: PNode): PNode = var s = result.sons[namePos].sym var t = s.typ if t.sons[0] == nil and s.typ.callConv != ccClosure: - LocalError(n.info, errXNeedsReturnType, "iterator") + localError(n.info, errXNeedsReturnType, "iterator") # iterators are either 'inline' or 'closure'; for backwards compatibility, # we require first class iterators to be marked with 'closure' explicitly # -- at least for 0.9.2. @@ -1095,7 +1097,7 @@ proc semIterator(c: PContext, n: PNode): PNode = # and they always at least use the 'env' for the state field: incl(s.typ.flags, tfCapturesEnv) if n.sons[bodyPos].kind == nkEmpty and s.magic == mNone: - LocalError(n.info, errImplOfXexpected, s.name.s) + localError(n.info, errImplOfXexpected, s.name.s) proc semProc(c: PContext, n: PNode): PNode = result = semProcAux(c, n, skProc, procPragmas) @@ -1146,11 +1148,11 @@ proc evalInclude(c: PContext, n: PNode): PNode = for i in countup(0, sonsLen(n) - 1): var f = checkModuleName(n.sons[i]) if f != InvalidFileIDX: - if ContainsOrIncl(c.includedFiles, f): - LocalError(n.info, errRecursiveDependencyX, f.toFilename) + if containsOrIncl(c.includedFiles, f): + localError(n.info, errRecursiveDependencyX, f.toFilename) else: addSon(result, semStmt(c, gIncludeFile(c.module, f))) - Excl(c.includedFiles, f) + excl(c.includedFiles, f) proc setLine(n: PNode, info: TLineInfo) = for i in 0 .. <safeLen(n): setLine(n.sons[i], info) @@ -1159,20 +1161,25 @@ proc setLine(n: PNode, info: TLineInfo) = proc semPragmaBlock(c: PContext, n: PNode): PNode = let pragmaList = n.sons[0] pragma(c, nil, pragmaList, exprPragmas) - result = semStmt(c, n.sons[1]) + result = semExpr(c, n.sons[1]) for i in 0 .. <pragmaList.len: if whichPragma(pragmaList.sons[i]) == wLine: setLine(result, pragmaList.sons[i].info) proc semStaticStmt(c: PContext, n: PNode): PNode = let a = semStmt(c, n.sons[0]) - result = evalStaticExpr(c, c.module, a, c.p.owner) - if result.isNil: - LocalError(n.info, errCannotInterpretNodeX, renderTree(n)) - result = emptyNode - elif result.kind == nkEmpty: - result = newNodeI(nkDiscardStmt, n.info, 1) - result.sons[0] = emptyNode + n.sons[0] = a + evalStaticStmt(c.module, a, c.p.owner) + result = newNodeI(nkDiscardStmt, n.info, 1) + result.sons[0] = emptyNode + when false: + result = evalStaticStmt(c.module, a, c.p.owner) + if result.isNil: + LocalError(n.info, errCannotInterpretNodeX, renderTree(n)) + result = emptyNode + elif result.kind == nkEmpty: + result = newNodeI(nkDiscardStmt, n.info, 1) + result.sons[0] = emptyNode proc usesResult(n: PNode): bool = # nkStmtList(expr) properly propagates the void context, @@ -1224,9 +1231,9 @@ proc semStmtList(c: PContext, n: PNode): PNode = return else: n.sons[i] = semExpr(c, n.sons[i]) - if n.sons[i].typ == EnforceVoidContext or usesResult(n.sons[i]): + if n.sons[i].typ == enforceVoidContext or usesResult(n.sons[i]): voidContext = true - n.typ = EnforceVoidContext + n.typ = enforceVoidContext if i != last or voidContext: discardCheck(c, n.sons[i]) else: @@ -1239,7 +1246,7 @@ proc semStmtList(c: PContext, n: PNode): PNode = if outer != nil: n.sons[i] = outer for j in countup(i+1, length-1): - inner.addSon(SemStmt(c, n.sons[j])) + inner.addSon(semStmt(c, n.sons[j])) n.sons.setLen(i+1) return of LastBlockStmts: @@ -1260,7 +1267,7 @@ proc semStmtList(c: PContext, n: PNode): PNode = # "Last expression must be explicitly returned if it " & # "is discardable or discarded") -proc SemStmt(c: PContext, n: PNode): PNode = +proc semStmt(c: PContext, n: PNode): PNode = # now: simply an alias: result = semExprNoType(c, n) diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 68abc9aa6..5abc3ef33 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2013 Andreas Rumpf +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -14,7 +14,7 @@ discard """ template `||` (a, b: expr): expr = let aa = a - (if aa: aa else: b) + if aa: aa else: b var a, b: T @@ -36,9 +36,9 @@ proc symBinding(n: PNode): TSymBinding = var key = if it.kind == nkExprColonExpr: it.sons[0] else: it if key.kind == nkIdent: case whichKeyword(key.ident) - of wGenSym: return spGenSym + of wGensym: return spGenSym of wInject: return spInject - else: nil + else: discard type TSymChoiceRule = enum @@ -79,7 +79,7 @@ proc semBindStmt(c: PContext, n: PNode, toBind: var TIntSet): PNode = # the same symbol! # This is however not true anymore for hygienic templates as semantic # processing for them changes the symbol table... - let s = QualifiedLookUp(c, a) + let s = qualifiedLookUp(c, a) if s != nil: # we need to mark all symbols: let sc = symChoice(c, n, s, scClosed) @@ -106,7 +106,7 @@ proc replaceIdentBySym(n: var PNode, s: PNode) = type TemplCtx {.pure, final.} = object c: PContext - toBind, toMixin: TIntSet + toBind, toMixin, toInject: TIntSet owner: PSym proc getIdentNode(c: var TemplCtx, n: PNode): PNode = @@ -115,7 +115,7 @@ proc getIdentNode(c: var TemplCtx, n: PNode): PNode = of nkPragmaExpr: result = getIdentNode(c, n.sons[0]) of nkIdent: result = n - let s = QualifiedLookUp(c.c, n, {}) + let s = qualifiedLookUp(c.c, n, {}) if s != nil: if s.owner == c.owner and s.kind == skParam: result = newSymNode(s, n.info) @@ -145,7 +145,18 @@ proc newGenSym(kind: TSymKind, n: PNode, c: var TemplCtx): PSym = proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) = # locals default to 'gensym': - if n.kind != nkPragmaExpr or symBinding(n.sons[1]) != spInject: + if n.kind == nkPragmaExpr and symBinding(n.sons[1]) == spInject: + # even if injected, don't produce a sym choice here: + #n = semTemplBody(c, n) + var x = n[0] + while true: + case x.kind + of nkPostfix: x = x[1] + of nkPragmaExpr: x = x[0] + of nkIdent: break + else: illFormedAst(x) + c.toInject.incl(x.ident.id) + else: let ident = getIdentNode(c, n) if not isTemplParam(c, ident): let local = newGenSym(k, ident, c) @@ -153,8 +164,37 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) = replaceIdentBySym(n, newSymNode(local, n.info)) else: replaceIdentBySym(n, ident) + +proc semTemplSymbol(c: PContext, n: PNode, s: PSym): PNode = + incl(s.flags, sfUsed) + case s.kind + of skUnknown: + # Introduced in this pass! Leave it as an identifier. + result = n + of skProc, skMethod, skIterator, skConverter, skTemplate, skMacro: + result = symChoice(c, n, s, scOpen) + of skGenericParam: + result = newSymNodeTypeDesc(s, n.info) + of skParam: + result = n + of skType: + if (s.typ != nil) and (s.typ.kind != tyGenericParam): + result = newSymNodeTypeDesc(s, n.info) + else: + result = n + else: result = newSymNode(s, n.info) + +proc semRoutineInTemplName(c: var TemplCtx, n: PNode): PNode = + result = n + if n.kind == nkIdent: + let s = qualifiedLookUp(c.c, n, {}) + if s != nil: + if s.owner == c.owner and (s.kind == skParam or sfGenSym in s.flags): + incl(s.flags, sfUsed) + result = newSymNode(s, n.info) else: - n = semTemplBody(c, n) + for i in countup(0, safeLen(n) - 1): + result.sons[i] = semRoutineInTemplName(c, n.sons[i]) proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode = result = n @@ -170,17 +210,17 @@ proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode = else: n.sons[namePos] = ident else: - n.sons[namePos] = semTemplBody(c, n.sons[namePos]) + n.sons[namePos] = semRoutineInTemplName(c, n.sons[namePos]) openScope(c) for i in patternPos..bodyPos: n.sons[i] = semTemplBody(c, n.sons[i]) closeScope(c) proc semTemplSomeDecl(c: var TemplCtx, n: PNode, symKind: TSymKind) = - for i in countup(ord(symkind == skConditional), sonsLen(n) - 1): + for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue - if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): IllFormedAst(a) + if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): illFormedAst(a) checkMinSonsLen(a, 3) var L = sonsLen(a) a.sons[L-2] = semTemplBody(c, a.sons[L-2]) @@ -193,18 +233,23 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = result = n case n.kind of nkIdent: - let s = QualifiedLookUp(c.c, n, {}) + if n.ident.id in c.toInject: return n + let s = qualifiedLookUp(c.c, n, {}) if s != nil: if s.owner == c.owner and s.kind == skParam: incl(s.flags, sfUsed) result = newSymNode(s, n.info) - elif Contains(c.toBind, s.id): + elif contains(c.toBind, s.id): result = symChoice(c.c, n, s, scClosed) + elif contains(c.toMixin, s.name.id): + result = symChoice(c.c, n, s, scForceOpen) elif s.owner == c.owner and sfGenSym in s.flags: # template tmp[T](x: var seq[T]) = # var yz: T incl(s.flags, sfUsed) result = newSymNode(s, n.info) + else: + result = semTemplSymbol(c.c, n, s) of nkBind: result = semTemplBody(c, n.sons[0]) of nkBindStmt: @@ -212,7 +257,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = of nkMixinStmt: result = semMixinStmt(c.c, n, c.toMixin) of nkEmpty, nkSym..nkNilLit: - nil + discard of nkIfStmt: for i in countup(0, sonsLen(n)-1): var it = n.sons[i] @@ -274,7 +319,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue - if (a.kind != nkConstDef): IllFormedAst(a) + if (a.kind != nkConstDef): illFormedAst(a) checkSonsLen(a, 3) addLocalDecl(c, a.sons[0], skConst) a.sons[1] = semTemplBody(c, a.sons[1]) @@ -283,13 +328,13 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue - if (a.kind != nkTypeDef): IllFormedAst(a) + if (a.kind != nkTypeDef): illFormedAst(a) checkSonsLen(a, 3) addLocalDecl(c, a.sons[0], skType) for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] if a.kind == nkCommentStmt: continue - if (a.kind != nkTypeDef): IllFormedAst(a) + if (a.kind != nkTypeDef): illFormedAst(a) checkSonsLen(a, 3) if a.sons[1].kind != nkEmpty: openScope(c) @@ -310,14 +355,22 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = result = semRoutineInTemplBody(c, n, skMacro) of nkConverterDef: result = semRoutineInTemplBody(c, n, skConverter) + of nkPragmaExpr: + result.sons[0] = semTemplBody(c, n.sons[0]) + of nkPragma: + discard else: # dotExpr is ambiguous: note that we explicitely allow 'x.TemplateParam', # so we use the generic code for nkDotExpr too if n.kind == nkDotExpr or n.kind == nkAccQuoted: - let s = QualifiedLookUp(c.c, n, {}) + let s = qualifiedLookUp(c.c, n, {}) if s != nil: - if Contains(c.toBind, s.id): + if contains(c.toBind, s.id): return symChoice(c.c, n, s, scClosed) + elif contains(c.toMixin, s.name.id): + return symChoice(c.c, n, s, scForceOpen) + else: + return symChoice(c.c, n, s, scOpen) result = n for i in countup(0, sonsLen(n) - 1): result.sons[i] = semTemplBody(c, n.sons[i]) @@ -326,24 +379,24 @@ proc semTemplBodyDirty(c: var TemplCtx, n: PNode): PNode = result = n case n.kind of nkIdent: - let s = QualifiedLookUp(c.c, n, {}) + let s = qualifiedLookUp(c.c, n, {}) if s != nil: if s.owner == c.owner and s.kind == skParam: result = newSymNode(s, n.info) - elif Contains(c.toBind, s.id): + elif contains(c.toBind, s.id): result = symChoice(c.c, n, s, scClosed) of nkBind: result = semTemplBodyDirty(c, n.sons[0]) of nkBindStmt: result = semBindStmt(c.c, n, c.toBind) of nkEmpty, nkSym..nkNilLit: - nil + discard else: # dotExpr is ambiguous: note that we explicitely allow 'x.TemplateParam', # so we use the generic code for nkDotExpr too if n.kind == nkDotExpr or n.kind == nkAccQuoted: - let s = QualifiedLookUp(c.c, n, {}) - if s != nil and Contains(c.toBind, s.id): + let s = qualifiedLookUp(c.c, n, {}) + if s != nil and contains(c.toBind, s.id): return symChoice(c.c, n, s, scClosed) result = n for i in countup(0, sonsLen(n) - 1): @@ -358,7 +411,7 @@ proc transformToExpr(n: PNode): PNode = for i in countup(0, sonsLen(n) - 1): case n.sons[i].kind of nkCommentStmt, nkEmpty, nkNilLit: - nil + discard else: if realStmt == - 1: realStmt = i else: realStmt = - 2 @@ -368,7 +421,7 @@ proc transformToExpr(n: PNode): PNode = n.kind = nkBlockExpr #nkIfStmt: n.kind = nkIfExpr // this is not correct! else: - nil + discard proc semTemplateDef(c: PContext, n: PNode): PNode = var s: PSym @@ -378,6 +431,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = else: s = semIdentVis(c, skTemplate, n.sons[0], {}) # check parameter list: + s.scope = c.currentScope pushOwner(s) openScope(c) n.sons[namePos] = newSymNode(s, n.sons[namePos].info) @@ -392,7 +446,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = gp = newNodeI(nkGenericParams, n.info) # process parameters: if n.sons[paramsPos].kind != nkEmpty: - semParamList(c, n.sons[ParamsPos], gp, s) + semParamList(c, n.sons[paramsPos], gp, s) if sonsLen(gp) > 0: if n.sons[genericParamsPos].kind == nkEmpty: # we have a list of implicit type parameters: @@ -413,6 +467,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = var ctx: TemplCtx ctx.toBind = initIntSet() ctx.toMixin = initIntSet() + ctx.toInject = initIntSet() ctx.c = c ctx.owner = s if sfDirty in s.flags: @@ -427,12 +482,12 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = s.ast = n result = n if n.sons[bodyPos].kind == nkEmpty: - LocalError(n.info, errImplOfXexpected, s.name.s) - var proto = SearchForProc(c, c.currentScope, s) + localError(n.info, errImplOfXexpected, s.name.s) + var proto = searchForProc(c, c.currentScope, s) if proto == nil: addInterfaceOverloadableSymAt(c, c.currentScope, s) else: - SymTabReplace(c.currentScope.symbols, proto, s) + symTabReplace(c.currentScope.symbols, proto, s) if n.sons[patternPos].kind != nkEmpty: c.patterns.add(s) @@ -455,17 +510,17 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode = if s != nil: if s.owner == c.owner and s.kind == skParam: result = newParam(c, n, s) - elif Contains(c.toBind, s.id): + elif contains(c.toBind, s.id): result = symChoice(c.c, n, s, scClosed) elif templToExpand(s): result = semPatternBody(c, semTemplateExpr(c.c, n, s, false)) else: - nil + discard # we keep the ident unbound for matching instantiated symbols and # more flexibility proc expectParam(c: var TemplCtx, n: PNode): PNode = - let s = QualifiedLookUp(c.c, n, {}) + let s = qualifiedLookUp(c.c, n, {}) if s != nil and s.owner == c.owner and s.kind == skParam: result = newParam(c, n, s) else: @@ -475,11 +530,11 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode = result = n case n.kind of nkIdent: - let s = QualifiedLookUp(c.c, n, {}) + let s = qualifiedLookUp(c.c, n, {}) result = handleSym(c, n, s) of nkBindStmt: result = semBindStmt(c.c, n, c.toBind) - of nkEmpty, nkSym..nkNilLit: nil + of nkEmpty, nkSym..nkNilLit: discard of nkCurlyExpr: # we support '(pattern){x}' to bind a subpattern to a parameter 'x'; # '(pattern){|x}' does the same but the matches will be gathered in 'x' @@ -498,10 +553,10 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode = else: localError(n.info, errInvalidExpression) of nkCallKinds: - let s = QualifiedLookUp(c.c, n.sons[0], {}) + let s = qualifiedLookUp(c.c, n.sons[0], {}) if s != nil: - if s.owner == c.owner and s.kind == skParam: nil - elif Contains(c.toBind, s.id): nil + if s.owner == c.owner and s.kind == skParam: discard + elif contains(c.toBind, s.id): discard elif templToExpand(s): return semPatternBody(c, semTemplateExpr(c.c, n, s, false)) @@ -537,15 +592,15 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode = # so we use the generic code for nkDotExpr too case n.kind of nkDotExpr, nkAccQuoted: - let s = QualifiedLookUp(c.c, n, {}) + let s = qualifiedLookUp(c.c, n, {}) if s != nil: - if Contains(c.toBind, s.id): + if contains(c.toBind, s.id): return symChoice(c.c, n, s, scClosed) else: return newIdentNode(s.name, n.info) of nkPar: if n.len == 1: return semPatternBody(c, n.sons[0]) - else: nil + else: discard for i in countup(0, sonsLen(n) - 1): result.sons[i] = semPatternBody(c, n.sons[i]) @@ -554,6 +609,7 @@ proc semPattern(c: PContext, n: PNode): PNode = var ctx: TemplCtx ctx.toBind = initIntSet() ctx.toMixin = initIntSet() + ctx.toInject = initIntSet() ctx.c = c ctx.owner = getCurrOwner() result = flattenStmts(semPatternBody(ctx, n)) @@ -561,5 +617,5 @@ proc semPattern(c: PContext, n: PNode): PNode = if result.len == 1: result = result.sons[0] elif result.len == 0: - LocalError(n.info, errInvalidExpression) + localError(n.info, errInvalidExpression) closeScope(c) diff --git a/compiler/semthreads.nim b/compiler/semthreads.nim index eded99325..f7322db80 100644 --- a/compiler/semthreads.nim +++ b/compiler/semthreads.nim @@ -97,7 +97,7 @@ proc `==`(a, b: TCall): bool = proc newProcCtx(owner: PSym): PProcCtx = assert owner != nil new(result) - result.mapping = tables.InitTable[int, TThreadOwner]() + result.mapping = tables.initTable[int, TThreadOwner]() result.owner = owner proc analyse(c: PProcCtx, n: PNode): TThreadOwner @@ -119,7 +119,7 @@ proc analyseSym(c: PProcCtx, n: PNode): TThreadOwner = of skParam: result = c.mapping[v.id] if result == toUndefined: - InternalError(n.info, "param not set: " & v.name.s) + internalError(n.info, "param not set: " & v.name.s) else: result = toNil c.mapping[v.id] = result @@ -132,7 +132,7 @@ proc lvalueSym(n: PNode): PNode = proc writeAccess(c: PProcCtx, n: PNode, owner: TThreadOwner) = if owner notin {toNil, toMine, toTheirs}: - InternalError(n.info, "writeAccess: " & $owner) + internalError(n.info, "writeAccess: " & $owner) var a = lvalueSym(n) if a.kind == nkSym: var v = a.sym @@ -151,21 +151,21 @@ proc writeAccess(c: PProcCtx, n: PNode, owner: TThreadOwner) = newOwner = toMine # XXX BUG what if the tuple contains both ``tyRef`` and ``tyString``? c.mapping[v.id] = newOwner - of toVoid, toUndefined: InternalError(n.info, "writeAccess") - of toTheirs: Message(n.info, warnWriteToForeignHeap) + of toVoid, toUndefined: internalError(n.info, "writeAccess") + of toTheirs: message(n.info, warnWriteToForeignHeap) of toMine: if lastOwner != owner and owner != toNil: - Message(n.info, warnDifferentHeaps) + message(n.info, warnDifferentHeaps) else: # we could not backtrack to a concrete symbol, but that's fine: var lastOwner = analyse(c, n) case lastOwner - of toNil: nil # fine, toNil can be overwritten - of toVoid, toUndefined: InternalError(n.info, "writeAccess") - of toTheirs: Message(n.info, warnWriteToForeignHeap) + of toNil: discard # fine, toNil can be overwritten + of toVoid, toUndefined: internalError(n.info, "writeAccess") + of toTheirs: message(n.info, warnWriteToForeignHeap) of toMine: if lastOwner != owner and owner != toNil: - Message(n.info, warnDifferentHeaps) + message(n.info, warnDifferentHeaps) proc analyseAssign(c: PProcCtx, le, ri: PNode) = var y = analyse(c, ri) # read access; ok @@ -192,7 +192,7 @@ proc analyseCall(c: PProcCtx, n: PNode): TThreadOwner = result = analyse(newCtx, prc.getBody) if prc.ast.sons[bodyPos].kind == nkEmpty and {sfNoSideEffect, sfThread, sfImportc} * prc.flags == {}: - Message(n.info, warnAnalysisLoophole, renderTree(n)) + message(n.info, warnAnalysisLoophole, renderTree(n)) if result == toUndefined: result = toNil if prc.typ.sons[0] != nil: if prc.ast.len > resultPos: @@ -215,12 +215,12 @@ proc analyseCall(c: PProcCtx, n: PNode): TThreadOwner = else: result = toNil proc analyseVarTuple(c: PProcCtx, n: PNode) = - if n.kind != nkVarTuple: InternalError(n.info, "analyseVarTuple") + if n.kind != nkVarTuple: internalError(n.info, "analyseVarTuple") var L = n.len - for i in countup(0, L-3): AnalyseAssign(c, n.sons[i], n.sons[L-1]) + for i in countup(0, L-3): analyseAssign(c, n.sons[i], n.sons[L-1]) proc analyseSingleVar(c: PProcCtx, a: PNode) = - if a.sons[2].kind != nkEmpty: AnalyseAssign(c, a.sons[0], a.sons[2]) + if a.sons[2].kind != nkEmpty: analyseAssign(c, a.sons[0], a.sons[2]) proc analyseVarSection(c: PProcCtx, n: PNode): TThreadOwner = for i in countup(0, sonsLen(n) - 1): @@ -238,7 +238,7 @@ proc analyseConstSection(c: PProcCtx, t: PNode): TThreadOwner = for i in countup(0, sonsLen(t) - 1): var it = t.sons[i] if it.kind == nkCommentStmt: continue - if it.kind != nkConstDef: InternalError(t.info, "analyseConstSection") + if it.kind != nkConstDef: internalError(t.info, "analyseConstSection") if sfFakeConst in it.sons[0].sym.flags: analyseSingleVar(c, it) result = toVoid @@ -246,7 +246,7 @@ template aggregateOwner(result, ana: expr) = var a = ana # eval once if result != a: if result == toNil: result = a - elif a != toNil: Message(n.info, warnDifferentHeaps) + elif a != toNil: message(n.info, warnDifferentHeaps) proc analyseArgs(c: PProcCtx, n: PNode, start = 1) = for i in start..n.len-1: discard analyse(c, n[i]) @@ -254,7 +254,7 @@ proc analyseArgs(c: PProcCtx, n: PNode, start = 1) = proc analyseOp(c: PProcCtx, n: PNode): TThreadOwner = if n[0].kind != nkSym or n[0].sym.kind != skProc: if {tfNoSideEffect, tfThread} * n[0].typ.flags == {}: - Message(n.info, warnAnalysisLoophole, renderTree(n)) + message(n.info, warnAnalysisLoophole, renderTree(n)) result = toNil else: var prc = n[0].sym @@ -352,7 +352,7 @@ proc analyse(c: PProcCtx, n: PNode): TThreadOwner = result = analyse(c, n.sons[0]) of nkRaiseStmt: var a = analyse(c, n.sons[0]) - if a != toMine: Message(n.info, warnDifferentHeaps) + if a != toMine: message(n.info, warnDifferentHeaps) result = toVoid of nkVarSection, nkLetSection: result = analyseVarSection(c, n) of nkConstSection: result = analyseConstSection(c, n) @@ -369,11 +369,11 @@ proc analyse(c: PProcCtx, n: PNode): TThreadOwner = result = toMine of nkAsmStmt, nkPragma, nkIteratorDef, nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef, - nkGotoState, nkState, nkBreakState, nkType: + nkGotoState, nkState, nkBreakState, nkType, nkIdent: result = toVoid of nkExprColonExpr: result = analyse(c, n.sons[1]) - else: InternalError(n.info, "analysis not implemented for: " & $n.kind) + else: internalError(n.info, "analysis not implemented for: " & $n.kind) proc analyseThreadProc*(prc: PSym) = var c = newProcCtx(prc) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 6c9c476d9..64c8f81e2 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -18,7 +18,7 @@ proc newOrPrevType(kind: TTypeKind, prev: PType, c: PContext): PType = if result.kind == tyForward: result.kind = kind proc newConstraint(c: PContext, k: TTypeKind): PType = - result = newTypeS(tyTypeClass, c) + result = newTypeS(tyBuiltInTypeClass, c) result.addSonSkipIntLit(newTypeS(k, c)) proc semEnum(c: PContext, n: PNode, prev: PType): PType = @@ -50,13 +50,13 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = of tyTuple: if sonsLen(v) == 2: strVal = v.sons[1] # second tuple part is the string value - if skipTypes(strVal.typ, abstractInst).kind in {tyString, tyCstring}: + if skipTypes(strVal.typ, abstractInst).kind in {tyString, tyCString}: x = getOrdValue(v.sons[0]) # first tuple part is the ordinal else: - LocalError(strVal.info, errStringLiteralExpected) + localError(strVal.info, errStringLiteralExpected) else: - LocalError(v.info, errWrongNumberOfVariables) - of tyString, tyCstring: + localError(v.info, errWrongNumberOfVariables) + of tyString, tyCString: strVal = v x = counter else: @@ -64,7 +64,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = if i != 1: if x != counter: incl(result.flags, tfEnumHasHoles) if x < counter: - LocalError(n.sons[i].info, errInvalidOrderInEnumX, e.name.s) + localError(n.sons[i].info, errInvalidOrderInEnumX, e.name.s) x = counter e.ast = strVal # might be nil counter = x @@ -79,7 +79,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = if result.sym != nil and sfExported in result.sym.flags: incl(e.flags, sfUsed) incl(e.flags, sfExported) - if not isPure: StrTableAdd(c.module.tab, e) + if not isPure: strTableAdd(c.module.tab, e) addSon(result.n, newSymNode(e)) if sfGenSym notin e.flags and not isPure: addDecl(c, e) inc(counter) @@ -93,11 +93,11 @@ proc semSet(c: PContext, n: PNode, prev: PType): PType = if base.kind == tyGenericInst: base = lastSon(base) if base.kind != tyGenericParam: if not isOrdinalType(base): - LocalError(n.info, errOrdinalTypeExpected) + localError(n.info, errOrdinalTypeExpected) elif lengthOrd(base) > MaxSetElements: - LocalError(n.info, errSetTooBig) + localError(n.info, errSetTooBig) else: - LocalError(n.info, errXExpectsOneTypeParam, "set") + localError(n.info, errXExpectsOneTypeParam, "set") addSonSkipIntLit(result, errorType(c)) proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string, @@ -107,7 +107,7 @@ proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string, var base = semTypeNode(c, n.sons[1], nil) addSonSkipIntLit(result, base) else: - LocalError(n.info, errXExpectsOneTypeParam, kindStr) + localError(n.info, errXExpectsOneTypeParam, kindStr) addSonSkipIntLit(result, errorType(c)) proc semVarargs(c: PContext, n: PNode, prev: PType): PType = @@ -118,7 +118,7 @@ proc semVarargs(c: PContext, n: PNode, prev: PType): PType = if sonsLen(n) == 3: result.n = newIdentNode(considerAcc(n.sons[2]), n.sons[2].info) else: - LocalError(n.info, errXExpectsOneTypeParam, "varargs") + localError(n.info, errXExpectsOneTypeParam, "varargs") addSonSkipIntLit(result, errorType(c)) proc semAnyRef(c: PContext, n: PNode, kind: TTypeKind, prev: PType): PType = @@ -134,7 +134,7 @@ proc semVarType(c: PContext, n: PNode, prev: PType): PType = result = newOrPrevType(tyVar, prev, c) var base = semTypeNode(c, n.sons[0], nil) if base.kind == tyVar: - LocalError(n.info, errVarVarTypeNotAllowed) + localError(n.info, errVarVarTypeNotAllowed) base = base.sons[0] addSonSkipIntLit(result, base) else: @@ -148,22 +148,22 @@ proc semDistinct(c: PContext, n: PNode, prev: PType): PType = result = newConstraint(c, tyDistinct) proc semRangeAux(c: PContext, n: PNode, prev: PType): PType = - assert IsRange(n) + assert isRange(n) checkSonsLen(n, 3) result = newOrPrevType(tyRange, prev, c) result.n = newNodeI(nkRange, n.info) if (n[1].kind == nkEmpty) or (n[2].kind == nkEmpty): - LocalError(n.Info, errRangeIsEmpty) + localError(n.info, errRangeIsEmpty) var a = semConstExpr(c, n[1]) var b = semConstExpr(c, n[2]) if not sameType(a.typ, b.typ): - LocalError(n.info, errPureTypeMismatch) + localError(n.info, errPureTypeMismatch) elif a.typ.kind notin {tyInt..tyInt64,tyEnum,tyBool,tyChar, tyFloat..tyFloat128,tyUInt8..tyUInt32}: - LocalError(n.info, errOrdinalTypeExpected) + localError(n.info, errOrdinalTypeExpected) elif enumHasHoles(a.typ): - LocalError(n.info, errEnumXHasHoles, a.typ.sym.name.s) - elif not leValue(a, b): LocalError(n.Info, errRangeIsEmpty) + localError(n.info, errEnumXHasHoles, a.typ.sym.name.s) + elif not leValue(a, b): localError(n.info, errRangeIsEmpty) addSon(result.n, a) addSon(result.n, b) addSonSkipIntLit(result, b.typ) @@ -180,12 +180,17 @@ proc semRange(c: PContext, n: PNode, prev: PType): PType = elif n.sons[0].floatVal > 0.0 or n.sons[1].floatVal < 0.0: incl(result.flags, tfNeedsInit) else: - LocalError(n.sons[0].info, errRangeExpected) + localError(n.sons[0].info, errRangeExpected) result = newOrPrevType(tyError, prev, c) else: - LocalError(n.info, errXExpectsOneTypeParam, "range") + localError(n.info, errXExpectsOneTypeParam, "range") result = newOrPrevType(tyError, prev, c) +proc nMinusOne(n: PNode): PNode = + result = newNode(nkCall, n.info, @[ + newSymNode(getSysMagic("<", mUnaryLt)), + n]) + proc semArray(c: PContext, n: PNode, prev: PType): PType = var indx, base: PType result = newOrPrevType(tyArray, prev, c) @@ -194,27 +199,43 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType = if isRange(n[1]): indx = semRangeAux(c, n[1], nil) else: let e = semExprWithType(c, n.sons[1], {efDetermineType}) - if e.kind in {nkIntLit..nkUInt64Lit}: + if e.typ.kind == tyFromExpr: + indx = e.typ + elif e.kind in {nkIntLit..nkUInt64Lit}: indx = makeRangeType(c, 0, e.intVal-1, n.info, e.typ) - elif e.kind == nkSym and e.typ.kind == tyExpr: + elif e.kind == nkSym and e.typ.kind == tyStatic: if e.sym.ast != nil: return semArray(c, e.sym.ast, nil) - InternalAssert c.InGenericContext > 0 + internalAssert c.inGenericContext > 0 if not isOrdinalType(e.typ.lastSon): localError(n[1].info, errOrdinalTypeExpected) indx = e.typ + elif e.kind in nkCallKinds and hasGenericArguments(e): + if not isOrdinalType(e.typ): + localError(n[1].info, errOrdinalTypeExpected) + # This is an int returning call, depending on an + # yet unknown generic param (see tgenericshardcases). + # We are going to construct a range type that will be + # properly filled-out in semtypinst (see how tyStaticExpr + # is handled there). + let intType = getSysType(tyInt) + indx = newTypeS(tyRange, c) + indx.sons = @[intType] + indx.n = newNode(nkRange, n.info, @[ + newIntTypeNode(nkIntLit, 0, intType), + makeStaticExpr(c, e.nMinusOne)]) else: indx = e.typ.skipTypes({tyTypeDesc}) addSonSkipIntLit(result, indx) if indx.kind == tyGenericInst: indx = lastSon(indx) - if indx.kind notin {tyGenericParam, tyExpr}: + if indx.kind notin {tyGenericParam, tyStatic, tyFromExpr}: if not isOrdinalType(indx): - LocalError(n.sons[1].info, errOrdinalTypeExpected) + localError(n.sons[1].info, errOrdinalTypeExpected) elif enumHasHoles(indx): - LocalError(n.sons[1].info, errEnumXHasHoles, indx.sym.name.s) + localError(n.sons[1].info, errEnumXHasHoles, indx.sym.name.s) base = semTypeNode(c, n.sons[2], nil) addSonSkipIntLit(result, base) else: - LocalError(n.info, errArrayExpectsTwoTypeParams) + localError(n.info, errArrayExpectsTwoTypeParams) result = newOrPrevType(tyError, prev, c) proc semOrdinal(c: PContext, n: PNode, prev: PType): PType = @@ -223,29 +244,29 @@ proc semOrdinal(c: PContext, n: PNode, prev: PType): PType = var base = semTypeNode(c, n.sons[1], nil) if base.kind != tyGenericParam: if not isOrdinalType(base): - LocalError(n.sons[1].info, errOrdinalTypeExpected) + localError(n.sons[1].info, errOrdinalTypeExpected) addSonSkipIntLit(result, base) else: - LocalError(n.info, errXExpectsOneTypeParam, "ordinal") + localError(n.info, errXExpectsOneTypeParam, "ordinal") result = newOrPrevType(tyError, prev, c) proc semTypeIdent(c: PContext, n: PNode): PSym = if n.kind == nkSym: result = n.sym else: - result = qualifiedLookup(c, n, {checkAmbiguity, checkUndeclared}) + result = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared}) if result != nil: markUsed(n, result) if result.kind == skParam and result.typ.kind == tyTypeDesc: # This is a typedesc param. is it already bound? # it's not bound when it's used multiple times in the # proc signature for example - if c.InGenericInst > 0: + if c.inGenericInst > 0: let bound = result.typ.sons[0].sym if bound != nil: return bound return result if result.typ.sym == nil: - LocalError(n.info, errTypeExpected) + localError(n.info, errTypeExpected) return errorSym(c, n) result = result.typ.sym.copySym result.typ = copyType(result.typ, result.typ.owner, true) @@ -253,12 +274,12 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = if result.kind != skType: # this implements the wanted ``var v: V, x: V`` feature ... var ov: TOverloadIter - var amb = InitOverloadIter(ov, c, n) + var amb = initOverloadIter(ov, c, n) while amb != nil and amb.kind != skType: amb = nextOverloadIter(ov, c, n) if amb != nil: result = amb else: - if result.kind != skError: LocalError(n.info, errTypeExpected) + if result.kind != skError: localError(n.info, errTypeExpected) return errorSym(c, n) if result.typ.kind != tyGenericParam: # XXX get rid of this hack! @@ -268,7 +289,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = n.sym = result n.info = oldInfo else: - LocalError(n.info, errIdentifierExpected) + localError(n.info, errIdentifierExpected) result = errorSym(c, n) proc semTuple(c: PContext, n: PNode, prev: PType): PType = @@ -280,26 +301,27 @@ proc semTuple(c: PContext, n: PNode, prev: PType): PType = var counter = 0 for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] - if (a.kind != nkIdentDefs): IllFormedAst(a) + if (a.kind != nkIdentDefs): illFormedAst(a) checkMinSonsLen(a, 3) var length = sonsLen(a) if a.sons[length - 2].kind != nkEmpty: typ = semTypeNode(c, a.sons[length - 2], nil) else: - LocalError(a.info, errTypeExpected) + localError(a.info, errTypeExpected) typ = errorType(c) if a.sons[length - 1].kind != nkEmpty: - LocalError(a.sons[length - 1].info, errInitHereNotAllowed) + localError(a.sons[length - 1].info, errInitHereNotAllowed) for j in countup(0, length - 3): var field = newSymG(skField, a.sons[j], c) field.typ = typ field.position = counter inc(counter) - if ContainsOrIncl(check, field.name.id): - LocalError(a.sons[j].info, errAttemptToRedefine, field.name.s) + if containsOrIncl(check, field.name.id): + localError(a.sons[j].info, errAttemptToRedefine, field.name.s) else: addSon(result.n, newSymNode(field)) addSonSkipIntLit(result, typ) + if gCmd == cmdPretty: checkDef(a.sons[j], field) proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, allowed: TSymFlags): PSym = @@ -313,7 +335,7 @@ proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, if sfExported in allowed and v.id == ord(wStar): incl(result.flags, sfExported) else: - LocalError(n.sons[0].info, errInvalidVisibilityX, v.s) + localError(n.sons[0].info, errInvalidVisibilityX, v.s) else: illFormedAst(n) else: @@ -331,9 +353,10 @@ proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode, of skVar: pragma(c, result, n.sons[1], varPragmas) of skLet: pragma(c, result, n.sons[1], letPragmas) of skConst: pragma(c, result, n.sons[1], constPragmas) - else: nil + else: discard else: result = semIdentVis(c, kind, n, allowed) + if gCmd == cmdPretty: checkDef(n, result) proc checkForOverlap(c: PContext, t: PNode, currentEx, branchIndex: int) = let ex = t[branchIndex][currentEx].skipConv @@ -341,9 +364,9 @@ proc checkForOverlap(c: PContext, t: PNode, currentEx, branchIndex: int) = for j in countup(0, sonsLen(t.sons[i]) - 2): if i == branchIndex and j == currentEx: break if overlap(t.sons[i].sons[j].skipConv, ex): - LocalError(ex.info, errDuplicateCaseLabel) + localError(ex.info, errDuplicateCaseLabel) -proc semBranchRange(c: PContext, t, a, b: PNode, covered: var biggestInt): PNode = +proc semBranchRange(c: PContext, t, a, b: PNode, covered: var BiggestInt): PNode = checkMinSonsLen(t, 1) let ac = semConstExpr(c, a) let bc = semConstExpr(c, b) @@ -353,16 +376,16 @@ proc semBranchRange(c: PContext, t, a, b: PNode, covered: var biggestInt): PNode result = newNodeI(nkRange, a.info) result.add(at) result.add(bt) - if emptyRange(ac, bc): LocalError(b.info, errRangeIsEmpty) + if emptyRange(ac, bc): localError(b.info, errRangeIsEmpty) else: covered = covered + getOrdValue(bc) - getOrdValue(ac) + 1 -proc SemCaseBranchRange(c: PContext, t, b: PNode, - covered: var biggestInt): PNode = +proc semCaseBranchRange(c: PContext, t, b: PNode, + covered: var BiggestInt): PNode = checkSonsLen(b, 3) result = semBranchRange(c, t, b.sons[1], b.sons[2], covered) proc semCaseBranchSetElem(c: PContext, t, b: PNode, - covered: var biggestInt): PNode = + covered: var BiggestInt): PNode = if isRange(b): checkSonsLen(b, 3) result = semBranchRange(c, t, b.sons[1], b.sons[2], covered) @@ -374,7 +397,7 @@ proc semCaseBranchSetElem(c: PContext, t, b: PNode, inc(covered) proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, - covered: var biggestInt) = + covered: var BiggestInt) = for i in countup(0, sonsLen(branch) - 2): var b = branch.sons[i] if b.kind == nkRange: @@ -411,14 +434,14 @@ proc semRecordCase(c: PContext, n: PNode, check: var TIntSet, pos: var int, internalError("semRecordCase: discriminant is no symbol") return incl(a.sons[0].sym.flags, sfDiscriminant) - var covered: biggestInt = 0 - var typ = skipTypes(a.sons[0].Typ, abstractVar-{tyTypeDesc}) + var covered: BiggestInt = 0 + var typ = skipTypes(a.sons[0].typ, abstractVar-{tyTypeDesc}) if not isOrdinalType(typ): - LocalError(n.info, errSelectorMustBeOrdinal) + localError(n.info, errSelectorMustBeOrdinal) elif firstOrd(typ) < 0: - LocalError(n.info, errOrdXMustNotBeNegative, a.sons[0].sym.name.s) + localError(n.info, errOrdXMustNotBeNegative, a.sons[0].sym.name.s) elif lengthOrd(typ) > 0x00007FFF: - LocalError(n.info, errLenXinvalid, a.sons[0].sym.name.s) + localError(n.info, errLenXinvalid, a.sons[0].sym.name.s) var chckCovered = true for i in countup(1, sonsLen(n) - 1): var b = copyTree(n.sons[i]) @@ -450,9 +473,9 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int, case it.kind of nkElifBranch: checkSonsLen(it, 2) - if c.InGenericContext == 0: + if c.inGenericContext == 0: var e = semConstBoolExpr(c, it.sons[0]) - if e.kind != nkIntLit: InternalError(e.info, "semRecordNodeAux") + if e.kind != nkIntLit: internalError(e.info, "semRecordNodeAux") elif e.intVal != 0 and branch == nil: branch = it.sons[1] else: it.sons[0] = forceBool(c, semExprWithType(c, it.sons[0])) @@ -461,15 +484,15 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int, if branch == nil: branch = it.sons[0] idx = 0 else: illFormedAst(n) - if c.InGenericContext > 0: + if c.inGenericContext > 0: # use a new check intset here for each branch: var newCheck: TIntSet assign(newCheck, check) var newPos = pos var newf = newNodeI(nkRecList, n.info) - semRecordNodeAux(c, it.sons[idx], newcheck, newpos, newf, rectype) + semRecordNodeAux(c, it.sons[idx], newCheck, newPos, newf, rectype) it.sons[idx] = if newf.len == 1: newf[0] else: newf - if c.InGenericContext > 0: + if c.inGenericContext > 0: addSon(father, n) elif branch != nil: semRecordNodeAux(c, branch, check, pos, father, rectype) @@ -493,7 +516,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int, localError(n.sons[length-1].info, errInitHereNotAllowed) var typ: PType if n.sons[length-2].kind == nkEmpty: - LocalError(n.info, errTypeExpected) + localError(n.info, errTypeExpected) typ = errorType(c) else: typ = semTypeNode(c, n.sons[length-2], nil) @@ -509,7 +532,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int, f.loc.r = toRope(f.name.s) f.flags = f.flags + ({sfImportc, sfExportc} * rec.flags) inc(pos) - if ContainsOrIncl(check, f.name.id): + if containsOrIncl(check, f.name.id): localError(n.sons[i].info, errAttemptToRedefine, f.name.s) if a.kind == nkEmpty: addSon(father, newSymNode(f)) else: addSon(a, newSymNode(f)) @@ -521,7 +544,7 @@ proc addInheritedFieldsAux(c: PContext, check: var TIntSet, pos: var int, n: PNode) = case n.kind of nkRecCase: - if (n.sons[0].kind != nkSym): InternalError(n.info, "addInheritedFieldsAux") + if (n.sons[0].kind != nkSym): internalError(n.info, "addInheritedFieldsAux") addInheritedFieldsAux(c, check, pos, n.sons[0]) for i in countup(1, sonsLen(n) - 1): case n.sons[i].kind @@ -532,9 +555,9 @@ proc addInheritedFieldsAux(c: PContext, check: var TIntSet, pos: var int, for i in countup(0, sonsLen(n) - 1): addInheritedFieldsAux(c, check, pos, n.sons[i]) of nkSym: - Incl(check, n.sym.name.id) + incl(check, n.sym.name.id) inc(pos) - else: InternalError(n.info, "addInheritedFieldsAux()") + else: internalError(n.info, "addInheritedFieldsAux()") proc addInheritedFields(c: PContext, check: var TIntSet, pos: var int, obj: PType) = @@ -565,7 +588,7 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType): PType = if concreteBase.kind != tyError: localError(n.sons[1].info, errInheritanceOnlyWithNonFinalObjects) base = nil - if n.kind != nkObjectTy: InternalError(n.info, "semObjectNode") + if n.kind != nkObjectTy: internalError(n.info, "semObjectNode") result = newOrPrevType(tyObject, prev, c) rawAddSon(result, base) result.n = newNodeI(nkRecList, n.info) @@ -577,9 +600,9 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType): PType = pragma(c, s, n.sons[0], typePragmas) if base == nil and tfInheritable notin result.flags: incl(result.flags, tfFinal) - + proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) = - if kind == skMacro and param.typ.kind != tyTypeDesc: + if kind == skMacro and param.typ.kind notin {tyTypeDesc, tyStatic}: # within a macro, every param has the type PNimrodNode! # and param.typ.kind in {tyTypeDesc, tyExpr, tyStmt}: let nn = getSysSym"PNimrodNode" @@ -591,18 +614,22 @@ proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) = let typedescId = getIdent"typedesc" +template shouldHaveMeta(t) = + InternalAssert tfHasMeta in t.flags + # result.lastSon.flags.incl tfHasMeta + proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, paramType: PType, paramName: string, info: TLineInfo, anon = false): PType = - if procKind in {skMacro, skTemplate}: - # generic param types in macros and templates affect overload - # resolution, but don't work as generic params when it comes - # to proc instantiation. We don't need to lift such params here. - return + if paramType == nil: return # (e.g. proc return type) proc addImplicitGenericImpl(typeClass: PType, typId: PIdent): PType = let finalTypId = if typId != nil: typId else: getIdent(paramName & ":type") + if genericParams == nil: + # This happens with anonymous proc types appearing in signatures + # XXX: we need to lift these earlier + return # is this a bindOnce type class already present in the param list? for i in countup(0, genericParams.len - 1): if genericParams.sons[i].sym.name.id == finalTypId.id: @@ -613,10 +640,11 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, var s = newSym(skType, finalTypId, owner, info) if typId == nil: s.flags.incl(sfAnon) s.linkTo(typeClass) + typeClass.flags.incl tfImplicitTypeParam s.position = genericParams.len genericParams.addSon(newSymNode(s)) result = typeClass - + # XXX: There are codegen errors if this is turned into a nested proc template liftingWalk(typ: PType, anonFlag = false): expr = liftParamType(c, procKind, genericParams, typ, paramName, info, anonFlag) @@ -629,34 +657,38 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, addImplicitGenericImpl(e, paramTypId) case paramType.kind: - of tyExpr: - if paramType.sonsLen == 0: - # proc(a, b: expr) - # no constraints, treat like generic param - result = addImplicitGeneric(newTypeS(tyGenericParam, c)) - else: - # proc(a: expr{string}, b: expr{nkLambda}) - # overload on compile time values and AST trees - result = addImplicitGeneric(c.newTypeWithSons(tyExpr, paramType.sons)) + of tyAnything: + result = addImplicitGeneric(newTypeS(tyGenericParam, c)) + + of tyStatic: + # proc(a: expr{string}, b: expr{nkLambda}) + # overload on compile time values and AST trees + result = addImplicitGeneric(c.newTypeWithSons(tyStatic, paramType.sons)) + result.flags.incl tfHasStatic + of tyTypeDesc: if tfUnresolved notin paramType.flags: # naked typedescs are not bindOnce types if paramType.sonsLen == 0 and paramTypId != nil and paramTypId.id == typedescId.id: paramTypId = nil result = addImplicitGeneric(c.newTypeWithSons(tyTypeDesc, paramType.sons)) + of tyDistinct: if paramType.sonsLen == 1: # disable the bindOnce behavior for the type class result = liftingWalk(paramType.sons[0], true) - of tySequence, tySet, tyArray, tyOpenArray: + + of tySequence, tySet, tyArray, tyOpenArray, + tyVar, tyPtr, tyRef, tyProc: # XXX: this is a bit strange, but proc(s: seq) # produces tySequence(tyGenericParam, null). # This also seems to be true when creating aliases # like: type myseq = distinct seq. # Maybe there is another better place to associate # the seq type class with the seq identifier. - if paramType.lastSon == nil: - let typ = c.newTypeWithSons(tyTypeClass, @[newTypeS(paramType.kind, c)]) + if paramType.kind == tySequence and paramType.lastSon == nil: + let typ = c.newTypeWithSons(tyBuiltInTypeClass, + @[newTypeS(paramType.kind, c)]) result = addImplicitGeneric(typ) else: for i in 0 .. <paramType.sons.len: @@ -664,29 +696,55 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, if lifted != nil: paramType.sons[i] = lifted result = paramType + of tyGenericBody: - # type Foo[T] = object - # proc x(a: Foo, b: Foo) - var typ = newTypeS(tyTypeClass, c) - typ.addSonSkipIntLit(paramType) - result = addImplicitGeneric(typ) + result = newTypeS(tyGenericInvokation, c) + result.rawAddSon(paramType) + for i in 0 .. paramType.sonsLen - 2: + result.rawAddSon newTypeS(tyAnything, c) + # result.rawAddSon(copyType(paramType.sons[i], getCurrOwner(), true)) + result = instGenericContainer(c, paramType.sym.info, result, + allowMetaTypes = true) + result.lastSon.shouldHaveMeta + result = newTypeWithSons(c, tyCompositeTypeClass, @[paramType, result]) + result = addImplicitGeneric(result) + of tyGenericInst: for i in 1 .. (paramType.sons.len - 2): var lifted = liftingWalk(paramType.sons[i]) if lifted != nil: paramType.sons[i] = lifted result = paramType + result.lastSon.shouldHaveMeta + + let liftBody = liftingWalk(paramType.lastSon) + if liftBody != nil: + result = liftBody + result.shouldHaveMeta + + of tyGenericInvokation: + for i in 1 .. <paramType.sonsLen: + let lifted = liftingWalk(paramType.sons[i]) + if lifted != nil: paramType.sons[i] = lifted + + let expanded = instGenericContainer(c, info, paramType, + allowMetaTypes = true) + result = liftingWalk(expanded) - if paramType.lastSon.kind == tyTypeClass: - result = paramType - result.kind = tyParametricTypeClass - result = addImplicitGeneric(copyType(result, - getCurrOwner(), false)) - elif result != nil: - result.kind = tyGenericInvokation - result.sons.setLen(result.sons.len - 1) - of tyTypeClass: - result = addImplicitGeneric(copyType(paramType, getCurrOwner(), false)) + of tyTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot: + result = addImplicitGeneric(copyType(paramType, getCurrOwner(), true)) + + of tyExpr: + if procKind notin {skMacro, skTemplate}: + result = addImplicitGeneric(newTypeS(tyAnything, c)) + + of tyGenericParam: + if tfGenericTypeParam in paramType.flags and false: + if paramType.sonsLen > 0: + result = liftingWalk(paramType.lastSon) + else: + result = addImplicitGeneric(newTypeS(tyAnything, c)) + else: nil # result = liftingWalk(paramType) @@ -719,7 +777,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, var counter = 0 for i in countup(1, n.len - 1): var a = n.sons[i] - if a.kind != nkIdentDefs: IllFormedAst(a) + if a.kind != nkIdentDefs: illFormedAst(a) checkMinSonsLen(a, 3) var typ: PType = nil @@ -743,8 +801,9 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, if not containsGenericType(typ): def = fitNode(c, typ, def) if not (hasType or hasDefault): - typ = newTypeS(tyExpr, c) - + let tdef = if kind in {skTemplate, skMacro}: tyExpr else: tyAnything + typ = newTypeS(tdef, c) + if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue for j in countup(0, length-3): var arg = newSymG(skParam, a.sons[j], c) @@ -756,11 +815,13 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, arg.constraint = constraint inc(counter) if def != nil and def.kind != nkEmpty: arg.ast = copyTree(def) - if ContainsOrIncl(check, arg.name.id): - LocalError(a.sons[j].info, errAttemptToRedefine, arg.name.s) + if containsOrIncl(check, arg.name.id): + localError(a.sons[j].info, errAttemptToRedefine, arg.name.s) addSon(result.n, newSymNode(arg)) rawAddSon(result, finalType) addParamOrResult(c, arg, kind) + if gCmd == cmdPretty: checkDef(a.sons[j], arg) + if n.sons[0].kind != nkEmpty: var r = semTypeNode(c, n.sons[0], nil) @@ -788,7 +849,7 @@ proc semStmtListType(c: PContext, n: PNode, prev: PType): PType = result = nil proc semBlockType(c: PContext, n: PNode, prev: PType): PType = - Inc(c.p.nestedBlockCounter) + inc(c.p.nestedBlockCounter) checkSonsLen(n, 2) openScope(c) if n.sons[0].kind notin {nkEmpty, nkSym}: @@ -797,39 +858,23 @@ proc semBlockType(c: PContext, n: PNode, prev: PType): PType = n.sons[1].typ = result n.typ = result closeScope(c) - Dec(c.p.nestedBlockCounter) + dec(c.p.nestedBlockCounter) proc semGenericParamInInvokation(c: PContext, n: PNode): PType = - # XXX hack 1022 for generics ... would have been nice if the compiler had - # been designed with them in mind from start ... - when false: - if n.kind == nkSym: - # for generics we need to lookup the type var again: - var s = searchInScopes(c, n.sym.name) - if s != nil: - if s.kind == skType and s.typ != nil: - var t = n.sym.typ - echo "came here" - return t - else: - echo "s is crap:" - debug(s) - else: - echo "s is nil!!!!" result = semTypeNode(c, n, nil) proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = result = newOrPrevType(tyGenericInvokation, prev, c) addSonSkipIntLit(result, s.typ) - + template addToResult(typ) = if typ.isNil: - InternalAssert false + internalAssert false rawAddSon(result, typ) else: addSonSkipIntLit(result, typ) if s.typ == nil: - LocalError(n.info, errCannotInstantiateX, s.name.s) + localError(n.info, errCannotInstantiateX, s.name.s) return newOrPrevType(tyError, prev, c) elif s.typ.kind == tyForward: for i in countup(1, sonsLen(n)-1): @@ -838,18 +883,18 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = else: internalAssert s.typ.kind == tyGenericBody - var m = newCandidate(s, n) + var m = newCandidate(c, s, n) matches(c, n, copyTree(n), m) if m.state != csMatch: var err = "cannot instantiate " & typeToString(s.typ) & "\n" & "got: (" & describeArgs(c, n) & ")\n" & "but expected: (" & describeArgs(c, s.typ.n, 0) & ")" - LocalError(n.info, errGenerated, err) + localError(n.info, errGenerated, err) return newOrPrevType(tyError, prev, c) var isConcrete = true - + for i in 1 .. <m.call.len: let typ = m.call[i].typ.skipTypes({tyTypeDesc}) if containsGenericType(typ): isConcrete = false @@ -857,20 +902,18 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = if isConcrete: if s.ast == nil: - LocalError(n.info, errCannotInstantiateX, s.name.s) + localError(n.info, errCannotInstantiateX, s.name.s) result = newOrPrevType(tyError, prev, c) else: - when oUseLateInstantiation: - result = lateInstantiateGeneric(c, result, n.info) - else: - result = instGenericContainer(c, n, result) + result = instGenericContainer(c, n.info, result, + allowMetaTypes = false) proc semTypeExpr(c: PContext, n: PNode): PType = var n = semExprWithType(c, n, {efDetermineType}) - if n.kind == nkSym and n.sym.kind == skType: - result = n.sym.typ + if n.typ.kind == tyTypeDesc: + result = n.typ.base else: - LocalError(n.info, errTypeExpected, n.renderTree) + localError(n.info, errTypeExpected, n.renderTree) proc freshType(res, prev: PType): PType {.inline.} = if prev.isNil: @@ -905,7 +948,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev) else: # XXX support anon tuple here - LocalError(n.info, errTypeExpected) + localError(n.info, errTypeExpected) result = newOrPrevType(tyError, prev, c) of nkCallKinds: if isRange(n): @@ -917,26 +960,29 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = var t1 = semTypeNode(c, n.sons[1], nil) t2 = semTypeNode(c, n.sons[2], nil) - if t1 == nil: - LocalError(n.sons[1].info, errTypeExpected) + if t1 == nil: + localError(n.sons[1].info, errTypeExpected) result = newOrPrevType(tyError, prev, c) - elif t2 == nil: - LocalError(n.sons[2].info, errTypeExpected) + elif t2 == nil: + localError(n.sons[2].info, errTypeExpected) result = newOrPrevType(tyError, prev, c) else: - result = newTypeS(tyTypeClass, c) - result.addSonSkipIntLit(t1) - result.addSonSkipIntLit(t2) - result.flags.incl(if op.id == ord(wAnd): tfAll else: tfAny) - result.flags.incl(tfHasMeta) + result = if op.id == ord(wAnd): makeAndType(c, t1, t2) + else: makeOrType(c, t1, t2) elif op.id == ord(wNot): - checkSonsLen(n, 3) - result = semTypeNode(c, n.sons[1], prev) - if result.kind in NilableTypes and n.sons[2].kind == nkNilLit: - result = freshType(result, prev) - result.flags.incl(tfNotNil) + case n.len + of 3: + result = semTypeNode(c, n.sons[1], prev) + if result.kind in NilableTypes and n.sons[2].kind == nkNilLit: + result = freshType(result, prev) + result.flags.incl(tfNotNil) + else: + LocalError(n.info, errGenerated, "invalid type") + of 2: + let negated = semTypeNode(c, n.sons[1], prev) + result = makeNotType(c, negated) else: - LocalError(n.info, errGenerated, "invalid type") + localError(n.info, errGenerated, "invalid type") else: result = semTypeExpr(c, n) else: @@ -964,13 +1010,19 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result.rawAddSon(semTypeNode(c, n.sons[i], nil)) else: result = semGeneric(c, n, s, prev) of nkIdent, nkDotExpr, nkAccQuoted: + if n.kind == nkDotExpr: + let head = qualifiedLookUp(c, n[0], {checkAmbiguity, checkUndeclared}) + if head.kind in {skType}: + var toBind = initIntSet() + var preprocessed = semGenericStmt(c, n, {}, toBind) + return makeTypeFromExpr(c, preprocessed) var s = semTypeIdent(c, n) if s.typ == nil: - if s.kind != skError: LocalError(n.info, errTypeExpected) + if s.kind != skError: localError(n.info, errTypeExpected) result = newOrPrevType(tyError, prev, c) elif s.kind == skParam and s.typ.kind == tyTypeDesc: assert s.typ.len > 0 - InternalAssert prev == nil + internalAssert prev == nil result = s.typ.sons[0] elif prev == nil: result = s.typ @@ -991,7 +1043,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = prev markUsed(n, n.sym) else: - if n.sym.kind != skError: LocalError(n.info, errTypeExpected) + if n.sym.kind != skError: localError(n.info, errTypeExpected) result = newOrPrevType(tyError, prev, c) of nkObjectTy: result = semObjectNode(c, n, prev) of nkTupleTy: result = semTuple(c, n, prev) @@ -1000,6 +1052,11 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = of nkPtrTy: result = semAnyRef(c, n, tyPtr, prev) of nkVarTy: result = semVarType(c, n, prev) of nkDistinctTy: result = semDistinct(c, n, prev) + of nkStaticTy: + result = newOrPrevType(tyStatic, prev, c) + var base = semTypeNode(c, n.sons[0], nil) + result.rawAddSon(base) + result.flags.incl tfHasStatic of nkProcTy, nkIteratorTy: if n.sonsLen == 0: result = newConstraint(c, tyProc) @@ -1016,7 +1073,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = #Message(n.info, warnImplicitClosure, renderTree(n)) else: pragma(c, s, n.sons[1], procTypePragmas) - when useEffectSystem: SetEffectsForProcType(result, n.sons[1]) + when useEffectSystem: setEffectsForProcType(result, n.sons[1]) closeScope(c) if n.kind == nkIteratorTy: result.flags.incl(tfIterator) @@ -1031,7 +1088,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = freshType(result, prev) result.flags.incl(tfShared) else: - LocalError(n.info, errTypeExpected) + localError(n.info, errTypeExpected) result = newOrPrevType(tyError, prev, c) proc setMagicType(m: PSym, kind: TTypeKind, size: int) = @@ -1081,14 +1138,10 @@ proc processMagicType(c: PContext, m: PSym) = of mSeq: setMagicType(m, tySequence, 0) of mOrdinal: setMagicType(m, tyOrdinal, 0) of mPNimrodNode: nil - else: LocalError(m.info, errTypeExpected) + else: localError(m.info, errTypeExpected) proc semGenericConstraints(c: PContext, x: PType): PType = - if x.kind in StructuralEquivTypes and ( - sonsLen(x) == 0 or x.sons[0].kind in {tyGenericParam, tyEmpty}): - result = newConstraint(c, x.kind) - else: - result = newTypeWithSons(c, tyGenericParam, @[x]) + result = newTypeWithSons(c, tyGenericParam, @[x]) proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = result = copyNode(n) @@ -1105,7 +1158,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = if constraint.kind != nkEmpty: typ = semTypeNode(c, constraint, nil) - if typ.kind != tyExpr or typ.len == 0: + if typ.kind != tyStatic or typ.len == 0: if typ.kind == tyTypeDesc: if typ.len == 0: typ = newTypeS(tyTypeDesc, c) @@ -1116,14 +1169,16 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = def = semConstExpr(c, def) if typ == nil: if def.typ.kind != tyTypeDesc: - typ = newTypeWithSons(c, tyExpr, @[def.typ]) + typ = newTypeWithSons(c, tyStatic, @[def.typ]) else: if not containsGenericType(def.typ): def = fitNode(c, typ, def) if typ == nil: typ = newTypeS(tyGenericParam, c) - + + typ.flags.incl tfGenericTypeParam + for j in countup(0, L-3): let finalType = if j == 0: typ else: copyType(typ, typ.owner, false) @@ -1132,7 +1187,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = # of the parameter will be stored in the # attached symbol. var s = case finalType.kind - of tyExpr: + of tyStatic: newSymG(skGenericParam, a.sons[j], c).linkTo(finalType) else: newSymG(skType, a.sons[j], c).linkTo(finalType) diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 61c31a4fe..b08119d4a 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -11,21 +11,24 @@ import ast, astalgo, msgs, types, magicsys, semdata, renderer +const + tfInstClearedFlags = {tfHasMeta} + proc checkPartialConstructedType(info: TLineInfo, t: PType) = if tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject: - LocalError(info, errInvalidPragmaX, "acyclic") + localError(info, errInvalidPragmaX, "acyclic") elif t.kind == tyVar and t.sons[0].kind == tyVar: - LocalError(info, errVarVarTypeNotAllowed) + localError(info, errVarVarTypeNotAllowed) -proc checkConstructedType*(info: TLineInfo, typ: PType) = +proc checkConstructedType*(info: TLineInfo, typ: PType) = var t = typ.skipTypes({tyDistinct}) - if t.kind in {tyTypeClass}: nil + if t.kind in tyTypeClasses: nil elif tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject: - LocalError(info, errInvalidPragmaX, "acyclic") + localError(info, errInvalidPragmaX, "acyclic") elif t.kind == tyVar and t.sons[0].kind == tyVar: - LocalError(info, errVarVarTypeNotAllowed) - elif computeSize(t) < 0: - LocalError(info, errIllegalRecursionInTypeX, typeToString(t)) + localError(info, errVarVarTypeNotAllowed) + elif computeSize(t) == szIllegalRecursion: + localError(info, errIllegalRecursionInTypeX, typeToString(t)) when false: if t.kind == tyObject and t.sons[0] != nil: if t.sons[0].kind != tyObject or tfFinal in t.sons[0].flags: @@ -33,7 +36,7 @@ proc checkConstructedType*(info: TLineInfo, typ: PType) = proc searchInstTypes*(key: PType): PType = let genericTyp = key.sons[0] - InternalAssert genericTyp.kind == tyGenericBody and + internalAssert genericTyp.kind == tyGenericBody and key.sons[0] == genericTyp and genericTyp.sym != nil @@ -47,12 +50,13 @@ proc searchInstTypes*(key: PType): PType = # types such as TChannel[empty]. Why? # See the notes for PActor in handleGenericInvokation return - block MatchType: + block matchType: for j in 1 .. high(key.sons): # XXX sameType is not really correct for nested generics? - if not sameType(inst.sons[j], key.sons[j]): - break MatchType - + if not compareTypes(inst.sons[j], key.sons[j], + flags = {ExactGenericParams}): + break matchType + return inst proc cacheTypeInst*(inst: PType) = @@ -66,30 +70,89 @@ type c*: PContext typeMap*: TIdTable # map PType to PType symMap*: TIdTable # map PSym to PSym + localCache*: TIdTable # local cache for remembering alraedy replaced + # types during instantiation of meta types + # (they are not stored in the global cache) info*: TLineInfo + allowMetaTypes*: bool # allow types such as seq[Number] + # i.e. the result contains unresolved generics -proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType -proc ReplaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym -proc ReplaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode +proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType +proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym +proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode + +template checkMetaInvariants(cl: TReplTypeVars, t: PType) = + when false: + if t != nil and tfHasMeta in t.flags and + cl.allowMetaTypes == false: + echo "UNEXPECTED META ", t.id, " ", instantiationInfo(-1) + debug t + writeStackTrace() + quit 1 + +proc replaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType = + result = replaceTypeVarsTAux(cl, t) + checkMetaInvariants(cl, result) proc prepareNode(cl: var TReplTypeVars, n: PNode): PNode = result = copyNode(n) - result.typ = ReplaceTypeVarsT(cl, n.typ) - if result.kind == nkSym: result.sym = ReplaceTypeVarsS(cl, n.sym) - for i in 0 .. safeLen(n)-1: - # XXX HACK: ``f(a, b)``, avoid to instantiate `f` - if i == 0: result.add(n[i]) + result.typ = replaceTypeVarsT(cl, n.typ) + if result.kind == nkSym: result.sym = replaceTypeVarsS(cl, n.sym) + let isCall = result.kind in nkCallKinds + for i in 0 .. <n.safeLen: + # XXX HACK: ``f(a, b)``, avoid to instantiate `f` + if isCall and i == 0: result.add(n[i]) else: result.add(prepareNode(cl, n[i])) -proc ReplaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode = +proc isTypeParam(n: PNode): bool = + # XXX: generic params should use skGenericParam instead of skType + return n.kind == nkSym and + (n.sym.kind == skGenericParam or + (n.sym.kind == skType and sfFromGeneric in n.sym.flags)) + +proc hasGenericArguments*(n: PNode): bool = + if n.kind == nkSym: + return n.sym.kind == skGenericParam or + (n.sym.kind == skType and + n.sym.typ.flags * {tfGenericTypeParam, tfImplicitTypeParam} != {}) + else: + for s in n.sons: + if hasGenericArguments(s): return true + return false + +proc reResolveCallsWithTypedescParams(cl: var TReplTypeVars, n: PNode): PNode = + # This is needed fo tgenericshardcases + # It's possible that a generic param will be used in a proc call to a + # typedesc accepting proc. After generic param substitution, such procs + # should be optionally instantiated with the correct type. In order to + # perform this instantiation, we need to re-run the generateInstance path + # in the compiler, but it's quite complicated to do so at the moment so we + # resort to a mild hack; the head symbol of the call is temporary reset and + # overload resolution is executed again (which may trigger generateInstance). + if n.kind in nkCallKinds and sfFromGeneric in n[0].sym.flags: + var needsFixing = false + for i in 1 .. <n.safeLen: + if isTypeParam(n[i]): needsFixing = true + if needsFixing: + n.sons[0] = newSymNode(n.sons[0].sym.owner) + return cl.c.semOverloadedCall(cl.c, n, n, {skProc}) + + for i in 0 .. <n.safeLen: + n.sons[i] = reResolveCallsWithTypedescParams(cl, n[i]) + + return n + +proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode = if n == nil: return result = copyNode(n) - result.typ = ReplaceTypeVarsT(cl, n.typ) + if n.typ != nil: + result.typ = replaceTypeVarsT(cl, n.typ) + checkMetaInvariants(cl, result.typ) case n.kind of nkNone..pred(nkSym), succ(nkSym)..nkNilLit: - nil + discard of nkSym: - result.sym = ReplaceTypeVarsS(cl, n.sym) + result.sym = replaceTypeVarsS(cl, n.sym) of nkRecWhen: var branch: PNode = nil # the branch to take for i in countup(0, sonsLen(n) - 1): @@ -101,72 +164,91 @@ proc ReplaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode = var cond = prepareNode(cl, it.sons[0]) var e = cl.c.semConstExpr(cl.c, cond) if e.kind != nkIntLit: - InternalError(e.info, "ReplaceTypeVarsN: when condition not a bool") + internalError(e.info, "ReplaceTypeVarsN: when condition not a bool") if e.intVal != 0 and branch == nil: branch = it.sons[1] of nkElse: checkSonsLen(it, 1) if branch == nil: branch = it.sons[0] else: illFormedAst(n) if branch != nil: - result = ReplaceTypeVarsN(cl, branch) + result = replaceTypeVarsN(cl, branch) else: result = newNodeI(nkRecList, n.info) + of nkStaticExpr: + var n = prepareNode(cl, n) + n = reResolveCallsWithTypedescParams(cl, n) + result = cl.c.semExpr(cl.c, n) else: var length = sonsLen(n) if length > 0: newSons(result, length) for i in countup(0, length - 1): - result.sons[i] = ReplaceTypeVarsN(cl, n.sons[i]) + result.sons[i] = replaceTypeVarsN(cl, n.sons[i]) -proc ReplaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym = +proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym = if s == nil: return nil result = PSym(idTableGet(cl.symMap, s)) if result == nil: result = copySym(s, false) incl(result.flags, sfFromGeneric) idTablePut(cl.symMap, s, result) - result.typ = ReplaceTypeVarsT(cl, s.typ) + result.typ = replaceTypeVarsT(cl, s.typ) result.owner = s.owner - result.ast = ReplaceTypeVarsN(cl, s.ast) + result.ast = replaceTypeVarsN(cl, s.ast) proc lookupTypeVar(cl: TReplTypeVars, t: PType): PType = result = PType(idTableGet(cl.typeMap, t)) if result == nil: - LocalError(t.sym.info, errCannotInstantiateX, typeToString(t)) + if cl.allowMetaTypes or tfRetType in t.flags: return + localError(t.sym.info, errCannotInstantiateX, typeToString(t)) result = errorType(cl.c) - elif result.kind == tyGenericParam: - InternalError(cl.info, "substitution with generic parameter") - + elif result.kind == tyGenericParam and not cl.allowMetaTypes: + internalError(cl.info, "substitution with generic parameter") + +proc instCopyType(cl: var TReplTypeVars, t: PType): PType = + # XXX: relying on allowMetaTypes is a kludge + result = copyType(t, t.owner, cl.allowMetaTypes) + result.flags.incl tfFromGeneric + result.flags.excl tfInstClearedFlags + proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType = # tyGenericInvokation[A, tyGenericInvokation[A, B]] # is difficult to handle: var body = t.sons[0] - if body.kind != tyGenericBody: InternalError(cl.info, "no generic body") + if body.kind != tyGenericBody: internalError(cl.info, "no generic body") var header: PType = nil # search for some instantiation here: - result = searchInstTypes(t) + if cl.allowMetaTypes: + result = PType(idTableGet(cl.localCache, t)) + else: + result = searchInstTypes(t) if result != nil: return for i in countup(1, sonsLen(t) - 1): var x = t.sons[i] if x.kind == tyGenericParam: x = lookupTypeVar(cl, x) - if header == nil: header = copyType(t, t.owner, false) - header.sons[i] = x - propagateToOwner(header, x) - #idTablePut(cl.typeMap, body.sons[i-1], x) - + if x != nil: + if header == nil: header = instCopyType(cl, t) + header.sons[i] = x + propagateToOwner(header, x) + if header != nil: # search again after first pass: result = searchInstTypes(header) if result != nil: return else: - header = copyType(t, t.owner, false) + header = instCopyType(cl, t) + + result = newType(tyGenericInst, t.sons[0].owner) + # be careful not to propagate unnecessary flags here (don't use rawAddSon) + result.sons = @[header.sons[0]] # ugh need another pass for deeply recursive generic types (e.g. PActor) # we need to add the candidate here, before it's fully instantiated for # recursive instantions: - result = newType(tyGenericInst, t.sons[0].owner) - result.rawAddSon(header.sons[0]) - cacheTypeInst(result) + if not cl.allowMetaTypes: + cacheTypeInst(result) + else: + idTablePut(cl.localCache, t, result) for i in countup(1, sonsLen(t) - 1): var x = replaceTypeVarsT(cl, t.sons[i]) @@ -175,71 +257,165 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType = propagateToOwner(header, x) idTablePut(cl.typeMap, body.sons[i-1], x) - for i in countup(1, sonsLen(t) - 1): + for i in countup(1, sonsLen(t) - 1): # if one of the params is not concrete, we cannot do anything # but we already raised an error! rawAddSon(result, header.sons[i]) - - var newbody = ReplaceTypeVarsT(cl, lastSon(body)) - newbody.flags = newbody.flags + t.flags + body.flags + + var newbody = replaceTypeVarsT(cl, lastSon(body)) + newbody.flags = newbody.flags + (t.flags + body.flags - tfInstClearedFlags) result.flags = result.flags + newbody.flags newbody.callConv = body.callConv - newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n) # This type may be a generic alias and we want to resolve it here. # One step is enough, because the recursive nature of # handleGenericInvokation will handle the alias-to-alias-to-alias case if newbody.isGenericAlias: newbody = newbody.skipGenericAlias rawAddSon(result, newbody) checkPartialConstructedType(cl.info, newbody) + +proc eraseVoidParams(t: PType) = + if t.sons[0] != nil and t.sons[0].kind == tyEmpty: + t.sons[0] = nil -proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType = + for i in 1 .. <t.sonsLen: + # don't touch any memory unless necessary + if t.sons[i].kind == tyEmpty: + var pos = i + for j in i+1 .. <t.sonsLen: + if t.sons[j].kind != tyEmpty: + t.sons[pos] = t.sons[j] + t.n.sons[pos] = t.n.sons[j] + inc pos + setLen t.sons, pos + setLen t.n.sons, pos + return + +proc skipIntLiteralParams(t: PType) = + for i in 0 .. <t.sonsLen: + let p = t.sons[i] + if p == nil: continue + let skipped = p.skipIntLit + if skipped != p: + t.sons[i] = skipped + if i > 0: t.n.sons[i].sym.typ = skipped + +proc propagateFieldFlags(t: PType, n: PNode) = + # This is meant for objects and tuples + # The type must be fully instantiated! + internalAssert n.kind != nkRecWhen + case n.kind + of nkSym: + propagateToOwner(t, n.sym.typ) + of nkRecList, nkRecCase, nkOfBranch, nkElse: + if n.sons != nil: + for son in n.sons: + propagateFieldFlags(t, son) + else: discard + +proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType = result = t - if t == nil: return + if t == nil: return + + if t.kind in {tyStatic, tyGenericParam} + tyTypeClasses: + let lookup = PType(idTableGet(cl.typeMap, t)) + if lookup != nil: return lookup + case t.kind - of tyTypeClass: nil - of tyGenericParam: - result = lookupTypeVar(cl, t) - if result.kind == tyGenericInvokation: - result = handleGenericInvokation(cl, result) - of tyExpr: - if t.sym != nil and t.sym.kind == skGenericParam: - result = lookupTypeVar(cl, t) - of tyGenericInvokation: + of tyGenericInvokation: result = handleGenericInvokation(cl, t) + of tyGenericBody: - InternalError(cl.info, "ReplaceTypeVarsT: tyGenericBody") - result = ReplaceTypeVarsT(cl, lastSon(t)) + internalError(cl.info, "ReplaceTypeVarsT: tyGenericBody" ) + result = replaceTypeVarsT(cl, lastSon(t)) + + of tyFromExpr: + var n = prepareNode(cl, t.n) + n = cl.c.semConstExpr(cl.c, n) + if n.typ.kind == tyTypeDesc: + # XXX: sometimes, chained typedescs enter here. + # It may be worth investigating why this is happening, + # because it may cause other bugs elsewhere. + result = n.typ.skipTypes({tyTypeDesc}) + # result = n.typ.base + else: + if n.typ.kind != tyStatic: + # XXX: In the future, semConstExpr should + # return tyStatic values to let anyone make + # use of this knowledge. The patching here + # won't be necessary then. + result = newTypeS(tyStatic, cl.c) + result.sons = @[n.typ] + result.n = n + else: + result = n.typ + of tyInt: result = skipIntLit(t) # XXX now there are also float literals + + of tyTypeDesc: + let lookup = PType(idTableGet(cl.typeMap, t)) # lookupTypeVar(cl, t) + if lookup != nil: + result = lookup + if tfUnresolved in t.flags: result = result.base + elif t.sonsLen > 0: + result = makeTypeDesc(cl.c, replaceTypeVarsT(cl, t.sons[0])) + + of tyGenericInst: + result = instCopyType(cl, t) + for i in 1 .. <result.sonsLen: + result.sons[i] = ReplaceTypeVarsT(cl, result.sons[i]) + propagateToOwner(result, result.lastSon) + else: - if t.kind == tyArray: - let idxt = t.sons[0] - if idxt.kind == tyExpr and - idxt.sym != nil and idxt.sym.kind == skGenericParam: - let value = lookupTypeVar(cl, idxt).n - t.sons[0] = makeRangeType(cl.c, 0, value.intVal - 1, value.info) if containsGenericType(t): - result = copyType(t, t.owner, false) - incl(result.flags, tfFromGeneric) + result = instCopyType(cl, t) result.size = -1 # needs to be recomputed + for i in countup(0, sonsLen(result) - 1): - result.sons[i] = ReplaceTypeVarsT(cl, result.sons[i]) - result.n = ReplaceTypeVarsN(cl, result.n) - if result.Kind in GenericTypes: - LocalError(cl.info, errCannotInstantiateX, TypeToString(t, preferName)) - if result.kind == tyProc and result.sons[0] != nil: - if result.sons[0].kind == tyEmpty: - result.sons[0] = nil - -proc generateTypeInstance*(p: PContext, pt: TIdTable, arg: PNode, - t: PType): PType = + if result.sons[i] != nil: + result.sons[i] = replaceTypeVarsT(cl, result.sons[i]) + propagateToOwner(result, result.sons[i]) + + result.n = replaceTypeVarsN(cl, result.n) + + # XXX: This is not really needed? + # if result.kind in GenericTypes: + # localError(cl.info, errCannotInstantiateX, typeToString(t, preferName)) + + case result.kind + of tyArray: + let idx = result.sons[0] + if idx.kind == tyStatic: + if idx.n == nil: + let lookup = lookupTypeVar(cl, idx) + internalAssert lookup != nil + idx.n = lookup.n + + result.sons[0] = makeRangeType(cl.c, 0, idx.n.intVal - 1, idx.n.info) + + of tyObject, tyTuple: + propagateFieldFlags(result, result.n) + + of tyProc: + eraseVoidParams(result) + skipIntLiteralParams(result) + + else: discard + +proc generateTypeInstance*(p: PContext, pt: TIdTable, info: TLineInfo, + t: PType): PType = var cl: TReplTypeVars - InitIdTable(cl.symMap) + initIdTable(cl.symMap) copyIdTable(cl.typeMap, pt) - cl.info = arg.info + initIdTable(cl.localCache) + cl.info = info cl.c = p - pushInfoContext(arg.info) - result = ReplaceTypeVarsT(cl, t) + pushInfoContext(info) + result = replaceTypeVarsT(cl, t) popInfoContext() +template generateTypeInstance*(p: PContext, pt: TIdTable, arg: PNode, + t: PType): expr = + generateTypeInstance(p, pt, arg.info, t) + diff --git a/compiler/service.nim b/compiler/service.nim index 1de83af7c..42c4aa9f4 100644 --- a/compiler/service.nim +++ b/compiler/service.nim @@ -29,23 +29,23 @@ var # the arguments to be passed to the program that # should be run -proc ProcessCmdLine*(pass: TCmdLinePass, cmd: string) = +proc processCmdLine*(pass: TCmdLinePass, cmd: string) = var p = parseopt.initOptParser(cmd) var argsCount = 0 while true: parseopt.next(p) case p.kind of cmdEnd: break - of cmdLongOption, cmdShortOption: + of cmdLongoption, cmdShortOption: # hint[X]:off is parsed as (p.key = "hint[X]", p.val = "off") # we fix this here var bracketLe = strutils.find(p.key, '[') if bracketLe >= 0: var key = substr(p.key, 0, bracketLe - 1) var val = substr(p.key, bracketLe + 1) & ':' & p.val - ProcessSwitch(key, val, pass, gCmdLineInfo) + processSwitch(key, val, pass, gCmdLineInfo) else: - ProcessSwitch(p.key, p.val, pass, gCmdLineInfo) + processSwitch(p.key, p.val, pass, gCmdLineInfo) of cmdArgument: if argsCount == 0: options.command = p.key @@ -79,11 +79,11 @@ proc serve*(action: proc (){.nimcall.}) = if line == "quit": quit() execute line echo "" - FlushFile(stdout) + flushFile(stdout) of "tcp", "": when useCaas: - var server = Socket() + var server = socket() let p = getConfigVar("server.port") let port = if p.len > 0: parseInt(p).TPort else: 6000.TPort server.bindAddr(port, getConfigVar("server.address")) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index cacf4782e..7066c5afd 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -21,7 +21,8 @@ type TCandidateState* = enum csEmpty, csMatch, csNoMatch - TCandidate* {.final.} = object + TCandidate* {.final.} = object + c*: PContext exactMatches*: int # also misused to prefer iters over procs genericMatches: int # also misused to prefer constraints subtypeMatches: int @@ -30,7 +31,8 @@ type state*: TCandidateState callee*: PType # may not be nil! calleeSym*: PSym # may be nil - calleeScope: int # may be -1 for unknown scope + calleeScope*: int # scope depth: + # is this a top-level symbol or a nested proc? call*: PNode # modified call bindings*: TIdTable # maps types to types baseTypeMatch: bool # needed for conversions from T to openarray[T] @@ -58,7 +60,9 @@ const proc markUsed*(n: PNode, s: PSym) -proc initCandidateAux(c: var TCandidate, callee: PType) {.inline.} = +proc initCandidateAux(ctx: PContext, + c: var TCandidate, callee: PType) {.inline.} = + c.c = ctx c.exactMatches = 0 c.subtypeMatches = 0 c.convMatches = 0 @@ -71,32 +75,44 @@ proc initCandidateAux(c: var TCandidate, callee: PType) {.inline.} = c.genericConverter = false c.inheritancePenalty = 0 -proc initCandidate*(c: var TCandidate, callee: PType) = - initCandidateAux(c, callee) +proc initCandidate*(ctx: PContext, c: var TCandidate, callee: PType) = + initCandidateAux(ctx, c, callee) c.calleeSym = nil initIdTable(c.bindings) proc put(t: var TIdTable, key, val: PType) {.inline.} = - IdTablePut(t, key, val) + idTablePut(t, key, val) -proc initCandidate*(c: var TCandidate, callee: PSym, binding: PNode, - calleeScope = -1) = - initCandidateAux(c, callee.typ) +proc initCandidate*(ctx: PContext, c: var TCandidate, callee: PSym, + binding: PNode, calleeScope = -1) = + initCandidateAux(ctx, c, callee.typ) c.calleeSym = callee - c.calleeScope = calleeScope + if callee.kind in skProcKinds and calleeScope == -1: + if callee.originatingModule == ctx.module: + let rootSym = if sfFromGeneric notin callee.flags: callee + else: callee.owner + c.calleeScope = rootSym.scope.depthLevel + else: + c.calleeScope = 1 + else: + c.calleeScope = calleeScope initIdTable(c.bindings) c.errors = nil - if binding != nil and callee.kind in RoutineKinds: + if binding != nil and callee.kind in routineKinds: var typeParams = callee.ast[genericParamsPos] for i in 1..min(sonsLen(typeParams), sonsLen(binding)-1): var formalTypeParam = typeParams.sons[i-1].typ - #debug(formalTypeParam) - put(c.bindings, formalTypeParam, binding[i].typ) + var bound = binding[i].typ + if formalTypeParam.kind != tyTypeDesc: + bound = bound.skipTypes({tyTypeDesc}) + put(c.bindings, formalTypeParam, bound) -proc newCandidate*(callee: PSym, binding: PNode, calleeScope = -1): TCandidate = - initCandidate(result, callee, binding, calleeScope) +proc newCandidate*(ctx: PContext, callee: PSym, + binding: PNode, calleeScope = -1): TCandidate = + initCandidate(ctx, result, callee, binding, calleeScope) proc copyCandidate(a: var TCandidate, b: TCandidate) = + a.c = b.c a.exactMatches = b.exactMatches a.subtypeMatches = b.subtypeMatches a.convMatches = b.convMatches @@ -124,7 +140,7 @@ proc sumGeneric(t: PType): int = result = ord(t.kind == tyGenericInvokation) for i in 0 .. <t.len: result += t.sons[i].sumGeneric break - of tyGenericParam, tyExpr, tyStmt, tyTypeDesc, tyTypeClass: break + of tyGenericParam, tyExpr, tyStatic, tyStmt, tyTypeDesc, tyTypeClass: break else: return 0 proc complexDisambiguation(a, b: PType): int = @@ -159,9 +175,8 @@ proc cmpCandidates*(a, b: TCandidate): int = if result != 0: return result = a.convMatches - b.convMatches if result != 0: return - if (a.calleeScope != -1) and (b.calleeScope != -1): - result = a.calleeScope - b.calleeScope - if result != 0: return + result = a.calleeScope - b.calleeScope + if result != 0: return # the other way round because of other semantics: result = b.inheritancePenalty - a.inheritancePenalty if result != 0: return @@ -169,11 +184,11 @@ proc cmpCandidates*(a, b: TCandidate): int = result = complexDisambiguation(a.callee, b.callee) proc writeMatches*(c: TCandidate) = - Writeln(stdout, "exact matches: " & $c.exactMatches) - Writeln(stdout, "subtype matches: " & $c.subtypeMatches) - Writeln(stdout, "conv matches: " & $c.convMatches) - Writeln(stdout, "intconv matches: " & $c.intConvMatches) - Writeln(stdout, "generic matches: " & $c.genericMatches) + writeln(stdout, "exact matches: " & $c.exactMatches) + writeln(stdout, "subtype matches: " & $c.subtypeMatches) + writeln(stdout, "conv matches: " & $c.convMatches) + writeln(stdout, "intconv matches: " & $c.intConvMatches) + writeln(stdout, "generic matches: " & $c.genericMatches) proc argTypeToString(arg: PNode): string = if arg.kind in nkSymChoices: @@ -203,7 +218,7 @@ proc describeArgs*(c: PContext, n: PNode, startIdx = 1): string = add(result, argTypeToString(arg)) if i != sonsLen(n) - 1: add(result, ", ") -proc typeRel*(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation +proc typeRel*(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation proc concreteType(c: TCandidate, t: PType): PType = case t.kind of tyArrayConstr: @@ -223,7 +238,7 @@ proc concreteType(c: TCandidate, t: PType): PType = # proc sort[T](cmp: proc(a, b: T): int = cmp) if result.kind != tyGenericParam: break of tyGenericInvokation: - InternalError("cannot resolve type: " & typeToString(t)) + internalError("cannot resolve type: " & typeToString(t)) result = t else: result = t # Note: empty is valid here @@ -296,24 +311,27 @@ proc minRel(a, b: TTypeRelation): TTypeRelation = if a <= b: result = a else: result = b -proc tupleRel(c: var TCandidate, f, a: PType): TTypeRelation = +proc recordRel(c: var TCandidate, f, a: PType): TTypeRelation = result = isNone - if sameType(f, a): - result = isEqual + if sameType(f, a): result = isEqual elif sonsLen(a) == sonsLen(f): result = isEqual - for i in countup(0, sonsLen(f) - 1): + let firstField = if f.kind == tyTuple: 0 + else: 1 + for i in countup(firstField, sonsLen(f) - 1): var m = typeRel(c, f.sons[i], a.sons[i]) if m < isSubtype: return isNone result = minRel(result, m) if f.n != nil and a.n != nil: for i in countup(0, sonsLen(f.n) - 1): # check field names: - if f.n.sons[i].kind != nkSym: InternalError(f.n.info, "tupleRel") - elif a.n.sons[i].kind != nkSym: InternalError(a.n.info, "tupleRel") + if f.n.sons[i].kind != nkSym: internalError(f.n.info, "recordRel") + elif a.n.sons[i].kind != nkSym: internalError(a.n.info, "recordRel") else: var x = f.n.sons[i].sym var y = a.n.sons[i].sym + if f.kind == tyObject and typeRel(c, x.typ, y.typ) < isSubtype: + return isNone if x.name.id != y.name.id: return isNone proc allowsNil(f: PType): TTypeRelation {.inline.} = @@ -354,9 +372,9 @@ proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation = return isNone elif f.flags * {tfIterator} != a.flags * {tfIterator}: return isNone - elif f.callconv != a.callconv: + elif f.callConv != a.callConv: # valid to pass a 'nimcall' thingie to 'closure': - if f.callconv == ccClosure and a.callconv == ccDefault: + if f.callConv == ccClosure and a.callConv == ccDefault: result = isConvertible else: return isNone @@ -365,10 +383,6 @@ proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation = of tyNil: result = f.allowsNil else: nil -proc matchTypeClass(c: var TCandidate, f, a: PType): TTypeRelation = - result = if matchTypeClass(c.bindings, f, a): isGeneric - else: isNone - proc typeRangeRel(f, a: PType): TTypeRelation {.noinline.} = let a0 = firstOrd(a) @@ -385,7 +399,7 @@ proc typeRangeRel(f, a: PType): TTypeRelation {.noinline.} = else: result = isNone -proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation = +proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = # typeRel can be used to establish various relationships between types: # # 1) When used with concrete types, it will check for type equivalence @@ -401,22 +415,31 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation = # order to give preferrence to the most specific one: # # seq[seq[any]] is a strict subset of seq[any] and hence more specific. - + result = isNone assert(f != nil) - assert(a != nil) + assert(aOrig != nil) + + # var and static arguments match regular modifier-free types + let a = aOrig.skipTypes({tyStatic, tyVar}) + if a.kind == tyGenericInst and skipTypes(f, {tyVar}).kind notin { tyGenericBody, tyGenericInvokation, - tyGenericParam, tyTypeClass}: + tyGenericInst, tyGenericParam} + tyTypeClasses: return typeRel(c, f, lastSon(a)) - if a.kind == tyVar and f.kind != tyVar: - return typeRel(c, f, a.sons[0]) - + template bindingRet(res) = - when res == isGeneric: put(c.bindings, f, a) + when res == isGeneric: + let bound = aOrig.skipTypes({tyRange}).skipIntLit + put(c.bindings, f, bound) return res - + + template considerPreviousT(body: stmt) {.immediate.} = + var prev = PType(idTableGet(c.bindings, f)) + if prev == nil: body + else: return typeRel(c, prev, a) + case a.kind of tyOr: # seq[int|string] vs seq[number] @@ -457,10 +480,10 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation = else: nil case f.kind - of tyEnum: + of tyEnum: if a.kind == f.kind and sameEnumTypes(f, a): result = isEqual elif sameEnumTypes(f, skipTypes(a, {tyRange})): result = isSubtype - of tyBool, tyChar: + of tyBool, tyChar: if a.kind == f.kind: result = isEqual elif skipTypes(a, {tyRange}).kind == f.kind: result = isSubtype of tyRange: @@ -488,9 +511,9 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation = of tyFloat32: result = handleFloatRange(f, a) of tyFloat64: result = handleFloatRange(f, a) of tyFloat128: result = handleFloatRange(f, a) - of tyVar: - if a.kind == f.kind: result = typeRel(c, base(f), base(a)) - else: result = typeRel(c, base(f), a) + of tyVar: + if aOrig.kind == tyVar: result = typeRel(c, f.base, aOrig.base) + else: result = typeRel(c, f.base, aOrig) of tyArray, tyArrayConstr: # tyArrayConstr cannot happen really, but # we wanna be safe here @@ -509,7 +532,7 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation = elif lengthOrd(fRange) != lengthOrd(a): result = isNone else: nil of tyOpenArray, tyVarargs: - case a.Kind + case a.kind of tyOpenArray, tyVarargs: result = typeRel(c, base(f), base(a)) if result < isGeneric: result = isNone @@ -530,7 +553,7 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation = result = isConvertible else: nil of tySequence: - case a.Kind + case a.kind of tySequence: if (f.sons[0].kind != tyGenericParam) and (a.sons[0].kind == tyEmpty): result = isSubtype @@ -544,7 +567,6 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation = of tyOrdinal: if isOrdinalType(a): var x = if a.kind == tyOrdinal: a.sons[0] else: a - if f.sonsLen == 0: result = isGeneric else: @@ -552,14 +574,16 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation = if result < isGeneric: result = isNone elif a.kind == tyGenericParam: result = isGeneric - of tyForward: InternalError("forward type in typeRel()") + of tyForward: internalError("forward type in typeRel()") of tyNil: if a.kind == f.kind: result = isEqual of tyTuple: - if a.kind == tyTuple: result = tupleRel(c, f, a) + if a.kind == tyTuple: result = recordRel(c, f, a) of tyObject: if a.kind == tyObject: - if sameObjectTypes(f, a): result = isEqual + if sameObjectTypes(f, a): + result = isEqual + # elif tfHasMeta in f.flags: result = recordRel(c, f, a) else: var depth = isObjectSubtype(a, f) if depth > 0: @@ -620,7 +644,7 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation = else: nil of tyCString: # conversion from string to cstring is automatic: - case a.Kind + case a.kind of tyCString: if tfNotNil in f.flags and tfNotNil notin a.flags: result = isNilConversion @@ -641,11 +665,26 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation = if a.kind == tyEmpty: result = isEqual of tyGenericInst: - result = typeRel(c, lastSon(f), a) + let roota = a.skipGenericAlias + let rootf = f.skipGenericAlias + if a.kind == tyGenericInst and roota.base == rootf.base : + for i in 1 .. rootf.sonsLen-2: + let ff = rootf.sons[i] + let aa = roota.sons[i] + result = typeRel(c, ff, aa) + if result == isNone: return + if ff.kind == tyRange and result != isEqual: return isNone + + result = isGeneric + else: + result = typeRel(c, lastSon(f), a) of tyGenericBody: - let ff = lastSon(f) - if ff != nil: result = typeRel(c, ff, a) + considerPreviousT: + if a.kind == tyGenericInst and a.sons[0] == f: + bindingRet isGeneric + let ff = lastSon(f) + if ff != nil: result = typeRel(c, ff, a) of tyGenericInvokation: var x = a.skipGenericAlias @@ -658,7 +697,7 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation = (sonsLen(x) - 1 == sonsLen(f)): for i in countup(1, sonsLen(f) - 1): if x.sons[i].kind == tyGenericParam: - InternalError("wrong instantiated type!") + internalError("wrong instantiated type!") elif typeRel(c, f.sons[i], x.sons[i]) <= isSubtype: return result = isGeneric else: @@ -668,40 +707,58 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation = for i in countup(1, sonsLen(f) - 1): var x = PType(idTableGet(c.bindings, f.sons[0].sons[i - 1])) if x == nil or x.kind in {tyGenericInvokation, tyGenericParam}: - InternalError("wrong instantiated type!") + internalError("wrong instantiated type!") put(c.bindings, f.sons[i], x) of tyAnd: - for branch in f.sons: - if typeRel(c, branch, a) == isNone: - return isNone + considerPreviousT: + for branch in f.sons: + if typeRel(c, branch, aOrig) == isNone: + return isNone - bindingRet isGeneric + bindingRet isGeneric of tyOr: - for branch in f.sons: - if typeRel(c, branch, a) != isNone: - bindingRet isGeneric - - return isNone + considerPreviousT: + for branch in f.sons: + if typeRel(c, branch, aOrig) != isNone: + bindingRet isGeneric + + return isNone of tyNot: - for branch in f.sons: - if typeRel(c, branch, a) != isNone: - return isNone - - bindingRet isGeneric + considerPreviousT: + for branch in f.sons: + if typeRel(c, branch, aOrig) != isNone: + return isNone + + bindingRet isGeneric of tyAnything: - var prev = PType(idTableGet(c.bindings, f)) - if prev == nil: + considerPreviousT: var concrete = concreteType(c, a) if concrete != nil and doBind: put(c.bindings, f, concrete) return isGeneric - else: - return typeRel(c, prev, a) - + + of tyBuiltInTypeClass: + considerPreviousT: + let targetKind = f.sons[0].kind + if targetKind == a.skipTypes({tyRange, tyGenericInst}).kind or + (targetKind in {tyProc, tyPointer} and a.kind == tyNil): + put(c.bindings, f, a) + return isGeneric + else: + return isNone + + of tyCompositeTypeClass: + considerPreviousT: + if typeRel(c, f.sons[1], a) != isNone: + put(c.bindings, f, a) + return isGeneric + else: + return isNone + of tyGenericParam, tyTypeClass: var x = PType(idTableGet(c.bindings, f)) if x == nil: @@ -716,17 +773,17 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation = if f.sons == nil or f.sons.len == 0: result = isGeneric else: - InternalAssert a.sons != nil and a.sons.len > 0 + internalAssert a.sons != nil and a.sons.len > 0 c.typedescMatched = true result = typeRel(c, f.sons[0], a.sons[0]) else: result = isNone else: - if a.kind == tyTypeClass: - result = isGeneric + if f.sonsLen > 0: + result = typeRel(c, f.lastSon, a) else: - result = matchTypeClass(c, f, a) - + result = isGeneric + if result == isGeneric: var concrete = concreteType(c, a) if concrete == nil: @@ -739,6 +796,14 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation = result = isGeneric else: result = typeRel(c, x, a) # check if it fits + + of tyStatic: + if aOrig.kind == tyStatic: + result = typeRel(c, f.lastSon, a) + if result != isNone: put(c.bindings, f, aOrig) + else: + result = isNone + of tyTypeDesc: var prev = PType(idTableGet(c.bindings, f)) if prev == nil: @@ -746,26 +811,29 @@ proc typeRel(c: var TCandidate, f, a: PType, doBind = true): TTypeRelation = if f.sonsLen == 0: result = isGeneric else: - result = matchTypeClass(c, f, a.sons[0]) - if result == isGeneric: + result = typeRel(c, f.sons[0], a.sons[0]) + if result != isNone: put(c.bindings, f, a) else: result = isNone else: - InternalAssert prev.sonsLen == 1 + internalAssert prev.sonsLen == 1 let toMatch = if tfUnresolved in f.flags: a else: a.sons[0] result = typeRel(c, prev.sons[0], toMatch) + of tyExpr, tyStmt: result = isGeneric + of tyProxy: result = isEqual + else: internalError("typeRel: " & $f.kind) -proc cmpTypes*(f, a: PType): TTypeRelation = - var c: TCandidate - InitCandidate(c, f) - result = typeRel(c, f, a) +proc cmpTypes*(c: PContext, f, a: PType): TTypeRelation = + var m: TCandidate + initCandidate(c, m, f) + result = typeRel(m, f, a) proc getInstantiatedType(c: PContext, arg: PNode, m: TCandidate, f: PType): PType = @@ -773,7 +841,7 @@ proc getInstantiatedType(c: PContext, arg: PNode, m: TCandidate, if result == nil: result = generateTypeInstance(c, m.bindings, arg, f) if result == nil: - InternalError(arg.info, "getInstantiatedType") + internalError(arg.info, "getInstantiatedType") result = errorType(c) proc implicitConv(kind: TNodeKind, f: PType, arg: PNode, m: TCandidate, @@ -786,7 +854,7 @@ proc implicitConv(kind: TNodeKind, f: PType, arg: PNode, m: TCandidate, result.typ = errorType(c) else: result.typ = f - if result.typ == nil: InternalError(arg.info, "implicitConv") + if result.typ == nil: internalError(arg.info, "implicitConv") addSon(result, ast.emptyNode) addSon(result, arg) @@ -825,7 +893,7 @@ proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType, var call = newNodeI(nkCall, arg.info) call.add(f.n.copyTree) call.add(arg.copyTree) - result = c.semOverloadedCall(c, call, call, RoutineKinds) + result = c.semOverloadedCall(c, call, call, routineKinds) if result != nil: # resulting type must be consistent with the other arguments: var r = typeRel(m, f.sons[0], result.typ) @@ -849,10 +917,10 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate, # pushInfoContext(arg.info) openScope(c) - inc c.InTypeClass + inc c.inTypeClass finally: - dec c.InTypeClass + dec c.inTypeClass closeScope(c) for param in f.n[0]: @@ -867,7 +935,7 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate, dummyName = param dummyType = a - InternalAssert dummyName.kind == nkIdent + internalAssert dummyName.kind == nkIdent var dummyParam = newSym(skType, dummyName.ident, f.sym, f.sym.info) dummyParam.typ = dummyType addDecl(c, dummyParam) @@ -887,47 +955,34 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate, result = arg put(m.bindings, f, a) -proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, argType: PType, +proc paramTypesMatchAux(m: var TCandidate, f, argType: PType, argSemantized, argOrig: PNode): PNode = var - r: TTypeRelation + fMaybeStatic = f.skipTypes({tyDistinct}) arg = argSemantized - - let + argType = argType + c = m.c + + if tfHasStatic in fMaybeStatic.flags: + # XXX: When implicit statics are the default + # this will be done earlier - we just have to + # make sure that static types enter here + var evaluated = c.semTryConstExpr(c, arg) + if evaluated != nil: + arg.typ = newTypeS(tyStatic, c) + arg.typ.sons = @[evaluated.typ] + arg.typ.n = evaluated + argType = arg.typ + + var + r: TTypeRelation a = if c.InTypeClass > 0: argType.skipTypes({tyTypeDesc}) else: argType - fMaybeExpr = f.skipTypes({tyDistinct}) - - case fMaybeExpr.kind - of tyExpr: - if fMaybeExpr.sonsLen == 0: - r = isGeneric - else: - if a.kind == tyExpr: - InternalAssert a.len > 0 - r = typeRel(m, f.lastSon, a.lastSon) - else: - let match = matchTypeClass(m.bindings, fMaybeExpr, a) - if not match: r = isNone - else: - # XXX: Ideally, this should happen much earlier somewhere near - # semOpAux, but to do that, we need to be able to query the - # overload set to determine whether compile-time value is expected - # for the param before entering the full-blown sigmatch algorithm. - # This is related to the immediate pragma since querying the - # overload set could help there too. - var evaluated = c.semConstExpr(c, arg) - if evaluated != nil: - r = isGeneric - arg.typ = newTypeS(tyExpr, c) - arg.typ.sons = @[evaluated.typ] - arg.typ.n = evaluated - - if r == isGeneric: - put(m.bindings, f, arg.typ) + + case fMaybeStatic.kind of tyTypeClass, tyParametricTypeClass: - if fMaybeExpr.n != nil: - let match = matchUserTypeClass(c, m, arg, fMaybeExpr, a) + if fMaybeStatic.n != nil: + let match = matchUserTypeClass(c, m, arg, fMaybeStatic, a) if match != nil: r = isGeneric arg = match @@ -935,11 +990,14 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, argType: PType, r = isNone else: r = typeRel(m, f, a) + of tyExpr: + r = isGeneric + put(m.bindings, f, arg.typ) else: r = typeRel(m, f, a) case r - of isConvertible: + of isConvertible: inc(m.convMatches) result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c) of isIntConv: @@ -961,6 +1019,8 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, argType: PType, result = argOrig[bodyPos] elif f.kind == tyTypeDesc: result = arg + elif f.kind == tyStatic: + result = arg.typ.n else: result = argOrig else: @@ -1003,19 +1063,20 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, argType: PType, else: result = userConvMatch(c, m, base(f), a, arg) -proc ParamTypesMatch*(c: PContext, m: var TCandidate, f, a: PType, +proc paramTypesMatch*(m: var TCandidate, f, a: PType, arg, argOrig: PNode): PNode = if arg == nil or arg.kind notin nkSymChoices: - result = ParamTypesMatchAux(c, m, f, a, arg, argOrig) + result = paramTypesMatchAux(m, f, a, arg, argOrig) else: # CAUTION: The order depends on the used hashing scheme. Thus it is # incorrect to simply use the first fitting match. However, to implement # this correctly is inefficient. We have to copy `m` here to be able to # roll back the side effects of the unification algorithm. + let c = m.c var x, y, z: TCandidate - initCandidate(x, m.callee) - initCandidate(y, m.callee) - initCandidate(z, m.callee) + initCandidate(c, x, m.callee) + initCandidate(c, y, m.callee) + initCandidate(c, z, m.callee) x.calleeSym = m.calleeSym y.calleeSym = m.calleeSym z.calleeSym = m.calleeSym @@ -1041,17 +1102,17 @@ proc ParamTypesMatch*(c: PContext, m: var TCandidate, f, a: PType, result = nil elif (y.state == csMatch) and (cmpCandidates(x, y) == 0): if x.state != csMatch: - InternalError(arg.info, "x.state is not csMatch") + internalError(arg.info, "x.state is not csMatch") # ambiguous: more than one symbol fits result = nil else: # only one valid interpretation found: markUsed(arg, arg.sons[best].sym) - result = ParamTypesMatchAux(c, m, f, arg.sons[best].typ, arg.sons[best], + result = paramTypesMatchAux(m, f, arg.sons[best].typ, arg.sons[best], argOrig) proc setSon(father: PNode, at: int, son: PNode) = - if sonsLen(father) <= at: setlen(father.sons, at + 1) + if sonsLen(father) <= at: setLen(father.sons, at + 1) father.sons[at] = son # we are allowed to modify the calling node in the 'prepare*' procs: @@ -1122,7 +1183,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, # check if m.callee has such a param: prepareNamedParam(n.sons[a]) if n.sons[a].sons[0].kind != nkIdent: - LocalError(n.sons[a].info, errNamedParamHasToBeIdent) + localError(n.sons[a].info, errNamedParamHasToBeIdent) m.state = csNoMatch return formal = getSymFromList(m.callee.n, n.sons[a].sons[0].ident, 1) @@ -1130,15 +1191,15 @@ proc matchesAux(c: PContext, n, nOrig: PNode, # no error message! m.state = csNoMatch return - if ContainsOrIncl(marker, formal.position): + if containsOrIncl(marker, formal.position): # already in namedParams: - LocalError(n.sons[a].info, errCannotBindXTwice, formal.name.s) + localError(n.sons[a].info, errCannotBindXTwice, formal.name.s) m.state = csNoMatch return m.baseTypeMatch = false n.sons[a].sons[1] = prepareOperand(c, formal.typ, n.sons[a].sons[1]) n.sons[a].typ = n.sons[a].sons[1].typ - var arg = ParamTypesMatch(c, m, formal.typ, n.sons[a].typ, + var arg = paramTypesMatch(m, formal.typ, n.sons[a].typ, n.sons[a].sons[1], nOrig.sons[a].sons[1]) if arg == nil: m.state = csNoMatch @@ -1156,7 +1217,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, # unnamed param if f >= formalLen: # too many arguments? - if tfVarArgs in m.callee.flags: + if tfVarargs in m.callee.flags: # is ok... but don't increment any counters... # we have no formal here to snoop at: n.sons[a] = prepareOperand(c, n.sons[a]) @@ -1168,7 +1229,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, elif formal != nil: m.baseTypeMatch = false n.sons[a] = prepareOperand(c, formal.typ, n.sons[a]) - var arg = ParamTypesMatch(c, m, formal.typ, n.sons[a].typ, + var arg = paramTypesMatch(m, formal.typ, n.sons[a].typ, n.sons[a], nOrig.sons[a]) if (arg != nil) and m.baseTypeMatch and (container != nil): addSon(container, arg) @@ -1181,17 +1242,17 @@ proc matchesAux(c: PContext, n, nOrig: PNode, return else: if m.callee.n.sons[f].kind != nkSym: - InternalError(n.sons[a].info, "matches") + internalError(n.sons[a].info, "matches") return formal = m.callee.n.sons[f].sym - if ContainsOrIncl(marker, formal.position): + if containsOrIncl(marker, formal.position): # already in namedParams: - LocalError(n.sons[a].info, errCannotBindXTwice, formal.name.s) + localError(n.sons[a].info, errCannotBindXTwice, formal.name.s) m.state = csNoMatch return m.baseTypeMatch = false n.sons[a] = prepareOperand(c, formal.typ, n.sons[a]) - var arg = ParamTypesMatch(c, m, formal.typ, n.sons[a].typ, + var arg = paramTypesMatch(m, formal.typ, n.sons[a].typ, n.sons[a], nOrig.sons[a]) if arg == nil: m.state = csNoMatch @@ -1228,7 +1289,7 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) = var f = 1 while f < sonsLen(m.callee.n): var formal = m.callee.n.sons[f].sym - if not ContainsOrIncl(marker, formal.position): + if not containsOrIncl(marker, formal.position): if formal.ast == nil: if formal.typ.kind == tyVarargs: var container = newNodeIT(nkBracket, n.info, arrayConstr(c, n.info)) @@ -1245,8 +1306,8 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) = proc argtypeMatches*(c: PContext, f, a: PType): bool = var m: TCandidate - initCandidate(m, f) - let res = paramTypesMatch(c, m, f, a, ast.emptyNode, nil) + initCandidate(c, m, f) + let res = paramTypesMatch(m, f, a, ast.emptyNode, nil) #instantiateGenericConverters(c, res, m) # XXX this is used by patterns.nim too; I think it's better to not # instantiate generic converters for that @@ -1308,7 +1369,7 @@ tests: setup: var c: TCandidate - InitCandidate(c, nil) + InitCandidate(nil, c, nil) template yes(x, y) = test astToStr(x) & " is " & astToStr(y): diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 76a6c21d9..1fde831b7 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -11,7 +11,7 @@ # included from sigmatch.nim -import algorithm, sequtils +import algorithm, sequtils, pretty const sep = '\t' @@ -28,7 +28,7 @@ proc origModuleName(m: PSym): string = else: m.name.s -proc SymToStr(s: PSym, isLocal: bool, section: string, li: TLineInfo): string = +proc symToStr(s: PSym, isLocal: bool, section: string, li: TLineInfo): string = result = section result.add(sep) result.add($s.kind) @@ -48,15 +48,15 @@ proc SymToStr(s: PSym, isLocal: bool, section: string, li: TLineInfo): string = result.add(sep) result.add(toFullPath(li)) result.add(sep) - result.add($ToLinenumber(li)) + result.add($toLinenumber(li)) result.add(sep) - result.add($ToColumn(li)) + result.add($toColumn(li)) result.add(sep) when not defined(noDocgen): result.add(s.extractDocComment.escape) -proc SymToStr(s: PSym, isLocal: bool, section: string): string = - result = SymToStr(s, isLocal, section, s.info) +proc symToStr(s: PSym, isLocal: bool, section: string): string = + result = symToStr(s, isLocal, section, s.info) proc filterSym(s: PSym): bool {.inline.} = result = s.name.s[0] in lexer.SymChars and s.kind != skModule @@ -68,7 +68,7 @@ proc fieldVisible*(c: PContext, f: PSym): bool {.inline.} = proc suggestField(c: PContext, s: PSym, outputs: var int) = if filterSym(s) and fieldVisible(c, s): - SuggestWriteln(SymToStr(s, isLocal=true, sectionSuggest)) + suggestWriteln(symToStr(s, isLocal=true, sectionSuggest)) inc outputs when not defined(nimhygiene): @@ -84,7 +84,7 @@ template wholeSymTab(cond, section: expr) {.immediate.} = for item in entries: let it {.inject.} = item if cond: - SuggestWriteln(SymToStr(it, isLocal = isLocal, section)) + suggestWriteln(symToStr(it, isLocal = isLocal, section)) inc outputs proc suggestSymList(c: PContext, list: PNode, outputs: var int) = @@ -119,7 +119,7 @@ proc argsFit(c: PContext, candidate: PSym, n, nOrig: PNode): bool = case candidate.kind of OverloadableSyms: var m: TCandidate - initCandidate(m, candidate, nil) + initCandidate(c, m, candidate, nil) sigmatch.partialMatch(c, n, nOrig, m) result = m.state != csNoMatch else: @@ -144,14 +144,14 @@ proc suggestEverything(c: PContext, n: PNode, outputs: var int) = if scope == c.topLevelScope: isLocal = false for it in items(scope.symbols): if filterSym(it): - SuggestWriteln(SymToStr(it, isLocal = isLocal, sectionSuggest)) + suggestWriteln(symToStr(it, isLocal = isLocal, sectionSuggest)) inc outputs if scope == c.topLevelScope: break proc suggestFieldAccess(c: PContext, n: PNode, outputs: var int) = # special code that deals with ``myObj.``. `n` is NOT the nkDotExpr-node, but # ``myObj``. - var typ = n.Typ + var typ = n.typ if typ == nil: # a module symbol has no type for example: if n.kind == nkSym and n.sym.kind == skModule: @@ -159,12 +159,12 @@ proc suggestFieldAccess(c: PContext, n: PNode, outputs: var int) = # all symbols accessible, because we are in the current module: for it in items(c.topLevelScope.symbols): if filterSym(it): - SuggestWriteln(SymToStr(it, isLocal=false, sectionSuggest)) + suggestWriteln(symToStr(it, isLocal=false, sectionSuggest)) inc outputs else: for it in items(n.sym.tab): if filterSym(it): - SuggestWriteln(SymToStr(it, isLocal=false, sectionSuggest)) + suggestWriteln(symToStr(it, isLocal=false, sectionSuggest)) inc outputs else: # fallback: @@ -203,7 +203,7 @@ const CallNodes = {nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit} proc findClosestCall(n: PNode): PNode = - if n.kind in callNodes and msgs.inCheckpoint(n.info) == cpExact: + if n.kind in CallNodes and msgs.inCheckpoint(n.info) == cpExact: result = n else: for i in 0.. <safeLen(n): @@ -246,16 +246,16 @@ var proc findUsages(node: PNode, s: PSym) = if usageSym == nil and isTracked(node.info, s.name.s.len): usageSym = s - SuggestWriteln(SymToStr(s, isLocal=false, sectionUsage)) + suggestWriteln(symToStr(s, isLocal=false, sectionUsage)) elif s == usageSym: if lastLineInfo != node.info: - SuggestWriteln(SymToStr(s, isLocal=false, sectionUsage, node.info)) + suggestWriteln(symToStr(s, isLocal=false, sectionUsage, node.info)) lastLineInfo = node.info proc findDefinition(node: PNode, s: PSym) = if isTracked(node.info, s.name.s.len): - SuggestWriteln(SymToStr(s, isLocal=false, sectionDef)) - SuggestQuit() + suggestWriteln(symToStr(s, isLocal=false, sectionDef)) + suggestQuit() type TSourceMap = object @@ -281,7 +281,7 @@ proc resetSourceMap*(fileIdx: int32) = ensureIdx(gSourceMaps, fileIdx) gSourceMaps[fileIdx].lines = @[] -proc addToSourceMap(sym: Psym, info: TLineInfo) = +proc addToSourceMap(sym: PSym, info: TLineInfo) = ensureIdx(gSourceMaps, info.fileIndex) ensureSeq(gSourceMaps[info.fileIndex].lines) ensureIdx(gSourceMaps[info.fileIndex].lines, info.line) @@ -302,7 +302,7 @@ proc defFromLine(entries: var seq[TEntry], col: int32) = # that the first expr that ends after the cursor column is # the one we are looking for. if e.pos >= col: - SuggestWriteln(SymToStr(e.sym, isLocal=false, sectionDef)) + suggestWriteln(symToStr(e.sym, isLocal=false, sectionDef)) return proc defFromSourceMap*(i: TLineInfo) = @@ -324,9 +324,10 @@ proc suggestSym*(n: PNode, s: PSym) {.inline.} = proc markUsed(n: PNode, s: PSym) = incl(s.flags, sfUsed) if {sfDeprecated, sfError} * s.flags != {}: - if sfDeprecated in s.flags: Message(n.info, warnDeprecated, s.name.s) - if sfError in s.flags: LocalError(n.info, errWrongSymbolX, s.name.s) + if sfDeprecated in s.flags: message(n.info, warnDeprecated, s.name.s) + if sfError in s.flags: localError(n.info, errWrongSymbolX, s.name.s) suggestSym(n, s) + if gCmd == cmdPretty: checkUse(n, s) proc useSym*(sym: PSym): PNode = result = newSymNode(sym) @@ -337,8 +338,8 @@ proc suggestExpr*(c: PContext, node: PNode) = if cp == cpNone: return var outputs = 0 # This keeps semExpr() from coming here recursively: - if c.InCompilesContext > 0: return - inc(c.InCompilesContext) + if c.inCompilesContext > 0: return + inc(c.inCompilesContext) if optSuggest in gGlobalOptions: var n = findClosestDot(node) @@ -368,8 +369,8 @@ proc suggestExpr*(c: PContext, node: PNode) = addSon(a, x) suggestCall(c, a, n, outputs) - dec(c.InCompilesContext) - if outputs > 0 and optUsages notin gGlobalOptions: SuggestQuit() + dec(c.inCompilesContext) + if outputs > 0 and optUsages notin gGlobalOptions: suggestQuit() proc suggestStmt*(c: PContext, n: PNode) = suggestExpr(c, n) diff --git a/compiler/syntaxes.nim b/compiler/syntaxes.nim index 3965cb3fe..7c44ec0b4 100644 --- a/compiler/syntaxes.nim +++ b/compiler/syntaxes.nim @@ -40,17 +40,17 @@ proc parseTopLevelStmt*(p: var TParsers): PNode # implementation -proc ParseFile(fileIdx: int32): PNode = +proc parseFile(fileIdx: int32): PNode = var p: TParsers - f: tfile + f: TFile let filename = fileIdx.toFullPath if not open(f, filename): rawMessage(errCannotOpenFile, filename) return - OpenParsers(p, fileIdx, LLStreamOpen(f)) - result = ParseAll(p) - CloseParsers(p) + openParsers(p, fileIdx, llStreamOpen(f)) + result = parseAll(p) + closeParsers(p) proc parseAll(p: var TParsers): PNode = case p.skin @@ -59,7 +59,7 @@ proc parseAll(p: var TParsers): PNode = of skinBraces: result = pbraces.parseAll(p.parser) of skinEndX: - InternalError("parser to implement") + internalError("parser to implement") result = ast.emptyNode # skinEndX: result := pendx.parseAll(p.parser); @@ -70,11 +70,11 @@ proc parseTopLevelStmt(p: var TParsers): PNode = of skinBraces: result = pbraces.parseTopLevelStmt(p.parser) of skinEndX: - InternalError("parser to implement") + internalError("parser to implement") result = ast.emptyNode #skinEndX: result := pendx.parseTopLevelStmt(p.parser); -proc UTF8_BOM(s: string): int = +proc utf8Bom(s: string): int = if (s[0] == '\xEF') and (s[1] == '\xBB') and (s[2] == '\xBF'): result = 3 else: @@ -83,37 +83,37 @@ proc UTF8_BOM(s: string): int = proc containsShebang(s: string, i: int): bool = if (s[i] == '#') and (s[i + 1] == '!'): var j = i + 2 - while s[j] in WhiteSpace: inc(j) + while s[j] in Whitespace: inc(j) result = s[j] == '/' proc parsePipe(filename: string, inputStream: PLLStream): PNode = result = ast.emptyNode - var s = LLStreamOpen(filename, fmRead) + var s = llStreamOpen(filename, fmRead) if s != nil: var line = newStringOfCap(80) - discard LLStreamReadLine(s, line) - var i = UTF8_Bom(line) + discard llStreamReadLine(s, line) + var i = utf8Bom(line) if containsShebang(line, i): - discard LLStreamReadLine(s, line) + discard llStreamReadLine(s, line) i = 0 if line[i] == '#' and line[i+1] == '!': inc(i, 2) - while line[i] in WhiteSpace: inc(i) + while line[i] in Whitespace: inc(i) var q: TParser - OpenParser(q, filename, LLStreamOpen(substr(line, i))) + openParser(q, filename, llStreamOpen(substr(line, i))) result = parser.parseAll(q) - CloseParser(q) - LLStreamClose(s) + closeParser(q) + llStreamClose(s) proc getFilter(ident: PIdent): TFilterKind = for i in countup(low(TFilterKind), high(TFilterKind)): - if IdentEq(ident, filterNames[i]): + if identEq(ident, filterNames[i]): return i result = filtNone proc getParser(ident: PIdent): TParserKind = for i in countup(low(TParserKind), high(TParserKind)): - if IdentEq(ident, parserNames[i]): + if identEq(ident, parserNames[i]): return i rawMessage(errInvalidDirectiveX, ident.s) @@ -142,32 +142,32 @@ proc applyFilter(p: var TParsers, n: PNode, filename: string, if f != filtNone: if gVerbosity >= 2: rawMessage(hintCodeBegin, []) - MsgWriteln(result.s) + msgWriteln(result.s) rawMessage(hintCodeEnd, []) proc evalPipe(p: var TParsers, n: PNode, filename: string, start: PLLStream): PLLStream = result = start if n.kind == nkEmpty: return - if (n.kind == nkInfix) and (n.sons[0].kind == nkIdent) and - IdentEq(n.sons[0].ident, "|"): - for i in countup(1, 2): - if n.sons[i].kind == nkInfix: + if n.kind == nkInfix and n.sons[0].kind == nkIdent and + identEq(n.sons[0].ident, "|"): + for i in countup(1, 2): + if n.sons[i].kind == nkInfix: result = evalPipe(p, n.sons[i], filename, result) - else: + else: result = applyFilter(p, n.sons[i], filename, result) - elif n.kind == nkStmtList: + elif n.kind == nkStmtList: result = evalPipe(p, n.sons[0], filename, result) - else: + else: result = applyFilter(p, n, filename, result) proc openParsers(p: var TParsers, fileIdx: int32, inputstream: PLLStream) = var s: PLLStream p.skin = skinStandard let filename = fileIdx.toFullPath - var pipe = parsePipe(filename, inputStream) - if pipe != nil: s = evalPipe(p, pipe, filename, inputStream) - else: s = inputStream + var pipe = parsePipe(filename, inputstream) + if pipe != nil: s = evalPipe(p, pipe, filename, inputstream) + else: s = inputstream case p.skin of skinStandard, skinBraces, skinEndX: parser.openParser(p.parser, fileIdx, s) diff --git a/compiler/transf.nim b/compiler/transf.nim index 206c21c3d..2332d0b48 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -88,7 +88,7 @@ proc pushTransCon(c: PTransf, t: PTransCon) = c.transCon = t proc popTransCon(c: PTransf) = - if (c.transCon == nil): InternalError("popTransCon") + if (c.transCon == nil): internalError("popTransCon") c.transCon = c.transCon.next proc getCurrOwner(c: PTransf): PSym = @@ -126,7 +126,7 @@ proc transformSymAux(c: PTransf, n: PNode): PNode = else: b = n while tc != nil: - result = IdNodeTableGet(tc.mapping, b.sym) + result = idNodeTableGet(tc.mapping, b.sym) if result != nil: return tc = tc.next result = b @@ -141,32 +141,32 @@ proc transformVarSection(c: PTransf, v: PNode): PTransNode = if it.kind == nkCommentStmt: result[i] = PTransNode(it) elif it.kind == nkIdentDefs: - if it.sons[0].kind != nkSym: InternalError(it.info, "transformVarSection") - InternalAssert(it.len == 3) + if it.sons[0].kind != nkSym: internalError(it.info, "transformVarSection") + internalAssert(it.len == 3) var newVar = copySym(it.sons[0].sym) incl(newVar.flags, sfFromGeneric) # fixes a strange bug for rodgen: #include(it.sons[0].sym.flags, sfFromGeneric); newVar.owner = getCurrOwner(c) - IdNodeTablePut(c.transCon.mapping, it.sons[0].sym, newSymNode(newVar)) + idNodeTablePut(c.transCon.mapping, it.sons[0].sym, newSymNode(newVar)) var defs = newTransNode(nkIdentDefs, it.info, 3) if importantComments(): # keep documentation information: - pnode(defs).comment = it.comment + PNode(defs).comment = it.comment defs[0] = newSymNode(newVar).PTransNode defs[1] = it.sons[1].PTransNode defs[2] = transform(c, it.sons[2]) result[i] = defs else: if it.kind != nkVarTuple: - InternalError(it.info, "transformVarSection: not nkVarTuple") + internalError(it.info, "transformVarSection: not nkVarTuple") var L = sonsLen(it) var defs = newTransNode(it.kind, it.info, L) for j in countup(0, L-3): var newVar = copySym(it.sons[j].sym) incl(newVar.flags, sfFromGeneric) newVar.owner = getCurrOwner(c) - IdNodeTablePut(c.transCon.mapping, it.sons[j].sym, newSymNode(newVar)) + idNodeTablePut(c.transCon.mapping, it.sons[j].sym, newSymNode(newVar)) defs[j] = newSymNode(newVar).PTransNode assert(it.sons[L-2].kind == nkEmpty) defs[L-1] = transform(c, it.sons[L-1]) @@ -179,14 +179,14 @@ proc transformConstSection(c: PTransf, v: PNode): PTransNode = if it.kind == nkCommentStmt: result[i] = PTransNode(it) else: - if it.kind != nkConstDef: InternalError(it.info, "transformConstSection") + if it.kind != nkConstDef: internalError(it.info, "transformConstSection") if it.sons[0].kind != nkSym: - InternalError(it.info, "transformConstSection") + internalError(it.info, "transformConstSection") if sfFakeConst in it[0].sym.flags: var b = newNodeI(nkConstDef, it.info) addSon(b, it[0]) addSon(b, ast.emptyNode) # no type description - addSon(b, transform(c, it[2]).pnode) + addSon(b, transform(c, it[2]).PNode) result[i] = PTransNode(b) else: result[i] = PTransNode(it) @@ -217,7 +217,7 @@ proc transformBlock(c: PTransf, n: PNode): PTransNode = proc transformBreak(c: PTransf, n: PNode): PTransNode = if c.inLoop > 0 or n.sons[0].kind != nkEmpty: - result = n.ptransNode + result = n.PTransNode else: let labl = c.breakSyms[c.breakSyms.high] result = transformSons(c, n) @@ -292,11 +292,11 @@ proc transformYield(c: PTransf, n: PNode): PTransNode = add(result, c.transCon.forLoopBody) else: # we need to introduce new local variables: - add(result, introduceNewLocalVars(c, c.transCon.forLoopBody.pnode)) + add(result, introduceNewLocalVars(c, c.transCon.forLoopBody.PNode)) proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode = result = transformSons(c, n) - var n = result.pnode + var n = result.PNode case n.sons[0].kind of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64: var m = n.sons[0].sons[0] @@ -429,15 +429,15 @@ proc findWrongOwners(c: PTransf, n: PNode) = proc transformFor(c: PTransf, n: PNode): PTransNode = # generate access statements for the parameters (unless they are constant) # put mapping from formal parameters to actual parameters - if n.kind != nkForStmt: InternalError(n.info, "transformFor") + if n.kind != nkForStmt: internalError(n.info, "transformFor") var length = sonsLen(n) var call = n.sons[length - 2] if call.kind notin nkCallKinds or call.sons[0].kind != nkSym or call.sons[0].typ.callConv == ccClosure or call.sons[0].sym.kind != skIterator: - n.sons[length-1] = transformLoopBody(c, n.sons[length-1]).pnode - return lambdalifting.liftForLoop(n).ptransNode + n.sons[length-1] = transformLoopBody(c, n.sons[length-1]).PNode + return lambdalifting.liftForLoop(n).PTransNode #InternalError(call.info, "transformFor") #echo "transforming: ", renderTree(n) @@ -446,7 +446,7 @@ proc transformFor(c: PTransf, n: PNode): PTransNode = var v = newNodeI(nkVarSection, n.info) for i in countup(0, length - 3): addVar(v, copyTree(n.sons[i])) # declare new vars - add(result, v.ptransNode) + add(result, v.PTransNode) # Bugfix: inlined locals belong to the invoking routine, not to the invoked # iterator! @@ -454,24 +454,24 @@ proc transformFor(c: PTransf, n: PNode): PTransNode = var newC = newTransCon(getCurrOwner(c)) newC.forStmt = n newC.forLoopBody = loopBody - if iter.kind != skIterator: InternalError(call.info, "transformFor") + if iter.kind != skIterator: internalError(call.info, "transformFor") # generate access statements for the parameters (unless they are constant) pushTransCon(c, newC) for i in countup(1, sonsLen(call) - 1): - var arg = transform(c, call.sons[i]).pnode + var arg = transform(c, call.sons[i]).PNode var formal = skipTypes(iter.typ, abstractInst).n.sons[i].sym case putArgInto(arg, formal.typ) of paDirectMapping: - IdNodeTablePut(newC.mapping, formal, arg) + idNodeTablePut(newC.mapping, formal, arg) of paFastAsgn: # generate a temporary and produce an assignment statement: var temp = newTemp(c, formal.typ, formal.info) addVar(v, newSymNode(temp)) - add(result, newAsgnStmt(c, newSymNode(temp), arg.ptransNode)) - IdNodeTablePut(newC.mapping, formal, newSymNode(temp)) + add(result, newAsgnStmt(c, newSymNode(temp), arg.PTransNode)) + idNodeTablePut(newC.mapping, formal, newSymNode(temp)) of paVarAsgn: assert(skipTypes(formal.typ, abstractInst).kind == tyVar) - IdNodeTablePut(newC.mapping, formal, arg) + idNodeTablePut(newC.mapping, formal, arg) # XXX BUG still not correct if the arg has a side effect! var body = iter.getBody pushInfoContext(n.info) @@ -500,20 +500,20 @@ proc transformCase(c: PTransf, n: PNode): PTransNode = var e = transform(c, it) case it.kind of nkElifBranch: - if ifs.pnode == nil: + if ifs.PNode == nil: ifs = newTransNode(nkIfStmt, it.info, 0) ifs.add(e) of nkElse: - if ifs.pnode == nil: result.add(e) + if ifs.PNode == nil: result.add(e) else: ifs.add(e) else: result.add(e) - if ifs.pnode != nil: + if ifs.PNode != nil: var elseBranch = newTransNode(nkElse, n.info, 1) elseBranch[0] = ifs result.add(elseBranch) - elif result.Pnode.lastSon.kind != nkElse and not ( - skipTypes(n.sons[0].Typ, abstractVarRange).Kind in + elif result.PNode.lastSon.kind != nkElse and not ( + skipTypes(n.sons[0].typ, abstractVarRange).kind in {tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32}): # fix a stupid code gen bug by normalizing: var elseBranch = newTransNode(nkElse, n.info, 1) @@ -523,7 +523,7 @@ proc transformCase(c: PTransf, n: PNode): PTransNode = proc transformArrayAccess(c: PTransf, n: PNode): PTransNode = # XXX this is really bad; transf should use a proper AST visitor if n.sons[0].kind == nkSym and n.sons[0].sym.kind == skType: - result = n.ptransnode + result = n.PTransNode else: result = newTransNode(n) for i in 0 .. < n.len: @@ -533,7 +533,7 @@ proc getMergeOp(n: PNode): PSym = case n.kind of nkCall, nkHiddenCallConv, nkCommand, nkInfix, nkPrefix, nkPostfix, nkCallStrLit: - if (n.sons[0].Kind == nkSym) and (n.sons[0].sym.kind == skProc) and + if (n.sons[0].kind == nkSym) and (n.sons[0].sym.kind == skProc) and (sfMerge in n.sons[0].sym.flags): result = n.sons[0].sym else: nil @@ -563,24 +563,24 @@ proc transformCall(c: PTransf, n: PNode): PTransNode = add(result, transform(c, n.sons[0])) var j = 1 while j < sonsLen(n): - var a = transform(c, n.sons[j]).pnode + var a = transform(c, n.sons[j]).PNode inc(j) if isConstExpr(a): while (j < sonsLen(n)): - let b = transform(c, n.sons[j]).pnode + let b = transform(c, n.sons[j]).PNode if not isConstExpr(b): break a = evalOp(op.magic, n, a, b, nil) inc(j) - add(result, a.ptransnode) + add(result, a.PTransNode) if len(result) == 2: result = result[1] else: - let s = transformSons(c, n).pnode + let s = transformSons(c, n).PNode # bugfix: check after 'transformSons' if it's still a method call: # use the dispatcher for the call: if s.sons[0].kind == nkSym and s.sons[0].sym.kind == skMethod: - result = methodCall(s).ptransNode + result = methodCall(s).PTransNode else: - result = s.ptransNode + result = s.PTransNode proc dontInlineConstant(orig, cnst: PNode): bool {.inline.} = # symbols that expand to a complex constant (array, etc.) should not be @@ -683,7 +683,7 @@ proc transform(c: PTransf, n: PNode): PTransNode = # completely: result = PTransNode(newNode(nkCommentStmt)) of nkCommentStmt, nkTemplateDef: - return n.ptransNode + return n.PTransNode of nkConstSection: # do not replace ``const c = 3`` with ``const 3 = 3`` return transformConstSection(c, n) @@ -707,7 +707,7 @@ proc transform(c: PTransf, n: PNode): PTransNode = result = transformSons(c, n) # XXX comment handling really sucks: if importantComments(): - pnode(result).comment = n.comment + PNode(result).comment = n.comment else: result = transformSons(c, n) var cnst = getConstExpr(c.module, PNode(result)) @@ -719,7 +719,7 @@ proc processTransf(c: PTransf, n: PNode, owner: PSym): PNode = # Note: For interactive mode we cannot call 'passes.skipCodegen' and skip # this step! We have to rely that the semantic pass transforms too errornous # nodes into an empty node. - if passes.skipCodegen(n) or c.fromCache or nfTransf in n.flags: return n + if c.fromCache or nfTransf in n.flags: return n pushTransCon(c, newTransCon(owner)) result = PNode(transform(c, n)) popTransCon(c) @@ -735,12 +735,9 @@ proc transformBody*(module: PSym, n: PNode, prc: PSym): PNode = if nfTransf in n.flags or prc.kind in {skTemplate}: result = n else: - #when useEffectSystem: trackProc(prc, n) var c = openTransf(module, "") result = processTransf(c, n, prc) - if prc.kind != skMacro: - # XXX no closures yet for macros: - result = liftLambdas(prc, result) + result = liftLambdas(prc, result) if prc.kind == skIterator and prc.typ.callConv == ccClosure: result = lambdalifting.liftIterator(prc, result) incl(result.flags, nfTransf) diff --git a/compiler/trees.nim b/compiler/trees.nim index ab5c97a19..35e9334cc 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -36,7 +36,7 @@ proc cyclicTree*(n: PNode): bool = var s = newNodeI(nkEmpty, n.info) result = cyclicTreeAux(n, s) -proc ExprStructuralEquivalent*(a, b: PNode): bool = +proc exprStructuralEquivalent*(a, b: PNode): bool = result = false if a == b: result = true @@ -53,17 +53,17 @@ proc ExprStructuralEquivalent*(a, b: PNode): bool = else: if sonsLen(a) == sonsLen(b): for i in countup(0, sonsLen(a) - 1): - if not ExprStructuralEquivalent(a.sons[i], b.sons[i]): return + if not exprStructuralEquivalent(a.sons[i], b.sons[i]): return result = true -proc sameTree*(a, b: PNode): bool = +proc sameTree*(a, b: PNode): bool = result = false - if a == b: + if a == b: result = true - elif (a != nil) and (b != nil) and (a.kind == b.kind): - if a.flags != b.flags: return - if a.info.line != b.info.line: return - if a.info.col != b.info.col: + elif a != nil and b != nil and a.kind == b.kind: + if a.flags != b.flags: return + if a.info.line != b.info.line: return + if a.info.col != b.info.col: return #if a.info.fileIndex <> b.info.fileIndex then exit; case a.kind of nkSym: @@ -74,7 +74,7 @@ proc sameTree*(a, b: PNode): bool = of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal of nkEmpty, nkNilLit, nkType: result = true - else: + else: if sonsLen(a) == sonsLen(b): for i in countup(0, sonsLen(a) - 1): if not sameTree(a.sons[i], b.sons[i]): return @@ -84,22 +84,22 @@ proc getProcSym*(call: PNode): PSym = result = call.sons[0].sym proc getOpSym*(op: PNode): PSym = - if not (op.kind in {nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit}): + if op.kind notin {nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit}: result = nil - else: - if (sonsLen(op) <= 0): InternalError(op.info, "getOpSym") - elif op.sons[0].Kind == nkSym: result = op.sons[0].sym + else: + if sonsLen(op) <= 0: internalError(op.info, "getOpSym") + elif op.sons[0].kind == nkSym: result = op.sons[0].sym else: result = nil - + proc getMagic*(op: PNode): TMagic = case op.kind of nkCallKinds: - case op.sons[0].Kind + case op.sons[0].kind of nkSym: result = op.sons[0].sym.magic else: result = mNone else: result = mNone -proc TreeToSym*(t: PNode): PSym = +proc treeToSym*(t: PNode): PSym = result = t.sym proc isConstExpr*(n: PNode): bool = @@ -118,7 +118,7 @@ proc isDeepConstExpr*(n: PNode): bool = for i in 0 .. <n.len: if not isDeepConstExpr(n.sons[i]): return false result = true - else: nil + else: discard proc flattenTreeAux(d, a: PNode, op: TMagic) = if (getMagic(a) == op): # a is a "leaf", so add it: @@ -129,17 +129,17 @@ proc flattenTreeAux(d, a: PNode, op: TMagic) = proc flattenTree*(root: PNode, op: TMagic): PNode = result = copyNode(root) - if (getMagic(root) == op): + if getMagic(root) == op: # BUGFIX: forget to copy prc addSon(result, copyNode(root.sons[0])) flattenTreeAux(result, root, op) -proc SwapOperands*(op: PNode) = +proc swapOperands*(op: PNode) = var tmp = op.sons[1] op.sons[1] = op.sons[2] op.sons[2] = tmp -proc IsRange*(n: PNode): bool {.inline.} = +proc isRange*(n: PNode): bool {.inline.} = if n.kind == nkInfix: if n[0].kind == nkIdent and n[0].ident.id == ord(wDotDot) or n[0].kind in {nkClosedSymChoice, nkOpenSymChoice} and diff --git a/compiler/treetab.nim b/compiler/treetab.nim index 75e3fd20a..ecb8fb083 100644 --- a/compiler/treetab.nim +++ b/compiler/treetab.nim @@ -17,7 +17,7 @@ proc hashTree(n: PNode): THash = result = ord(n.kind) case n.kind of nkEmpty, nkNilLit, nkType: - nil + discard of nkIdent: result = result !& n.ident.h of nkSym: @@ -34,7 +34,7 @@ proc hashTree(n: PNode): THash = for i in countup(0, sonsLen(n) - 1): result = result !& hashTree(n.sons[i]) -proc TreesEquivalent(a, b: PNode): bool = +proc treesEquivalent(a, b: PNode): bool = if a == b: result = true elif (a != nil) and (b != nil) and (a.kind == b.kind): @@ -48,24 +48,24 @@ proc TreesEquivalent(a, b: PNode): bool = else: if sonsLen(a) == sonsLen(b): for i in countup(0, sonsLen(a) - 1): - if not TreesEquivalent(a.sons[i], b.sons[i]): return + if not treesEquivalent(a.sons[i], b.sons[i]): return result = true if result: result = sameTypeOrNil(a.typ, b.typ) -proc NodeTableRawGet(t: TNodeTable, k: THash, key: PNode): int = +proc nodeTableRawGet(t: TNodeTable, k: THash, key: PNode): int = var h: THash = k and high(t.data) while t.data[h].key != nil: - if (t.data[h].h == k) and TreesEquivalent(t.data[h].key, key): + if (t.data[h].h == k) and treesEquivalent(t.data[h].key, key): return h h = nextTry(h, high(t.data)) result = -1 -proc NodeTableGet*(t: TNodeTable, key: PNode): int = - var index = NodeTableRawGet(t, hashTree(key), key) +proc nodeTableGet*(t: TNodeTable, key: PNode): int = + var index = nodeTableRawGet(t, hashTree(key), key) if index >= 0: result = t.data[index].val else: result = low(int) -proc NodeTableRawInsert(data: var TNodePairSeq, k: THash, key: PNode, +proc nodeTableRawInsert(data: var TNodePairSeq, k: THash, key: PNode, val: int) = var h: THash = k and high(data) while data[h].key != nil: h = nextTry(h, high(data)) @@ -74,37 +74,37 @@ proc NodeTableRawInsert(data: var TNodePairSeq, k: THash, key: PNode, data[h].key = key data[h].val = val -proc NodeTablePut*(t: var TNodeTable, key: PNode, val: int) = +proc nodeTablePut*(t: var TNodeTable, key: PNode, val: int) = var n: TNodePairSeq var k: THash = hashTree(key) - var index = NodeTableRawGet(t, k, key) + var index = nodeTableRawGet(t, k, key) if index >= 0: assert(t.data[index].key != nil) t.data[index].val = val else: if mustRehash(len(t.data), t.counter): - newSeq(n, len(t.data) * growthFactor) + newSeq(n, len(t.data) * GrowthFactor) for i in countup(0, high(t.data)): if t.data[i].key != nil: - NodeTableRawInsert(n, t.data[i].h, t.data[i].key, t.data[i].val) + nodeTableRawInsert(n, t.data[i].h, t.data[i].key, t.data[i].val) swap(t.data, n) - NodeTableRawInsert(t.data, k, key, val) + nodeTableRawInsert(t.data, k, key, val) inc(t.counter) -proc NodeTableTestOrSet*(t: var TNodeTable, key: PNode, val: int): int = +proc nodeTableTestOrSet*(t: var TNodeTable, key: PNode, val: int): int = var n: TNodePairSeq var k: THash = hashTree(key) - var index = NodeTableRawGet(t, k, key) + var index = nodeTableRawGet(t, k, key) if index >= 0: assert(t.data[index].key != nil) result = t.data[index].val else: if mustRehash(len(t.data), t.counter): - newSeq(n, len(t.data) * growthFactor) + newSeq(n, len(t.data) * GrowthFactor) for i in countup(0, high(t.data)): if t.data[i].key != nil: - NodeTableRawInsert(n, t.data[i].h, t.data[i].key, t.data[i].val) + nodeTableRawInsert(n, t.data[i].h, t.data[i].key, t.data[i].val) swap(t.data, n) - NodeTableRawInsert(t.data, k, key, val) + nodeTableRawInsert(t.data, k, key, val) result = val inc(t.counter) diff --git a/compiler/types.nim b/compiler/types.nim index 7e07a0667..36c9f1934 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -10,16 +10,16 @@ # this module contains routines for accessing and iterating over types import - intsets, ast, astalgo, trees, msgs, strutils, platform + intsets, ast, astalgo, trees, msgs, strutils, platform, renderer -proc firstOrd*(t: PType): biggestInt -proc lastOrd*(t: PType): biggestInt -proc lengthOrd*(t: PType): biggestInt +proc firstOrd*(t: PType): BiggestInt +proc lastOrd*(t: PType): BiggestInt +proc lengthOrd*(t: PType): BiggestInt type TPreferedDesc* = enum preferName, preferDesc, preferExported -proc TypeToString*(typ: PType, prefer: TPreferedDesc = preferName): string +proc typeToString*(typ: PType, prefer: TPreferedDesc = preferName): string proc getProcHeader*(sym: PSym): string proc base*(t: PType): PType # ------------------- type iterator: ---------------------------------------- @@ -28,7 +28,7 @@ type TTypeMutator* = proc (t: PType, closure: PObject): PType {.nimcall.} # copy t and mutate it TTypePredicate* = proc (t: PType): bool {.nimcall.} -proc IterOverType*(t: PType, iter: TTypeIter, closure: PObject): bool +proc iterOverType*(t: PType, iter: TTypeIter, closure: PObject): bool # Returns result of `iter`. proc mutateType*(t: PType, iter: TTypeMutator, closure: PObject): PType # Returns result of `iter`. @@ -64,17 +64,16 @@ const typedescPtrs* = abstractPtrs + {tyTypeDesc} typedescInst* = abstractInst + {tyTypeDesc} -proc skipTypes*(t: PType, kinds: TTypeKinds): PType proc containsObject*(t: PType): bool proc containsGarbageCollectedRef*(typ: PType): bool proc containsHiddenPointer*(typ: PType): bool proc canFormAcycle*(typ: PType): bool proc isCompatibleToCString*(a: PType): bool -proc getOrdValue*(n: PNode): biggestInt -proc computeSize*(typ: PType): biggestInt -proc getSize*(typ: PType): biggestInt +proc getOrdValue*(n: PNode): BiggestInt +proc computeSize*(typ: PType): BiggestInt +proc getSize*(typ: PType): BiggestInt proc isPureObject*(typ: PType): bool -proc InvalidGenericInst*(f: PType): bool +proc invalidGenericInst*(f: PType): bool # for debugging type TTypeFieldResult* = enum @@ -89,21 +88,21 @@ proc analyseObjectWithTypeField*(t: PType): TTypeFieldResult proc typeAllowed*(t: PType, kind: TSymKind): bool # implementation -proc InvalidGenericInst(f: PType): bool = - result = (f.kind == tyGenericInst) and (lastSon(f) == nil) +proc invalidGenericInst(f: PType): bool = + result = f.kind == tyGenericInst and lastSon(f) == nil proc isPureObject(typ: PType): bool = var t = typ while t.kind == tyObject and t.sons[0] != nil: t = t.sons[0] result = t.sym != nil and sfPure in t.sym.flags -proc getOrdValue(n: PNode): biggestInt = +proc getOrdValue(n: PNode): BiggestInt = case n.kind of nkCharLit..nkInt64Lit: result = n.intVal of nkNilLit: result = 0 of nkHiddenStdConv: result = getOrdValue(n.sons[1]) else: - LocalError(n.info, errOrdinalTypeExpected) + localError(n.info, errOrdinalTypeExpected) result = 0 proc isIntLit*(t: PType): bool {.inline.} = @@ -132,7 +131,7 @@ proc getProcHeader(sym: PSym): string = add(result, typeToString(p.sym.typ)) if i != sonsLen(n)-1: add(result, ", ") else: - InternalError("getProcHeader") + internalError("getProcHeader") add(result, ')') if n.sons[0].typ != nil: result.add(": " & typeToString(n.sons[0].typ)) @@ -148,21 +147,17 @@ proc skipGeneric(t: PType): PType = result = t while result.kind == tyGenericInst: result = lastSon(result) -proc skipTypes(t: PType, kinds: TTypeKinds): PType = - result = t - while result.kind in kinds: result = lastSon(result) - proc isOrdinalType(t: PType): bool = assert(t != nil) # caution: uint, uint64 are no ordinal types! - result = t.Kind in {tyChar,tyInt..tyInt64,tyUInt8..tyUInt32,tyBool,tyEnum} or - (t.Kind in {tyRange, tyOrdinal, tyConst, tyMutable, tyGenericInst}) and + result = t.kind in {tyChar,tyInt..tyInt64,tyUInt8..tyUInt32,tyBool,tyEnum} or + (t.kind in {tyRange, tyOrdinal, tyConst, tyMutable, tyGenericInst}) and isOrdinalType(t.sons[0]) proc enumHasHoles(t: PType): bool = var b = t while b.kind in {tyConst, tyMutable, tyRange, tyGenericInst}: b = b.sons[0] - result = b.Kind == tyEnum and tfEnumHasHoles in b.flags + result = b.kind == tyEnum and tfEnumHasHoles in b.flags proc iterOverTypeAux(marker: var TIntSet, t: PType, iter: TTypeIter, closure: PObject): bool @@ -184,7 +179,7 @@ proc iterOverTypeAux(marker: var TIntSet, t: PType, iter: TTypeIter, if t == nil: return result = iter(t, closure) if result: return - if not ContainsOrIncl(marker, t.id): + if not containsOrIncl(marker, t.id): case t.kind of tyGenericInst, tyGenericBody: result = iterOverTypeAux(marker, lastSon(t), iter, closure) @@ -194,8 +189,8 @@ proc iterOverTypeAux(marker: var TIntSet, t: PType, iter: TTypeIter, if result: return if t.n != nil: result = iterOverNode(marker, t.n, iter, closure) -proc IterOverType(t: PType, iter: TTypeIter, closure: PObject): bool = - var marker = InitIntSet() +proc iterOverType(t: PType, iter: TTypeIter, closure: PObject): bool = + var marker = initIntSet() result = iterOverTypeAux(marker, t, iter, closure) proc searchTypeForAux(t: PType, predicate: TTypePredicate, @@ -228,8 +223,8 @@ proc searchTypeForAux(t: PType, predicate: TTypePredicate, # iterates over VALUE types! result = false if t == nil: return - if ContainsOrIncl(marker, t.id): return - result = Predicate(t) + if containsOrIncl(marker, t.id): return + result = predicate(t) if result: return case t.kind of tyObject: @@ -242,10 +237,10 @@ proc searchTypeForAux(t: PType, predicate: TTypePredicate, result = searchTypeForAux(t.sons[i], predicate, marker) if result: return else: - nil + discard proc searchTypeFor(t: PType, predicate: TTypePredicate): bool = - var marker = InitIntSet() + var marker = initIntSet() result = searchTypeForAux(t, predicate, marker) proc isObjectPredicate(t: PType): bool = @@ -284,10 +279,10 @@ proc analyseObjectWithTypeFieldAux(t: PType, if res != frNone: return frEmbedded else: - nil + discard proc analyseObjectWithTypeField(t: PType): TTypeFieldResult = - var marker = InitIntSet() + var marker = initIntSet() result = analyseObjectWithTypeFieldAux(t, marker) proc isGCRef(t: PType): bool = @@ -322,7 +317,7 @@ proc canFormAcycleNode(marker: var TIntSet, n: PNode, startId: int): bool = if not result: case n.kind of nkNone..nkNilLit: - nil + discard else: for i in countup(0, sonsLen(n) - 1): result = canFormAcycleNode(marker, n.sons[i], startId) @@ -337,7 +332,7 @@ proc canFormAcycleAux(marker: var TIntSet, typ: PType, startId: int): bool = case t.kind of tyTuple, tyObject, tyRef, tySequence, tyArray, tyArrayConstr, tyOpenArray, tyVarargs: - if not ContainsOrIncl(marker, t.id): + if not containsOrIncl(marker, t.id): for i in countup(0, sonsLen(t) - 1): result = canFormAcycleAux(marker, t.sons[i], startId) if result: return @@ -353,7 +348,7 @@ proc canFormAcycleAux(marker: var TIntSet, typ: PType, startId: int): bool = else: nil proc canFormAcycle(typ: PType): bool = - var marker = InitIntSet() + var marker = initIntSet() result = canFormAcycleAux(marker, typ, typ.id) proc mutateTypeAux(marker: var TIntSet, t: PType, iter: TTypeMutator, @@ -367,6 +362,7 @@ proc mutateNode(marker: var TIntSet, n: PNode, iter: TTypeMutator, case n.kind of nkNone..nkNilLit: # a leaf + discard else: for i in countup(0, sonsLen(n) - 1): addSon(result, mutateNode(marker, n.sons[i], iter, closure)) @@ -376,17 +372,17 @@ proc mutateTypeAux(marker: var TIntSet, t: PType, iter: TTypeMutator, result = nil if t == nil: return result = iter(t, closure) - if not ContainsOrIncl(marker, t.id): + if not containsOrIncl(marker, t.id): for i in countup(0, sonsLen(t) - 1): result.sons[i] = mutateTypeAux(marker, result.sons[i], iter, closure) if t.n != nil: result.n = mutateNode(marker, t.n, iter, closure) assert(result != nil) proc mutateType(t: PType, iter: TTypeMutator, closure: PObject): PType = - var marker = InitIntSet() + var marker = initIntSet() result = mutateTypeAux(marker, t, iter, closure) -proc ValueToString(a: PNode): string = +proc valueToString(a: PNode): string = case a.kind of nkCharLit..nkUInt64Lit: result = $(a.intVal) of nkFloatLit..nkFloat128Lit: result = $(a.floatVal) @@ -395,7 +391,7 @@ proc ValueToString(a: PNode): string = proc rangeToStr(n: PNode): string = assert(n.kind == nkRange) - result = ValueToString(n.sons[0]) & ".." & ValueToString(n.sons[1]) + result = valueToString(n.sons[0]) & ".." & valueToString(n.sons[1]) const typeToStr: array[TTypeKind, string] = ["None", "bool", "Char", "empty", @@ -409,28 +405,18 @@ const "uint", "uint8", "uint16", "uint32", "uint64", "bignum", "const ", "!", "varargs[$1]", "iter[$1]", "Error Type", "TypeClass", - "ParametricTypeClass", "and", "or", "not", "any"] - -proc consToStr(t: PType): string = - if t.len > 0: result = t.typeToString - else: result = typeToStr[t.kind].strip - -proc constraintsToStr(t: PType): string = - let sep = if tfAny in t.flags: " or " else: " and " - result = "" - for i in countup(0, t.len - 1): - if i > 0: result.add(sep) - result.add(t.sons[i].consToStr) + "ParametricTypeClass", "BuiltInTypeClass", "CompositeTypeClass", + "and", "or", "not", "any", "static", "TypeFromExpr"] -proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string = +proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = var t = typ result = "" if t == nil: return if prefer == preferName and t.sym != nil and sfAnon notin t.sym.flags: if t.kind == tyInt and isIntLit(t): - return t.sym.Name.s & " literal(" & $t.n.intVal & ")" - return t.sym.Name.s - case t.Kind + return t.sym.name.s & " literal(" & $t.n.intVal & ")" + return t.sym.name.s + case t.kind of tyInt: if not isIntLit(t) or prefer == preferExported: result = typeToStr[t.kind] @@ -444,16 +430,26 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string = add(result, ']') of tyTypeDesc: if t.len == 0: result = "typedesc" - else: result = "typedesc[" & constraintsToStr(t) & "]" + else: result = "typedesc[" & typeToString(t.sons[0]) & "]" + of tyStatic: + InternalAssert t.len > 0 + result = "static[" & typeToString(t.sons[0]) & "]" of tyTypeClass: - if t.n != nil: return t.sym.owner.name.s - case t.len - of 0: result = "typeclass[]" - of 1: result = "typeclass[" & consToStr(t.sons[0]) & "]" - else: result = constraintsToStr(t) + InternalAssert t.sym != nil and t.sym.owner != nil + return t.sym.owner.name.s + of tyBuiltInTypeClass: + return "TypeClass" + of tyAnd: + result = typeToString(t.sons[0]) & " and " & typeToString(t.sons[1]) + of tyOr: + result = typeToString(t.sons[0]) & " and " & typeToString(t.sons[1]) + of tyNot: + result = "not " & typeToString(t.sons[0]) of tyExpr: - if t.len == 0: result = "expr" - else: result = "expr[" & constraintsToStr(t) & "]" + InternalAssert t.len == 0 + result = "expr" + of tyFromExpr: + result = renderTree(t.n) of tyArray: if t.sons[0].kind == tyRange: result = "array[" & rangeToStr(t.sons[0].n) & ", " & @@ -500,7 +496,7 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string = add(result, typeToString(t.sons[i])) if i < sonsLen(t) - 1: add(result, ", ") add(result, ')') - if t.sons[0] != nil: add(result, ": " & TypeToString(t.sons[0])) + if t.sons[0] != nil: add(result, ": " & typeToString(t.sons[0])) var prag: string if t.callConv != ccDefault: prag = CallingConvToStr[t.callConv] else: prag = "" @@ -525,7 +521,7 @@ proc resultType(t: PType): PType = proc base(t: PType): PType = result = t.sons[0] -proc firstOrd(t: PType): biggestInt = +proc firstOrd(t: PType): BiggestInt = case t.kind of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyProxy: result = 0 @@ -553,10 +549,10 @@ proc firstOrd(t: PType): biggestInt = of tyGenericInst, tyDistinct, tyConst, tyMutable, tyTypeDesc: result = firstOrd(lastSon(t)) else: - InternalError("invalid kind for first(" & $t.kind & ')') + internalError("invalid kind for first(" & $t.kind & ')') result = 0 -proc lastOrd(t: PType): biggestInt = +proc lastOrd(t: PType): BiggestInt = case t.kind of tyBool: result = 1 of tyChar: result = 255 @@ -587,10 +583,10 @@ proc lastOrd(t: PType): biggestInt = result = lastOrd(lastSon(t)) of tyProxy: result = 0 else: - InternalError("invalid kind for last(" & $t.kind & ')') + internalError("invalid kind for last(" & $t.kind & ')') result = 0 -proc lengthOrd(t: PType): biggestInt = +proc lengthOrd(t: PType): BiggestInt = case t.kind of tyInt64, tyInt32, tyInt: result = lastOrd(t) of tyDistinct, tyConst, tyMutable: result = lengthOrd(t.sons[0]) @@ -606,8 +602,11 @@ type dcEqOrDistinctOf ## a equals b or a is distinct of b TTypeCmpFlag* = enum - IgnoreTupleFields, - TypeDescExactMatch, + IgnoreTupleFields + IgnoreCC + ExactTypeDescValues + ExactGenericParams + ExactConstraints AllowCommonBase TTypeCmpFlags* = set[TTypeCmpFlag] @@ -621,39 +620,41 @@ type proc initSameTypeClosure: TSameTypeClosure = # we do the initialization lazily for performance (avoids memory allocations) - nil + discard proc containsOrIncl(c: var TSameTypeClosure, a, b: PType): bool = - result = not IsNil(c.s) and c.s.contains((a.id, b.id)) + result = not isNil(c.s) and c.s.contains((a.id, b.id)) if not result: - if IsNil(c.s): c.s = @[] + if isNil(c.s): c.s = @[] c.s.add((a.id, b.id)) -proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool -proc SameTypeOrNilAux(a, b: PType, c: var TSameTypeClosure): bool = +proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool +proc sameTypeOrNilAux(a, b: PType, c: var TSameTypeClosure): bool = if a == b: result = true else: if a == nil or b == nil: result = false - else: result = SameTypeAux(a, b, c) + else: result = sameTypeAux(a, b, c) -proc SameTypeOrNil*(a, b: PType, flags: TTypeCmpFlags = {}): bool = +proc sameType*(a, b: PType, flags: TTypeCmpFlags = {}): bool = + var c = initSameTypeClosure() + c.flags = flags + result = sameTypeAux(a, b, c) + +proc sameTypeOrNil*(a, b: PType, flags: TTypeCmpFlags = {}): bool = if a == b: result = true - else: + else: if a == nil or b == nil: result = false - else: - var c = initSameTypeClosure() - c.flags = flags - result = SameTypeAux(a, b, c) + else: result = sameType(a, b, flags) proc equalParam(a, b: PSym): TParamsEquality = - if SameTypeOrNil(a.typ, b.typ, {TypeDescExactMatch}) and - ExprStructuralEquivalent(a.constraint, b.constraint): + if sameTypeOrNil(a.typ, b.typ, {ExactTypeDescValues}) and + exprStructuralEquivalent(a.constraint, b.constraint): if a.ast == b.ast: result = paramsEqual elif a.ast != nil and b.ast != nil: - if ExprStructuralEquivalent(a.ast, b.ast): result = paramsEqual + if exprStructuralEquivalent(a.ast, b.ast): result = paramsEqual else: result = paramsIncompatible elif a.ast != nil: result = paramsEqual @@ -661,7 +662,15 @@ proc equalParam(a, b: PSym): TParamsEquality = result = paramsIncompatible else: result = paramsNotEqual - + +proc sameConstraints(a, b: PNode): bool = + internalAssert a.len == b.len + for i in 1 .. <a.len: + if not exprStructuralEquivalent(a[i].sym.constraint, + b[i].sym.constraint): + return false + return true + proc equalParams(a, b: PNode): TParamsEquality = result = paramsEqual var length = sonsLen(a) @@ -676,7 +685,7 @@ proc equalParams(a, b: PNode): TParamsEquality = of paramsNotEqual: return paramsNotEqual of paramsEqual: - nil + discard of paramsIncompatible: result = paramsIncompatible if (m.name.id != n.name.id): @@ -684,14 +693,14 @@ proc equalParams(a, b: PNode): TParamsEquality = return paramsNotEqual # paramsIncompatible; # continue traversal! If not equal, we can return immediately; else # it stays incompatible - if not SameTypeOrNil(a.sons[0].typ, b.sons[0].typ, {TypeDescExactMatch}): + if not sameTypeOrNil(a.sons[0].typ, b.sons[0].typ, {ExactTypeDescValues}): if (a.sons[0].typ == nil) or (b.sons[0].typ == nil): result = paramsNotEqual # one proc has a result, the other not is OK else: result = paramsIncompatible # overloading by different # result types does not work -proc SameLiteral(x, y: PNode): bool = +proc sameLiteral(x, y: PNode): bool = if x.kind == y.kind: case x.kind of nkCharLit..nkInt64Lit: result = x.intVal == y.intVal @@ -699,9 +708,9 @@ proc SameLiteral(x, y: PNode): bool = of nkNilLit: result = true else: assert(false) -proc SameRanges(a, b: PNode): bool = - result = SameLiteral(a.sons[0], b.sons[0]) and - SameLiteral(a.sons[1], b.sons[1]) +proc sameRanges(a, b: PNode): bool = + result = sameLiteral(a.sons[0], b.sons[0]) and + sameLiteral(a.sons[1], b.sons[1]) proc sameTuple(a, b: PType, c: var TSameTypeClosure): bool = # two tuples are equivalent iff the names, types and positions are the same; @@ -716,7 +725,7 @@ proc sameTuple(a, b: PType, c: var TSameTypeClosure): bool = x = skipTypes(x, {tyRange}) y = skipTypes(y, {tyRange}) - result = SameTypeAux(x, y, c) + result = sameTypeAux(x, y, c) if not result: return if a.n != nil and b.n != nil and IgnoreTupleFields notin c.flags: for i in countup(0, sonsLen(a.n) - 1): @@ -726,11 +735,11 @@ proc sameTuple(a, b: PType, c: var TSameTypeClosure): bool = var y = b.n.sons[i].sym result = x.name.id == y.name.id if not result: break - else: InternalError(a.n.info, "sameTuple") + else: internalError(a.n.info, "sameTuple") else: result = false -template IfFastObjectTypeCheckFailed(a, b: PType, body: stmt) {.immediate.} = +template ifFastObjectTypeCheckFailed(a, b: PType, body: stmt) {.immediate.} = if tfFromGeneric notin a.flags + b.flags: # fast case: id comparison suffices: result = a.id == b.id @@ -745,15 +754,15 @@ template IfFastObjectTypeCheckFailed(a, b: PType, body: stmt) {.immediate.} = # TA[T] = object # TB[T] = object # --> TA[int] != TB[int] - if tfFromGeneric in a.flags * b.flags and a.sym.Id == b.sym.Id: + if tfFromGeneric in a.flags * b.flags and a.sym.id == b.sym.id: # ok, we need the expensive structural check body proc sameObjectTypes*(a, b: PType): bool = # specialized for efficiency (sigmatch uses it) - IfFastObjectTypeCheckFailed(a, b): + ifFastObjectTypeCheckFailed(a, b): var c = initSameTypeClosure() - result = sameTypeAux(a, b, c) + result = sameTypeAux(a, b, c) proc sameDistinctTypes*(a, b: PType): bool {.inline.} = result = sameObjectTypes(a, b) @@ -761,7 +770,7 @@ proc sameDistinctTypes*(a, b: PType): bool {.inline.} = proc sameEnumTypes*(a, b: PType): bool {.inline.} = result = a.id == b.id -proc SameObjectTree(a, b: PNode, c: var TSameTypeClosure): bool = +proc sameObjectTree(a, b: PNode, c: var TSameTypeClosure): bool = if a == b: result = true elif (a != nil) and (b != nil) and (a.kind == b.kind): @@ -778,26 +787,26 @@ proc SameObjectTree(a, b: PNode, c: var TSameTypeClosure): bool = else: if sonsLen(a) == sonsLen(b): for i in countup(0, sonsLen(a) - 1): - if not SameObjectTree(a.sons[i], b.sons[i], c): return + if not sameObjectTree(a.sons[i], b.sons[i], c): return result = true proc sameObjectStructures(a, b: PType, c: var TSameTypeClosure): bool = # check base types: if sonsLen(a) != sonsLen(b): return for i in countup(0, sonsLen(a) - 1): - if not SameTypeOrNilAux(a.sons[i], b.sons[i], c): return - if not SameObjectTree(a.n, b.n, c): return + if not sameTypeOrNilAux(a.sons[i], b.sons[i], c): return + if not sameObjectTree(a.n, b.n, c): return result = true proc sameChildrenAux(a, b: PType, c: var TSameTypeClosure): bool = if sonsLen(a) != sonsLen(b): return false result = true for i in countup(0, sonsLen(a) - 1): - result = SameTypeOrNilAux(a.sons[i], b.sons[i], c) + result = sameTypeOrNilAux(a.sons[i], b.sons[i], c) if not result: return -proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = - template CycleCheck() = +proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = + template cycleCheck() = # believe it or not, the direct check for ``containsOrIncl(c, a, b)`` # increases bootstrapping time from 2.4s to 3.3s on my laptop! So we cheat # again: Since the recursion check is only to not get caught in an endless @@ -826,21 +835,21 @@ proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = of dcEqOrDistinctOf: while a.kind == tyDistinct: a = a.sons[0] if a.kind != b.kind: return false - case a.Kind + case a.kind of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString, - tyInt..tyBigNum, tyStmt: + tyInt..tyBigNum, tyStmt, tyExpr: result = sameFlags(a, b) - of tyExpr: - result = ExprStructuralEquivalent(a.n, b.n) and sameFlags(a, b) + of tyStatic, tyFromExpr: + result = exprStructuralEquivalent(a.n, b.n) and sameFlags(a, b) of tyObject: - IfFastObjectTypeCheckFailed(a, b): - CycleCheck() + ifFastObjectTypeCheckFailed(a, b): + cycleCheck() result = sameObjectStructures(a, b, c) and sameFlags(a, b) of tyDistinct: - CycleCheck() + cycleCheck() if c.cmp == dcEq: if sameFlags(a, b): - IfFastObjectTypeCheckFailed(a, b): + ifFastObjectTypeCheckFailed(a, b): result = sameTypeAux(a.sons[0], b.sons[0], c) else: result = sameTypeAux(a.sons[0], b.sons[0], c) and sameFlags(a, b) @@ -848,36 +857,38 @@ proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = # XXX generic enums do not make much sense, but require structural checking result = a.id == b.id and sameFlags(a, b) of tyTuple: - CycleCheck() + cycleCheck() result = sameTuple(a, b, c) and sameFlags(a, b) of tyGenericInst: result = sameTypeAux(lastSon(a), lastSon(b), c) of tyTypeDesc: if c.cmp == dcEqIgnoreDistinct: result = false - elif TypeDescExactMatch in c.flags: - CycleCheck() + elif ExactTypeDescValues in c.flags: + cycleCheck() result = sameChildrenAux(x, y, c) and sameFlags(a, b) else: result = sameFlags(a, b) - of tyGenericParam, tyGenericInvokation, tyGenericBody, tySequence, + of tyGenericParam: + result = sameChildrenAux(a, b, c) and sameFlags(a, b) + if result and ExactGenericParams in c.flags: + result = a.sym.position == b.sym.position + of tyGenericInvokation, tyGenericBody, tySequence, tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc, tyConst, tyMutable, tyVarargs, tyIter, tyOrdinal, tyTypeClasses: - CycleCheck() + cycleCheck() + if a.kind == tyTypeClass and a.n != nil: return a.n == b.n result = sameChildrenAux(a, b, c) and sameFlags(a, b) - if result and (a.kind == tyProc): - result = a.callConv == b.callConv + if result and a.kind == tyProc: + result = ((IgnoreCC in c.flags) or a.callConv == b.callConv) and + ((ExactConstraints notin c.flags) or sameConstraints(a.n, b.n)) of tyRange: - CycleCheck() - result = SameTypeOrNilAux(a.sons[0], b.sons[0], c) and - SameValue(a.n.sons[0], b.n.sons[0]) and - SameValue(a.n.sons[1], b.n.sons[1]) + cycleCheck() + result = sameTypeOrNilAux(a.sons[0], b.sons[0], c) and + sameValue(a.n.sons[0], b.n.sons[0]) and + sameValue(a.n.sons[1], b.n.sons[1]) of tyNone: result = false -proc sameType*(x, y: PType): bool = - var c = initSameTypeClosure() - result = sameTypeAux(x, y, c) - proc sameBackendType*(x, y: PType): bool = var c = initSameTypeClosure() c.flags.incl IgnoreTupleFields @@ -954,7 +965,7 @@ proc typeAllowedNode(marker: var TIntSet, n: PNode, kind: TSymKind, if result: case n.kind of nkNone..nkNilLit: - nil + discard else: for i in countup(0, sonsLen(n) - 1): result = typeAllowedNode(marker, n.sons[i], kind, flags) @@ -965,7 +976,7 @@ proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]], var a = a for k, i in pattern.items: if a.kind != k: return false - if i >= a.sonslen or a.sons[i] == nil: return false + if i >= a.sonsLen or a.sons[i] == nil: return false a = a.sons[i] result = a.kind == last @@ -975,42 +986,6 @@ proc isGenericAlias*(t: PType): bool = proc skipGenericAlias*(t: PType): PType = return if t.isGenericAlias: t.lastSon else: t -proc matchTypeClass*(bindings: var TIdTable, typeClass, t: PType): bool = - for i in countup(0, typeClass.sonsLen - 1): - let req = typeClass.sons[i] - var match = req.kind == skipTypes(t, {tyRange, tyGenericInst}).kind - - if not match: - case req.kind - of tyGenericBody: - if t.kind == tyGenericInst and t.sons[0] == req: - match = true - IdTablePut(bindings, typeClass, t) - of tyTypeClass: - match = matchTypeClass(bindings, req, t) - elif t.kind == tyTypeClass: - match = matchTypeClass(bindings, t, req) - - elif t.kind in {tyObject} and req.len != 0: - # empty 'object' is fine as constraint in a type class - match = sameType(t, req) - - if tfAny in typeClass.flags: - if match: return true - else: - if not match: return false - - # if the loop finished without returning, either all constraints matched - # or none of them matched. - result = if tfAny in typeClass.flags: false else: true - if result == true: - IdTablePut(bindings, typeClass, t) - -proc matchTypeClass*(typeClass, typ: PType): bool = - var bindings: TIdTable - initIdTable(bindings) - result = matchTypeClass(bindings, typeClass, typ) - proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind, flags: TTypeAllowedFlags = {}): bool = assert(kind in {skVar, skLet, skConst, skParam, skResult}) @@ -1018,7 +993,7 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind, # evaluation if something is wrong: result = true if typ == nil: return - if ContainsOrIncl(marker, typ.id): return + if containsOrIncl(marker, typ.id): return var t = skipTypes(typ, abstractInst-{tyTypeDesc}) case t.kind of tyVar: @@ -1038,14 +1013,15 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind, if not result: break if result and t.sons[0] != nil: result = typeAllowedAux(marker, t.sons[0], skResult, flags) - of tyExpr, tyStmt, tyTypeDesc: + of tyExpr, tyStmt, tyTypeDesc, tyStatic: result = true # XXX er ... no? these should not be allowed! of tyEmpty: result = taField in flags of tyTypeClasses: result = true - of tyGenericBody, tyGenericParam, tyForward, tyNone, tyGenericInvokation: + of tyGenericBody, tyGenericParam, tyGenericInvokation, + tyNone, tyForward, tyFromExpr: result = false of tyNil: result = kind == skConst @@ -1088,15 +1064,15 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind, result = true proc typeAllowed(t: PType, kind: TSymKind): bool = - var marker = InitIntSet() + var marker = initIntSet() result = typeAllowedAux(marker, t, kind, {}) -proc align(address, alignment: biggestInt): biggestInt = +proc align(address, alignment: BiggestInt): BiggestInt = result = (address + (alignment - 1)) and not (alignment - 1) -proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt -proc computeRecSizeAux(n: PNode, a, currOffset: var biggestInt): biggestInt = - var maxAlign, maxSize, b, res: biggestInt +proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt +proc computeRecSizeAux(n: PNode, a, currOffset: var BiggestInt): BiggestInt = + var maxAlign, maxSize, b, res: BiggestInt case n.kind of nkRecCase: assert(n.sons[0].kind == nkSym) @@ -1128,25 +1104,29 @@ proc computeRecSizeAux(n: PNode, a, currOffset: var biggestInt): biggestInt = result = computeSizeAux(n.sym.typ, a) n.sym.offset = int(currOffset) else: - InternalError("computeRecSizeAux()") + internalError("computeRecSizeAux()") a = 1 result = - 1 -proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt = - var res, maxAlign, length, currOffset: biggestInt - if typ.size == - 2: +const + szIllegalRecursion* = -2 + szUnknownSize* = -1 + +proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt = + var res, maxAlign, length, currOffset: BiggestInt + if typ.size == szIllegalRecursion: # we are already computing the size of the type # --> illegal recursion in type - return - 2 - if typ.size >= 0: + return szIllegalRecursion + if typ.size >= 0: # size already computed result = typ.size a = typ.align return - typ.size = - 2 # mark as being computed + typ.size = szIllegalRecursion # mark as being computed case typ.kind of tyInt, tyUInt: - result = IntSize + result = intSize a = result of tyInt8, tyUInt8, tyBool, tyChar: result = 1 @@ -1174,8 +1154,10 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt = tyBigNum: result = ptrSize a = result - of tyArray, tyArrayConstr: - result = lengthOrd(typ.sons[0]) * computeSizeAux(typ.sons[1], a) + of tyArray, tyArrayConstr: + let elemSize = computeSizeAux(typ.sons[1], a) + if elemSize < 0: return elemSize + result = lengthOrd(typ.sons[0]) * elemSize of tyEnum: if firstOrd(typ) < 0: result = 4 # use signed int32 @@ -1183,7 +1165,7 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt = length = lastOrd(typ) # BUGFIX: use lastOrd! if length + 1 < `shl`(1, 8): result = 1 elif length + 1 < `shl`(1, 16): result = 2 - elif length + 1 < `shl`(biggestInt(1), 32): result = 4 + elif length + 1 < `shl`(BiggestInt(1), 32): result = 4 else: result = 8 a = result of tySet: @@ -1226,16 +1208,17 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt = of tyGenericInst, tyDistinct, tyGenericBody, tyMutable, tyConst, tyIter: result = computeSizeAux(lastSon(typ), a) of tyTypeDesc: - result = (if typ.len == 1: computeSizeAux(typ.sons[0], a) else: -1) - of tyProxy: result = 1 + result = if typ.len == 1: computeSizeAux(typ.sons[0], a) + else: szUnknownSize + of tyForward: return szIllegalRecursion else: #internalError("computeSizeAux()") - result = - 1 + result = szUnknownSize typ.size = result typ.align = int(a) -proc computeSize(typ: PType): biggestInt = - var a: biggestInt = 1 +proc computeSize(typ: PType): BiggestInt = + var a: BiggestInt = 1 result = computeSizeAux(typ, a) proc getReturnType*(s: PSym): PType = @@ -1243,13 +1226,13 @@ proc getReturnType*(s: PSym): PType = assert s.kind in {skProc, skTemplate, skMacro, skIterator} result = s.typ.sons[0] -proc getSize(typ: PType): biggestInt = +proc getSize(typ: PType): BiggestInt = result = computeSize(typ) - if result < 0: InternalError("getSize: " & $typ.kind) + if result < 0: internalError("getSize: " & $typ.kind) - -proc containsGenericTypeIter(t: PType, closure: PObject): bool = - result = t.kind in GenericTypes +proc containsGenericTypeIter(t: PType, closure: PObject): bool = + result = t.kind in GenericTypes + tyTypeClasses + {tyTypeDesc,tyFromExpr} or + t.kind == tyStatic and t.n == nil proc containsGenericType*(t: PType): bool = result = iterOverType(t, containsGenericTypeIter, nil) @@ -1288,8 +1271,8 @@ proc compatibleEffectsAux(se, re: PNode): bool = proc compatibleEffects*(formal, actual: PType): bool = # for proc type compatibility checking: assert formal.kind == tyProc and actual.kind == tyProc - InternalAssert formal.n.sons[0].kind == nkEffectList - InternalAssert actual.n.sons[0].kind == nkEffectList + internalAssert formal.n.sons[0].kind == nkEffectList + internalAssert actual.n.sons[0].kind == nkEffectList var spec = formal.n.sons[0] if spec.len != 0: @@ -1299,7 +1282,7 @@ proc compatibleEffects*(formal, actual: PType): bool = # if 'se.kind == nkArgList' it is no formal type really, but a # computed effect and as such no spec: # 'r.msgHandler = if isNil(msgHandler): defaultMsgHandler else: msgHandler' - if not IsNil(se) and se.kind != nkArgList: + if not isNil(se) and se.kind != nkArgList: # spec requires some exception or tag, but we don't know anything: if real.len == 0: return false result = compatibleEffectsAux(se, real.sons[exceptionEffects]) @@ -1314,7 +1297,7 @@ proc compatibleEffects*(formal, actual: PType): bool = result = true proc isCompileTimeOnly*(t: PType): bool {.inline.} = - result = t.kind in {tyTypedesc, tyExpr} + result = t.kind in {tyTypeDesc, tyStatic} proc containsCompileTimeOnly*(t: PType): bool = if isCompileTimeOnly(t): return true diff --git a/compiler/vm.nim b/compiler/vm.nim index 7705746de..9ed18d29e 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -10,11 +10,17 @@ ## This file implements the new evaluation engine for Nimrod code. ## An instruction is 1-2 int32s in memory, it is a register based VM. +import ast except getstr + import - strutils, ast, astalgo, msgs, vmdef, vmgen, nimsets, types, passes, unsigned, - parser, vmdeps, idents + strutils, astalgo, msgs, vmdef, vmgen, nimsets, types, passes, unsigned, + parser, vmdeps, idents, trees, renderer, options from semfold import leValueConv, ordinalValToString +from evaltempl import evalTemplate + +when hasFFI: + import evalffi type PStackFrame* = ref TStackFrame @@ -34,7 +40,7 @@ proc stackTraceAux(c: PCtx; x: PStackFrame; pc: int) = var info = c.debug[pc] # we now use the same format as in system/except.nim var s = toFilename(info) - var line = toLineNumber(info) + var line = toLinenumber(info) if line > 0: add(s, '(') add(s, $line) @@ -42,13 +48,13 @@ proc stackTraceAux(c: PCtx; x: PStackFrame; pc: int) = if x.prc != nil: for k in 1..max(1, 25-s.len): add(s, ' ') add(s, x.prc.name.s) - MsgWriteln(s) + msgWriteln(s) proc stackTrace(c: PCtx, tos: PStackFrame, pc: int, msg: TMsgKind, arg = "") = - MsgWriteln("stack trace: (most recent call last)") + msgWriteln("stack trace: (most recent call last)") stackTraceAux(c, tos, pc) - LocalError(c.debug[pc], msg, arg) + localError(c.debug[pc], msg, arg) proc bailOut(c: PCtx; tos: PStackFrame) = stackTrace(c, tos, c.exceptionInstr, errUnhandledExceptionX, @@ -57,15 +63,25 @@ proc bailOut(c: PCtx; tos: PStackFrame) = when not defined(nimComputedGoto): {.pragma: computedGoto.} -template inc(pc: ptr TInstr, diff = 1) = - inc cast[TAddress](pc), TInstr.sizeof * diff - proc myreset(n: PNode) = when defined(system.reset): var oldInfo = n.info reset(n[]) n.info = oldInfo +proc skipMeta(n: PNode): PNode = (if n.kind != nkMetaNode: n else: n.sons[0]) + +proc setMeta(n, child: PNode) = + assert n.kind == nkMetaNode + let child = child.skipMeta + if n.sons.isNil: n.sons = @[child] + else: n.sons[0] = child + +proc uast(n: PNode): PNode {.inline.} = + # "underlying ast" + assert n.kind == nkMetaNode + n.sons[0] + template ensureKind(k: expr) {.immediate, dirty.} = if regs[ra].kind != k: myreset(regs[ra]) @@ -93,26 +109,56 @@ template decodeBx(k: expr) {.immediate, dirty.} = let rbx = instr.regBx - wordExcess ensureKind(k) -template move(a, b: expr) = system.shallowCopy(a, b) +template move(a, b: expr) {.immediate, dirty.} = system.shallowCopy(a, b) # XXX fix minor 'shallowCopy' overloading bug in compiler -proc asgnRef(x, y: PNode) = - myreset(x) - x.kind = y.kind +proc moveConst(x, y: PNode) = + if x.kind != y.kind: + myreset(x) + x.kind = y.kind x.typ = y.typ case x.kind of nkCharLit..nkInt64Lit: x.intVal = y.intVal of nkFloatLit..nkFloat64Lit: x.floatVal = y.floatVal - of nkStrLit..nkTripleStrLit: x.strVal = y.strVal + of nkStrLit..nkTripleStrLit: move(x.strVal, y.strVal) of nkIdent: x.ident = y.ident of nkSym: x.sym = y.sym + of nkMetaNode: + if x.sons.isNil: x.sons = @[y.sons[0]] + else: x.sons[0] = y.sons[0] else: if x.kind notin {nkEmpty..nkNilLit}: move(x.sons, y.sons) +# this seems to be the best way to model the reference semantics +# of PNimrodNode: +template asgnRef(x, y: expr) = moveConst(x, y) + +proc copyValue(src: PNode): PNode = + if src == nil or nfIsRef in src.flags: + return src + result = newNode(src.kind) + result.info = src.info + result.typ = src.typ + result.flags = src.flags * PersistentNodeFlags + when defined(useNodeIds): + if result.id == nodeIdToDebug: + echo "COMES FROM ", src.id + case src.kind + of nkCharLit..nkUInt64Lit: result.intVal = src.intVal + of nkFloatLit..nkFloat128Lit: result.floatVal = src.floatVal + of nkSym: result.sym = src.sym + of nkIdent: result.ident = src.ident + of nkStrLit..nkTripleStrLit: result.strVal = src.strVal + else: + newSeq(result.sons, sonsLen(src)) + for i in countup(0, sonsLen(src) - 1): + result.sons[i] = copyValue(src.sons[i]) + proc asgnComplex(x, y: PNode) = - myreset(x) - x.kind = y.kind + if x.kind != y.kind: + myreset(x) + x.kind = y.kind x.typ = y.typ case x.kind of nkCharLit..nkInt64Lit: x.intVal = y.intVal @@ -120,13 +166,18 @@ proc asgnComplex(x, y: PNode) = of nkStrLit..nkTripleStrLit: x.strVal = y.strVal of nkIdent: x.ident = y.ident of nkSym: x.sym = y.sym + of nkMetaNode: + if x.sons.isNil: x.sons = @[y.sons[0]] + else: x.sons[0] = y.sons[0] else: if x.kind notin {nkEmpty..nkNilLit}: - let y = y.copyTree - for i in countup(0, sonsLen(y) - 1): addSon(x, y.sons[i]) + let y = y.copyValue + for i in countup(0, sonsLen(y) - 1): + if i < x.len: x.sons[i] = y.sons[i] + else: addSon(x, y.sons[i]) template getstr(a: expr): expr = - (if a.kind == nkStrLit: a.strVal else: $chr(int(a.intVal))) + (if a.kind in {nkStrLit..nkTripleStrLit}: a.strVal else: $chr(int(a.intVal))) proc pushSafePoint(f: PStackFrame; pc: int) = if f.safePoints.isNil: f.safePoints = @[] @@ -231,16 +282,23 @@ proc compile(c: PCtx, s: PSym): int = result = vmgen.genProc(c, s) #c.echoCode -proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = +proc regsContents(regs: TNodeSeq) = + for i in 0.. <regs.len: + echo "Register ", i + #debug regs[i] + +proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode = var pc = start var tos = tos var regs: TNodeSeq # alias to tos.slots for performance move(regs, tos.slots) + #echo "NEW RUN ------------------------" while true: - {.computedGoto.} + #{.computedGoto.} let instr = c.code[pc] let ra = instr.regA #echo "PC ", pc, " ", c.code[pc].opcode, " ra ", ra + #message(c.debug[pc], warnUser, "gah") case instr.opcode of opcEof: return regs[ra] of opcRet: @@ -248,20 +306,26 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = pc = tos.comesFrom tos = tos.next let retVal = regs[0] - if tos.isNil: return retVal + if tos.isNil: + #echo "RET ", retVal.rendertree + return retVal move(regs, tos.slots) assert c.code[pc].opcode in {opcIndCall, opcIndCallAsgn} if c.code[pc].opcode == opcIndCallAsgn: regs[c.code[pc].regA] = retVal + #echo "RET2 ", retVal.rendertree, " ", c.code[pc].regA of opcYldYoid: assert false of opcYldVal: assert false of opcAsgnInt: decodeB(nkIntLit) regs[ra].intVal = regs[rb].intVal of opcAsgnStr: - decodeB(nkStrLit) - regs[ra].strVal = regs[rb].strVal + if regs[instr.regB].kind == nkNilLit: + decodeB(nkNilLit) + else: + decodeB(nkStrLit) + regs[ra].strVal = regs[rb].strVal of opcAsgnFloat: decodeB(nkFloatLit) regs[ra].floatVal = regs[rb].floatVal @@ -270,42 +334,63 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = of opcAsgnRef: asgnRef(regs[ra], regs[instr.regB]) of opcWrGlobalRef: - asgnRef(c.globals[instr.regBx-wordExcess-1], regs[ra]) + asgnRef(c.globals.sons[instr.regBx-wordExcess-1], regs[ra]) of opcWrGlobal: asgnComplex(c.globals.sons[instr.regBx-wordExcess-1], regs[ra]) of opcLdArr: # a = b[c] let rb = instr.regB let rc = instr.regC - let idx = regs[rc].intVal + if regs[rc].intVal > high(int): + stackTrace(c, tos, pc, errIndexOutOfBounds) + let idx = regs[rc].intVal.int # XXX what if the array is not 0-based? -> codegen should insert a sub - regs[ra] = regs[rb].sons[idx.int] + assert regs[rb].kind != nkMetaNode + let src = regs[rb] + if src.kind notin {nkEmpty..nkNilLit} and idx <% src.len: + asgnComplex(regs[ra], src.sons[idx]) + else: + stackTrace(c, tos, pc, errIndexOutOfBounds) of opcLdStrIdx: decodeBC(nkIntLit) - let idx = regs[rc].intVal - regs[ra].intVal = regs[rb].strVal[idx.int].ord + let idx = regs[rc].intVal.int + if idx <=% regs[rb].strVal.len: + regs[ra].intVal = regs[rb].strVal[idx].ord + else: + stackTrace(c, tos, pc, errIndexOutOfBounds) of opcWrArr: # a[b] = c let rb = instr.regB let rc = instr.regC - let idx = regs[rb].intVal - asgnComplex(regs[ra].sons[idx.int], regs[rc]) + let idx = regs[rb].intVal.int + if idx <% regs[ra].len: + asgnComplex(regs[ra].sons[idx], regs[rc]) + else: + stackTrace(c, tos, pc, errIndexOutOfBounds) of opcWrArrRef: let rb = instr.regB let rc = instr.regC - let idx = regs[rb].intVal - asgnRef(regs[ra].sons[idx.int], regs[rc]) + let idx = regs[rb].intVal.int + if idx <% regs[ra].len: + asgnRef(regs[ra].sons[idx], regs[rc]) + else: + stackTrace(c, tos, pc, errIndexOutOfBounds) of opcLdObj: # a = b.c let rb = instr.regB let rc = instr.regC # XXX this creates a wrong alias - #Message(c.debug[pc], warnUser, $regs[rb].len & " " & $rc) + #Message(c.debug[pc], warnUser, $regs[rb].safeLen & " " & $rc) asgnComplex(regs[ra], regs[rb].sons[rc]) of opcWrObj: # a.b = c let rb = instr.regB let rc = instr.regC + #if regs[ra].isNil or regs[ra].sons.isNil or rb >= len(regs[ra]): + # debug regs[ra] + # debug regs[rc] + # echo "RB ", rb + # internalError(c.debug[pc], "argl") asgnComplex(regs[ra].sons[rb], regs[rc]) of opcWrObjRef: let rb = instr.regB @@ -314,7 +399,10 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = of opcWrStrIdx: decodeBC(nkStrLit) let idx = regs[rb].intVal.int - regs[ra].strVal[idx] = chr(regs[rc].intVal) + if idx <% regs[ra].strVal.len: + regs[ra].strVal[idx] = chr(regs[rc].intVal) + else: + stackTrace(c, tos, pc, errIndexOutOfBounds) of opcAddr: decodeB(nkRefTy) if regs[ra].len == 0: regs[ra].add regs[rb] @@ -325,6 +413,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = if regs[rb].kind == nkNilLit: stackTrace(c, tos, pc, errNilAccess) assert regs[rb].kind == nkRefTy + # XXX this is not correct regs[ra] = regs[rb].sons[0] of opcAddInt: decodeBC(nkIntLit) @@ -341,15 +430,24 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = of opcLenSeq: decodeBImm(nkIntLit) #assert regs[rb].kind == nkBracket - # also used by mNLen - regs[ra].intVal = regs[rb].len - imm + # also used by mNLen: + regs[ra].intVal = regs[rb].skipMeta.len - imm of opcLenStr: decodeBImm(nkIntLit) - assert regs[rb].kind == nkStrLit - regs[ra].intVal = regs[rb].strVal.len - imm + if regs[rb].kind == nkNilLit: + stackTrace(c, tos, pc, errNilAccess) + else: + assert regs[rb].kind in {nkStrLit..nkTripleStrLit} + regs[ra].intVal = regs[rb].strVal.len - imm of opcIncl: decodeB(nkCurly) if not inSet(regs[ra], regs[rb]): addSon(regs[ra], copyTree(regs[rb])) + of opcInclRange: + decodeBC(nkCurly) + var r = newNode(nkRange) + r.add regs[rb] + r.add regs[rc] + addSon(regs[ra], r.copyTree) of opcExcl: decodeB(nkCurly) var b = newNodeIT(nkCurly, regs[rb].info, regs[rb].typ) @@ -440,6 +538,9 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = regs[ra].intVal = ord((regs[rb].kind == nkNilLit and regs[rc].kind == nkNilLit) or regs[rb].sons == regs[rc].sons) + of opcEqNimrodNode: + decodeBC(nkIntLit) + regs[ra].intVal = ord(regs[rb].skipMeta == regs[rc].skipMeta) of opcXor: decodeBC(nkIntLit) regs[ra].intVal = ord(regs[rb].intVal != regs[rc].intVal) @@ -461,24 +562,24 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = regs[ra].intVal = not regs[rb].intVal of opcEqStr: decodeBC(nkIntLit) - regs[ra].intVal = Ord(regs[rb].strVal == regs[rc].strVal) + regs[ra].intVal = ord(regs[rb].strVal == regs[rc].strVal) of opcLeStr: decodeBC(nkIntLit) - regs[ra].intVal = Ord(regs[rb].strVal <= regs[rc].strVal) + regs[ra].intVal = ord(regs[rb].strVal <= regs[rc].strVal) of opcLtStr: decodeBC(nkIntLit) - regs[ra].intVal = Ord(regs[rb].strVal < regs[rc].strVal) + regs[ra].intVal = ord(regs[rb].strVal < regs[rc].strVal) of opcLeSet: decodeBC(nkIntLit) - regs[ra].intVal = Ord(containsSets(regs[rb], regs[rc])) + regs[ra].intVal = ord(containsSets(regs[rb], regs[rc])) of opcEqSet: decodeBC(nkIntLit) - regs[ra].intVal = Ord(equalSets(regs[rb], regs[rc])) + regs[ra].intVal = ord(equalSets(regs[rb], regs[rc])) of opcLtSet: decodeBC(nkIntLit) let a = regs[rb] let b = regs[rc] - regs[ra].intVal = Ord(containsSets(a, b) and not equalSets(a, b)) + regs[ra].intVal = ord(containsSets(a, b) and not equalSets(a, b)) of opcMulSet: decodeBC(nkCurly) move(regs[ra].sons, nimsets.intersectSets(regs[rb], regs[rc]).sons) @@ -488,7 +589,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = of opcMinusSet: decodeBC(nkCurly) move(regs[ra].sons, nimsets.diffSets(regs[rb], regs[rc]).sons) - of opcSymDiffSet: + of opcSymdiffSet: decodeBC(nkCurly) move(regs[ra].sons, nimsets.symdiffSets(regs[rb], regs[rc]).sons) of opcConcatStr: @@ -508,12 +609,12 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = of opcEcho: let rb = instr.regB for i in ra..ra+rb-1: - if regs[i].kind != nkStrLit: debug regs[i] + #if regs[i].kind != nkStrLit: debug regs[i] write(stdout, regs[i].strVal) writeln(stdout, "") of opcContainsSet: decodeBC(nkIntLit) - regs[ra].intVal = Ord(inSet(regs[rb], regs[rc])) + regs[ra].intVal = ord(inSet(regs[rb], regs[rc])) of opcSubStr: decodeBC(nkStrLit) inc pc @@ -533,22 +634,55 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = # dest = call regStart, n; where regStart = fn, arg1, ... let rb = instr.regB let rc = instr.regC - let prc = regs[rb].sym - let newPc = compile(c, prc) - var newFrame = PStackFrame(prc: prc, comesFrom: pc, next: tos) - newSeq(newFrame.slots, prc.position) - if not isEmptyType(prc.typ.sons[0]): - newFrame.slots[0] = getNullValue(prc.typ.sons[0], prc.info) - # pass every parameter by var (the language definition allows this): - for i in 1 .. rc-1: - newFrame.slots[i] = regs[rb+i] - # allocate the temporaries: - for i in rc .. <prc.position: - newFrame.slots[i] = newNode(nkEmpty) - tos = newFrame - move(regs, newFrame.slots) - # -1 for the following 'inc pc' - pc = newPc-1 + let isClosure = regs[rb].kind == nkPar + let prc = if not isClosure: regs[rb].sym else: regs[rb].sons[0].sym + if sfImportc in prc.flags: + if allowFFI notin c.features: + globalError(c.debug[pc], errGenerated, "VM not allowed to do FFI") + # we pass 'tos.slots' instead of 'regs' so that the compiler can keep + # 'regs' in a register: + when hasFFI: + let prcValue = c.globals.sons[prc.position-1] + if prcValue.kind == nkEmpty: + globalError(c.debug[pc], errGenerated, "canot run " & prc.name.s) + let newValue = callForeignFunction(prcValue, prc.typ, tos.slots, + rb+1, rc-1, c.debug[pc]) + if newValue.kind != nkEmpty: + assert instr.opcode == opcIndCallAsgn + asgnRef(regs[ra], newValue) + else: + globalError(c.debug[pc], errGenerated, "VM not built with FFI support") + elif prc.kind != skTemplate: + let newPc = compile(c, prc) + #echo "new pc ", newPc, " calling: ", prc.name.s + var newFrame = PStackFrame(prc: prc, comesFrom: pc, next: tos) + newSeq(newFrame.slots, prc.offset) + if not isEmptyType(prc.typ.sons[0]) or prc.kind == skMacro: + newFrame.slots[0] = getNullValue(prc.typ.sons[0], prc.info) + # pass every parameter by var (the language definition allows this): + for i in 1 .. rc-1: + newFrame.slots[i] = regs[rb+i] + if isClosure: + newFrame.slots[rc] = regs[rb].sons[1] + # allocate the temporaries: + for i in rc+ord(isClosure) .. <prc.offset: + newFrame.slots[i] = newNode(nkEmpty) + tos = newFrame + move(regs, newFrame.slots) + # -1 for the following 'inc pc' + pc = newPc-1 + else: + # for 'getAst' support we need to support template expansion here: + let genSymOwner = if tos.next != nil and tos.next.prc != nil: + tos.next.prc + else: + c.module + var macroCall = newNodeI(nkCall, c.debug[pc]) + macroCall.add(newSymNode(prc)) + for i in 1 .. rc-1: macroCall.add(regs[rb+i].skipMeta) + let a = evalTemplate(macroCall, prc, genSymOwner) + ensureKind(nkMetaNode) + setMeta(regs[ra], a) of opcTJmp: # jump Bx if A != 0 let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc' @@ -564,18 +698,18 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc' inc pc, rbx of opcBranch: - # we know the next instruction is a 'jmp': + # we know the next instruction is a 'fjmp': let branch = c.constants[instr.regBx-wordExcess] var cond = false for j in countup(0, sonsLen(branch) - 2): if overlap(regs[ra], branch.sons[j]): cond = true break - assert c.code[pc+1].opcode == opcJmp + assert c.code[pc+1].opcode == opcFJmp inc pc # we skip this instruction so that the final 'inc(pc)' skips # the following jump - if cond: + if not cond: let instr2 = c.code[pc] let rbx = instr2.regBx - wordExcess - 1 # -1 for the following 'inc pc' inc pc, rbx @@ -592,7 +726,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = of opcFinallyEnd: if c.currentExceptionA != nil: # we are in a cleanup run: - pc = cleanupOnException(c, tos, regs)-1 + pc = cleanUpOnException(c, tos, regs)-1 if pc < 0: bailOut(c, tos) return @@ -601,23 +735,24 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = c.currentExceptionA = raised c.exceptionInstr = pc # -1 because of the following 'inc' - pc = cleanupOnException(c, tos, regs) - 1 + pc = cleanUpOnException(c, tos, regs) - 1 if pc < 0: bailOut(c, tos) return of opcNew: let typ = c.types[instr.regBx - wordExcess] regs[ra] = getNullValue(typ, regs[ra].info) + regs[ra].flags.incl nfIsRef of opcNewSeq: let typ = c.types[instr.regBx - wordExcess] inc pc ensureKind(nkBracket) let instr2 = c.code[pc] - let rb = instr2.regA + let count = regs[instr2.regA].intVal.int regs[ra].typ = typ - newSeq(regs[ra].sons, rb) - for i in 0 .. <rb: - regs[ra].sons[i] = getNullValue(typ, regs[ra].info) + newSeq(regs[ra].sons, count) + for i in 0 .. <count: + regs[ra].sons[i] = getNullValue(typ.sons[0], regs[ra].info) of opcNewStr: decodeB(nkStrLit) regs[ra].strVal = newString(regs[rb].intVal.int) @@ -629,7 +764,11 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = let typ = c.types[instr.regBx - wordExcess] regs[ra] = getNullValue(typ, c.debug[pc]) of opcLdConst: - regs[ra] = c.constants.sons[instr.regBx - wordExcess] + let rb = instr.regBx - wordExcess + if regs[ra].isNil: + regs[ra] = copyTree(c.constants.sons[rb]) + else: + moveConst(regs[ra], c.constants.sons[rb]) of opcAsgnConst: let rb = instr.regBx - wordExcess if regs[ra].isNil: @@ -637,67 +776,111 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = else: asgnComplex(regs[ra], c.constants.sons[rb]) of opcLdGlobal: - let rb = instr.regBx - wordExcess + let rb = instr.regBx - wordExcess - 1 if regs[ra].isNil: regs[ra] = copyTree(c.globals.sons[rb]) else: asgnComplex(regs[ra], c.globals.sons[rb]) - of opcRepr, opcSetLenStr, opcSetLenSeq, - opcSwap, opcIsNil, opcOf, - opcCast, opcQuit, opcReset: + of opcRepr: + decodeB(nkStrLit) + regs[ra].strVal = renderTree(regs[rb].skipMeta, {renderNoComments}) + of opcQuit: + if c.mode in {emRepl, emStaticExpr, emStaticStmt}: + message(c.debug[pc], hintQuitCalled) + quit(int(getOrdValue(regs[ra]))) + else: + return nil + of opcSetLenStr: + decodeB(nkStrLit) + regs[ra].strVal.setLen(regs[rb].getOrdValue.int) + of opcOf: + decodeBC(nkIntLit) + let typ = c.types[regs[rc].intVal.int] + regs[ra].intVal = ord(inheritanceDiff(regs[rb].typ, typ) >= 0) + of opcIs: + decodeBC(nkIntLit) + let t1 = regs[rb].typ.skipTypes({tyTypeDesc}) + let t2 = c.types[regs[rc].intVal.int] + # XXX: This should use the standard isOpImpl + let match = if t2.kind == tyTypeClass: true + else: sameType(t1, t2) + regs[ra].intVal = ord(match) + of opcSetLenSeq: + decodeB(nkBracket) + let newLen = regs[rb].getOrdValue.int + setLen(regs[ra].sons, newLen) + of opcSwap, opcReset: internalError(c.debug[pc], "too implement") + of opcIsNil: + decodeB(nkIntLit) + regs[ra].intVal = ord(regs[rb].skipMeta.kind == nkNilLit) of opcNBindSym: - # trivial implementation: - let rb = instr.regB - regs[ra] = regs[rb].sons[1] + decodeBx(nkMetaNode) + setMeta(regs[ra], copyTree(c.constants.sons[rbx])) of opcNChild: - let rb = instr.regB - let rc = instr.regC - regs[ra] = regs[rb].sons[regs[rc].intVal.int] + decodeBC(nkMetaNode) + if regs[rb].kind != nkMetaNode: + internalError(c.debug[pc], "no MetaNode") + let idx = regs[rc].intVal.int + let src = regs[rb].uast + if src.kind notin {nkEmpty..nkNilLit} and idx <% src.len: + setMeta(regs[ra], src.sons[idx]) + else: + stackTrace(c, tos, pc, errIndexOutOfBounds) of opcNSetChild: - let rb = instr.regB - let rc = instr.regC - regs[ra].sons[regs[rb].intVal.int] = regs[rc] + decodeBC(nkMetaNode) + let idx = regs[rb].intVal.int + var dest = regs[ra].uast + if dest.kind notin {nkEmpty..nkNilLit} and idx <% dest.len: + dest.sons[idx] = regs[rc].uast + else: + stackTrace(c, tos, pc, errIndexOutOfBounds) of opcNAdd: - declBC() - regs[rb].add(regs[rb]) - regs[ra] = regs[rb] + decodeBC(nkMetaNode) + var u = regs[rb].uast + u.add(regs[rc].uast) + setMeta(regs[ra], u) of opcNAddMultiple: - declBC() + decodeBC(nkMetaNode) let x = regs[rc] + var u = regs[rb].uast # XXX can be optimized: - for i in 0.. <x.len: regs[rb].add(x.sons[i]) - regs[ra] = regs[rb] + for i in 0.. <x.len: u.add(x.sons[i].skipMeta) + setMeta(regs[ra], u) of opcNKind: decodeB(nkIntLit) - regs[ra].intVal = ord(regs[rb].kind) + regs[ra].intVal = ord(regs[rb].uast.kind) of opcNIntVal: decodeB(nkIntLit) - let a = regs[rb] + let a = regs[rb].uast case a.kind of nkCharLit..nkInt64Lit: regs[ra].intVal = a.intVal else: stackTrace(c, tos, pc, errFieldXNotFound, "intVal") of opcNFloatVal: decodeB(nkFloatLit) - let a = regs[rb] + let a = regs[rb].uast case a.kind of nkFloatLit..nkFloat64Lit: regs[ra].floatVal = a.floatVal else: stackTrace(c, tos, pc, errFieldXNotFound, "floatVal") of opcNSymbol: - let rb = instr.regB - if regs[rb].kind != nkSym: + decodeB(nkSym) + let a = regs[rb].uast + if a.kind == nkSym: + regs[ra].sym = a.sym + else: stackTrace(c, tos, pc, errFieldXNotFound, "symbol") - regs[ra] = regs[rb] of opcNIdent: - let rb = instr.regB - if regs[rb].kind != nkIdent: + decodeB(nkIdent) + let a = regs[rb].uast + if a.kind == nkIdent: + regs[ra].ident = a.ident + else: stackTrace(c, tos, pc, errFieldXNotFound, "ident") - regs[ra] = regs[rb] of opcNGetType: - InternalError(c.debug[pc], "unknown opcode " & $instr.opcode) + internalError(c.debug[pc], "unknown opcode " & $instr.opcode) of opcNStrVal: decodeB(nkStrLit) - let a = regs[rb] + let a = regs[rb].uast case a.kind of nkStrLit..nkTripleStrLit: regs[ra].strVal = a.strVal else: stackTrace(c, tos, pc, errFieldXNotFound, "strVal") @@ -710,29 +893,30 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = of opcNError: stackTrace(c, tos, pc, errUser, regs[ra].strVal) of opcNWarning: - Message(c.debug[pc], warnUser, regs[ra].strVal) + message(c.debug[pc], warnUser, regs[ra].strVal) of opcNHint: - Message(c.debug[pc], hintUser, regs[ra].strVal) + message(c.debug[pc], hintUser, regs[ra].strVal) of opcParseExprToAst: - let rb = instr.regB + decodeB(nkMetaNode) # c.debug[pc].line.int - countLines(regs[rb].strVal) ? let ast = parseString(regs[rb].strVal, c.debug[pc].toFilename, c.debug[pc].line.int) if sonsLen(ast) != 1: - GlobalError(c.debug[pc], errExprExpected, "multiple statements") - regs[ra] = ast.sons[0] + globalError(c.debug[pc], errExprExpected, "multiple statements") + setMeta(regs[ra], ast.sons[0]) of opcParseStmtToAst: - let rb = instr.regB + decodeB(nkMetaNode) let ast = parseString(regs[rb].strVal, c.debug[pc].toFilename, c.debug[pc].line.int) - regs[ra] = ast + setMeta(regs[ra], ast) of opcCallSite: - if c.callsite != nil: regs[ra] = c.callsite + ensureKind(nkMetaNode) + if c.callsite != nil: setMeta(regs[ra], c.callsite) else: stackTrace(c, tos, pc, errFieldXNotFound, "callsite") of opcNLineInfo: - let rb = instr.regB + decodeB(nkStrLit) let n = regs[rb] - regs[ra] = newStrNode(nkStrLit, n.info.toFileLineCol) + regs[ra].strVal = n.info.toFileLineCol regs[ra].info = c.debug[pc] of opcEqIdent: decodeBC(nkIntLit) @@ -741,16 +925,16 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = else: regs[ra].intVal = 0 of opcStrToIdent: - let rb = instr.regB + decodeB(nkIdent) if regs[rb].kind notin {nkStrLit..nkTripleStrLit}: stackTrace(c, tos, pc, errFieldXNotFound, "strVal") else: - regs[ra] = newNodeI(nkIdent, c.debug[pc]) + regs[ra].info = c.debug[pc] regs[ra].ident = getIdent(regs[rb].strVal) of opcIdentToStr: - let rb = instr.regB + decodeB(nkStrLit) let a = regs[rb] - regs[ra] = newNodeI(nkStrLit, c.debug[pc]) + regs[ra].info = c.debug[pc] if a.kind == nkSym: regs[ra].strVal = a.sym.name.s elif a.kind == nkIdent: @@ -767,84 +951,118 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame) = stackTrace(c, tos, pc, errGenerated, msgKindToString(errIllegalConvFromXtoY) % [ "unknown type" , "unknown type"]) - of opcNSetIntVal: + of opcCast: let rb = instr.regB - if regs[ra].kind in {nkCharLit..nkInt64Lit} and + inc pc + let typ = c.types[c.code[pc].regBx - wordExcess] + when hasFFI: + let dest = fficast(regs[rb], typ) + asgnRef(regs[ra], dest) + else: + globalError(c.debug[pc], "cannot evaluate cast") + of opcNSetIntVal: + decodeB(nkMetaNode) + var dest = regs[ra].uast + if dest.kind in {nkCharLit..nkInt64Lit} and regs[rb].kind in {nkCharLit..nkInt64Lit}: - regs[ra].intVal = regs[rb].intVal - else: + dest.intVal = regs[rb].intVal + else: stackTrace(c, tos, pc, errFieldXNotFound, "intVal") of opcNSetFloatVal: - let rb = instr.regB - if regs[ra].kind in {nkFloatLit..nkFloat64Lit} and + decodeB(nkMetaNode) + var dest = regs[ra].uast + if dest.kind in {nkFloatLit..nkFloat64Lit} and regs[rb].kind in {nkFloatLit..nkFloat64Lit}: - regs[ra].floatVal = regs[rb].floatVal + dest.floatVal = regs[rb].floatVal else: stackTrace(c, tos, pc, errFieldXNotFound, "floatVal") of opcNSetSymbol: - let rb = instr.regB - if regs[ra].kind == nkSym and regs[rb].kind == nkSym: - regs[ra].sym = regs[rb].sym + decodeB(nkMetaNode) + var dest = regs[ra].uast + if dest.kind == nkSym and regs[rb].kind == nkSym: + dest.sym = regs[rb].sym else: stackTrace(c, tos, pc, errFieldXNotFound, "symbol") of opcNSetIdent: - let rb = instr.regB - if regs[ra].kind == nkIdent and regs[rb].kind == nkIdent: - regs[ra].ident = regs[rb].ident + decodeB(nkMetaNode) + var dest = regs[ra].uast + if dest.kind == nkIdent and regs[rb].kind == nkIdent: + dest.ident = regs[rb].ident else: stackTrace(c, tos, pc, errFieldXNotFound, "ident") of opcNSetType: - let b = regs[instr.regB] - InternalAssert b.kind == nkSym and b.sym.kind == skType - regs[ra].typ = b.sym.typ + decodeB(nkMetaNode) + let b = regs[rb].skipMeta + internalAssert b.kind == nkSym and b.sym.kind == skType + regs[ra].uast.typ = b.sym.typ of opcNSetStrVal: - let rb = instr.regB - if regs[ra].kind in {nkStrLit..nkTripleStrLit} and + decodeB(nkMetaNode) + var dest = regs[ra].uast + if dest.kind in {nkStrLit..nkTripleStrLit} and regs[rb].kind in {nkStrLit..nkTripleStrLit}: - regs[ra].strVal = regs[rb].strVal + dest.strVal = regs[rb].strVal else: stackTrace(c, tos, pc, errFieldXNotFound, "strVal") of opcNNewNimNode: - let rb = instr.regB - let rc = instr.regC + decodeBC(nkMetaNode) var k = regs[rb].intVal - if k < 0 or k > ord(high(TNodeKind)): + if k < 0 or k > ord(high(TNodeKind)) or k == ord(nkMetaNode): internalError(c.debug[pc], - "request to create a NimNode with invalid kind") - regs[ra] = newNodeI(TNodeKind(int(k)), - if regs[rc].kind == nkNilLit: c.debug[pc] else: regs[rc].info) + "request to create a NimNode of invalid kind") + let cc = regs[rc].skipMeta + setMeta(regs[ra], newNodeI(TNodeKind(int(k)), + if cc.kind == nkNilLit: c.debug[pc] else: cc.info)) + regs[ra].sons[0].flags.incl nfIsRef of opcNCopyNimNode: - let rb = instr.regB - regs[ra] = copyNode(regs[rb]) + decodeB(nkMetaNode) + setMeta(regs[ra], copyNode(regs[rb])) of opcNCopyNimTree: - let rb = instr.regB - regs[ra] = copyTree(regs[rb]) + decodeB(nkMetaNode) + setMeta(regs[ra], copyTree(regs[rb])) of opcNDel: - let rb = instr.regB - let rc = instr.regC + decodeBC(nkMetaNode) + let bb = regs[rb].intVal.int for i in countup(0, regs[rc].intVal.int-1): - delSon(regs[ra], regs[rb].intVal.int) + delSon(regs[ra].uast, bb) of opcGenSym: - let k = regs[instr.regB].intVal - let b = regs[instr.regC] - let name = if b.strVal.len == 0: ":tmp" else: b.strVal + decodeBC(nkMetaNode) + let k = regs[rb].intVal + let name = if regs[rc].strVal.len == 0: ":tmp" else: regs[rc].strVal if k < 0 or k > ord(high(TSymKind)): internalError(c.debug[pc], "request to create symbol of invalid kind") - regs[ra] = newSymNode(newSym(k.TSymKind, name.getIdent, c.module, - c.debug[pc])) - incl(regs[ra].sym.flags, sfGenSym) + var sym = newSym(k.TSymKind, name.getIdent, c.module, c.debug[pc]) + incl(sym.flags, sfGenSym) + setMeta(regs[ra], newSymNode(sym)) of opcTypeTrait: # XXX only supports 'name' for now; we can use regC to encode the # type trait operation decodeB(nkStrLit) let typ = regs[rb].sym.typ.skipTypes({tyTypeDesc}) regs[ra].strVal = typ.typeToString(preferExported) + of opcGlobalOnce: + let rb = instr.regBx + if c.globals.sons[rb - wordExcess - 1].kind != nkEmpty: + # skip initialization instructions: + while true: + inc pc + if c.code[pc].opcode in {opcWrGlobal, opcWrGlobalRef} and + c.code[pc].regBx == rb: + break + of opcGlobalAlias: + let rb = instr.regBx - wordExcess - 1 + regs[ra] = c.globals.sons[rb] inc pc -proc execute(c: PCtx, start: int) = +proc fixType(result, n: PNode) {.inline.} = + # XXX do it deeply for complex values; there seems to be no simple + # solution except to check it deeply here. + #if result.typ.isNil: result.typ = n.typ + +proc execute(c: PCtx, start: int): PNode = var tos = PStackFrame(prc: nil, comesFrom: 0, next: nil) newSeq(tos.slots, c.prc.maxSlots) - rawExecute(c, start, tos) + for i in 0 .. <c.prc.maxSlots: tos.slots[i] = newNode(nkEmpty) + result = rawExecute(c, start, tos) proc evalStmt*(c: PCtx, n: PNode) = let start = genStmt(c, n) @@ -857,12 +1075,30 @@ proc evalExpr*(c: PCtx, n: PNode): PNode = let start = genExpr(c, n) assert c.code[start].opcode != opcEof result = execute(c, start) + if not result.isNil: + result = result.skipMeta + fixType(result, n) + +# for now we share the 'globals' environment. XXX Coming soon: An API for +# storing&loading the 'globals' environment to get what a component system +# requires. +var + globalCtx: PCtx + +proc setupGlobalCtx(module: PSym) = + if globalCtx.isNil: globalCtx = newCtx(module) + else: refresh(globalCtx, module) proc myOpen(module: PSym): PPassContext = #var c = newEvalContext(module, emRepl) #c.features = {allowCast, allowFFI, allowInfiniteLoops} #pushStackFrame(c, newStackFrame()) - result = newCtx(module) + + # XXX produce a new 'globals' environment here: + setupGlobalCtx(module) + result = globalCtx + when hasFFI: + globalCtx.features = {allowFFI, allowCast} var oldErrorCount: int @@ -875,50 +1111,70 @@ proc myProcess(c: PPassContext, n: PNode): PNode = result = n oldErrorCount = msgs.gErrorCounter -const vmPass* = makePass(myOpen, nil, myProcess, myProcess) +const evalPass* = makePass(myOpen, nil, myProcess, myProcess) -proc evalConstExprAux(module, prc: PSym, e: PNode, mode: TEvalMode): PNode = - var p = newCtx(module) - var s = newStackFrame() - s.call = e - s.prc = prc - pushStackFrame(p, s) - result = tryEval(p, e) - if result != nil and result.kind == nkExceptBranch: result = nil - popStackFrame(p) +proc evalConstExprAux(module, prc: PSym, n: PNode, mode: TEvalMode): PNode = + setupGlobalCtx(module) + var c = globalCtx + c.mode = mode + let start = genExpr(c, n, requiresValue = mode!=emStaticStmt) + assert c.code[start].opcode != opcEof + var tos = PStackFrame(prc: prc, comesFrom: 0, next: nil) + newSeq(tos.slots, c.prc.maxSlots) + for i in 0 .. <c.prc.maxSlots: tos.slots[i] = newNode(nkEmpty) + result = rawExecute(c, start, tos) + fixType(result, n) proc evalConstExpr*(module: PSym, e: PNode): PNode = result = evalConstExprAux(module, nil, e, emConst) -proc evalStaticExpr*(module: PSym, e: PNode, prc: PSym): PNode = - result = evalConstExprAux(module, prc, e, emStatic) +proc evalStaticExpr*(module: PSym, e: PNode, prc: PSym): PNode = + result = evalConstExprAux(module, prc, e, emStaticExpr) + +proc evalStaticStmt*(module: PSym, e: PNode, prc: PSym) = + discard evalConstExprAux(module, prc, e, emStaticStmt) proc setupMacroParam(x: PNode): PNode = result = x if result.kind in {nkHiddenSubConv, nkHiddenStdConv}: result = result.sons[1] + let y = result + y.flags.incl nfIsRef + result = newNode(nkMetaNode) + result.add y + result.typ = x.typ -proc evalMacroCall(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode = +var evalMacroCounter: int + +proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode = # XXX GlobalError() is ugly here, but I don't know a better solution for now - inc(evalTemplateCounter) - if evalTemplateCounter > 100: - GlobalError(n.info, errTemplateInstantiationTooNested) + inc(evalMacroCounter) + if evalMacroCounter > 100: + globalError(n.info, errTemplateInstantiationTooNested) + setupGlobalCtx(module) + var c = globalCtx c.callsite = nOrig - let body = optBody(c, sym) - let start = genStmt(c, body) + let start = genProc(c, sym) var tos = PStackFrame(prc: sym, comesFrom: 0, next: nil) - newSeq(tos.slots, c.prc.maxSlots) + let maxSlots = sym.offset + newSeq(tos.slots, maxSlots) # setup arguments: var L = n.safeLen if L == 0: L = 1 - InternalAssert tos.slots.len >= L + # This is wrong for tests/reject/tind1.nim where the passed 'else' part + # doesn't end up in the parameter: + #InternalAssert tos.slots.len >= L # return value: tos.slots[0] = newNodeIT(nkNilLit, n.info, sym.typ.sons[0]) # setup parameters: - for i in 1 .. < L: tos.slots[i] = setupMacroParam(n.sons[i]) - rawExecute(c, start, tos) - result = tos.slots[0] - if cyclicTree(result): GlobalError(n.info, errCyclicTree) - dec(evalTemplateCounter) + for i in 1 .. < min(tos.slots.len, L): + tos.slots[i] = setupMacroParam(n.sons[i]) + # temporary storage: + for i in L .. <maxSlots: tos.slots[i] = newNode(nkEmpty) + result = rawExecute(c, start, tos) + if cyclicTree(result): globalError(n.info, errCyclicTree) + dec(evalMacroCounter) + if result != nil: + result = result.skipMeta c.callsite = nil diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim index d4b3d891d..480c7f31b 100644 --- a/compiler/vmdef.nim +++ b/compiler/vmdef.nim @@ -51,16 +51,16 @@ type opcLenSeq, opcLenStr, - opcIncl, opcExcl, opcCard, opcMulInt, opcDivInt, opcModInt, + opcIncl, opcInclRange, opcExcl, opcCard, opcMulInt, opcDivInt, opcModInt, opcAddFloat, opcSubFloat, opcMulFloat, opcDivFloat, opcShrInt, opcShlInt, opcBitandInt, opcBitorInt, opcBitxorInt, opcAddu, opcSubu, opcMulu, opcDivu, opcModu, opcEqInt, opcLeInt, opcLtInt, opcEqFloat, - opcLeFloat, opcLtFloat, opcLeu, opcLtu, opcEqRef, opcXor, + opcLeFloat, opcLtFloat, opcLeu, opcLtu, opcEqRef, opcEqNimrodNode, opcXor, opcNot, opcUnaryMinusInt, opcUnaryMinusFloat, opcBitnotInt, opcEqStr, opcLeStr, opcLtStr, opcEqSet, opcLeSet, opcLtSet, opcMulSet, opcPlusSet, opcMinusSet, opcSymdiffSet, opcConcatStr, opcContainsSet, opcRepr, opcSetLenStr, opcSetLenSeq, - opcSwap, opcIsNil, opcOf, + opcSwap, opcIsNil, opcOf, opcIs, opcSubStr, opcConv, opcCast, opcQuit, opcReset, opcAddStrCh, @@ -101,7 +101,6 @@ type opcRaise, opcNChild, opcNSetChild, - opcNBindSym, # opcodes for the AST manipulation following opcCallSite, opcNewStr, @@ -120,8 +119,11 @@ type opcAsgnConst, # dest = copy(constants[Bx]) opcLdGlobal, # dest = globals[Bx] opcLdImmInt, # dest = immediate value + opcNBindSym, opcWrGlobal, opcWrGlobalRef, + opcGlobalAlias, # load an alias to a global into a register + opcGlobalOnce, # used to introduce an assignment to a global once opcSetType, # dest.typ = types[Bx] opcTypeTrait @@ -129,6 +131,21 @@ type label*: PSym fixups*: seq[TPosition] + TEvalMode* = enum ## reason for evaluation + emRepl, ## evaluate because in REPL mode + emConst, ## evaluate for 'const' according to spec + emOptimize, ## evaluate for optimization purposes (same as + ## emConst?) + emStaticExpr, ## evaluate for enforced compile time eval + ## ('static' context) + emStaticStmt ## 'static' as an expression + + TSandboxFlag* = enum ## what the evaluation engine should allow + allowCast, ## allow unsafe language feature: 'cast' + allowFFI, ## allow the FFI + allowInfiniteLoops ## allow endless loops + TSandboxFlags* = set[TSandboxFlag] + TSlotKind* = enum # We try to re-use slots in a smart way to # minimize allocations; however the VM supports arbitrary # temporary slot usage. This is required for the parameter @@ -146,6 +163,8 @@ type blocks*: seq[TBlock] # blocks; temp data structure slots*: array[TRegister, tuple[inUse: bool, kind: TSlotKind]] maxSlots*: int + globals*: array[TRegister, int] # hack: to support passing globals byref + # we map a slot persistently to a global PCtx* = ref TCtx TCtx* = object of passes.TPassContext # code gen context @@ -160,21 +179,26 @@ type prc*: PProc module*: PSym callsite*: PNode + mode*: TEvalMode + features*: TSandboxFlags TPosition* = distinct int PEvalContext* = PCtx - proc newCtx*(module: PSym): PCtx = PCtx(code: @[], debug: @[], - globals: newNode(nkStmtList), constants: newNode(nkStmtList), types: @[], + globals: newNode(nkStmtListExpr), constants: newNode(nkStmtList), types: @[], prc: PProc(blocks: @[]), module: module) +proc refresh*(c: PCtx, module: PSym) = + c.module = module + c.prc = PProc(blocks: @[]) + const firstABxInstr* = opcTJmp largeInstrs* = { # instructions which use 2 int32s instead of 1: - opcSubstr, opcConv, opcCast, opcNewSeq, opcOf} + opcSubStr, opcConv, opcCast, opcNewSeq, opcOf} slotSomeTemp* = slotTempUnknown relativeJumps* = {opcTJmp, opcFJmp, opcJmp} @@ -183,3 +207,5 @@ template regA*(x: TInstr): TRegister {.immediate.} = TRegister(x.uint32 shr 8'u3 template regB*(x: TInstr): TRegister {.immediate.} = TRegister(x.uint32 shr 16'u32 and 0xff'u32) template regC*(x: TInstr): TRegister {.immediate.} = TRegister(x.uint32 shr 24'u32) template regBx*(x: TInstr): int {.immediate.} = (x.uint32 shr 16'u32).int + +template jmpDiff*(x: TInstr): int {.immediate.} = regBx(x) - wordExcess diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index 2a40276d1..0e01f5031 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -25,69 +25,12 @@ proc opGorge*(cmd, input: string): string = proc opSlurp*(file: string, info: TLineInfo, module: PSym): string = try: - let filename = file.FindFile + let filename = file.findFile result = readFile(filename) # we produce a fake include statement for every slurped filename, so that # the module dependencies are accurate: appendToModule(module, newNode(nkIncludeStmt, info, @[ newStrNode(nkStrLit, filename)])) except EIO: + localError(info, errCannotOpenFile, file) result = "" - LocalError(info, errCannotOpenFile, file) - -when false: - proc opExpandToAst*(c: PEvalContext, original: PNode): PNode = - var - n = original.copyTree - macroCall = n.sons[1] - expandedSym = macroCall.sons[0].sym - - for i in countup(1, macroCall.sonsLen - 1): - macroCall.sons[i] = evalAux(c, macroCall.sons[i], {}) - - case expandedSym.kind - of skTemplate: - let genSymOwner = if c.tos != nil and c.tos.prc != nil: - c.tos.prc - else: - c.module - result = evalTemplate(macroCall, expandedSym, genSymOwner) - of skMacro: - # At this point macroCall.sons[0] is nkSym node. - # To be completely compatible with normal macro invocation, - # we want to replace it with nkIdent node featuring - # the original unmangled macro name. - macroCall.sons[0] = newIdentNode(expandedSym.name, expandedSym.info) - result = evalMacroCall(c, macroCall, original, expandedSym) - else: - InternalError(macroCall.info, - "ExpandToAst: expanded symbol is no macro or template") - result = emptyNode - - proc opIs*(n: PNode): PNode = - InternalAssert n.sonsLen == 3 and - n[1].kind == nkSym and n[1].sym.kind == skType and - n[2].kind in {nkStrLit..nkTripleStrLit, nkType} - - let t1 = n[1].sym.typ - - if n[2].kind in {nkStrLit..nkTripleStrLit}: - case n[2].strVal.normalize - of "closure": - let t = skipTypes(t1, abstractRange) - result = newIntNode(nkIntLit, ord(t.kind == tyProc and - t.callConv == ccClosure and - tfIterator notin t.flags)) - of "iterator": - let t = skipTypes(t1, abstractRange) - result = newIntNode(nkIntLit, ord(t.kind == tyProc and - t.callConv == ccClosure and - tfIterator in t.flags)) - else: - let t2 = n[2].typ - var match = if t2.kind == tyTypeClass: matchTypeClass(t2, t1) - else: sameType(t1, t2) - result = newIntNode(nkIntLit, ord(match)) - - result.typ = n.typ - diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 84d82e117..aea05bb2c 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -11,19 +11,22 @@ import unsigned, strutils, ast, astalgo, types, msgs, renderer, vmdef, - trees, intsets, rodread, magicsys + trees, intsets, rodread, magicsys, options -proc codeListing(c: PCtx, result: var string) = +when hasFFI: + import evalffi + +proc codeListing(c: PCtx, result: var string, start=0) = # first iteration: compute all necessary labels: var jumpTargets = initIntSet() - for i in 0.. < c.code.len: + for i in start.. < c.code.len: let x = c.code[i] if x.opcode in relativeJumps: jumpTargets.incl(i+x.regBx-wordExcess) # for debugging purposes - var i = 0 + var i = start while i < c.code.len: if i in jumpTargets: result.addf("L$1:\n", i) let x = c.code[i] @@ -45,9 +48,9 @@ proc codeListing(c: PCtx, result: var string) = result.add("\n") inc i -proc echoCode*(c: PCtx) = +proc echoCode*(c: PCtx, start=0) {.deprecated.} = var buf = "" - codeListing(c, buf) + codeListing(c, buf, start) echo buf proc gABC(ctx: PCtx; n: PNode; opc: TOpcode; a, b, c: TRegister = 0) = @@ -58,7 +61,7 @@ proc gABC(ctx: PCtx; n: PNode; opc: TOpcode; a, b, c: TRegister = 0) = ctx.code.add(ins) ctx.debug.add(n.info) -proc gABI(c: PCtx; n: PNode; opc: TOpcode; a, b: TRegister; imm: biggestInt) = +proc gABI(c: PCtx; n: PNode; opc: TOpcode; a, b: TRegister; imm: BiggestInt) = let ins = (opc.uint32 or (a.uint32 shl 8'u32) or (b.uint32 shl 16'u32) or (imm+byteExcess).uint32 shl 24'u32).TInstr @@ -82,7 +85,7 @@ proc genLabel(c: PCtx): TPosition = proc jmpBack(c: PCtx, n: PNode, opc: TOpcode, p = TPosition(0)) = let dist = p.int - c.code.len - InternalAssert(-0x7fff < dist and dist < 0x7fff) + internalAssert(-0x7fff < dist and dist < 0x7fff) gABx(c, n, opc, 0, dist) proc patch(c: PCtx, p: TPosition) = @@ -90,7 +93,7 @@ proc patch(c: PCtx, p: TPosition) = let p = p.int let diff = c.code.len - p #c.jumpTargets.incl(c.code.len) - InternalAssert(-0x7fff < diff and diff < 0x7fff) + internalAssert(-0x7fff < diff and diff < 0x7fff) let oldInstr = c.code[p] # opcode and regA stay the same: c.code[p] = ((oldInstr.uint32 and 0xffff'u32).uint32 or @@ -112,8 +115,10 @@ const proc getTemp(c: PCtx; typ: PType): TRegister = let c = c.prc - # we prefer the same slot kind here for efficiency: - let k = typ.getSlotKind + # we prefer the same slot kind here for efficiency. Unfortunately for + # discardable return types we may not know the desired type. This can happen + # for e.g. mNAdd[Multiple]: + let k = if typ.isNil: slotTempComplex else: typ.getSlotKind for i in 0 .. c.maxSlots-1: if c.slots[i].kind == k and not c.slots[i].inUse: c.slots[i].inUse = true @@ -129,6 +134,21 @@ proc getTemp(c: PCtx; typ: PType): TRegister = c.slots[c.maxSlots] = (inUse: true, kind: k) inc c.maxSlots +proc getGlobalSlot(c: PCtx; n: PNode; s: PSym): TRegister = + let p = c.prc + for i in 0 .. p.maxSlots-1: + if p.globals[i] == s.id: return TRegister(i) + + result = TRegister(p.maxSlots) + p.slots[p.maxSlots] = (inUse: true, kind: slotFixedVar) + p.globals[p.maxSlots] = s.id + inc p.maxSlots + # XXX this is still not correct! We need to load the global in a proc init + # section, otherwise control flow could lead to a usage before it's been + # loaded. + c.gABx(n, opcGlobalAlias, result, s.position) + # XXX add some internal asserts here + proc freeTemp(c: PCtx; r: TRegister) = let c = c.prc if c.slots[r].kind >= slotSomeTemp: c.slots[r].inUse = false @@ -146,7 +166,7 @@ proc getTempRange(c: PCtx; n: int; kind: TSlotKind): TRegister = for k in result .. result+n-1: c.slots[k] = (inUse: true, kind: kind) return if c.maxSlots+n >= high(TRegister): - InternalError("cannot generate code; too many registers required") + internalError("cannot generate code; too many registers required") result = TRegister(c.maxSlots) inc c.maxSlots, n for k in result .. result+n-1: c.slots[k] = (inUse: true, kind: kind) @@ -174,18 +194,24 @@ proc gen(c: PCtx; n: PNode; dest: var TDest) proc gen(c: PCtx; n: PNode; dest: TRegister) = var d: TDest = dest gen(c, n, d) - InternalAssert d == dest + internalAssert d == dest proc gen(c: PCtx; n: PNode) = var tmp: TDest = -1 gen(c, n, tmp) - InternalAssert tmp < 0 + #if n.typ.isEmptyType: InternalAssert tmp < 0 proc genx(c: PCtx; n: PNode): TRegister = var tmp: TDest = -1 gen(c, n, tmp) + internalAssert tmp >= 0 result = TRegister(tmp) +proc clearDest(n: PNode; dest: var TDest) {.inline.} = + # stmt is different from 'void' in meta programming contexts. + # So we only set dest to -1 if 'void': + if n.typ.isNil or n.typ.kind == tyEmpty: dest = -1 + proc isNotOpr(n: PNode): bool = n.kind in nkCallKinds and n.sons[0].kind == nkSym and n.sons[0].sym.magic == mNot @@ -224,6 +250,7 @@ proc genWhile(c: PCtx; n: PNode) = proc genBlock(c: PCtx; n: PNode; dest: var TDest) = withBlock(n.sons[0].sym): c.gen(n.sons[1], dest) + clearDest(n, dest) proc genBreak(c: PCtx; n: PNode) = let L1 = c.xjmp(n, opcJmp) @@ -233,7 +260,7 @@ proc genBreak(c: PCtx; n: PNode) = if c.prc.blocks[i].label == n.sons[0].sym: c.prc.blocks[i].fixups.add L1 return - InternalError(n.info, "cannot find 'break' target") + internalError(n.info, "cannot find 'break' target") else: c.prc.blocks[c.prc.blocks.high].fixups.add L1 @@ -268,6 +295,7 @@ proc genIf(c: PCtx, n: PNode; dest: var TDest) = else: c.gen(it.sons[0], dest) for endPos in endings: c.patch(endPos) + clearDest(n, dest) proc genAndOr(c: PCtx; n: PNode; opc: TOpcode; dest: var TDest) = # asgn dest, a @@ -275,15 +303,15 @@ proc genAndOr(c: PCtx; n: PNode; opc: TOpcode; dest: var TDest) = # asgn dest, b # L1: if dest < 0: dest = getTemp(c, n.typ) - c.gen(n.sons[0], dest) - let L1 = c.xjmp(n, opc) c.gen(n.sons[1], dest) + let L1 = c.xjmp(n, opc, dest) + c.gen(n.sons[2], dest) c.patch(L1) proc rawGenLiteral(c: PCtx; n: PNode): int = result = c.constants.len c.constants.add n - InternalAssert result < 0x7fff + internalAssert result < 0x7fff proc sameConstant*(a, b: PNode): bool = result = false @@ -296,7 +324,8 @@ proc sameConstant*(a, b: PNode): bool = of nkCharLit..nkInt64Lit: result = a.intVal == b.intVal of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal - of nkEmpty, nkNilLit, nkType: result = true + of nkType: result = a.typ == b.typ + of nkEmpty, nkNilLit: result = true else: if sonsLen(a) == sonsLen(b): for i in countup(0, sonsLen(a) - 1): @@ -309,6 +338,11 @@ proc genLiteral(c: PCtx; n: PNode): int = if sameConstant(c.constants[i], n): return i result = rawGenLiteral(c, n) +proc unused(n: PNode; x: TDest) {.inline.} = + if x >= 0: + #debug(n) + internalError(n.info, "not unused") + proc genCase(c: PCtx; n: PNode; dest: var TDest) = # if (!expr1) goto L1; # thenPart @@ -320,7 +354,10 @@ proc genCase(c: PCtx; n: PNode; dest: var TDest) = # L2: # elsePart # Lend: - if dest < 0 and not isEmptyType(n.typ): dest = getTemp(c, n.typ) + if not isEmptyType(n.typ): + if dest < 0: dest = getTemp(c, n.typ) + else: + unused(n, dest) var endings: seq[TPosition] = @[] withTemp(tmp, n.sons[0].typ): c.gen(n.sons[0], tmp) @@ -340,6 +377,7 @@ proc genCase(c: PCtx; n: PNode; dest: var TDest) = endings.add(c.xjmp(it.lastSon, opcJmp, 0)) c.patch(elsePos) for endPos in endings: c.patch(endPos) + clearDest(n, dest) proc genType(c: PCtx; typ: PType): int = for i, t in c.types: @@ -379,6 +417,7 @@ proc genTry(c: PCtx; n: PNode; dest: var TDest) = if fin.kind == nkFinally: c.gen(fin.sons[0], dest) c.gABx(fin, opcFinallyEnd, 0, 0) + clearDest(n, dest) proc genRaise(c: PCtx; n: PNode) = let dest = genx(c, n.sons[0]) @@ -393,30 +432,57 @@ proc genReturn(c: PCtx; n: PNode) = proc genCall(c: PCtx; n: PNode; dest: var TDest) = if dest < 0 and not isEmptyType(n.typ): dest = getTemp(c, n.typ) let x = c.getTempRange(n.len, slotTempUnknown) - for i in 0.. <n.len: + # varargs need 'opcSetType' for the FFI support: + let fntyp = n.sons[0].typ + for i in 0.. <n.len: var r: TRegister = x+i c.gen(n.sons[i], r) + if i >= fntyp.len: + internalAssert tfVarargs in fntyp.flags + c.gABx(n, opcSetType, r, c.genType(n.sons[i].typ)) if dest < 0: c.gABC(n, opcIndCall, 0, x, n.len) else: c.gABC(n, opcIndCallAsgn, dest, x, n.len) c.freeTempRange(x, n.len) +proc needsAsgnPatch(n: PNode): bool = + n.kind in {nkBracketExpr, nkDotExpr, nkCheckedFieldExpr} + +proc genAsgnPatch(c: PCtx; le: PNode, value: TRegister) = + case le.kind + of nkBracketExpr: + let dest = c.genx(le.sons[0]) + let idx = c.genx(le.sons[1]) + c.gABC(le, opcWrArrRef, dest, idx, value) + of nkDotExpr, nkCheckedFieldExpr: + # XXX field checks here + let left = if le.kind == nkDotExpr: le else: le.sons[0] + let dest = c.genx(left.sons[0]) + let idx = c.genx(left.sons[1]) + c.gABC(left, opcWrObjRef, dest, idx, value) + else: + discard + proc genNew(c: PCtx; n: PNode) = - let dest = c.genx(n.sons[1]) + let dest = if needsAsgnPatch(n.sons[1]): c.getTemp(n.sons[1].typ) + else: c.genx(n.sons[1]) # we use the ref's base type here as the VM conflates 'ref object' # and 'object' since internally we already have a pointer. c.gABx(n, opcNew, dest, c.genType(n.sons[1].typ.skipTypes(abstractVar).sons[0])) + c.genAsgnPatch(n.sons[1], dest) c.freeTemp(dest) proc genNewSeq(c: PCtx; n: PNode) = - let dest = c.genx(n.sons[1]) + let dest = if needsAsgnPatch(n.sons[1]): c.getTemp(n.sons[1].typ) + else: c.genx(n.sons[1]) c.gABx(n, opcNewSeq, dest, c.genType(n.sons[1].typ.skipTypes(abstractVar))) let tmp = c.genx(n.sons[2]) c.gABx(n, opcNewSeq, tmp, 0) - c.freeTemp(dest) c.freeTemp(tmp) + c.genAsgnPatch(n.sons[1], dest) + c.freeTemp(dest) proc genUnaryABC(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) = let tmp = c.genx(n.sons[1]) @@ -463,7 +529,7 @@ proc genBinaryStmt(c: PCtx; n: PNode; opc: TOpcode) = c.freeTemp(tmp) proc genUnaryStmt(c: PCtx; n: PNode; opc: TOpcode) = - let tmp = c.genx(n.sons[2]) + let tmp = c.genx(n.sons[1]) c.gABC(n, opc, tmp, 0, 0) c.freeTemp(tmp) @@ -493,9 +559,6 @@ proc genAddSubInt(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) = else: genBinaryABC(c, n, dest, opc) -proc unused(n: PNode; x: TDest) {.inline.} = - if x >= 0: InternalError(n.info, "not unused") - proc genConv(c: PCtx; n, arg: PNode; dest: var TDest; opc=opcConv) = let tmp = c.genx(arg) c.gABx(n, opcSetType, tmp, genType(c, arg.typ)) @@ -508,7 +571,7 @@ proc genCard(c: PCtx; n: PNode; dest: var TDest) = let tmp = c.genx(n.sons[1]) if dest < 0: dest = c.getTemp(n.typ) c.genSetType(n.sons[1], tmp) - c.gABC(n, opc, dest, tmp) + c.gABC(n, opcCard, dest, tmp) c.freeTemp(tmp) proc genMagic(c: PCtx; n: PNode; dest: var TDest) = @@ -529,6 +592,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = unused(n, dest) var d = c.genx(n.sons[1]).TDest c.genAddSubInt(n, d, if m == mInc: opcAddInt else: opcSubInt) + c.genAsgnPatch(n.sons[1], d) c.freeTemp(d.TRegister) of mOrd, mChr, mArrToSeq: c.gen(n.sons[1], dest) of mNew, mNewFinalize: @@ -624,6 +688,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = var d = c.genx(n.sons[1]) var tmp = c.genx(n.sons[2]) c.gABC(n, if m == mSetLengthStr: opcSetLenStr else: opcSetLenSeq, d, tmp) + c.genAsgnPatch(n.sons[1], d) c.freeTemp(tmp) of mSwap: unused(n, dest) @@ -639,8 +704,8 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = tmp2 = c.genx(n.sons[2]) tmp3 = c.getTemp(n.sons[2].typ) c.gABC(n, opcLenStr, tmp3, tmp1) - c.gABC(n, opcSubstr, dest, tmp1, tmp2) - c.gABC(n, opcSubstr, tmp3) + c.gABC(n, opcSubStr, dest, tmp1, tmp2) + c.gABC(n, opcSubStr, tmp3) c.freeTemp(tmp1) c.freeTemp(tmp2) c.freeTemp(tmp3) @@ -650,8 +715,8 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = tmp1 = c.genx(n.sons[1]) tmp2 = c.genx(n.sons[2]) tmp3 = c.genx(n.sons[3]) - c.gABC(n, opcSubstr, dest, tmp1, tmp2) - c.gABC(n, opcSubstr, tmp3) + c.gABC(n, opcSubStr, dest, tmp1, tmp2) + c.gABC(n, opcSubStr, tmp3) c.freeTemp(tmp1) c.freeTemp(tmp2) c.freeTemp(tmp3) @@ -659,14 +724,18 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = unused(n, dest) var d = c.genx(n.sons[1]) c.gABC(n, opcReset, d) - of mOf: + of mOf, mIs: if dest < 0: dest = c.getTemp(n.typ) var tmp = c.genx(n.sons[1]) - c.gABC(n, opcOf, dest, tmp) - c.gABx(n, opcOf, 0, c.genType(n.sons[2].typ.skipTypes(abstractPtrs))) + var idx = c.getTemp(getSysType(tyInt)) + var typ = n.sons[2].typ + if m == mOf: typ = typ.skipTypes(abstractPtrs) + c.gABx(n, opcLdImmInt, idx, c.genType(typ)) + c.gABC(n, if m == mOf: opcOf else: opcIs, dest, tmp, idx) c.freeTemp(tmp) + c.freeTemp(idx) of mSizeOf: - GlobalError(n.info, errCannotInterpretNodeX, renderTree(n)) + globalError(n.info, errCannotInterpretNodeX, renderTree(n)) of mHigh: if dest < 0: dest = c.getTemp(n.typ) let tmp = c.genx(n.sons[1]) @@ -696,16 +765,12 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = genUnaryABC(c, n, dest, opcParseExprToAst) of mParseStmtToAst: genUnaryABC(c, n, dest, opcParseStmtToAst) - of mExpandToAst: - InternalError(n.info, "cannot generate code for: " & $m) of mTypeTrait: let tmp = c.genx(n.sons[1]) if dest < 0: dest = c.getTemp(n.typ) - c.gABx(n, opcSetType, tmp, c.genType(n.sons[1])) + c.gABx(n, opcSetType, tmp, c.genType(n.sons[1].typ)) c.gABC(n, opcTypeTrait, dest, tmp) c.freeTemp(tmp) - of mIs: - InternalError(n.info, "cannot generate code for: " & $m) of mSlurp: genUnaryABC(c, n, dest, opcSlurp) of mStaticExec: genBinaryABC(c, n, dest, opcGorge) of mNLen: genUnaryABI(c, n, dest, opcLenSeq) @@ -750,11 +815,17 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = of mNNewNimNode: genBinaryABC(c, n, dest, opcNNewNimNode) of mNCopyNimNode: genUnaryABC(c, n, dest, opcNCopyNimNode) of mNCopyNimTree: genUnaryABC(c, n, dest, opcNCopyNimTree) - of mNBindSym: genUnaryABC(c, n, dest, opcNBindSym) + of mNBindSym: + if n[1].kind in {nkClosedSymChoice, nkOpenSymChoice, nkSym}: + let idx = c.genLiteral(n[1]) + if dest < 0: dest = c.getTemp(n.typ) + c.gABx(n, opcNBindSym, dest, idx) + else: + internalError(n.info, "invalid bindSym usage") of mStrToIdent: genUnaryABC(c, n, dest, opcStrToIdent) of mIdentToStr: genUnaryABC(c, n, dest, opcIdentToStr) of mEqIdent: genBinaryABC(c, n, dest, opcEqIdent) - of mEqNimrodNode: genBinaryABC(c, n, dest, opcEqRef) + of mEqNimrodNode: genBinaryABC(c, n, dest, opcEqNimrodNode) of mNLineInfo: genUnaryABC(c, n, dest, opcNLineInfo) of mNHint: unused(n, dest) @@ -771,13 +842,27 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = of mNGenSym: genBinaryABC(c, n, dest, opcGenSym) of mMinI, mMaxI, mMinI64, mMaxI64, mAbsF64, mMinF64, mMaxF64, mAbsI, mAbsI64: c.genCall(n, dest) + clearDest(n, dest) + of mExpandToAst: + if n.len != 2: + globalError(n.info, errGenerated, "expandToAst requires 1 argument") + let arg = n.sons[1] + if arg.kind in nkCallKinds: + #if arg[0].kind != nkSym or arg[0].sym.kind notin {skTemplate, skMacro}: + # "ExpandToAst: expanded symbol is no macro or template" + if dest < 0: dest = c.getTemp(n.typ) + c.genCall(arg, dest) + # do not call clearDest(n, dest) here as getAst has a meta-type as such + # produces a value + else: + globalError(n.info, "expandToAst requires a call expression") else: # mGCref, mGCunref, - InternalError(n.info, "cannot generate code for: " & $m) + internalError(n.info, "cannot generate code for: " & $m) const atomicTypes = {tyBool, tyChar, - tyExpr, tyStmt, tyTypeDesc, + tyExpr, tyStmt, tyTypeDesc, tyStatic, tyEnum, tyOrdinal, tyRange, @@ -823,7 +908,7 @@ proc whichAsgnOpc(n: PNode): TOpcode = opcAsgnStr of tyFloat..tyFloat128: opcAsgnFloat - of tyRef, tyNil: + of tyRef, tyNil, tyVar: opcAsgnRef else: opcAsgnComplex @@ -839,6 +924,8 @@ proc genAsgn(c: PCtx; dest: TDest; ri: PNode; requiresCopy: bool) = gABC(c, ri, whichAsgnOpc(ri), dest, tmp) c.freeTemp(tmp) +template isGlobal(s: PSym): bool = sfGlobal in s.flags and s.kind != skForVar + proc genAsgn(c: PCtx; le, ri: PNode; requiresCopy: bool) = case le.kind of nkBracketExpr: @@ -850,20 +937,22 @@ proc genAsgn(c: PCtx; le, ri: PNode; requiresCopy: bool) = else: c.gABC(le, whichAsgnOpc(le, opcWrArr), dest, idx, tmp) c.freeTemp(tmp) - of nkDotExpr: - let dest = c.genx(le.sons[0]) - let idx = c.genx(le.sons[1]) + of nkDotExpr, nkCheckedFieldExpr: + # XXX field checks here + let left = if le.kind == nkDotExpr: le else: le.sons[0] + let dest = c.genx(left.sons[0]) + let idx = c.genx(left.sons[1]) let tmp = c.genx(ri) - c.gABC(le, whichAsgnOpc(le, opcWrObj), dest, idx, tmp) + c.gABC(left, whichAsgnOpc(left, opcWrObj), dest, idx, tmp) c.freeTemp(tmp) of nkSym: let s = le.sym - if sfGlobal in s.flags: + if s.isGlobal: withTemp(tmp, le.typ): gen(c, ri, tmp) c.gABx(le, whichAsgnOpc(le, opcWrGlobal), tmp, s.position) else: - InternalAssert s.position > 0 or (s.position == 0 and + internalAssert s.position > 0 or (s.position == 0 and s.kind in {skParam, skResult}) var dest: TRegister = s.position + ord(s.kind == skParam) gen(c, ri, dest) @@ -878,15 +967,52 @@ proc genLit(c: PCtx; n: PNode; dest: var TDest) = let lit = genLiteral(c, n) c.gABx(n, opc, dest, lit) +proc genTypeLit(c: PCtx; t: PType; dest: var TDest) = + var n = newNode(nkType) + n.typ = t + genLit(c, n, dest) + +proc importcSym(c: PCtx; info: TLineInfo; s: PSym) = + when hasFFI: + if allowFFI in c.features: + c.globals.add(importcSymbol(s)) + s.position = c.globals.len + else: + localError(info, errGenerated, "VM is not allowed to 'importc'") + else: + localError(info, errGenerated, + "cannot 'importc' variable at compile time") + +proc cannotEval(n: PNode) {.noinline.} = + globalError(n.info, errGenerated, "cannot evaluate at compile time: " & + n.renderTree) + +proc genGlobalInit(c: PCtx; n: PNode; s: PSym) = + c.globals.add(emptyNode.copyNode) + s.position = c.globals.len + # This is rather hard to support, due to the laziness of the VM code + # generator. See tests/compile/tmacro2 for why this is necesary: + # var decls{.compileTime.}: seq[PNimrodNode] = @[] + c.gABx(n, opcGlobalOnce, 0, s.position) + let tmp = c.genx(s.ast) + c.gABx(n, whichAsgnOpc(n, opcWrGlobal), tmp, s.position) + c.freeTemp(tmp) + proc genRdVar(c: PCtx; n: PNode; dest: var TDest) = let s = n.sym - if sfGlobal in s.flags: - if dest < 0: dest = c.getTemp(s.typ) + if s.isGlobal: + if sfCompileTime in s.flags or c.mode == emRepl: + discard + else: + cannotEval(n) if s.position == 0: - c.globals.add(s.ast) - s.position = c.globals.len - # XXX var g = codeHere() ? - c.gABx(n, opcLdGlobal, dest, s.position) + if sfImportc in s.flags: c.importcSym(n.info, s) + else: genGlobalInit(c, n, s) + if dest < 0: + dest = c.getGlobalSlot(n, s) + #c.gABx(n, opcAliasGlobal, dest, s.position) + else: + c.gABx(n, opcLdGlobal, dest, s.position) else: if s.position > 0 or (s.position == 0 and s.kind in {skParam, skResult}): if dest < 0: @@ -895,7 +1021,9 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest) = # we need to generate an assignment: genAsgn(c, dest, n, c.prc.slots[dest].kind >= slotSomeTemp) else: - InternalError(n.info, s.name.s & " " & $s.position) + # see tests/t99bott for an example that triggers it: + cannotEval(n) + #InternalError(n.info, s.name.s & " " & $s.position) proc genAccess(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) = let a = c.genx(n.sons[0]) @@ -908,6 +1036,10 @@ proc genAccess(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) = proc genObjAccess(c: PCtx; n: PNode; dest: var TDest) = genAccess(c, n, dest, opcLdObj) +proc genCheckedObjAccess(c: PCtx; n: PNode; dest: var TDest) = + # XXX implement field checks! + genAccess(c, n.sons[0], dest, opcLdObj) + proc genArrAccess(c: PCtx; n: PNode; dest: var TDest) = if n.sons[0].typ.skipTypes(abstractVarRange).kind in {tyString, tyCString}: genAccess(c, n, dest, opcLdStrIdx) @@ -925,7 +1057,7 @@ proc getNullValueAux(obj: PNode, result: PNode) = getNullValueAux(lastSon(obj.sons[i]), result) of nkSym: addSon(result, getNullValue(obj.sym.typ, result.info)) - else: InternalError(result.info, "getNullValueAux") + else: internalError(result.info, "getNullValueAux") proc getNullValue(typ: PType, info: TLineInfo): PNode = var t = skipTypes(typ, abstractRange-{tyTypeDesc}) @@ -936,10 +1068,17 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode = of tyUInt..tyUInt64: result = newNodeIT(nkUIntLit, info, t) of tyFloat..tyFloat128: - result = newNodeIt(nkFloatLit, info, t) - of tyVar, tyPointer, tyPtr, tyCString, tySequence, tyString, tyExpr, - tyStmt, tyTypeDesc, tyProc, tyRef: + result = newNodeIT(nkFloatLit, info, t) + of tyVar, tyPointer, tyPtr, tyCString, tySequence, tyString, tyExpr, + tyStmt, tyTypeDesc, tyStatic, tyRef: result = newNodeIT(nkNilLit, info, t) + of tyProc: + if t.callConv != ccClosure: + result = newNodeIT(nkNilLit, info, t) + else: + result = newNodeIT(nkPar, info, t) + result.add(newNodeIT(nkNilLit, info, t)) + result.add(newNodeIT(nkNilLit, info, t)) of tyObject: result = newNodeIT(nkPar, info, t) getNullValueAux(t.n, result) @@ -958,7 +1097,7 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode = addSon(result, getNullValue(t.sons[i], info)) of tySet: result = newNodeIT(nkCurly, info, t) - else: InternalError("getNullValue: " & $t.kind) + else: internalError("getNullValue: " & $t.kind) proc setSlot(c: PCtx; v: PSym) = # XXX generate type initialization here? @@ -984,11 +1123,14 @@ proc genVarSection(c: PCtx; n: PNode) = c.freeTemp(tmp) elif a.sons[0].kind == nkSym: let s = a.sons[0].sym - if sfGlobal in s.flags: + if s.isGlobal: if s.position == 0: - let sa = if s.ast.isNil: getNullValue(s.typ, a.info) else: s.ast - c.globals.add(sa) - s.position = c.globals.len + if sfImportc in s.flags: c.importcSym(a.info, s) + else: + let sa = if s.ast.isNil: getNullValue(s.typ, a.info) else: s.ast + c.globals.add(sa) + s.position = c.globals.len + # "Once support" is unnecessary here if a.sons[2].kind == nkEmpty: when false: withTemp(tmp, s.typ): @@ -1016,23 +1158,31 @@ proc genVarSection(c: PCtx; n: PNode) = proc genArrayConstr(c: PCtx, n: PNode, dest: var TDest) = if dest < 0: dest = c.getTemp(n.typ) c.gABx(n, opcLdNull, dest, c.genType(n.typ)) - let intType = getSysType(tyInt) - var tmp = getTemp(c, intType) - c.gABx(n, opcLdNull, tmp, c.genType(intType)) - for x in n: - let a = c.genx(x) - c.gABC(n, opcWrArr, dest, a, tmp) - c.gABI(n, opcAddImmInt, tmp, tmp, 1) - c.freeTemp(a) - c.freeTemp(tmp) + if n.len > 0: + let intType = getSysType(tyInt) + var tmp = getTemp(c, intType) + c.gABx(n, opcLdNull, tmp, c.genType(intType)) + for x in n: + let a = c.genx(x) + c.gABC(n, whichAsgnOpc(x, opcWrArr), dest, tmp, a) + c.gABI(n, opcAddImmInt, tmp, tmp, 1) + c.freeTemp(a) + c.freeTemp(tmp) proc genSetConstr(c: PCtx, n: PNode, dest: var TDest) = if dest < 0: dest = c.getTemp(n.typ) c.gABx(n, opcLdNull, dest, c.genType(n.typ)) for x in n: - let a = c.genx(x) - c.gABC(n, opcIncl, dest, a) - c.freeTemp(a) + if x.kind == nkRange: + let a = c.genx(x.sons[0]) + let b = c.genx(x.sons[1]) + c.gABC(n, opcInclRange, dest, a, b) + c.freeTemp(b) + c.freeTemp(a) + else: + let a = c.genx(x) + c.gABC(n, opcIncl, dest, a) + c.freeTemp(a) proc genObjConstr(c: PCtx, n: PNode, dest: var TDest) = if dest < 0: dest = c.getTemp(n.typ) @@ -1054,7 +1204,8 @@ proc genObjConstr(c: PCtx, n: PNode, dest: var TDest) = proc genTupleConstr(c: PCtx, n: PNode, dest: var TDest) = if dest < 0: dest = c.getTemp(n.typ) - var idx = getTemp(c, getSysType(tyInt)) + c.gABx(n, opcLdNull, dest, c.genType(n.typ)) + # XXX x = (x.old, 22) produces wrong code ... stupid self assignments for i in 0.. <n.len: let it = n.sons[i] if it.kind == nkExprColonExpr: @@ -1065,10 +1216,8 @@ proc genTupleConstr(c: PCtx, n: PNode, dest: var TDest) = c.freeTemp(idx) else: let tmp = c.genx(it) - c.gABx(it, opcLdImmInt, idx, i) - c.gABC(it, whichAsgnOpc(it, opcWrObj), dest, idx, tmp) + c.gABC(it, whichAsgnOpc(it, opcWrObj), dest, i.TRegister, tmp) c.freeTemp(tmp) - c.freeTemp(idx) proc genProc*(c: PCtx; s: PSym): int @@ -1079,7 +1228,9 @@ proc gen(c: PCtx; n: PNode; dest: var TDest) = case s.kind of skVar, skForVar, skTemp, skLet, skParam, skResult: genRdVar(c, n, dest) - of skProc, skConverter, skMacro, skMethod, skIterator: + of skProc, skConverter, skMacro, skTemplate, skMethod, skIterator: + # 'skTemplate' is only allowed for 'getAst' support: + if sfImportc in s.flags: c.importcSym(n.info, s) genLit(c, n, dest) of skConst: gen(c, s.ast, dest) @@ -1091,29 +1242,36 @@ proc gen(c: PCtx; n: PNode; dest: var TDest) = var lit = genLiteral(c, newIntNode(nkIntLit, s.position)) c.gABx(n, opcLdConst, dest, lit) of skField: - InternalAssert dest < 0 + internalAssert dest < 0 if s.position > high(dest): - InternalError(n.info, + internalError(n.info, "too large offset! cannot generate code for: " & s.name.s) dest = s.position + of skType: + genTypeLit(c, s.typ, dest) else: - InternalError(n.info, "cannot generate code for: " & s.name.s) + internalError(n.info, "cannot generate code for: " & s.name.s) of nkCallKinds: if n.sons[0].kind == nkSym and n.sons[0].sym.magic != mNone: genMagic(c, n, dest) else: genCall(c, n, dest) + clearDest(n, dest) of nkCharLit..nkInt64Lit: if isInt16Lit(n): if dest < 0: dest = c.getTemp(n.typ) c.gABx(n, opcLdImmInt, dest, n.intVal.int) else: genLit(c, n, dest) - of nkUIntLit..nkNilLit: genLit(c, n, dest) + of nkUIntLit..pred(nkNilLit): genLit(c, n, dest) + of nkNilLit: + if not n.typ.isEmptyType: genLit(c, n, dest) + else: unused(n, dest) of nkAsgn, nkFastAsgn: unused(n, dest) genAsgn(c, n.sons[0], n.sons[1], n.kind == nkAsgn) of nkDotExpr: genObjAccess(c, n, dest) + of nkCheckedFieldExpr: genCheckedObjAccess(c, n, dest) of nkBracketExpr: genArrAccess(c, n, dest) of nkDerefExpr, nkHiddenDeref: genAddrDeref(c, n, dest, opcDeref) of nkAddr, nkHiddenAddr: genAddrDeref(c, n, dest, opcAddr) @@ -1168,7 +1326,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest) = else: dest = tmp0 of nkEmpty, nkCommentStmt, nkTypeSection, nkConstSection, nkPragma, - nkTemplateDef, nkIncludeStmt, nkImportStmt: + nkTemplateDef, nkIncludeStmt, nkImportStmt, nkFromStmt: unused(n, dest) of nkStringToCString, nkCStringToString: gen(c, n.sons[0], dest) @@ -1176,8 +1334,13 @@ proc gen(c: PCtx; n: PNode; dest: var TDest) = of nkCurly: genSetConstr(c, n, dest) of nkObjConstr: genObjConstr(c, n, dest) of nkPar, nkClosure: genTupleConstr(c, n, dest) + of nkCast: + if allowCast in c.features: + genConv(c, n, n.sons[1], dest, opcCast) + else: + localError(n.info, errGenerated, "VM is not allowed to 'cast'") else: - InternalError n.info, "too implement " & $n.kind + internalError n.info, "too implement " & $n.kind proc removeLastEof(c: PCtx) = let last = c.code.len-1 @@ -1193,14 +1356,16 @@ proc genStmt*(c: PCtx; n: PNode): int = var d: TDest = -1 c.gen(n, d) c.gABC(n, opcEof) - InternalAssert d < 0 + if d >= 0: internalError(n.info, "some destination set") -proc genExpr*(c: PCtx; n: PNode): int = +proc genExpr*(c: PCtx; n: PNode, requiresValue = true): int = c.removeLastEof result = c.code.len var d: TDest = -1 c.gen(n, d) - InternalAssert d >= 0 + if d < 0: + if requiresValue: internalError(n.info, "no destination set") + d = 0 c.gABC(n, opcEof, d) proc genParams(c: PCtx; params: PNode) = @@ -1212,7 +1377,7 @@ proc genParams(c: PCtx; params: PNode) = c.prc.maxSlots = max(params.len, 1) proc finalJumpTarget(c: PCtx; pc, diff: int) = - InternalAssert(-0x7fff < diff and diff < 0x7fff) + internalAssert(-0x7fff < diff and diff < 0x7fff) let oldInstr = c.code[pc] # opcode and regA stay the same: c.code[pc] = ((oldInstr.uint32 and 0xffff'u32).uint32 or @@ -1225,12 +1390,11 @@ proc optimizeJumps(c: PCtx; start: int) = case opc of opcTJmp, opcFJmp: var reg = c.code[i].regA - var d = i + c.code[i].regBx - var iters = maxIterations - while iters > 0: + var d = i + c.code[i].jmpDiff + for iters in countdown(maxIterations, 0): case c.code[d].opcode of opcJmp: - d = d + c.code[d].regBx + d = d + c.code[d].jmpDiff of opcTJmp, opcFJmp: if c.code[d].regA != reg: break # tjmp x, 23 @@ -1238,28 +1402,40 @@ proc optimizeJumps(c: PCtx; start: int) = # tjmp x, 12 # -- we know 'x' is true, and so can jump to 12+13: if c.code[d].opcode == opc: - d = d + c.code[d].regBx + d = d + c.code[d].jmpDiff else: # tjmp x, 23 # fjmp x, 22 # We know 'x' is true so skip to the next instruction: d = d + 1 else: break - dec iters - c.finalJumpTarget(i, d - i) + if d != i + c.code[i].jmpDiff: + c.finalJumpTarget(i, d - i) of opcJmp: - var d = i + c.code[i].regBx + var d = i + c.code[i].jmpDiff var iters = maxIterations while c.code[d].opcode == opcJmp and iters > 0: - d = d + c.code[d].regBx + d = d + c.code[d].jmpDiff dec iters - c.finalJumpTarget(i, d - i) + if c.code[d].opcode == opcRet: + # optimize 'jmp to ret' to 'ret' here + c.code[i] = c.code[d] + elif d != i + c.code[i].jmpDiff: + c.finalJumpTarget(i, d - i) else: discard proc genProc(c: PCtx; s: PSym): int = let x = s.ast.sons[optimizedCodePos] if x.kind == nkEmpty: - c.removeLastEof + #if s.name.s == "outterMacro" or s.name.s == "innerProc": + # echo "GENERATING CODE FOR ", s.name.s + let last = c.code.len-1 + var eofInstr: TInstr + if last >= 0 and c.code[last].opcode == opcEof: + eofInstr = c.code[last] + c.code.setLen(last) + c.debug.setLen(last) + #c.removeLastEof result = c.code.len+1 # skip the jump instruction s.ast.sons[optimizedCodePos] = newIntNode(nkIntLit, result) # thanks to the jmp we can add top level statements easily and also nest @@ -1271,13 +1447,22 @@ proc genProc(c: PCtx; s: PSym): int = c.prc = p # iterate over the parameters and allocate space for them: genParams(c, s.typ.n) + if tfCapturesEnv in s.typ.flags: + #let env = s.ast.sons[paramsPos].lastSon.sym + #assert env.position == 2 + c.prc.slots[c.prc.maxSlots] = (inUse: true, kind: slotFixedLet) + inc c.prc.maxSlots gen(c, body) # generate final 'return' statement: c.gABC(body, opcRet) c.patch(procStart) - c.gABC(body, opcEof) - s.position = c.prc.maxSlots + c.gABC(body, opcEof, eofInstr.regA) + c.optimizeJumps(result) + s.offset = c.prc.maxSlots + #if s.name.s == "rawGet": + # c.echoCode(result) + # echo renderTree(body) c.prc = oldPrc - #c.echoCode else: + c.prc.maxSlots = s.offset result = x.intVal.int diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index 39b19646e..837bb4f50 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -28,9 +28,9 @@ type wElif, wElse, wEnd, wEnum, wExcept, wExport, wFinally, wFor, wFrom, wGeneric, wIf, wImport, wIn, wInclude, wInterface, wIs, wIsnot, wIterator, wLambda, wLet, - wMacro, wMethod, wMixin, wUsing, wMod, wNil, + wMacro, wMethod, wMixin, wMod, wNil, wNot, wNotin, wObject, wOf, wOr, wOut, wProc, wPtr, wRaise, wRef, wReturn, - wShared, wShl, wShr, wStatic, wTemplate, wTry, wTuple, wType, wVar, + wShared, wShl, wShr, wStatic, wTemplate, wTry, wTuple, wType, wUsing, wVar, wWhen, wWhile, wWith, wWithout, wXor, wYield, wColon, wColonColon, wEquals, wDot, wDotDot, @@ -95,7 +95,7 @@ const cppNimSharedKeywords* = { wAsm, wBreak, wCase, wConst, wContinue, wDo, wElse, wEnum, wExport, - wFor, wIf, wReturn, wStatic, wTemplate, wTry, wWhile, wUsing } + wFor, wIf, wReturn, wStatic, wTemplate, wTry, wWhile, wUsing} specialWords*: array[low(TSpecialWord)..high(TSpecialWord), string] = ["", @@ -107,11 +107,11 @@ const "finally", "for", "from", "generic", "if", "import", "in", "include", "interface", "is", "isnot", "iterator", "lambda", "let", - "macro", "method", "mixin", "using", "mod", "nil", "not", "notin", + "macro", "method", "mixin", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc", "ptr", "raise", "ref", "return", "shared", "shl", "shr", "static", - "template", "try", "tuple", "type", "var", + "template", "try", "tuple", "type", "using", "var", "when", "while", "with", "without", "xor", "yield", @@ -166,7 +166,7 @@ const "inout", "bycopy", "byref", "oneway", ] -proc findStr*(a: openarray[string], s: string): int = +proc findStr*(a: openArray[string], s: string): int = for i in countup(low(a), high(a)): if cmpIgnoreStyle(a[i], s) == 0: return i @@ -176,7 +176,7 @@ proc whichKeyword*(id: PIdent): TSpecialWord = if id.id < 0: result = wInvalid else: result = TSpecialWord(id.id) -proc whichKeyword*(id: String): TSpecialWord = +proc whichKeyword*(id: string): TSpecialWord = result = whichKeyword(getIdent(id)) proc initSpecials() = diff --git a/config/nimrod.cfg b/config/nimrod.cfg index 37024f3de..2817eac55 100644 --- a/config/nimrod.cfg +++ b/config/nimrod.cfg @@ -27,6 +27,7 @@ path="$lib/wrappers/readline" path="$lib/wrappers/sdl" # path="$lib/wrappers/x11" path="$lib/wrappers/zip" +path="$lib/wrappers/libffi" path="$lib/windows" path="$lib/posix" path="$lib/js" diff --git a/doc/keywords.txt b/doc/keywords.txt index fa3ce4786..2d18d7969 100644 --- a/doc/keywords.txt +++ b/doc/keywords.txt @@ -7,13 +7,14 @@ finally for from generic if import in include interface is isnot iterator lambda let -macro method mixin using mod +macro method mixin mod nil not notin object of or out proc ptr raise ref return shared shl shr static template try tuple type +using var when while with without xor diff --git a/doc/lib.txt b/doc/lib.txt index 92a4a7c83..ba0cb0a90 100644 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -227,7 +227,12 @@ Parsers ------- * `parseopt <parseopt.html>`_ - The ``parseopt`` module implements a command line option parser. This + The ``parseopt`` module implements a command line option parser. + **Deprecated since version 0.9.3:** Use the `parseopt2 + <parseopt2.html>`_ module instead. + +* `parseopt2 <parseopt2.html>`_ + The ``parseopt2`` module implements a command line option parser. This supports long and short command options with optional values and command line arguments. @@ -381,9 +386,6 @@ Database support * `db_mongo <db_mongo.html>`_ A higher level **mongodb** wrapper. -* `mongodb <mongo.html>`_ - Lower level wrapper for the **mongodb** client C library. - Other ----- @@ -446,45 +448,6 @@ UNIX specific * `posix <posix.html>`_ Contains a wrapper for the POSIX standard. -* `cursorfont <cursorfont.html>`_ - Part of the wrapper for X11. -* `keysym <keysym.html>`_ - Part of the wrapper for X11. -* `x <x.html>`_ - Part of the wrapper for X11. -* `xatom <xatom.html>`_ - Part of the wrapper for X11. -* `xcms <xcms.html>`_ - Part of the wrapper for X11. -* `xf86dga <xf86dga.html>`_ - Part of the wrapper for X11. -* `xf86vmode <xf86vmode.html>`_ - Part of the wrapper for X11. -* `xi <xi.html>`_ - Part of the wrapper for X11. -* `xinerama <xinerama.html>`_ - Part of the wrapper for X11. -* `xkb <xkb.html>`_ - Part of the wrapper for X11. -* `xkblib <xkblib.html>`_ - Part of the wrapper for X11. -* `xlib <xlib.html>`_ - Part of the wrapper for X11. -* `xrandr <xrandr.html>`_ - Part of the wrapper for X11. -* `xrender <xrender.html>`_ - Part of the wrapper for X11. -* `xresource <xresource.html>`_ - Part of the wrapper for X11. -* `xshm <xshm.html>`_ - Part of the wrapper for X11. -* `xutil <xutil.html>`_ - Part of the wrapper for X11. -* `xv <xv.html>`_ - Part of the wrapper for X11. -* `xvlib <xvlib.html>`_ - Part of the wrapper for X11. - * `readline <readline.html>`_ Part of the wrapper for the GNU readline library. * `history <history.html>`_ @@ -505,15 +468,6 @@ Regular expressions Graphics libraries ------------------ -* `cairo <cairo.html>`_ - Wrapper for the cairo library. -* `cairoft <cairoft.html>`_ - Wrapper for the cairoft library. -* `cairowin32 <cairowin32.html>`_ - Wrapper for the cairowin32 library. -* `cairoxlib <cairoxlib.html>`_ - Wrapper for the cairoxlib library. - * `sdl <sdl.html>`_ Part of the wrapper for SDL. * `sdl_gfx <sdl_gfx.html>`_ @@ -529,47 +483,10 @@ Graphics libraries * `smpeg <smpeg.html>`_ Part of the wrapper for SDL. -* `gl <gl.html>`_ - Part of the wrapper for OpenGL. -* `glext <glext.html>`_ - Part of the wrapper for OpenGL. -* `glu <glu.html>`_ - Part of the wrapper for OpenGL. -* `glut <glut.html>`_ - Part of the wrapper for OpenGL. -* `glx <glx.html>`_ - Part of the wrapper for OpenGL. -* `wingl <wingl.html>`_ - Part of the wrapper for OpenGL. - -* `opengl <opengl.html>`_ - New wrapper for OpenGL supporting up to version 4.2. - GUI libraries ------------- -* `atk <atk.html>`_ - Wrapper for the atk library. -* `gdk2 <gdk2.html>`_ - Wrapper for the gdk2 library. -* `gdk2pixbuf <gdk2pixbuf.html>`_ - Wrapper for the gdk2pixbuf library. -* `gdkglext <gdkglext.html>`_ - Wrapper for the gdkglext library. -* `glib2 <glib2.html>`_ - Wrapper for the glib2 library. -* `gtk2 <gtk2.html>`_ - Wrapper for the gtk2 library. -* `gtkglext <gtkglext.html>`_ - Wrapper for the gtkglext library. -* `gtkhtml <gtkhtml.html>`_ - Wrapper for the gtkhtml library. -* `libglade2 <libglade2.html>`_ - Wrapper for the libglade2 library. -* `pango <pango.html>`_ - Wrapper for the pango library. -* `pangoutils <pangoutils.html>`_ - Wrapper for the pangoutils library. + * `iup <iup.html>`_ Wrapper of the IUP GUI library. @@ -583,6 +500,8 @@ Database support Contains a wrapper for the mySQL API. * `sqlite3 <sqlite3.html>`_ Contains a wrapper for SQLite 3 API. +* `mongodb <mongo.html>`_ + Lower level wrapper for the **mongodb** client C library. * `odbcsql <odbcsql.html>`_ interface to the ODBC driver. * `sphinx <sphinx.html>`_ @@ -612,21 +531,6 @@ Network Programming and Internet Protocols Wrapper for OpenSSL. -Scripting languages -------------------- - -* `lua <lua.html>`_ - Part of the wrapper for Lua. -* `lualib <lualib.html>`_ - Part of the wrapper for Lua. -* `lauxlib <lauxlib.html>`_ - Part of the wrapper for Lua. -* `tcl <tcl.html>`_ - Wrapper for the TCL programming language. -* `python <python.html>`_ - Wrapper for the Python programming language. - - Data Compression and Archiving ------------------------------ diff --git a/doc/manual.txt b/doc/manual.txt index 0a9aec8d0..f6dd1f521 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -312,14 +312,39 @@ Character literals ------------------ Character literals are enclosed in single quotes ``''`` and can contain the -same escape sequences as strings - with one exception: ``\n`` is not allowed -as it may be wider than one character (often it is the pair CR/LF for example). +same escape sequences as strings - with one exception: `newline`:idx: (``\n``) +is not allowed as it may be wider than one character (often it is the pair +CR/LF for example). Here are the valid `escape sequences`:idx: for character +literals: + +================== =================================================== + Escape sequence Meaning +================== =================================================== + ``\r``, ``\c`` `carriage return`:idx: + ``\l`` `line feed`:idx: + ``\f`` `form feed`:idx: + ``\t`` `tabulator`:idx: + ``\v`` `vertical tabulator`:idx: + ``\\`` `backslash`:idx: + ``\"`` `quotation mark`:idx: + ``\'`` `apostrophe`:idx: + ``\`` '0'..'9'+ `character with decimal value d`:idx:; + all decimal digits directly + following are used for the character + ``\a`` `alert`:idx: + ``\b`` `backspace`:idx: + ``\e`` `escape`:idx: `[ESC]`:idx: + ``\x`` HH `character with hex value HH`:idx:; + exactly two hex digits are allowed +================== =================================================== + A character is not an Unicode character but a single byte. The reason for this is efficiency: for the overwhelming majority of use-cases, the resulting programs will still handle UTF-8 properly as UTF-8 was specially designed for -this. -Another reason is that Nimrod can thus support ``array[char, int]`` or -``set[char]`` efficiently as many algorithms rely on this feature. +this. Another reason is that Nimrod can thus support ``array[char, int]`` or +``set[char]`` efficiently as many algorithms rely on this feature. The `TRune` +type is used for Unicode characters, it can represent any Unicode character. +``TRune`` is declared in the `unicode module <unicode.html>`_. Numerical constants @@ -750,7 +775,8 @@ designed for this. Another reason is that Nimrod can support ``array[char, int]`` or ``set[char]`` efficiently as many algorithms rely on this feature. The `TRune` type is used for Unicode characters, it can represent any Unicode -character. ``TRune`` is declared in the ``unicode`` module. +character. ``TRune`` is declared in the `unicode module <unicode.html>`_. + @@ -847,8 +873,8 @@ arrays, they can be used in case statements: Per convention, all strings are UTF-8 strings, but this is not enforced. For example, when reading strings from binary files, they are merely a sequence of bytes. The index operation ``s[i]`` means the i-th *char* of ``s``, not the -i-th *unichar*. The iterator ``runes`` from the ``unicode`` -module can be used for iteration over all Unicode characters. +i-th *unichar*. The iterator ``runes`` from the `unicode module +<unicode.html>`_ can be used for iteration over all Unicode characters. CString type @@ -1268,12 +1294,13 @@ exclude ``nil`` as a valid value with the `not nil`:idx: annotation: # compiler catches this: p(nil) - # but not this: + # and also this: var x: PObject p(x) -As shown in the example this is merely an annotation for documentation purposes; -for now the compiler can only catch the most trivial type violations. +The compiler ensures that every code path initializes variables which contain +not nilable pointers. The details of this analysis are still to be specified +here. Procedural type @@ -1504,8 +1531,8 @@ The ``void`` type is particularly useful for generic code: else: p(x) - proc intProc(x: int) = nil - proc emptyProc() = nil + proc intProc(x: int) = discard + proc emptyProc() = discard callProc[int](intProc, 12) callProc[void](emptyProc) @@ -1767,6 +1794,15 @@ been declared with the `discardable`:idx: pragma: p(3, 4) # now valid +An empty ``discard`` statement is often used as a null statement: + +.. code-block:: nimrod + proc classify(s: string) = + case s[0] + of SymChars, '_': echo "an identifier" + of '0'..'9': echo "a number" + else: discard + Var statement ------------- @@ -1816,7 +1852,7 @@ If a proc is annotated with the ``noinit`` pragma this refers to its implicit ``result`` variable: .. code-block:: nimrod - proc returnUndefinedValue: int {.noinit.} = nil + proc returnUndefinedValue: int {.noinit.} = discard The implicit initialization can be also prevented by the `requiresInit`:idx: @@ -2196,12 +2232,12 @@ Instead of: Using statement --------------- -The using statement provides syntactic convenience for procs that heavily use a -single contextual parameter. When applied to a variable or a constant, it will -instruct Nimrod to automatically consider the used symbol as a hidden leading -parameter for any procedure calls, following the using statement in the current -scope. Thus, it behaves much like the hidden `this` parameter available in some -object-oriented programming languages. +The `using statement`:idx: provides syntactic convenience for procs that +heavily use a single contextual parameter. When applied to a variable or a +constant, it will instruct Nimrod to automatically consider the used symbol as +a hidden leading parameter for any procedure calls, following the using +statement in the current scope. Thus, it behaves much like the hidden `this` +parameter available in some object-oriented programming languages. .. code-block:: nimrod @@ -2224,6 +2260,24 @@ from different modules having the same name. import windows, sdl using sdl.SetTimer +Note that ``using`` only *adds* to the current context, it doesn't remove or +replace, **neither** does it create a new scope. What this means is that if you +apply this to multiple variables the compiler will find conflicts in what +variable to use: + +.. code-block:: nimrod + var a, b = "kill it" + using a + add(" with fire") + using b + add(" with water") + echo a + echo b + +When the compiler reaches the second ``add`` call, both ``a`` and ``b`` could +be used with the proc, so you get ``Error: expression '(a|b)' has no type (or +is ambiguous)``. To solve this you would need to nest ``using`` with a +``block`` statement so as to control the reach of the ``using`` statement. If expression ------------- @@ -3207,7 +3261,7 @@ Nimrod also allows for type classes and regular types to be specified as `type constraints`:idx: of the generic type parameter: .. code-block:: nimrod - proc onlyIntOrString[T: int|string](x, y: T) = nil + proc onlyIntOrString[T: int|string](x, y: T) = discard onlyIntOrString(450, 616) # valid onlyIntOrString(5.0, 0.0) # type mismatch @@ -3782,7 +3836,7 @@ regular expressions: macro case_token(n: stmt): stmt = # creates a lexical analyzer from regular expressions # ... (implementation is an exercise for the reader :-) - nil + discard case_token: # this colon tells the parser it is a macro statement of r"[A-Za-z_]+[A-Za-z_0-9]*": @@ -3811,22 +3865,76 @@ Whole routines (procs, iterators etc.) can also be passed to a template or a macro via the pragma notation: .. code-block:: nimrod - template m(s: stmt) = nil + template m(s: stmt) = discard - proc p() {.m.} = nil + proc p() {.m.} = discard This is a simple syntactic transformation into: .. code-block:: nimrod - template m(s: stmt) = nil + template m(s: stmt) = discard m: - proc p() = nil + proc p() = discard Special Types ============= +static[T] +--------- + +As their name suggests, static params must be known at compile-time: + +.. code-block:: nimrod + + proc precompiledRegex(pattern: static[string]): TRegEx = + var res {.global.} = re(pattern) + return res + + precompiledRegex("/d+") # Replaces the call with a precompiled + # regex, stored in a global variable + + precompiledRegex(paramStr(1)) # Error, command-line options + # are not known at compile-time + + +For the purposes of code generation, all static params are treated as +generic params - the proc will be compiled separately for each unique +supplied value (or combination of values). + +Furthermore, the system module defines a `semistatic[T]` type than can be +used to declare procs accepting both static and run-time values, which can +optimize their body according to the supplied param using the `isStatic(p)` +predicate: + +.. code-block:: nimrod + + # The following proc will be compiled once for each unique static + # value and also once for the case handling all run-time values: + + proc re(pattern: semistatic[string]): TRegEx = + when isStatic(pattern): + return precompiledRegex(pattern) + else: + return compile(pattern) + +Static params can also appear in the signatures of generic types: + +.. code-block:: nimrod + + type + Matrix[M,N: static[int]; T: Number] = array[0..(M*N - 1), T] + # Please, note how `Number` is just a type constraint here, while + # `static[int]` requires us to supply a compile-time int value + + AffineTransform2D[T] = Matrix[3, 3, T] + AffineTransform3D[T] = Matrix[4, 4, T] + + AffineTransform3D[float] # OK + AffineTransform2D[string] # Error, `string` is not a `Number` + + typedesc -------- @@ -4142,9 +4250,9 @@ all the arguments, but also the matched operators in reverse polish notation: TMatrix = object dummy: int - proc `*`(a, b: TMatrix): TMatrix = nil - proc `+`(a, b: TMatrix): TMatrix = nil - proc `-`(a, b: TMatrix): TMatrix = nil + proc `*`(a, b: TMatrix): TMatrix = discard + proc `+`(a, b: TMatrix): TMatrix = discard + proc `-`(a, b: TMatrix): TMatrix = discard proc `$`(a: TMatrix): string = result = $a.dummy proc mat21(): TMatrix = result.dummy = 21 @@ -4564,6 +4672,8 @@ the support of destructors. delegator pragma ---------------- +**Note**: The design of the delegator feature is subject to change. + The delegator pragma can be used to intercept and rewrite proc call and field access attempts referring to previously undeclared symbol names. It can be used to provide a fluent interface to objects lying outside the static confines of diff --git a/doc/subexes.txt b/doc/subexes.txt index 3565dbf43..10e0f4cc1 100644 --- a/doc/subexes.txt +++ b/doc/subexes.txt @@ -14,7 +14,9 @@ Thanks to its conditional construct ``$[0|1|2|else]`` it supports Notation meaning ===================== ===================================================== ``$#`` use first or next argument -``$name`` use named argument +``$name`` use named argument, you can wrap the named argument + in curly braces (eg. ``${name}``) to separate it from + the next characters. ``$1`` use first argument ``$-1`` use last argument ``${1..3}`` use arguments 1 to 3 diff --git a/doc/tut1.txt b/doc/tut1.txt index 2070c69d6..2e7f9d27f 100644 --- a/doc/tut1.txt +++ b/doc/tut1.txt @@ -202,6 +202,12 @@ statement and all the variables will have the same value: echo "x ", x # outputs "x 42" echo "y ", y # outputs "y 3" +Note that declaring multiple variables with a single assignment which calls a +procedure can have unexpected results: the compiler will *unroll* the +assignments and end up calling the procedure several times. If the result of +the procedure depends on side effects, your variables may end up having +different values! For safety use only constant values. + Constants ========= @@ -807,7 +813,11 @@ important differences: However, you can also use a ``closure`` iterator to get a different set of restrictions. See `first class iterators <manual.html#first-class-iterators>`_ -for details. +for details. Iterators can have the same name and parameters as a proc, +essentially they have their own namespace. Therefore it is common practice to +wrap iterators in procs of the same name which accumulate the result of the +iterator and return it as a sequence, like ``split`` from the `strutils module +<strutils.html>`_. Basic types @@ -1582,6 +1592,17 @@ rules apply: write(stdout, x(3)) # ambiguous: which `x` is to call? +Excluding symbols +----------------- + +The normal ``import`` statement will bring in all exported symbols. +These can be limited by naming symbols which should be excluded with +the ``except`` qualifier. + +.. code-block:: nimrod + import mymodule except y + + From statement -------------- @@ -1592,6 +1613,30 @@ exported symbols. An alternative that only imports listed symbols is the .. code-block:: nimrod from mymodule import x, y, z +The ``from`` statement can also force namespace qualification on +symbols, thereby making symbols available, but needing to be qualified +to be used. + +.. code-block:: nimrod + from mymodule import x, y, z + + x() # use x without any qualification + +.. code-block:: nimrod + from mymodule import nil + + mymodule.x() # must qualify x with the module name as prefix + + x() # using x here without qualification is a compile error + +Since module names are generally long to be descriptive, you can also +define a shorter alias to use when qualifying symbols. + +.. code-block:: nimrod + from mymodule as m import nil + + m.x() # m is aliasing mymodule + Include statement ----------------- diff --git a/koch.nim b/koch.nim index 3b13690fa..1814a0efc 100644 --- a/koch.nim +++ b/koch.nim @@ -1,7 +1,7 @@ # # # Maintenance program for Nimrod -# (c) Copyright 2013 Andreas Rumpf +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -26,7 +26,7 @@ const +-----------------------------------------------------------------+ | Maintenance program for Nimrod | | Version $1| -| (c) 2013 Andreas Rumpf | +| (c) 2014 Andreas Rumpf | +-----------------------------------------------------------------+ Build time: $2, $3 @@ -45,6 +45,7 @@ Possible Commands: tests run the testsuite update updates nimrod to the latest version from github (compile koch with -d:withUpdate to enable) + temp options creates a temporary compiler for testing Boot options: -d:release produce a release version of the compiler -d:tinyc include the Tiny C backend (not supported on Windows) @@ -109,16 +110,16 @@ proc findStartNimrod: string = # If these fail, we try to build nimrod with the "build.(sh|bat)" script. var nimrod = "nimrod".exe result = "bin" / nimrod - if ExistsFile(result): return + if existsFile(result): return for dir in split(getEnv("PATH"), PathSep): - if ExistsFile(dir / nimrod): return dir / nimrod + if existsFile(dir / nimrod): return dir / nimrod when defined(Posix): const buildScript = "build.sh" - if ExistsFile(buildScript): + if existsFile(buildScript): if tryExec("./" & buildScript): return "bin" / nimrod else: const buildScript = "build.bat" - if ExistsFile(buildScript): + if existsFile(buildScript): if tryExec(buildScript): return "bin" / nimrod echo("Found no nimrod compiler and every attempt to build one failed!") @@ -177,24 +178,24 @@ proc cleanAux(dir: string) = of "nimcache": echo "removing dir: ", path removeDir(path) - of "dist", ".git", "icons": nil + of "dist", ".git", "icons": discard else: cleanAux(path) - else: nil + else: discard proc removePattern(pattern: string) = - for f in WalkFiles(pattern): + for f in walkFiles(pattern): echo "removing: ", f removeFile(f) proc clean(args: string) = - if ExistsFile("koch.dat"): removeFile("koch.dat") + if existsFile("koch.dat"): removeFile("koch.dat") removePattern("web/*.html") removePattern("doc/*.html") cleanAux(getCurrentDir()) for kind, path in walkDir(getCurrentDir() / "build"): if kind == pcDir: echo "removing dir: ", path - RemoveDir(path) + removeDir(path) # -------------- update ------------------------------------------------------- @@ -262,11 +263,15 @@ when defined(withUpdate): proc tests(args: string) = # we compile the tester with taintMode:on to have a basic # taint mode test :-) - exec("nimrod cc --taintMode:on tests/tester") - exec(getCurrentDir() / "tests/tester".exe & " reject") - exec(getCurrentDir() / "tests/tester".exe & " compile") - exec(getCurrentDir() / "tests/tester".exe & " run") - exec(getCurrentDir() / "tests/tester".exe & " merge") + exec("nimrod cc --taintMode:on tests/testament/tester") + exec(getCurrentDir() / "tests/testament/tester".exe & " all") + +proc temp(args: string) = + var output = "compiler" / "nimrod".exe + var finalDest = "bin" / "nimrod_temp".exe + exec("nimrod c compiler" / "nimrod") + copyExe(output, finalDest) + if args.len > 0: exec(finalDest & " " & args) proc showHelp() = quit(HelpText % [NimrodVersion & repeatChar(44-len(NimrodVersion)), @@ -291,6 +296,7 @@ of cmdArgument: update(op.cmdLineRest) else: quit "this Koch has not been compiled with -d:withUpdate" + of "temp": temp(op.cmdLineRest) else: showHelp() of cmdEnd: showHelp() diff --git a/lib/core/locks.nim b/lib/core/locks.nim index 071bde93a..894965a85 100644 --- a/lib/core/locks.nim +++ b/lib/core/locks.nim @@ -45,28 +45,28 @@ when noDeadlocks: locksLen {.threadvar.}: int locks {.threadvar.}: array [0..MaxLocksPerThread-1, pointer] - proc OrderedLocks(): bool = + proc orderedLocks(): bool = for i in 0 .. locksLen-2: if locks[i] >= locks[i+1]: return false result = true -proc InitLock*(lock: var TLock) {.inline.} = +proc initLock*(lock: var TLock) {.inline.} = ## Initializes the given lock. - InitSysLock(lock) + initSysLock(lock) -proc DeinitLock*(lock: var TLock) {.inline.} = +proc deinitLock*(lock: var TLock) {.inline.} = ## Frees the resources associated with the lock. - DeinitSys(lock) + deinitSys(lock) -proc TryAcquire*(lock: var TLock): bool {.tags: [FAquireLock].} = +proc tryAcquire*(lock: var TLock): bool {.tags: [FAquireLock].} = ## Tries to acquire the given lock. Returns `true` on success. - result = TryAcquireSys(lock) + result = tryAcquireSys(lock) when noDeadlocks: if not result: return # we have to add it to the ordered list. Oh, and we might fail if # there is no space in the array left ... if locksLen >= len(locks): - ReleaseSys(lock) + releaseSys(lock) raise newException(EResourceExhausted, "cannot acquire additional lock") # find the position to add: var p = addr(lock) @@ -83,14 +83,14 @@ proc TryAcquire*(lock: var TLock): bool {.tags: [FAquireLock].} = dec L locks[i] = p inc(locksLen) - assert OrderedLocks() + assert orderedLocks() return # simply add to the end: locks[locksLen] = p inc(locksLen) - assert OrderedLocks() + assert orderedLocks() -proc Acquire*(lock: var TLock) {.tags: [FAquireLock].} = +proc acquire*(lock: var TLock) {.tags: [FAquireLock].} = ## Acquires the given lock. when nodeadlocks: var p = addr(lock) @@ -106,36 +106,36 @@ proc Acquire*(lock: var TLock) {.tags: [FAquireLock].} = raise newException(EResourceExhausted, "cannot acquire additional lock") while L >= i: - ReleaseSys(cast[ptr TSysLock](locks[L])[]) + releaseSys(cast[ptr TSysLock](locks[L])[]) locks[L+1] = locks[L] dec L # acquire the current lock: - AcquireSys(lock) + acquireSys(lock) locks[i] = p inc(locksLen) # acquire old locks in proper order again: L = locksLen-1 inc i while i <= L: - AcquireSys(cast[ptr TSysLock](locks[i])[]) + acquireSys(cast[ptr TSysLock](locks[i])[]) inc(i) # DANGER: We can only modify this global var if we gained every lock! # NO! We need an atomic increment. Crap. discard system.atomicInc(deadlocksPrevented, 1) - assert OrderedLocks() + assert orderedLocks() return # simply add to the end: if locksLen >= len(locks): raise newException(EResourceExhausted, "cannot acquire additional lock") - AcquireSys(lock) + acquireSys(lock) locks[locksLen] = p inc(locksLen) - assert OrderedLocks() + assert orderedLocks() else: - AcquireSys(lock) + acquireSys(lock) -proc Release*(lock: var TLock) {.tags: [FReleaseLock].} = +proc release*(lock: var TLock) {.tags: [FReleaseLock].} = ## Releases the given lock. when nodeadlocks: var p = addr(lock) @@ -145,20 +145,20 @@ proc Release*(lock: var TLock) {.tags: [FReleaseLock].} = for j in i..L-2: locks[j] = locks[j+1] dec locksLen break - ReleaseSys(lock) + releaseSys(lock) -proc InitCond*(cond: var TCond) {.inline.} = +proc initCond*(cond: var TCond) {.inline.} = ## Initializes the given condition variable. - InitSysCond(cond) + initSysCond(cond) -proc DeinitCond*(cond: var TCond) {.inline.} = +proc deinitCond*(cond: var TCond) {.inline.} = ## Frees the resources associated with the lock. - DeinitSysCond(cond) + deinitSysCond(cond) proc wait*(cond: var TCond, lock: var TLock) {.inline.} = ## waits on the condition variable `cond`. - WaitSysCond(cond, lock) + waitSysCond(cond, lock) proc signal*(cond: var TCond) {.inline.} = ## sends a signal to the condition variable `cond`. diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 52ee9326f..0356067f1 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -59,7 +59,8 @@ type nnkBindStmt, nnkMixinStmt, nnkUsingStmt, nnkCommentStmt, nnkStmtListExpr, nnkBlockExpr, nnkStmtListType, nnkBlockType, nnkTypeOfExpr, nnkObjectTy, - nnkTupleTy, nnkTypeClassTy, nnkRecList, nnkRecCase, nnkRecWhen, + nnkTupleTy, nnkTypeClassTy, nnkStaticTy, + nnkRecList, nnkRecCase, nnkRecWhen, nnkRefTy, nnkPtrTy, nnkVarTy, nnkConstTy, nnkMutableTy, nnkDistinctTy, @@ -147,18 +148,24 @@ proc del*(father: PNimrodNode, idx = 0, n = 1) {.magic: "NDel".} proc kind*(n: PNimrodNode): TNimrodNodeKind {.magic: "NKind".} ## returns the `kind` of the node `n`. -proc intVal*(n: PNimrodNode): biggestInt {.magic: "NIntVal".} -proc floatVal*(n: PNimrodNode): biggestFloat {.magic: "NFloatVal".} +proc intVal*(n: PNimrodNode): BiggestInt {.magic: "NIntVal".} +proc floatVal*(n: PNimrodNode): BiggestFloat {.magic: "NFloatVal".} proc symbol*(n: PNimrodNode): PNimrodSymbol {.magic: "NSymbol".} proc ident*(n: PNimrodNode): TNimrodIdent {.magic: "NIdent".} proc typ*(n: PNimrodNode): typedesc {.magic: "NGetType".} proc strVal*(n: PNimrodNode): string {.magic: "NStrVal".} -proc `intVal=`*(n: PNimrodNode, val: biggestInt) {.magic: "NSetIntVal".} -proc `floatVal=`*(n: PNimrodNode, val: biggestFloat) {.magic: "NSetFloatVal".} +proc `intVal=`*(n: PNimrodNode, val: BiggestInt) {.magic: "NSetIntVal".} +proc `floatVal=`*(n: PNimrodNode, val: BiggestFloat) {.magic: "NSetFloatVal".} proc `symbol=`*(n: PNimrodNode, val: PNimrodSymbol) {.magic: "NSetSymbol".} proc `ident=`*(n: PNimrodNode, val: TNimrodIdent) {.magic: "NSetIdent".} -proc `typ=`*(n: PNimrodNode, typ: typedesc) {.magic: "NSetType".} +#proc `typ=`*(n: PNimrodNode, typ: typedesc) {.magic: "NSetType".} +# this is not sound! Unfortunately forbidding 'typ=' is not enough, as you +# can easily do: +# let bracket = semCheck([1, 2]) +# let fake = semCheck(2.0) +# bracket[0] = fake # constructs a mixed array with ints and floats! + proc `strVal=`*(n: PNimrodNode, val: string) {.magic: "NSetStrVal".} proc newNimNode*(kind: TNimrodNodeKind, @@ -181,12 +188,12 @@ proc newStrLitNode*(s: string): PNimrodNode {.compileTime.} = result = newNimNode(nnkStrLit) result.strVal = s -proc newIntLitNode*(i: biggestInt): PNimrodNode {.compileTime.} = +proc newIntLitNode*(i: BiggestInt): PNimrodNode {.compileTime.} = ## creates a int literal node from `i` result = newNimNode(nnkIntLit) result.intVal = i -proc newFloatLitNode*(f: biggestFloat): PNimrodNode {.compileTime.} = +proc newFloatLitNode*(f: BiggestFloat): PNimrodNode {.compileTime.} = ## creates a float literal node from `f` result = newNimNode(nnkFloatLit) result.floatVal = f @@ -287,16 +294,15 @@ proc quote*(bl: stmt, op = "``"): PNimrodNode {.magic: "QuoteAst".} ## if not `ex`: ## echo `info` & ": Check failed: " & `expString` -template emit*(e: expr[string]): stmt = - ## accepts a single string argument and treats it as nimrod code - ## that should be inserted verbatim in the program - ## Example: - ## - ## .. code-block:: nimrod - ## - ## emit("echo " & '"' & "hello world".toUpper & '"') - ## - eval: result = e.parseStmt +when not defined(booting): + template emit*(e: static[string]): stmt = + ## accepts a single string argument and treats it as nimrod code + ## that should be inserted verbatim in the program + ## Example: + ## + ## emit("echo " & '"' & "hello world".toUpper & '"') + ## + eval: result = e.parseStmt proc expectKind*(n: PNimrodNode, k: TNimrodNodeKind) {.compileTime.} = ## checks that `n` is of kind `k`. If this is not the case, @@ -345,12 +351,12 @@ proc newLit*(c: char): PNimrodNode {.compileTime.} = result = newNimNode(nnkCharLit) result.intVal = ord(c) -proc newLit*(i: biggestInt): PNimrodNode {.compileTime.} = +proc newLit*(i: BiggestInt): PNimrodNode {.compileTime.} = ## produces a new integer literal node. result = newNimNode(nnkIntLit) result.intVal = i -proc newLit*(f: biggestFloat): PNimrodNode {.compileTime.} = +proc newLit*(f: BiggestFloat): PNimrodNode {.compileTime.} = ## produces a new float literal node. result = newNimNode(nnkFloatLit) result.floatVal = f @@ -529,7 +535,7 @@ from strutils import cmpIgnoreStyle, format proc expectKind*(n: PNimrodNode; k: set[TNimrodNodeKind]) {.compileTime.} = assert n.kind in k, "Expected one of $1, got $2".format(k, n.kind) -proc newProc*(name = newEmptyNode(); params: openarray[PNimrodNode] = [newEmptyNode()]; +proc newProc*(name = newEmptyNode(); params: openArray[PNimrodNode] = [newEmptyNode()]; body: PNimrodNode = newStmtList(), procType = nnkProcDef): PNimrodNode {.compileTime.} = ## shortcut for creating a new proc ## @@ -567,7 +573,7 @@ proc copyChildrenTo*(src, dest: PNimrodNode) {.compileTime.}= dest.add src[i].copyNimTree template expectRoutine(node: PNimrodNode): stmt = - expectKind(node, routineNodes) + expectKind(node, RoutineNodes) proc name*(someProc: PNimrodNode): PNimrodNode {.compileTime.} = someProc.expectRoutine @@ -604,7 +610,7 @@ proc body*(someProc: PNimrodNode): PNimrodNode {.compileTime.} = of routineNodes: return someProc[6] of nnkBlockStmt, nnkWhileStmt: - return someproc[1] + return someProc[1] of nnkForStmt: return someProc.last else: @@ -628,7 +634,7 @@ proc `$`*(node: PNimrodNode): string {.compileTime.} = of nnkIdent: result = $node.ident of nnkStrLit: - result = node.strval + result = node.strVal else: badNodeKind node.kind, "$" @@ -651,7 +657,7 @@ template findChild*(n: PNimrodNode; cond: expr): PNimrodNode {.immediate, dirty. break result -proc insert*(a: PNimrodNOde; pos: int; b: PNimrodNode) {.compileTime.} = +proc insert*(a: PNimrodNode; pos: int; b: PNimrodNode) {.compileTime.} = ## Insert node B into A at pos if high(a) < pos: ## add some empty nodes first @@ -672,14 +678,14 @@ proc basename*(a: PNimrodNode): PNimrodNode {.compiletime.} = of nnkIdent: return a of nnkPostfix, nnkPrefix: return a[1] else: - quit "Do not know how to get basename of ("& treerepr(a) &")\n"& repr(a) + quit "Do not know how to get basename of ("& treeRepr(a) &")\n"& repr(a) proc `basename=`*(a: PNimrodNode; val: string) {.compileTime.}= case a.kind of nnkIdent: macros.`ident=`(a, !val) of nnkPostfix, nnkPrefix: a[1] = ident(val) else: - quit "Do not know how to get basename of ("& treerepr(a)& ")\n"& repr(a) + quit "Do not know how to get basename of ("& treeRepr(a)& ")\n"& repr(a) proc postfix*(node: PNimrodNode; op: string): PNimrodNode {.compileTime.} = newNimNode(nnkPostfix).add(ident(op), node) diff --git a/lib/impure/db_mongo.nim b/lib/impure/db_mongo.nim index b11db78f8..d012f677f 100644 --- a/lib/impure/db_mongo.nim +++ b/lib/impure/db_mongo.nim @@ -47,12 +47,12 @@ proc dbError*(db: TDbConn, msg: string) {.noreturn.} = e.msg = $db.err & " " & msg raise e -proc Close*(db: var TDbConn) {.tags: [FDB].} = +proc close*(db: var TDbConn) {.tags: [FDB].} = ## closes the database connection. disconnect(db) destroy(db) -proc Open*(host: string = defaultHost, port: int = defaultPort): TDbConn {. +proc open*(host: string = defaultHost, port: int = defaultPort): TDbConn {. tags: [FDB].} = ## opens a database connection. Raises `EDb` if the connection could not ## be established. @@ -113,7 +113,7 @@ proc getId*(obj: var TBSon): TOid = else: raise newException(EInvalidIndex, "_id not in object") -proc insertID*(db: var TDbConn, namespace: string, data: PJsonNode): TOid {. +proc insertId*(db: var TDbConn, namespace: string, data: PJsonNode): TOid {. tags: [FWriteDb].} = ## converts `data` to BSON format and inserts it in `namespace`. Returns ## the generated OID for the ``_id`` field. diff --git a/lib/impure/db_mysql.nim b/lib/impure/db_mysql.nim index 91cf8a5eb..8cdccda01 100644 --- a/lib/impure/db_mysql.nim +++ b/lib/impure/db_mysql.nim @@ -65,7 +65,7 @@ proc dbFormat(formatstr: TSqlQuery, args: varargs[string]): string = else: add(result, c) -proc TryExec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): bool {. +proc tryExec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): bool {. tags: [FReadDB, FWriteDb].} = ## tries to execute the query and returns true if successful, false otherwise. var q = dbFormat(query, args) @@ -75,7 +75,7 @@ proc rawExec(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) = var q = dbFormat(query, args) if mysql.RealQuery(db, q, q.len) != 0'i32: dbError(db) -proc Exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) {. +proc exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) {. tags: [FReadDB, FWriteDb].} = ## executes the query and raises EDB if not successful. var q = dbFormat(query, args) @@ -90,7 +90,7 @@ proc properFreeResult(sqlres: mysql.PRES, row: cstringArray) = while mysql.FetchRow(sqlres) != nil: nil mysql.FreeResult(sqlres) -iterator FastRows*(db: TDbConn, query: TSqlQuery, +iterator fastRows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## executes the query and iterates over the result dataset. This is very ## fast, but potenially dangerous: If the for-loop-body executes another @@ -126,7 +126,7 @@ proc getRow*(db: TDbConn, query: TSqlQuery, add(result[i], row[i]) properFreeResult(sqlres, row) -proc GetAllRows*(db: TDbConn, query: TSqlQuery, +proc getAllRows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): seq[TRow] {.tags: [FReadDB].} = ## executes the query and returns the whole result dataset. result = @[] @@ -145,12 +145,12 @@ proc GetAllRows*(db: TDbConn, query: TSqlQuery, inc(j) mysql.FreeResult(sqlres) -iterator Rows*(db: TDbConn, query: TSqlQuery, +iterator rows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## same as `FastRows`, but slower and safe. for r in items(GetAllRows(db, query, args)): yield r -proc GetValue*(db: TDbConn, query: TSqlQuery, +proc getValue*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): string {.tags: [FReadDB].} = ## executes the query and returns the first column of the first row of the ## result dataset. Returns "" if the dataset contains no rows or the database @@ -160,7 +160,7 @@ proc GetValue*(db: TDbConn, query: TSqlQuery, result = row[0] break -proc TryInsertID*(db: TDbConn, query: TSqlQuery, +proc tryInsertId*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): int64 {.tags: [FWriteDb].} = ## executes the query (typically "INSERT") and returns the ## generated ID for the row or -1 in case of an error. @@ -170,14 +170,14 @@ proc TryInsertID*(db: TDbConn, query: TSqlQuery, else: result = mysql.InsertId(db) -proc InsertID*(db: TDbConn, query: TSqlQuery, +proc insertId*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): int64 {.tags: [FWriteDb].} = ## executes the query (typically "INSERT") and returns the ## generated ID for the row. result = TryInsertID(db, query, args) if result < 0: dbError(db) -proc ExecAffectedRows*(db: TDbConn, query: TSqlQuery, +proc execAffectedRows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): int64 {. tags: [FReadDB, FWriteDb].} = ## runs the query (typically "UPDATE") and returns the @@ -185,11 +185,11 @@ proc ExecAffectedRows*(db: TDbConn, query: TSqlQuery, rawExec(db, query, args) result = mysql.AffectedRows(db) -proc Close*(db: TDbConn) {.tags: [FDb].} = +proc close*(db: TDbConn) {.tags: [FDb].} = ## closes the database connection. - if db != nil: mysql.Close(db) + if db != nil: mysql.close(db) -proc Open*(connection, user, password, database: string): TDbConn {. +proc open*(connection, user, password, database: string): TDbConn {. tags: [FDb].} = ## opens a database connection. Raises `EDb` if the connection could not ## be established. diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim index 157d58c7c..f6ae93303 100644 --- a/lib/impure/db_postgres.nim +++ b/lib/impure/db_postgres.nim @@ -64,7 +64,7 @@ proc dbFormat(formatstr: TSqlQuery, args: varargs[string]): string = else: add(result, c) -proc TryExec*(db: TDbConn, query: TSqlQuery, +proc tryExec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): bool {.tags: [FReadDB, FWriteDb].} = ## tries to execute the query and returns true if successful, false otherwise. var q = dbFormat(query, args) @@ -72,7 +72,7 @@ proc TryExec*(db: TDbConn, query: TSqlQuery, result = PQresultStatus(res) == PGRES_COMMAND_OK PQclear(res) -proc Exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) {. +proc exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) {. tags: [FReadDB, FWriteDb].} = ## executes the query and raises EDB if not successful. var q = dbFormat(query, args) @@ -96,7 +96,7 @@ proc setRow(res: PPGresult, r: var TRow, line, cols: int32) = var x = PQgetvalue(res, line, col) add(r[col], x) -iterator FastRows*(db: TDbConn, query: TSqlQuery, +iterator fastRows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## executes the query and iterates over the result dataset. This is very ## fast, but potenially dangerous: If the for-loop-body executes another @@ -119,19 +119,19 @@ proc getRow*(db: TDbConn, query: TSqlQuery, setRow(res, result, 0, L) PQclear(res) -proc GetAllRows*(db: TDbConn, query: TSqlQuery, +proc getAllRows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): seq[TRow] {.tags: [FReadDB].} = ## executes the query and returns the whole result dataset. result = @[] for r in FastRows(db, query, args): result.add(r) -iterator Rows*(db: TDbConn, query: TSqlQuery, +iterator rows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## same as `FastRows`, but slower and safe. for r in items(GetAllRows(db, query, args)): yield r -proc GetValue*(db: TDbConn, query: TSqlQuery, +proc getValue*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): string {.tags: [FReadDB].} = ## executes the query and returns the first column of the first row of the ## result dataset. Returns "" if the dataset contains no rows or the database @@ -139,7 +139,7 @@ proc GetValue*(db: TDbConn, query: TSqlQuery, var x = PQgetvalue(setupQuery(db, query, args), 0, 0) result = if isNil(x): "" else: $x -proc TryInsertID*(db: TDbConn, query: TSqlQuery, +proc tryInsertID*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): int64 {.tags: [FWriteDb].}= ## executes the query (typically "INSERT") and returns the ## generated ID for the row or -1 in case of an error. For Postgre this adds @@ -152,7 +152,7 @@ proc TryInsertID*(db: TDbConn, query: TSqlQuery, else: result = -1 -proc InsertID*(db: TDbConn, query: TSqlQuery, +proc insertID*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): int64 {.tags: [FWriteDb].} = ## executes the query (typically "INSERT") and returns the ## generated ID for the row. For Postgre this adds @@ -161,7 +161,7 @@ proc InsertID*(db: TDbConn, query: TSqlQuery, result = TryInsertID(db, query, args) if result < 0: dbError(db) -proc ExecAffectedRows*(db: TDbConn, query: TSqlQuery, +proc execAffectedRows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): int64 {.tags: [ FReadDB, FWriteDb].} = ## executes the query (typically "UPDATE") and returns the @@ -172,11 +172,11 @@ proc ExecAffectedRows*(db: TDbConn, query: TSqlQuery, result = parseBiggestInt($PQcmdTuples(res)) PQclear(res) -proc Close*(db: TDbConn) {.tags: [FDb].} = +proc close*(db: TDbConn) {.tags: [FDb].} = ## closes the database connection. if db != nil: PQfinish(db) -proc Open*(connection, user, password, database: string): TDbConn {. +proc open*(connection, user, password, database: string): TDbConn {. tags: [FDb].} = ## opens a database connection. Raises `EDb` if the connection could not ## be established. diff --git a/lib/impure/db_sqlite.nim b/lib/impure/db_sqlite.nim index 693077553..a3499a6df 100644 --- a/lib/impure/db_sqlite.nim +++ b/lib/impure/db_sqlite.nim @@ -64,7 +64,7 @@ proc dbFormat(formatstr: TSqlQuery, args: varargs[string]): string = else: add(result, c) -proc TryExec*(db: TDbConn, query: TSqlQuery, +proc tryExec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): bool {.tags: [FReadDB, FWriteDb].} = ## tries to execute the query and returns true if successful, false otherwise. var q = dbFormat(query, args) @@ -73,10 +73,10 @@ proc TryExec*(db: TDbConn, query: TSqlQuery, if step(stmt) == SQLITE_DONE: result = finalize(stmt) == SQLITE_OK -proc Exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) {. +proc exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) {. tags: [FReadDB, FWriteDb].} = ## executes the query and raises EDB if not successful. - if not TryExec(db, query, args): dbError(db) + if not tryExec(db, query, args): dbError(db) proc newRow(L: int): TRow = newSeq(result, L) @@ -94,7 +94,7 @@ proc setRow(stmt: PStmt, r: var TRow, cols: cint) = let x = column_text(stmt, col) if not isNil(x): add(r[col], x) -iterator FastRows*(db: TDbConn, query: TSqlQuery, +iterator fastRows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## executes the query and iterates over the result dataset. This is very ## fast, but potenially dangerous: If the for-loop-body executes another @@ -118,19 +118,19 @@ proc getRow*(db: TDbConn, query: TSqlQuery, setRow(stmt, result, L) if finalize(stmt) != SQLITE_OK: dbError(db) -proc GetAllRows*(db: TDbConn, query: TSqlQuery, +proc getAllRows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): seq[TRow] {.tags: [FReadDB].} = ## executes the query and returns the whole result dataset. result = @[] - for r in FastRows(db, query, args): + for r in fastRows(db, query, args): result.add(r) -iterator Rows*(db: TDbConn, query: TSqlQuery, +iterator rows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## same as `FastRows`, but slower and safe. - for r in FastRows(db, query, args): yield r + for r in fastRows(db, query, args): yield r -proc GetValue*(db: TDbConn, query: TSqlQuery, +proc getValue*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): string {.tags: [FReadDB].} = ## executes the query and returns the first column of the first row of the ## result dataset. Returns "" if the dataset contains no rows or the database @@ -143,44 +143,44 @@ proc GetValue*(db: TDbConn, query: TSqlQuery, else: result = newStringOfCap(cb) add(result, column_text(stmt, 0)) - if finalize(stmt) != SQLITE_OK: dbError(db) else: result = "" + if finalize(stmt) != SQLITE_OK: dbError(db) -proc TryInsertID*(db: TDbConn, query: TSqlQuery, +proc tryInsertID*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): int64 {.tags: [FWriteDb].} = ## executes the query (typically "INSERT") and returns the ## generated ID for the row or -1 in case of an error. var q = dbFormat(query, args) var stmt: sqlite3.PStmt + result = -1 if prepare_v2(db, q, q.len.cint, stmt, nil) == SQLITE_OK: if step(stmt) == SQLITE_DONE: - if finalize(stmt) == SQLITE_OK: - return last_insert_rowid(db) - result = -1 + result = last_insert_rowid(db) + if finalize(stmt) != SQLITE_OK: dbError(db) -proc InsertID*(db: TDbConn, query: TSqlQuery, +proc insertID*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): int64 {.tags: [FWriteDb].} = ## 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 = TryInsertID(db, query, args) + result = tryInsertID(db, query, args) if result < 0: dbError(db) -proc ExecAffectedRows*(db: TDbConn, query: TSqlQuery, +proc execAffectedRows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): int64 {. tags: [FReadDB, FWriteDb].} = ## executes the query (typically "UPDATE") and returns the ## number of affected rows. - Exec(db, query, args) + exec(db, query, args) result = changes(db) -proc Close*(db: TDbConn) {.tags: [FDB].} = +proc close*(db: TDbConn) {.tags: [FDB].} = ## closes the database connection. if sqlite3.close(db) != SQLITE_OK: dbError(db) -proc Open*(connection, user, password, database: string): TDbConn {. +proc open*(connection, user, password, database: string): TDbConn {. tags: [FDB].} = ## opens a database connection. Raises `EDb` if the connection could not ## be established. Only the ``connection`` parameter is used for ``sqlite``. @@ -192,7 +192,7 @@ proc Open*(connection, user, password, database: string): TDbConn {. when isMainModule: var db = open("db.sql", "", "", "") - Exec(db, sql"create table tbl1(one varchar(10), two smallint)", []) + exec(db, sql"create table tbl1(one varchar(10), two smallint)", []) exec(db, sql"insert into tbl1 values('hello!',10)", []) exec(db, sql"insert into tbl1 values('goodbye', 20)", []) #db.query("create table tbl1(one varchar(10), two smallint)") diff --git a/lib/impure/dialogs.nim b/lib/impure/dialogs.nim index 5bd7bf6f6..00ba2663e 100644 --- a/lib/impure/dialogs.nim +++ b/lib/impure/dialogs.nim @@ -57,7 +57,7 @@ proc error*(window: PWindow, msg: string) = destroy(PWidget(dialog)) -proc ChooseFileToOpen*(window: PWindow, root: string = ""): string = +proc chooseFileToOpen*(window: PWindow, root: string = ""): string = ## Opens a dialog that requests a filename from the user. Returns "" ## if the user closed the dialog without selecting a file. On Windows, ## the native dialog is used, else the GTK dialog is used. @@ -92,7 +92,7 @@ proc ChooseFileToOpen*(window: PWindow, root: string = ""): string = result = "" destroy(PWidget(chooser)) -proc ChooseFilesToOpen*(window: PWindow, root: string = ""): seq[string] = +proc chooseFilesToOpen*(window: PWindow, root: string = ""): seq[string] = ## Opens a dialog that requests filenames from the user. Returns ``@[]`` ## if the user closed the dialog without selecting a file. On Windows, ## the native dialog is used, else the GTK dialog is used. @@ -153,7 +153,7 @@ proc ChooseFilesToOpen*(window: PWindow, root: string = ""): seq[string] = destroy(PWidget(chooser)) -proc ChooseFileToSave*(window: PWindow, root: string = ""): string = +proc chooseFileToSave*(window: PWindow, root: string = ""): string = ## Opens a dialog that requests a filename to save to from the user. ## Returns "" if the user closed the dialog without selecting a file. ## On Windows, the native dialog is used, else the GTK dialog is used. @@ -190,7 +190,7 @@ proc ChooseFileToSave*(window: PWindow, root: string = ""): string = destroy(PWidget(chooser)) -proc ChooseDir*(window: PWindow, root: string = ""): string = +proc chooseDir*(window: PWindow, root: string = ""): string = ## Opens a dialog that requests a directory from the user. ## Returns "" if the user closed the dialog without selecting a directory. ## On Windows, the native dialog is used, else the GTK dialog is used. diff --git a/lib/impure/graphics.nim b/lib/impure/graphics.nim index 85eeaed42..2c8e96460 100644 --- a/lib/impure/graphics.nim +++ b/lib/impure/graphics.nim @@ -343,7 +343,7 @@ proc fillRect*(sur: PSurface, r: TRect, col: TColor) = if sdl.FillRect(sur.s, addr(rect), sur.createSdlColor(col)) == -1: raiseEGraphics() -proc Plot4EllipsePoints(sur: PSurface, CX, CY, X, Y: Natural, col: TColor) = +proc plot4EllipsePoints(sur: PSurface, CX, CY, X, Y: Natural, col: TColor) = var video = cast[PPixels](sur.s.pixels) var pitch = sur.s.pitch.int div ColSize if CX+X <= sur.s.w-1: diff --git a/lib/impure/osinfo_win.nim b/lib/impure/osinfo_win.nim index 208ef7114..572e50273 100644 --- a/lib/impure/osinfo_win.nim +++ b/lib/impure/osinfo_win.nim @@ -151,7 +151,7 @@ const # GetSystemMetrics SM_SERVERR2 = 89 -proc GlobalMemoryStatusEx*(lpBuffer: var TMEMORYSTATUSEX){.stdcall, dynlib: "kernel32", +proc globalMemoryStatusEx*(lpBuffer: var TMEMORYSTATUSEX){.stdcall, dynlib: "kernel32", importc: "GlobalMemoryStatusEx".} proc getMemoryInfo*(): TMemoryInfo = @@ -159,7 +159,7 @@ proc getMemoryInfo*(): TMemoryInfo = var statex: TMEMORYSTATUSEX statex.dwLength = sizeof(statex).int32 - GlobalMemoryStatusEx(statex) + globalMemoryStatusEx(statex) result.MemoryLoad = statex.dwMemoryLoad result.TotalPhysMem = statex.ullTotalPhys result.AvailablePhysMem = statex.ullAvailPhys @@ -168,20 +168,20 @@ proc getMemoryInfo*(): TMemoryInfo = result.TotalVirtualMem = statex.ullTotalVirtual result.AvailableVirtualMem = statex.ullAvailExtendedVirtual -proc GetVersionEx*(lpVersionInformation: var TOSVERSIONINFOEX): WINBOOL{.stdcall, +proc getVersionEx*(lpVersionInformation: var TOSVERSIONINFOEX): WINBOOL{.stdcall, dynlib: "kernel32", importc: "GetVersionExA".} -proc GetProcAddress*(hModule: int, lpProcName: cstring): pointer{.stdcall, +proc getProcAddress*(hModule: int, lpProcName: cstring): pointer{.stdcall, dynlib: "kernel32", importc: "GetProcAddress".} -proc GetModuleHandleA*(lpModuleName: cstring): int{.stdcall, - dynlib: "kernel32", importc.} +proc getModuleHandleA*(lpModuleName: cstring): int{.stdcall, + dynlib: "kernel32", importc: "GetModuleHandleA".} proc getVersionInfo*(): TVersionInfo = ## Retrieves operating system info var osvi: TOSVERSIONINFOEX osvi.dwOSVersionInfoSize = sizeof(osvi).int32 - discard GetVersionEx(osvi) + discard getVersionEx(osvi) result.majorVersion = osvi.dwMajorVersion result.minorVersion = osvi.dwMinorVersion result.buildNumber = osvi.dwBuildNumber @@ -197,8 +197,8 @@ proc getProductInfo*(majorVersion, minorVersion, SPMajorVersion, ## Retrieves Windows' ProductInfo, this function only works in Vista and 7 var pGPI = cast[proc (dwOSMajorVersion, dwOSMinorVersion, - dwSpMajorVersion, dwSpMinorVersion: int32, outValue: Pint32)](GetProcAddress( - GetModuleHandleA("kernel32.dll"), "GetProductInfo")) + dwSpMajorVersion, dwSpMinorVersion: int32, outValue: Pint32)](getProcAddress( + getModuleHandleA("kernel32.dll"), "GetProductInfo")) if pGPI != nil: var dwType: int32 @@ -207,25 +207,25 @@ proc getProductInfo*(majorVersion, minorVersion, SPMajorVersion, else: return PRODUCT_UNDEFINED -proc GetSystemInfo*(lpSystemInfo: LPSYSTEM_INFO){.stdcall, dynlib: "kernel32", +proc getSystemInfo*(lpSystemInfo: LPSYSTEM_INFO){.stdcall, dynlib: "kernel32", importc: "GetSystemInfo".} proc getSystemInfo*(): TSYSTEM_INFO = ## Returns the SystemInfo # Use GetNativeSystemInfo if it's available - var pGNSI = cast[proc (lpSystemInfo: LPSYSTEM_INFO)](GetProcAddress( - GetModuleHandleA("kernel32.dll"), "GetNativeSystemInfo")) + var pGNSI = cast[proc (lpSystemInfo: LPSYSTEM_INFO)](getProcAddress( + getModuleHandleA("kernel32.dll"), "GetNativeSystemInfo")) var systemi: TSYSTEM_INFO if pGNSI != nil: pGNSI(addr(systemi)) else: - GetSystemInfo(addr(systemi)) + getSystemInfo(addr(systemi)) return systemi -proc GetSystemMetrics*(nIndex: int32): int32{.stdcall, dynlib: "user32", +proc getSystemMetrics*(nIndex: int32): int32{.stdcall, dynlib: "user32", importc: "GetSystemMetrics".} proc `$`*(osvi: TVersionInfo): string = @@ -283,11 +283,11 @@ proc `$`*(osvi: TVersionInfo): string = of PRODUCT_WEB_SERVER: result.add("Web Server Edition") else: - nil + discard # End of Windows 6.* if osvi.majorVersion == 5 and osvi.minorVersion == 2: - if GetSystemMetrics(SM_SERVERR2) != 0: + if getSystemMetrics(SM_SERVERR2) != 0: result.add("Windows Server 2003 R2, ") elif (osvi.SuiteMask and VER_SUITE_PERSONAL) != 0: # Not sure if this will work result.add("Windows Storage Server 2003") @@ -365,21 +365,21 @@ proc `$`*(osvi: TVersionInfo): string = result = "Unknown version of windows[Kernel version <= 4]" -proc getFileSize*(file: string): biggestInt = +proc getFileSize*(file: string): BiggestInt = var fileData: TWIN32_FIND_DATA when useWinUnicode: var aa = newWideCString(file) - var hFile = FindFirstFileW(aa, fileData) + var hFile = findFirstFileW(aa, fileData) else: - var hFile = FindFirstFileA(file, fileData) + var hFile = findFirstFileA(file, fileData) if hFile == INVALID_HANDLE_VALUE: - raise newException(EIO, $GetLastError()) + raise newException(EIO, $getLastError()) return fileData.nFileSizeLow -proc GetDiskFreeSpaceEx*(lpDirectoryName: cstring, lpFreeBytesAvailableToCaller, +proc getDiskFreeSpaceEx*(lpDirectoryName: cstring, lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes: var TFiletime): WINBOOL{. stdcall, dynlib: "kernel32", importc: "GetDiskFreeSpaceExA".} @@ -387,7 +387,7 @@ proc GetDiskFreeSpaceEx*(lpDirectoryName: cstring, lpFreeBytesAvailableToCaller, proc getPartitionInfo*(partition: string): TPartitionInfo = ## Retrieves partition info, for example ``partition`` may be ``"C:\"`` var FreeBytes, TotalBytes, TotalFreeBytes: TFiletime - var res = GetDiskFreeSpaceEx(r"C:\", FreeBytes, TotalBytes, + var res = getDiskFreeSpaceEx(r"C:\", FreeBytes, TotalBytes, TotalFreeBytes) return (FreeBytes, TotalBytes) diff --git a/lib/impure/rdstdin.nim b/lib/impure/rdstdin.nim index cf076e929..1037d3bda 100644 --- a/lib/impure/rdstdin.nim +++ b/lib/impure/rdstdin.nim @@ -14,13 +14,13 @@ ## wanted functionality. when defined(Windows): - proc ReadLineFromStdin*(prompt: string): TaintedString {. + proc readLineFromStdin*(prompt: string): TaintedString {. tags: [FReadIO, FWriteIO].} = ## Reads a line from stdin. stdout.write(prompt) result = readLine(stdin) - proc ReadLineFromStdin*(prompt: string, line: var TaintedString): bool {. + proc readLineFromStdin*(prompt: string, line: var TaintedString): bool {. tags: [FReadIO, FWriteIO].} = ## Reads a `line` from stdin. `line` must not be ## ``nil``! May throw an IO exception. @@ -34,7 +34,7 @@ when defined(Windows): else: import readline, history - proc ReadLineFromStdin*(prompt: string): TaintedString {. + proc readLineFromStdin*(prompt: string): TaintedString {. tags: [FReadIO, FWriteIO].} = var buffer = readline.readLine(prompt) if isNil(buffer): quit(0) @@ -43,7 +43,7 @@ else: add_history(buffer) readline.free(buffer) - proc ReadLineFromStdin*(prompt: string, line: var TaintedString): bool {. + proc readLineFromStdin*(prompt: string, line: var TaintedString): bool {. tags: [FReadIO, FWriteIO].} = var buffer = readline.readLine(prompt) if isNil(buffer): quit(0) @@ -56,7 +56,7 @@ else: # initialization: # disable auto-complete: - proc doNothing(a, b: cint): cint {.cdecl, procvar.} = nil + proc doNothing(a, b: cint): cint {.cdecl, procvar.} = discard discard readline.bind_key('\t'.ord, doNothing) diff --git a/lib/impure/re.nim b/lib/impure/re.nim index b92d39bf0..f6511dab4 100644 --- a/lib/impure/re.nim +++ b/lib/impure/re.nim @@ -28,7 +28,7 @@ const ## More subpatterns cannot be captured! type - TRegExFlag* = enum ## options for regular expressions + TRegexFlag* = enum ## options for regular expressions reIgnoreCase = 0, ## do caseless matching reMultiLine = 1, ## ``^`` and ``$`` match newlines within data reDotAll = 2, ## ``.`` matches anything including NL @@ -36,11 +36,11 @@ type reStudy = 4 ## study the expression (may be omitted if the ## expression will be used only once) - TRegExDesc {.pure, final.} = object + TRegexDesc {.pure, final.} = object h: PPcre e: ptr TExtra - TRegEx* = ref TRegExDesc ## a compiled regular expression + TRegex* = ref TRegexDesc ## a compiled regular expression EInvalidRegEx* = object of EInvalidValue ## is raised if the pattern is no valid regular expression. @@ -53,13 +53,13 @@ proc raiseInvalidRegex(msg: string) {.noinline, noreturn.} = proc rawCompile(pattern: string, flags: cint): PPcre = var - msg: CString + msg: cstring offset: cint result = pcre.Compile(pattern, flags, addr(msg), addr(offset), nil) if result == nil: - raiseInvalidRegEx($msg & "\n" & pattern & "\n" & repeatChar(offset) & "^\n") + raiseInvalidRegex($msg & "\n" & pattern & "\n" & repeatChar(offset) & "^\n") -proc finalizeRegEx(x: TRegEx) = +proc finalizeRegEx(x: TRegex) = # XXX This is a hack, but PCRE does not export its "free" function properly. # Sigh. The hack relies on PCRE's implementation (see ``pcre_get.c``). # Fortunately the implementation is unlikely to change. @@ -67,7 +67,7 @@ proc finalizeRegEx(x: TRegEx) = if not isNil(x.e): pcre.free_substring(cast[cstring](x.e)) -proc re*(s: string, flags = {reExtended, reStudy}): TRegEx = +proc re*(s: string, flags = {reExtended, reStudy}): TRegex = ## Constructor of regular expressions. Note that Nimrod's ## extended raw string literals support this syntax ``re"[abc]"`` as ## a short form for ``re(r"[abc]")``. @@ -78,7 +78,7 @@ proc re*(s: string, flags = {reExtended, reStudy}): TRegEx = result.e = pcre.study(result.h, 0, msg) if not isNil(msg): raiseInvalidRegex($msg) -proc matchOrFind(s: string, pattern: TRegEx, matches: var openarray[string], +proc matchOrFind(s: string, pattern: TRegex, matches: var openArray[string], start, flags: cint): cint = var rawMatches: array[0..maxSubpatterns * 3 - 1, cint] @@ -92,7 +92,7 @@ proc matchOrFind(s: string, pattern: TRegEx, matches: var openarray[string], else: matches[i-1] = "" return rawMatches[1] - rawMatches[0] -proc findBounds*(s: string, pattern: TRegEx, matches: var openarray[string], +proc findBounds*(s: string, pattern: TRegex, matches: var openArray[string], start = 0): tuple[first, last: int] = ## returns the starting position and end position of `pattern` in `s` ## and the captured @@ -110,8 +110,8 @@ proc findBounds*(s: string, pattern: TRegEx, matches: var openarray[string], else: matches[i-1] = "" return (rawMatches[0].int, rawMatches[1].int - 1) -proc findBounds*(s: string, pattern: TRegEx, - matches: var openarray[tuple[first, last: int]], +proc findBounds*(s: string, pattern: TRegex, + matches: var openArray[tuple[first, last: int]], start = 0): tuple[first, last: int] = ## returns the starting position and end position of ``pattern`` in ``s`` ## and the captured substrings in the array `matches`. @@ -129,7 +129,7 @@ proc findBounds*(s: string, pattern: TRegEx, else: matches[i-1] = (-1,0) return (rawMatches[0].int, rawMatches[1].int - 1) -proc findBounds*(s: string, pattern: TRegEx, +proc findBounds*(s: string, pattern: TRegex, start = 0): tuple[first, last: int] = ## returns the starting position of `pattern` in `s`. If it does not ## match, ``(-1,0)`` is returned. @@ -140,14 +140,14 @@ proc findBounds*(s: string, pattern: TRegEx, if res < 0'i32: return (int(res), 0) return (int(rawMatches[0]), int(rawMatches[1]-1)) -proc matchOrFind(s: string, pattern: TRegEx, start, flags: cint): cint = +proc matchOrFind(s: string, pattern: TRegex, start, flags: cint): cint = var rawMatches: array [0..maxSubpatterns * 3 - 1, cint] result = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start, flags, cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3) if result >= 0'i32: result = rawMatches[1] - rawMatches[0] -proc match*(s: string, pattern: TRegEx, matches: var openarray[string], +proc match*(s: string, pattern: TRegex, matches: var openArray[string], start = 0): bool = ## returns ``true`` if ``s[start..]`` matches the ``pattern`` and ## the captured substrings in the array ``matches``. If it does not @@ -156,24 +156,24 @@ proc match*(s: string, pattern: TRegEx, matches: var openarray[string], return matchOrFind(s, pattern, matches, start.cint, pcre.ANCHORED) == cint(s.len - start) -proc match*(s: string, pattern: TRegEx, start = 0): bool = +proc match*(s: string, pattern: TRegex, start = 0): bool = ## returns ``true`` if ``s[start..]`` matches the ``pattern``. return matchOrFind(s, pattern, start.cint, pcre.ANCHORED) == cint(s.len-start) -proc matchLen*(s: string, pattern: TRegEx, matches: var openarray[string], +proc matchLen*(s: string, pattern: TRegex, matches: var openArray[string], start = 0): int = ## the same as ``match``, but it returns the length of the match, ## if there is no match, -1 is returned. Note that a match length ## of zero can happen. return matchOrFind(s, pattern, matches, start.cint, pcre.ANCHORED) -proc matchLen*(s: string, pattern: TRegEx, start = 0): int = +proc matchLen*(s: string, pattern: TRegex, start = 0): int = ## the same as ``match``, but it returns the length of the match, ## if there is no match, -1 is returned. Note that a match length ## of zero can happen. return matchOrFind(s, pattern, start.cint, pcre.ANCHORED) -proc find*(s: string, pattern: TRegEx, matches: var openarray[string], +proc find*(s: string, pattern: TRegex, matches: var openArray[string], start = 0): int = ## returns the starting position of ``pattern`` in ``s`` and the captured ## substrings in the array ``matches``. If it does not match, nothing @@ -190,7 +190,7 @@ proc find*(s: string, pattern: TRegEx, matches: var openarray[string], else: matches[i-1] = "" return rawMatches[0] -proc find*(s: string, pattern: TRegEx, start = 0): int = +proc find*(s: string, pattern: TRegex, start = 0): int = ## returns the starting position of ``pattern`` in ``s``. If it does not ## match, -1 is returned. var @@ -200,7 +200,7 @@ proc find*(s: string, pattern: TRegEx, start = 0): int = if res < 0'i32: return res return rawMatches[0] -iterator findAll*(s: string, pattern: TRegEx, start = 0): string = +iterator findAll*(s: string, pattern: TRegex, start = 0): string = ## Yields all matching *substrings* of `s` that match `pattern`. ## ## Note that since this is an iterator you should not modify the string you @@ -216,7 +216,7 @@ iterator findAll*(s: string, pattern: TRegEx, start = 0): string = yield substr(s, int(a), int(b)-1) i = b -proc findAll*(s: string, pattern: TRegEx, start = 0): seq[string] = +proc findAll*(s: string, pattern: TRegex, start = 0): seq[string] = ## returns all matching *substrings* of `s` that match `pattern`. ## If it does not match, @[] is returned. accumulateResult(findAll(s, pattern, start)) @@ -224,7 +224,7 @@ proc findAll*(s: string, pattern: TRegEx, start = 0): seq[string] = when not defined(nimhygiene): {.pragma: inject.} -template `=~` *(s: string, pattern: TRegEx): expr = +template `=~` *(s: string, pattern: TRegex): expr = ## This calls ``match`` with an implicit declared ``matches`` array that ## can be used in the scope of the ``=~`` call: ## @@ -244,30 +244,30 @@ template `=~` *(s: string, pattern: TRegEx): expr = ## bind maxSubPatterns when not definedInScope(matches): - var matches {.inject.}: array[0..maxSubPatterns-1, string] + var matches {.inject.}: array[0..MaxSubpatterns-1, string] match(s, pattern, matches) # ------------------------- more string handling ------------------------------ -proc contains*(s: string, pattern: TRegEx, start = 0): bool = +proc contains*(s: string, pattern: TRegex, start = 0): bool = ## same as ``find(s, pattern, start) >= 0`` return find(s, pattern, start) >= 0 -proc contains*(s: string, pattern: TRegEx, matches: var openArray[string], +proc contains*(s: string, pattern: TRegex, matches: var openArray[string], start = 0): bool = ## same as ``find(s, pattern, matches, start) >= 0`` return find(s, pattern, matches, start) >= 0 -proc startsWith*(s: string, prefix: TRegEx): bool = +proc startsWith*(s: string, prefix: TRegex): bool = ## returns true if `s` starts with the pattern `prefix` result = matchLen(s, prefix) >= 0 -proc endsWith*(s: string, suffix: TRegEx): bool = +proc endsWith*(s: string, suffix: TRegex): bool = ## returns true if `s` ends with the pattern `prefix` for i in 0 .. s.len-1: if matchLen(s, suffix, i) == s.len - i: return true -proc replace*(s: string, sub: TRegEx, by = ""): string = +proc replace*(s: string, sub: TRegex, by = ""): string = ## Replaces `sub` in `s` by the string `by`. Captures cannot be ## accessed in `by`. Examples: ## @@ -289,7 +289,7 @@ proc replace*(s: string, sub: TRegEx, by = ""): string = prev = match.last + 1 add(result, substr(s, prev)) -proc replacef*(s: string, sub: TRegEx, by: string): string = +proc replacef*(s: string, sub: TRegex, by: string): string = ## Replaces `sub` in `s` by the string `by`. Captures can be accessed in `by` ## with the notation ``$i`` and ``$#`` (see strutils.`%`). Examples: ## @@ -327,7 +327,7 @@ proc replacef*(s: string, sub: TRegEx, by: string): string = add(result, substr(s, i)) proc parallelReplace*(s: string, subs: openArray[ - tuple[pattern: TRegEx, repl: string]]): string = + tuple[pattern: TRegex, repl: string]]): string = ## Returns a modified copy of `s` with the substitutions in `subs` ## applied in parallel. result = "" @@ -347,14 +347,14 @@ proc parallelReplace*(s: string, subs: openArray[ add(result, substr(s, i)) proc transformFile*(infile, outfile: string, - subs: openArray[tuple[pattern: TRegEx, repl: string]]) = + subs: openArray[tuple[pattern: TRegex, repl: string]]) = ## reads in the file `infile`, performs a parallel replacement (calls ## `parallelReplace`) and writes back to `outfile`. Raises ``EIO`` if an ## error occurs. This is supposed to be used for quick scripting. var x = readFile(infile).string writeFile(outfile, x.parallelReplace(subs)) -iterator split*(s: string, sep: TRegEx): string = +iterator split*(s: string, sep: TRegex): string = ## Splits the string `s` into substrings. ## ## Substrings are separated by the regular expression `sep`. @@ -386,7 +386,7 @@ iterator split*(s: string, sep: TRegEx): string = if first < last: yield substr(s, first, last-1) -proc split*(s: string, sep: TRegEx): seq[string] = +proc split*(s: string, sep: TRegex): seq[string] = ## Splits the string `s` into substrings. accumulateResult(split(s, sep)) diff --git a/lib/impure/zipfiles.nim b/lib/impure/zipfiles.nim index de73b500d..1726449d8 100644 --- a/lib/impure/zipfiles.nim +++ b/lib/impure/zipfiles.nim @@ -71,7 +71,7 @@ proc addFile*(z: var TZipArchive, file: string) = addFile(z, file, file) proc mySourceCallback(state, data: pointer, len: int, - cmd: Tzip_source_cmd): int {.cdecl.} = + cmd: TZipSourceCmd): int {.cdecl.} = var src = cast[PStream](state) case cmd of ZIP_SOURCE_OPEN: @@ -108,7 +108,7 @@ proc addFile*(z: var TZipArchive, dest: string, src: PStream) = type TZipFileStream = object of TStream - f: Pzip_file + f: PZipFile PZipFileStream* = ref TZipFileStream ## a reader stream of a file within a zip archive diff --git a/lib/packages/docutils/highlite.nim b/lib/packages/docutils/highlite.nim index 69da2bba8..b41a37309 100644 --- a/lib/packages/docutils/highlite.nim +++ b/lib/packages/docutils/highlite.nim @@ -53,7 +53,7 @@ const "interface", "is", "isnot", "iterator", "lambda", "let", "macro", "method", "mixin", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc", "ptr", "raise", "ref", "return", "shared", "shl", "shr", "static", - "template", "try", "tuple", "type", "var", "when", "while", "with", + "template", "try", "tuple", "type", "using", "var", "when", "while", "with", "without", "xor", "yield"] proc getSourceLanguage*(name: string): TSourceLanguage = @@ -321,7 +321,7 @@ proc generalStrLit(g: var TGeneralTokenizer, position: int): int = inc(pos) result = pos -proc isKeyword(x: openarray[string], y: string): int = +proc isKeyword(x: openArray[string], y: string): int = var a = 0 var b = len(x) - 1 while a <= b: @@ -335,7 +335,7 @@ proc isKeyword(x: openarray[string], y: string): int = return mid result = - 1 -proc isKeywordIgnoreCase(x: openarray[string], y: string): int = +proc isKeywordIgnoreCase(x: openArray[string], y: string): int = var a = 0 var b = len(x) - 1 while a <= b: @@ -354,7 +354,7 @@ type hasPreprocessor, hasNestedComments TTokenizerFlags = set[TTokenizerFlag] -proc clikeNextToken(g: var TGeneralTokenizer, keywords: openarray[string], +proc clikeNextToken(g: var TGeneralTokenizer, keywords: openArray[string], flags: TTokenizerFlags) = const hexChars = {'0'..'9', 'A'..'F', 'a'..'f'} @@ -428,7 +428,7 @@ proc clikeNextToken(g: var TGeneralTokenizer, keywords: openarray[string], g.kind = gtOperator of 'a'..'z', 'A'..'Z', '_', '\x80'..'\xFF': var id = "" - while g.buf[pos] in SymChars: + while g.buf[pos] in symChars: add(id, g.buf[pos]) inc(pos) if isKeyword(keywords, id) >= 0: g.kind = gtKeyword diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim index 6dd407155..e6ffadcbd 100644 --- a/lib/packages/docutils/rst.nim +++ b/lib/packages/docutils/rst.nim @@ -130,7 +130,7 @@ proc getThing(L: var TLexer, tok: var TToken, s: TCharSet) = tok.line = L.line tok.col = L.col var pos = L.bufpos - while True: + while true: add(tok.symbol, L.buf[pos]) inc(pos) if L.buf[pos] notin s: break @@ -143,7 +143,7 @@ proc getAdornment(L: var TLexer, tok: var TToken) = tok.col = L.col var pos = L.bufpos var c = L.buf[pos] - while True: + while true: add(tok.symbol, L.buf[pos]) inc(pos) if L.buf[pos] != c: break @@ -162,7 +162,7 @@ proc getIndentAux(L: var TLexer, start: int): int = if L.skipPounds: if buf[pos] == '#': inc(pos) if buf[pos] == '#': inc(pos) - while True: + while true: case buf[pos] of ' ', '\x0B', '\x0C': inc(pos) @@ -242,7 +242,7 @@ proc getTokens(buffer: string, skipPounds: bool, tokens: var TTokenSeq): int = inc(result) while true: inc(length) - setlen(tokens, length) + setLen(tokens, length) rawGetTok(L, tokens[length - 1]) if tokens[length - 1].kind == tkEof: break if tokens[0].kind == tkWhite: @@ -251,7 +251,7 @@ proc getTokens(buffer: string, skipPounds: bool, tokens: var TTokenSeq): int = tokens[0].kind = tkIndent type - TLevelMap = array[Char, int] + TLevelMap = array[char, int] TSubstitution{.final.} = object key*: string value*: PRstNode @@ -294,11 +294,11 @@ proc whichMsgClass*(k: TMsgKind): TMsgClass = proc defaultMsgHandler*(filename: string, line, col: int, msgkind: TMsgKind, arg: string) {.procvar.} = - let mc = msgKind.whichMsgClass - let a = messages[msgKind] % arg + let mc = msgkind.whichMsgClass + let a = messages[msgkind] % arg let message = "$1($2, $3) $4: $5" % [filename, $line, $col, $mc, a] if mc == mcError: raise newException(EParseError, message) - else: Writeln(stdout, message) + else: writeln(stdout, message) proc defaultFindFile*(filename: string): string {.procvar.} = if existsFile(filename): result = filename @@ -339,7 +339,7 @@ proc pushInd(p: var TRstParser, ind: int) = add(p.indentStack, ind) proc popInd(p: var TRstParser) = - if len(p.indentStack) > 1: setlen(p.indentStack, len(p.indentStack) - 1) + if len(p.indentStack) > 1: setLen(p.indentStack, len(p.indentStack) - 1) proc initParser(p: var TRstParser, sharedState: PSharedState) = p.indentStack = @[0] @@ -408,7 +408,7 @@ proc setSub(p: var TRstParser, key: string, value: PRstNode) = if key == p.s.subs[i].key: p.s.subs[i].value = value return - setlen(p.s.subs, length + 1) + setLen(p.s.subs, length + 1) p.s.subs[length].key = key p.s.subs[length].value = value @@ -421,7 +421,7 @@ proc setRef(p: var TRstParser, key: string, value: PRstNode) = p.s.refs[i].value = value return - setlen(p.s.refs, length + 1) + setLen(p.s.refs, length + 1) p.s.refs[length].key = key p.s.refs[length].value = value @@ -479,7 +479,7 @@ proc isInlineMarkupEnd(p: TRstParser, markup: string): bool = result = false proc isInlineMarkupStart(p: TRstParser, markup: string): bool = - var d: Char + var d: char result = p.tok[p.idx].symbol == markup if not result: return # Rule 1: @@ -615,7 +615,7 @@ proc matchVerbatim(p: TRstParser, start: int, expr: string): int = proc parseSmiley(p: var TRstParser): PRstNode = if p.tok[p.idx].symbol[0] notin SmileyStartChars: return - for key, val in items(smilies): + for key, val in items(Smilies): let m = matchVerbatim(p, p.idx, key) if m > 0: p.idx = m @@ -629,14 +629,14 @@ when false: '$', '(', ')', '~', '_', '?', '+', '-', '=', '\\', '.', '&', '\128'..'\255'} -proc isURL(p: TRstParser, i: int): bool = +proc isUrl(p: TRstParser, i: int): bool = result = (p.tok[i+1].symbol == ":") and (p.tok[i+2].symbol == "//") and (p.tok[i+3].kind == tkWord) and (p.tok[i].symbol in ["http", "https", "ftp", "telnet", "file"]) -proc parseURL(p: var TRstParser, father: PRstNode) = +proc parseUrl(p: var TRstParser, father: PRstNode) = #if p.tok[p.idx].symbol[strStart] == '<': - if isURL(p, p.idx): + if isUrl(p, p.idx): var n = newRstNode(rnStandaloneHyperlink) while true: case p.tok[p.idx].kind @@ -835,14 +835,14 @@ proc parseComment(p: var TRstParser): PRstNode = inc(p.idx) # empty comment else: var indent = p.tok[p.idx].ival - while True: + while true: case p.tok[p.idx].kind of tkEof: break of tkIndent: if (p.tok[p.idx].ival < indent): break else: - nil + discard inc(p.idx) else: while p.tok[p.idx].kind notin {tkIndent, tkEof}: inc(p.idx) @@ -864,13 +864,13 @@ proc getDirKind(s: string): TDirKind = else: result = dkNone proc parseLine(p: var TRstParser, father: PRstNode) = - while True: + while true: case p.tok[p.idx].kind of tkWhite, tkWord, tkOther, tkPunct: parseInline(p, father) else: break proc parseUntilNewline(p: var TRstParser, father: PRstNode) = - while True: + while true: case p.tok[p.idx].kind of tkWhite, tkWord, tkAdornment, tkOther, tkPunct: parseInline(p, father) of tkEof, tkIndent: break @@ -879,9 +879,9 @@ proc parseSection(p: var TRstParser, result: PRstNode) proc parseField(p: var TRstParser): PRstNode = result = newRstNode(rnField) var col = p.tok[p.idx].col - var fieldname = newRstNode(rnFieldname) + var fieldname = newRstNode(rnFieldName) parseUntil(p, fieldname, ":", false) - var fieldbody = newRstNode(rnFieldbody) + var fieldbody = newRstNode(rnFieldBody) if p.tok[p.idx].kind != tkIndent: parseLine(p, fieldbody) if p.tok[p.idx].kind == tkIndent: var indent = p.tok[p.idx].ival @@ -933,7 +933,7 @@ proc parseLiteralBlock(p: var TRstParser): PRstNode = if p.tok[p.idx].kind == tkIndent: var indent = p.tok[p.idx].ival inc(p.idx) - while True: + while true: case p.tok[p.idx].kind of tkEof: break @@ -953,7 +953,7 @@ proc parseLiteralBlock(p: var TRstParser): PRstNode = inc(p.idx) add(result, n) -proc getLevel(map: var TLevelMap, lvl: var int, c: Char): int = +proc getLevel(map: var TLevelMap, lvl: var int, c: char): int = if map[c] == 0: inc(lvl) map[c] = lvl @@ -999,7 +999,7 @@ proc whichSection(p: TRstParser): TRstNodeKind = elif match(p, p.idx + 1, "i"): result = rnOverline else: result = rnLeaf of tkPunct: - if match(p, tokenAfterNewLine(p), "ai"): + if match(p, tokenAfterNewline(p), "ai"): result = rnHeadline elif p.tok[p.idx].symbol == "::": result = rnLiteralBlock @@ -1026,7 +1026,7 @@ proc whichSection(p: TRstParser): TRstNodeKind = else: result = rnParagraph of tkWord, tkOther, tkWhite: - if match(p, tokenAfterNewLine(p), "ai"): result = rnHeadline + if match(p, tokenAfterNewline(p), "ai"): result = rnHeadline elif match(p, p.idx, "e) ") or match(p, p.idx, "e. "): result = rnEnumList elif isDefList(p): result = rnDefList else: result = rnParagraph @@ -1052,7 +1052,7 @@ proc parseLineBlock(p: var TRstParser): PRstNode = popInd(p) proc parseParagraph(p: var TRstParser, result: PRstNode) = - while True: + while true: case p.tok[p.idx].kind of tkIndent: if p.tok[p.idx + 1].kind == tkIndent: @@ -1084,7 +1084,7 @@ proc parseParagraph(p: var TRstParser, result: PRstNode) = proc parseHeadline(p: var TRstParser): PRstNode = result = newRstNode(rnHeadline) - parseUntilNewLine(p, result) + parseUntilNewline(p, result) assert(p.tok[p.idx].kind == tkIndent) assert(p.tok[p.idx + 1].kind == tkAdornment) var c = p.tok[p.idx + 1].symbol[0] @@ -1101,7 +1101,7 @@ proc getColumns(p: var TRstParser, cols: var TIntSeq) = var L = 0 while true: inc(L) - setlen(cols, L) + setLen(cols, L) cols[L - 1] = tokEnd(p) assert(p.tok[p.idx].kind == tkAdornment) inc(p.idx) @@ -1119,7 +1119,7 @@ proc parseSimpleTable(p: var TRstParser): PRstNode = cols: TIntSeq row: seq[string] i, last, line: int - c: Char + c: char q: TRstParser a, b: PRstNode result = newRstNode(rnTable) @@ -1135,7 +1135,7 @@ proc parseSimpleTable(p: var TRstParser): PRstNode = p.idx = last break getColumns(p, cols) - setlen(row, len(cols)) + setLen(row, len(cols)) if a != nil: for j in 0..len(a)-1: a.sons[j].kind = rnTableHeaderCell if p.tok[p.idx].kind == tkEof: break @@ -1243,7 +1243,7 @@ proc parseOptionList(p: var TRstParser): PRstNode = proc parseDefinitionList(p: var TRstParser): PRstNode = result = nil - var j = tokenAfterNewLine(p) - 1 + var j = tokenAfterNewline(p) - 1 if (j >= 1) and (p.tok[j].kind == tkIndent) and (p.tok[j].ival > currInd(p)) and (p.tok[j - 1].symbol != "::"): var col = p.tok[p.idx].col @@ -1269,10 +1269,10 @@ proc parseDefinitionList(p: var TRstParser): PRstNode = break if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx].ival == col): inc(p.idx) - j = tokenAfterNewLine(p) - 1 + j = tokenAfterNewline(p) - 1 if j >= 1 and p.tok[j].kind == tkIndent and p.tok[j].ival > col and p.tok[j-1].symbol != "::" and p.tok[j+1].kind != tkIndent: - nil + discard else: break if len(result) == 0: result = nil @@ -1290,7 +1290,7 @@ proc parseEnumList(p: var TRstParser): PRstNode = var col = p.tok[p.idx].col result = newRstNode(rnEnumList) inc(p.idx, wildpos[w] + 3) - var j = tokenAfterNewLine(p) + var j = tokenAfterNewline(p) if (p.tok[j].col == p.tok[p.idx].col) or match(p, j, wildcards[w]): pushInd(p, p.tok[p.idx].col) while true: @@ -1335,7 +1335,7 @@ proc parseSection(p: var TRstParser, result: PRstNode) = inc(p.idx) # skip '::' a = parseLiteralBlock(p) of rnBulletList: a = parseBulletList(p) - of rnLineblock: a = parseLineBlock(p) + of rnLineBlock: a = parseLineBlock(p) of rnDirective: a = parseDotDot(p) of rnEnumList: a = parseEnumList(p) of rnLeaf: rstMessage(p, meNewSectionExpected) @@ -1394,7 +1394,7 @@ proc parseDirective(p: var TRstParser, flags: TDirFlags): PRstNode = if hasArg in flags: args = newRstNode(rnDirArg) if argIsFile in flags: - while True: + while true: case p.tok[p.idx].kind of tkWord, tkOther, tkPunct, tkAdornment: add(args, newLeaf(p)) @@ -1566,7 +1566,7 @@ proc parseDotDot(p: var TRstParser): PRstNode = result = dirRaw(p) else: rstMessage(p, meInvalidDirective, d) - of dkCodeblock: result = dirCodeBlock(p) + of dkCodeBlock: result = dirCodeBlock(p) of dkIndex: result = dirIndex(p) else: rstMessage(p, meInvalidDirective, d) popInd(p) diff --git a/lib/packages/docutils/rstast.nim b/lib/packages/docutils/rstast.nim index 3d191dacb..f5ef0f53d 100644 --- a/lib/packages/docutils/rstast.nim +++ b/lib/packages/docutils/rstast.nim @@ -62,9 +62,9 @@ type # leaf val - PRSTNode* = ref TRstNode ## an RST node + PRstNode* = ref TRstNode ## an RST node TRstNodeSeq* = seq[PRstNode] - TRSTNode* {.acyclic, final.} = object ## an RST node's description + TRstNode* {.acyclic, final.} = object ## an RST node's description kind*: TRstNodeKind ## the node's kind text*: string ## valid for leafs in the AST; and the title of ## the document or the section @@ -120,11 +120,11 @@ proc renderRstToRst(d: var TRenderContext, n: PRstNode, result: var string) = let oldLen = result.len renderRstSons(d, n, result) - let HeadlineLen = result.len - oldLen + let headlineLen = result.len - oldLen result.add("\n") result.add(ind) - result.add repeatChar(HeadlineLen, lvlToChar[n.level]) + result.add repeatChar(headlineLen, lvlToChar[n.level]) of rnOverline: result.add("\n") result.add(ind) @@ -132,7 +132,7 @@ proc renderRstToRst(d: var TRenderContext, n: PRstNode, result: var string) = var headline = "" renderRstSons(d, n, headline) - let lvl = repeatChar(headline.Len - d.indent, lvlToChar[n.level]) + let lvl = repeatChar(headline.len - d.indent, lvlToChar[n.level]) result.add(lvl) result.add("\n") result.add(headline) diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index bc4f3d351..a56f62448 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -44,7 +44,7 @@ type splitAfter*: int # split too long entries in the TOC tocPart*: seq[TTocEntry] hasToc*: bool - theIndex: string + theIndex: string # Contents of the index file to be dumped at the end. options*: TRstParseOptions findFile*: TFindFileHandler msgHandler*: TMsgHandler @@ -111,9 +111,13 @@ proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget, for i in low(g.meta)..high(g.meta): g.meta[i] = "" proc writeIndexFile*(g: var TRstGenerator, outfile: string) = + ## Writes the current index buffer to the specified output file. + ## + ## You previously need to add entries to the index with the ``setIndexTerm`` + ## proc. If the index is empty the file won't be created. if g.theIndex.len > 0: writeFile(outfile, g.theIndex) -proc addXmlChar(dest: var string, c: Char) = +proc addXmlChar(dest: var string, c: char) = case c of '&': add(dest, "&") of '<': add(dest, "<") @@ -121,14 +125,14 @@ proc addXmlChar(dest: var string, c: Char) = of '\"': add(dest, """) else: add(dest, c) -proc addRtfChar(dest: var string, c: Char) = +proc addRtfChar(dest: var string, c: char) = case c of '{': add(dest, "\\{") of '}': add(dest, "\\}") of '\\': add(dest, "\\\\") else: add(dest, c) -proc addTexChar(dest: var string, c: Char) = +proc addTexChar(dest: var string, c: char) = case c of '_': add(dest, "\\_") of '{': add(dest, "\\symbol{123}") @@ -148,7 +152,7 @@ proc addTexChar(dest: var string, c: Char) = var splitter*: string = "<wbr />" -proc escChar*(target: TOutputTarget, dest: var string, c: Char) {.inline.} = +proc escChar*(target: TOutputTarget, dest: var string, c: char) {.inline.} = case target of outHtml: addXmlChar(dest, c) of outLatex: addTexChar(dest, c) @@ -224,6 +228,13 @@ proc renderAux(d: PDoc, n: PRstNode, frmtA, frmtB: string, result: var string) = # ---------------- index handling -------------------------------------------- proc setIndexTerm*(d: var TRstGenerator, id, term: string) = + ## Adds a `term` to the index using the specified hyperlink identifier. + ## + ## The ``d.theIndex`` string will be used to append the term in the format + ## ``term<tab>file#id``. The anchor will be the based on the name of the file + ## currently being parsed plus the `id`, which will be appended after a hash. + ## + ## The index won't be written to disk unless you call ``writeIndexFile``. d.theIndex.add(term) d.theIndex.add('\t') let htmlFile = changeFileExt(extractFilename(d.filename), HtmlExt) @@ -263,14 +274,14 @@ proc `<-`(a: var TIndexEntry, b: TIndexEntry) = proc sortIndex(a: var openArray[TIndexEntry]) = # we use shellsort here; fast and simple - let N = len(a) + let n = len(a) var h = 1 while true: h = 3 * h + 1 - if h > N: break + if h > n: break while true: h = h div 3 - for i in countup(h, N - 1): + for i in countup(h, n - 1): var v: TIndexEntry v <- a[i] var j = i @@ -320,7 +331,7 @@ proc renderHeadline(d: PDoc, n: PRstNode, result: var string) = var refname = rstnodeToRefname(n) if d.hasToc: var length = len(d.tocPart) - setlen(d.tocPart, length + 1) + setLen(d.tocPart, length + 1) d.tocPart[length].refname = refname d.tocPart[length].n = n d.tocPart[length].header = tmp @@ -456,7 +467,7 @@ proc renderField(d: PDoc, n: PRstNode, result: var string) = if d.meta[metaAuthor].len == 0: d.meta[metaAuthor] = fieldval b = true - elif cmpIgnoreStyle(fieldName, "version") == 0: + elif cmpIgnoreStyle(fieldname, "version") == 0: if d.meta[metaVersion].len == 0: d.meta[metaVersion] = fieldval b = true @@ -620,14 +631,14 @@ proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) = # ----------------------------------------------------------------------------- -proc getVarIdx(varnames: openarray[string], id: string): int = +proc getVarIdx(varnames: openArray[string], id: string): int = for i in countup(0, high(varnames)): if cmpIgnoreStyle(varnames[i], id) == 0: return i result = -1 -proc formatNamedVars*(frmt: string, varnames: openarray[string], - varvalues: openarray[string]): string = +proc formatNamedVars*(frmt: string, varnames: openArray[string], + varvalues: openArray[string]): string = var i = 0 var L = len(frmt) result = "" @@ -646,7 +657,7 @@ proc formatNamedVars*(frmt: string, varnames: openarray[string], of '0'..'9': var j = 0 while true: - j = (j * 10) + Ord(frmt[i]) - ord('0') + j = (j * 10) + ord(frmt[i]) - ord('0') inc(i) if i > L-1 or frmt[i] notin {'0'..'9'}: break if j > high(varvalues) + 1: diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index 806c255ee..685a1dafc 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -85,15 +85,15 @@ type Tdirent* {.importc: "struct dirent", header: "<dirent.h>", final, pure.} = object ## dirent_t struct - d_ino*: TIno ## File serial number. + d_ino*: Tino ## File serial number. d_name*: array [0..255, char] ## Name of entry. Tflock* {.importc: "flock", final, pure, header: "<fcntl.h>".} = object ## flock type l_type*: cshort ## Type of lock; F_RDLCK, F_WRLCK, F_UNLCK. l_whence*: cshort ## Flag for starting offset. - l_start*: Toff ## Relative offset in bytes. - l_len*: Toff ## Size; if 0 then until EOF. + l_start*: TOff ## Relative offset in bytes. + l_len*: TOff ## Size; if 0 then until EOF. l_pid*: TPid ## Process ID of the process holding the lock; ## returned with F_GETLK. @@ -172,7 +172,7 @@ type TPasswd* {.importc: "struct passwd", header: "<pwd.h>", final, pure.} = object ## struct passwd pw_name*: cstring ## User's login name. - pw_uid*: TUid ## Numerical user ID. + pw_uid*: Tuid ## Numerical user ID. pw_gid*: TGid ## Numerical group ID. pw_dir*: cstring ## Initial working directory. pw_shell*: cstring ## Program to use as shell. @@ -240,20 +240,20 @@ type TSem* {.importc: "sem_t", header: "<semaphore.h>", final, pure.} = object Tipc_perm* {.importc: "struct ipc_perm", header: "<sys/ipc.h>", final, pure.} = object ## struct ipc_perm - uid*: tuid ## Owner's user ID. - gid*: tgid ## Owner's group ID. + uid*: Tuid ## Owner's user ID. + gid*: TGid ## Owner's group ID. cuid*: Tuid ## Creator's user ID. - cgid*: Tgid ## Creator's group ID. + cgid*: TGid ## Creator's group ID. mode*: TMode ## Read/write permission. TStat* {.importc: "struct stat", header: "<sys/stat.h>", final, pure.} = object ## struct stat st_dev*: TDev ## Device ID of device containing file. - st_ino*: TIno ## File serial number. + st_ino*: Tino ## File serial number. st_mode*: TMode ## Mode of file (see below). - st_nlink*: tnlink ## Number of hard links to the file. - st_uid*: tuid ## User ID of file. - st_gid*: Tgid ## Group ID of file. + st_nlink*: TNlink ## Number of hard links to the file. + st_uid*: Tuid ## User ID of file. + st_gid*: TGid ## Group ID of file. st_rdev*: TDev ## Device ID (if file is character or block special). st_size*: TOff ## For regular files, the file size in bytes. ## For symbolic links, the length in bytes of the @@ -262,9 +262,9 @@ type ## For a typed memory object, the length in bytes. ## For other file types, the use of this field is ## unspecified. - st_atime*: ttime ## Time of last access. - st_mtime*: ttime ## Time of last data modification. - st_ctime*: ttime ## Time of last status change. + st_atime*: TTime ## Time of last access. + st_mtime*: TTime ## Time of last data modification. + st_ctime*: TTime ## Time of last status change. st_blksize*: Tblksize ## A file system-specific preferred I/O block size ## for this object. In some file system types, this ## may vary from file to file. @@ -305,12 +305,12 @@ type tm_isdst*: cint ## Daylight Savings flag. Ttimespec* {.importc: "struct timespec", header: "<time.h>", final, pure.} = object ## struct timespec - tv_sec*: Ttime ## Seconds. + tv_sec*: TTime ## Seconds. tv_nsec*: int ## Nanoseconds. titimerspec* {.importc: "struct itimerspec", header: "<time.h>", final, pure.} = object ## struct itimerspec - it_interval*: ttimespec ## Timer period. - it_value*: ttimespec ## Timer expiration. + it_interval*: Ttimespec ## Timer period. + it_value*: Ttimespec ## Timer expiration. Tsig_atomic* {.importc: "sig_atomic_t", header: "<signal.h>".} = cint ## Possibly volatile-qualified integer type of an object that can be @@ -322,9 +322,9 @@ type header: "<signal.h>", final, pure.} = object ## struct sigevent sigev_notify*: cint ## Notification type. sigev_signo*: cint ## Signal number. - sigev_value*: Tsigval ## Signal value. - sigev_notify_function*: proc (x: TSigval) {.noconv.} ## Notification func. - sigev_notify_attributes*: ptr Tpthreadattr ## Notification attributes. + sigev_value*: TsigVal ## Signal value. + sigev_notify_function*: proc (x: TsigVal) {.noconv.} ## Notification func. + sigev_notify_attributes*: ptr Tpthread_attr ## Notification attributes. TsigVal* {.importc: "union sigval", header: "<signal.h>", final, pure.} = object ## struct sigval @@ -335,10 +335,10 @@ type sa_handler*: proc (x: cint) {.noconv.} ## Pointer to a signal-catching ## function or one of the macros ## SIG_IGN or SIG_DFL. - sa_mask*: TsigSet ## Set of signals to be blocked during execution of + sa_mask*: Tsigset ## Set of signals to be blocked during execution of ## the signal handling function. sa_flags*: cint ## Special flags. - sa_sigaction*: proc (x: cint, y: var TSigInfo, z: pointer) {.noconv.} + sa_sigaction*: proc (x: cint, y: var TsigInfo, z: pointer) {.noconv.} TStack* {.importc: "stack_t", header: "<signal.h>", final, pure.} = object ## stack_t @@ -357,12 +357,12 @@ type si_code*: cint ## Signal code. si_errno*: cint ## If non-zero, an errno value associated with ## this signal, as defined in <errno.h>. - si_pid*: tpid ## Sending process ID. - si_uid*: tuid ## Real user ID of sending process. + si_pid*: TPid ## Sending process ID. + si_uid*: Tuid ## Real user ID of sending process. si_addr*: pointer ## Address of faulting instruction. si_status*: cint ## Exit value or signal. si_band*: int ## Band event for SIGPOLL. - si_value*: TSigval ## Signal value. + si_value*: TsigVal ## Signal value. Tnl_item* {.importc: "nl_item", header: "<nl_types.h>".} = cint Tnl_catd* {.importc: "nl_catd", header: "<nl_types.h>".} = cint @@ -373,9 +373,9 @@ type sched_priority*: cint sched_ss_low_priority*: cint ## Low scheduling priority for ## sporadic server. - sched_ss_repl_period*: ttimespec ## Replenishment period for + sched_ss_repl_period*: Ttimespec ## Replenishment period for ## sporadic server. - sched_ss_init_budget*: ttimespec ## Initial budget for sporadic server. + sched_ss_init_budget*: Ttimespec ## Initial budget for sporadic server. sched_ss_max_repl*: cint ## Maximum pending replenishments for ## sporadic server. @@ -383,8 +383,8 @@ type final, pure.} = object ## struct timeval tv_sec*: int ## Seconds. tv_usec*: int ## Microseconds. - Tfd_set* {.importc: "fd_set", header: "<sys/select.h>", - final, pure.} = object + TFdSet* {.importc: "fd_set", header: "<sys/select.h>", + final, pure.} = object Tmcontext* {.importc: "mcontext_t", header: "<ucontext.h>", final, pure.} = object Tucontext* {.importc: "ucontext_t", header: "<ucontext.h>", @@ -406,7 +406,7 @@ when hasAioH: aio_buf*: pointer ## Location of buffer. aio_nbytes*: int ## Length of transfer. aio_reqprio*: cint ## Request priority offset. - aio_sigevent*: TSigEvent ## Signal number and value. + aio_sigevent*: TsigEvent ## Signal number and value. aio_lio_opcode: cint ## Operation to be performed. when hasSpawnH: @@ -422,13 +422,13 @@ type TSockAddr* {.importc: "struct sockaddr", header: "<sys/socket.h>", pure, final.} = object ## struct sockaddr - sa_family*: Tsa_family ## Address family. + sa_family*: TSa_Family ## Address family. sa_data*: array [0..255, char] ## Socket address (variable-length data). Tsockaddr_storage* {.importc: "struct sockaddr_storage", header: "<sys/socket.h>", pure, final.} = object ## struct sockaddr_storage - ss_family*: Tsa_family ## Address family. + ss_family*: TSa_Family ## Address family. Tif_nameindex* {.importc: "struct if_nameindex", final, pure, header: "<net/if.h>".} = object ## struct if_nameindex @@ -444,17 +444,17 @@ type Tmsghdr* {.importc: "struct msghdr", pure, final, header: "<sys/socket.h>".} = object ## struct msghdr msg_name*: pointer ## Optional address. - msg_namelen*: TSockLen ## Size of address. + msg_namelen*: TSocklen ## Size of address. msg_iov*: ptr TIOVec ## Scatter/gather array. msg_iovlen*: cint ## Members in msg_iov. msg_control*: pointer ## Ancillary data; see below. - msg_controllen*: TSockLen ## Ancillary data buffer len. + msg_controllen*: TSocklen ## Ancillary data buffer len. msg_flags*: cint ## Flags on received message. Tcmsghdr* {.importc: "struct cmsghdr", pure, final, header: "<sys/socket.h>".} = object ## struct cmsghdr - cmsg_len*: TSockLen ## Data byte count, including the cmsghdr. + cmsg_len*: TSocklen ## Data byte count, including the cmsghdr. cmsg_level*: cint ## Originating protocol. cmsg_type*: cint ## Protocol-specific type. @@ -475,7 +475,7 @@ type Tsockaddr_in* {.importc: "struct sockaddr_in", pure, final, header: "<netinet/in.h>".} = object ## struct sockaddr_in - sin_family*: TSa_family ## AF_INET. + sin_family*: TSa_Family ## AF_INET. sin_port*: TInPort ## Port number. sin_addr*: TInAddr ## IP address. @@ -485,10 +485,10 @@ type Tsockaddr_in6* {.importc: "struct sockaddr_in6", pure, final, header: "<netinet/in.h>".} = object ## struct sockaddr_in6 - sin6_family*: TSa_family ## AF_INET6. + sin6_family*: TSa_Family ## AF_INET6. sin6_port*: TInPort ## Port number. sin6_flowinfo*: int32 ## IPv6 traffic class and flow information. - sin6_addr*: Tin6Addr ## IPv6 address. + sin6_addr*: TIn6Addr ## IPv6 address. sin6_scope_id*: int32 ## Set of interfaces for a scope. Tipv6_mreq* {.importc: "struct ipv6_mreq", pure, final, @@ -543,10 +543,10 @@ type ai_family*: cint ## Address family of socket. ai_socktype*: cint ## Socket type. ai_protocol*: cint ## Protocol of socket. - ai_addrlen*: TSockLen ## Length of socket address. + ai_addrlen*: TSocklen ## Length of socket address. ai_addr*: ptr TSockAddr ## Socket address of socket. ai_canonname*: cstring ## Canonical name of service location. - ai_next*: ptr TAddrInfo ## Pointer to next in list. + ai_next*: ptr Taddrinfo ## Pointer to next in list. TPollfd* {.importc: "struct pollfd", pure, final, header: "<poll.h>".} = object ## struct pollfd @@ -1616,9 +1616,9 @@ var IPPROTO_UDP* {.importc, header: "<netinet/in.h>".}: cint ## User datagram protocol. - INADDR_ANY* {.importc, header: "<netinet/in.h>".}: TinAddrScalar + INADDR_ANY* {.importc, header: "<netinet/in.h>".}: TInAddrScalar ## IPv4 local host address. - INADDR_BROADCAST* {.importc, header: "<netinet/in.h>".}: TinAddrScalar + INADDR_BROADCAST* {.importc, header: "<netinet/in.h>".}: TInAddrScalar ## IPv4 broadcast address. INET_ADDRSTRLEN* {.importc, header: "<netinet/in.h>".}: cint @@ -1726,7 +1726,7 @@ var ## Invalid fd member (revents only). -when hasSpawnh: +when hasSpawnH: var POSIX_SPAWN_RESETIDS* {.importc, header: "<spawn.h>".}: cint POSIX_SPAWN_SETPGROUP* {.importc, header: "<spawn.h>".}: cint @@ -1750,11 +1750,11 @@ when hasAioH: proc aio_fsync*(a1: cint, a2: ptr Taiocb): cint {.importc, header: "<aio.h>".} proc aio_read*(a1: ptr Taiocb): cint {.importc, header: "<aio.h>".} proc aio_return*(a1: ptr Taiocb): int {.importc, header: "<aio.h>".} - proc aio_suspend*(a1: ptr ptr Taiocb, a2: cint, a3: ptr ttimespec): cint {. + proc aio_suspend*(a1: ptr ptr Taiocb, a2: cint, a3: ptr Ttimespec): cint {. importc, header: "<aio.h>".} proc aio_write*(a1: ptr Taiocb): cint {.importc, header: "<aio.h>".} proc lio_listio*(a1: cint, a2: ptr ptr Taiocb, a3: cint, - a4: ptr Tsigevent): cint {.importc, header: "<aio.h>".} + a4: ptr TsigEvent): cint {.importc, header: "<aio.h>".} # arpa/inet.h proc htonl*(a1: int32): int32 {.importc, header: "<arpa/inet.h>".} @@ -1778,9 +1778,9 @@ proc IN6ADDR_LOOPBACK_INIT* (): TIn6Addr {.importc, header: "<netinet/in.h>".} # dirent.h proc closedir*(a1: ptr TDIR): cint {.importc, header: "<dirent.h>".} -proc opendir*(a1: cstring): ptr TDir {.importc, header: "<dirent.h>".} -proc readdir*(a1: ptr TDIR): ptr TDirent {.importc, header: "<dirent.h>".} -proc readdir_r*(a1: ptr TDIR, a2: ptr Tdirent, a3: ptr ptr TDirent): cint {. +proc opendir*(a1: cstring): ptr TDIR {.importc, header: "<dirent.h>".} +proc readdir*(a1: ptr TDIR): ptr Tdirent {.importc, header: "<dirent.h>".} +proc readdir_r*(a1: ptr TDIR, a2: ptr Tdirent, a3: ptr ptr Tdirent): cint {. importc, header: "<dirent.h>".} proc rewinddir*(a1: ptr TDIR) {.importc, header: "<dirent.h>".} proc seekdir*(a1: ptr TDIR, a2: int) {.importc, header: "<dirent.h>".} @@ -1792,12 +1792,12 @@ proc dlerror*(): cstring {.importc, header: "<dlfcn.h>".} proc dlopen*(a1: cstring, a2: cint): pointer {.importc, header: "<dlfcn.h>".} proc dlsym*(a1: pointer, a2: cstring): pointer {.importc, header: "<dlfcn.h>".} -proc creat*(a1: cstring, a2: Tmode): cint {.importc, header: "<fcntl.h>".} +proc creat*(a1: cstring, a2: TMode): cint {.importc, header: "<fcntl.h>".} proc fcntl*(a1: cint | TSocketHandle, a2: cint): cint {.varargs, importc, header: "<fcntl.h>".} proc open*(a1: cstring, a2: cint): cint {.varargs, importc, header: "<fcntl.h>".} -proc posix_fadvise*(a1: cint, a2, a3: Toff, a4: cint): cint {. +proc posix_fadvise*(a1: cint, a2, a3: TOff, a4: cint): cint {. importc, header: "<fcntl.h>".} -proc posix_fallocate*(a1: cint, a2, a3: Toff): cint {. +proc posix_fallocate*(a1: cint, a2, a3: TOff): cint {. importc, header: "<fcntl.h>".} proc feclearexcept*(a1: cint): cint {.importc, header: "<fenv.h>".} @@ -1812,7 +1812,7 @@ proc fesetround*(a1: cint): cint {.importc, header: "<fenv.h>".} proc fegetenv*(a1: ptr Tfenv): cint {.importc, header: "<fenv.h>".} proc feholdexcept*(a1: ptr Tfenv): cint {.importc, header: "<fenv.h>".} proc fesetenv*(a1: ptr Tfenv): cint {.importc, header: "<fenv.h>".} -proc feupdateenv*(a1: ptr TFenv): cint {.importc, header: "<fenv.h>".} +proc feupdateenv*(a1: ptr Tfenv): cint {.importc, header: "<fenv.h>".} when not defined(haiku): proc fmtmsg*(a1: int, a2: cstring, a3: cint, @@ -1830,12 +1830,12 @@ proc nftw*(a1: cstring, proc glob*(a1: cstring, a2: cint, a3: proc (x1: cstring, x2: cint): cint {.noconv.}, - a4: ptr Tglob): cint {.importc, header: "<glob.h>".} + a4: ptr TGlob): cint {.importc, header: "<glob.h>".} proc globfree*(a1: ptr TGlob) {.importc, header: "<glob.h>".} proc getgrgid*(a1: TGid): ptr TGroup {.importc, header: "<grp.h>".} proc getgrnam*(a1: cstring): ptr TGroup {.importc, header: "<grp.h>".} -proc getgrgid_r*(a1: Tgid, a2: ptr TGroup, a3: cstring, a4: int, +proc getgrgid_r*(a1: TGid, a2: ptr TGroup, a3: cstring, a4: int, a5: ptr ptr TGroup): cint {.importc, header: "<grp.h>".} proc getgrnam_r*(a1: cstring, a2: ptr TGroup, a3: cstring, a4: int, a5: ptr ptr TGroup): cint {. @@ -1845,7 +1845,7 @@ proc endgrent*() {.importc, header: "<grp.h>".} proc setgrent*() {.importc, header: "<grp.h>".} -proc iconv_open*(a1, a2: cstring): TIconv {.importc, header: "<iconv.h>".} +proc iconv_open*(a1, a2: cstring): Ticonv {.importc, header: "<iconv.h>".} proc iconv*(a1: Ticonv, a2: var cstring, a3: var int, a4: var cstring, a5: var int): int {.importc, header: "<iconv.h>".} proc iconv_close*(a1: Ticonv): cint {.importc, header: "<iconv.h>".} @@ -1862,33 +1862,33 @@ proc setlocale*(a1: cint, a2: cstring): cstring {. proc strfmon*(a1: cstring, a2: int, a3: cstring): int {.varargs, importc, header: "<monetary.h>".} -proc mq_close*(a1: Tmqd): cint {.importc, header: "<mqueue.h>".} -proc mq_getattr*(a1: Tmqd, a2: ptr Tmq_attr): cint {. +proc mq_close*(a1: TMqd): cint {.importc, header: "<mqueue.h>".} +proc mq_getattr*(a1: TMqd, a2: ptr TMqAttr): cint {. importc, header: "<mqueue.h>".} -proc mq_notify*(a1: Tmqd, a2: ptr Tsigevent): cint {. +proc mq_notify*(a1: TMqd, a2: ptr TsigEvent): cint {. importc, header: "<mqueue.h>".} proc mq_open*(a1: cstring, a2: cint): TMqd {. varargs, importc, header: "<mqueue.h>".} -proc mq_receive*(a1: Tmqd, a2: cstring, a3: int, a4: var int): int {. +proc mq_receive*(a1: TMqd, a2: cstring, a3: int, a4: var int): int {. importc, header: "<mqueue.h>".} -proc mq_send*(a1: Tmqd, a2: cstring, a3: int, a4: int): cint {. +proc mq_send*(a1: TMqd, a2: cstring, a3: int, a4: int): cint {. importc, header: "<mqueue.h>".} -proc mq_setattr*(a1: Tmqd, a2, a3: ptr Tmq_attr): cint {. +proc mq_setattr*(a1: TMqd, a2, a3: ptr TMqAttr): cint {. importc, header: "<mqueue.h>".} -proc mq_timedreceive*(a1: Tmqd, a2: cstring, a3: int, a4: int, - a5: ptr TTimespec): int {.importc, header: "<mqueue.h>".} -proc mq_timedsend*(a1: Tmqd, a2: cstring, a3: int, a4: int, - a5: ptr TTimeSpec): cint {.importc, header: "<mqueue.h>".} +proc mq_timedreceive*(a1: TMqd, a2: cstring, a3: int, a4: int, + a5: ptr Ttimespec): int {.importc, header: "<mqueue.h>".} +proc mq_timedsend*(a1: TMqd, a2: cstring, a3: int, a4: int, + a5: ptr Ttimespec): cint {.importc, header: "<mqueue.h>".} proc mq_unlink*(a1: cstring): cint {.importc, header: "<mqueue.h>".} proc getpwnam*(a1: cstring): ptr TPasswd {.importc, header: "<pwd.h>".} proc getpwuid*(a1: Tuid): ptr TPasswd {.importc, header: "<pwd.h>".} -proc getpwnam_r*(a1: cstring, a2: ptr Tpasswd, a3: cstring, a4: int, - a5: ptr ptr Tpasswd): cint {.importc, header: "<pwd.h>".} -proc getpwuid_r*(a1: Tuid, a2: ptr Tpasswd, a3: cstring, - a4: int, a5: ptr ptr Tpasswd): cint {.importc, header: "<pwd.h>".} +proc getpwnam_r*(a1: cstring, a2: ptr TPasswd, a3: cstring, a4: int, + a5: ptr ptr TPasswd): cint {.importc, header: "<pwd.h>".} +proc getpwuid_r*(a1: Tuid, a2: ptr TPasswd, a3: cstring, + a4: int, a5: ptr ptr TPasswd): cint {.importc, header: "<pwd.h>".} proc endpwent*() {.importc, header: "<pwd.h>".} proc getpwent*(): ptr TPasswd {.importc, header: "<pwd.h>".} proc setpwent*() {.importc, header: "<pwd.h>".} @@ -1933,9 +1933,9 @@ proc pthread_attr_setscope*(a1: ptr Tpthread_attr, a2: cint): cint {.importc, header: "<pthread.h>".} proc pthread_attr_setstack*(a1: ptr Tpthread_attr, a2: pointer, a3: int): cint {. importc, header: "<pthread.h>".} -proc pthread_attr_setstackaddr*(a1: ptr TPthread_attr, a2: pointer): cint {. +proc pthread_attr_setstackaddr*(a1: ptr Tpthread_attr, a2: pointer): cint {. importc, header: "<pthread.h>".} -proc pthread_attr_setstacksize*(a1: ptr TPthread_attr, a2: int): cint {. +proc pthread_attr_setstacksize*(a1: ptr Tpthread_attr, a2: int): cint {. importc, header: "<pthread.h>".} proc pthread_barrier_destroy*(a1: ptr Tpthread_barrier): cint {. importc, header: "<pthread.h>".} @@ -1949,9 +1949,9 @@ proc pthread_barrierattr_destroy*(a1: ptr Tpthread_barrierattr): cint {. proc pthread_barrierattr_getpshared*( a1: ptr Tpthread_barrierattr, a2: var cint): cint {. importc, header: "<pthread.h>".} -proc pthread_barrierattr_init*(a1: ptr TPthread_barrierattr): cint {. +proc pthread_barrierattr_init*(a1: ptr Tpthread_barrierattr): cint {. importc, header: "<pthread.h>".} -proc pthread_barrierattr_setpshared*(a1: ptr TPthread_barrierattr, +proc pthread_barrierattr_setpshared*(a1: ptr Tpthread_barrierattr, a2: cint): cint {.importc, header: "<pthread.h>".} proc pthread_cancel*(a1: Tpthread): cint {.importc, header: "<pthread.h>".} proc pthread_cleanup_push*(a1: proc (x: pointer) {.noconv.}, a2: pointer) {. @@ -1970,13 +1970,13 @@ proc pthread_cond_wait*(a1: ptr Tpthread_cond, a2: ptr Tpthread_mutex): cint {.importc, header: "<pthread.h>".} proc pthread_condattr_destroy*(a1: ptr Tpthread_condattr): cint {.importc, header: "<pthread.h>".} proc pthread_condattr_getclock*(a1: ptr Tpthread_condattr, - a2: var Tclockid): cint {.importc, header: "<pthread.h>".} + a2: var TClockId): cint {.importc, header: "<pthread.h>".} proc pthread_condattr_getpshared*(a1: ptr Tpthread_condattr, a2: var cint): cint {.importc, header: "<pthread.h>".} -proc pthread_condattr_init*(a1: ptr TPthread_condattr): cint {.importc, header: "<pthread.h>".} -proc pthread_condattr_setclock*(a1: ptr TPthread_condattr,a2: Tclockid): cint {.importc, header: "<pthread.h>".} -proc pthread_condattr_setpshared*(a1: ptr TPthread_condattr, a2: cint): cint {.importc, header: "<pthread.h>".} +proc pthread_condattr_init*(a1: ptr Tpthread_condattr): cint {.importc, header: "<pthread.h>".} +proc pthread_condattr_setclock*(a1: ptr Tpthread_condattr,a2: TClockId): cint {.importc, header: "<pthread.h>".} +proc pthread_condattr_setpshared*(a1: ptr Tpthread_condattr, a2: cint): cint {.importc, header: "<pthread.h>".} proc pthread_create*(a1: ptr Tpthread, a2: ptr Tpthread_attr, a3: proc (x: pointer): pointer {.noconv.}, a4: pointer): cint {.importc, header: "<pthread.h>".} @@ -1984,7 +1984,7 @@ proc pthread_detach*(a1: Tpthread): cint {.importc, header: "<pthread.h>".} proc pthread_equal*(a1, a2: Tpthread): cint {.importc, header: "<pthread.h>".} proc pthread_exit*(a1: pointer) {.importc, header: "<pthread.h>".} proc pthread_getconcurrency*(): cint {.importc, header: "<pthread.h>".} -proc pthread_getcpuclockid*(a1: Tpthread, a2: var Tclockid): cint {.importc, header: "<pthread.h>".} +proc pthread_getcpuclockid*(a1: Tpthread, a2: var TClockId): cint {.importc, header: "<pthread.h>".} proc pthread_getschedparam*(a1: Tpthread, a2: var cint, a3: ptr Tsched_param): cint {.importc, header: "<pthread.h>".} proc pthread_getspecific*(a1: Tpthread_key): pointer {.importc, header: "<pthread.h>".} @@ -2016,7 +2016,7 @@ proc pthread_mutexattr_gettype*(a1: ptr Tpthread_mutexattr, a2: var cint): cint {.importc, header: "<pthread.h>".} proc pthread_mutexattr_init*(a1: ptr Tpthread_mutexattr): cint {.importc, header: "<pthread.h>".} -proc pthread_mutexattr_setprioceiling*(a1: ptr tpthread_mutexattr, a2: cint): cint {.importc, header: "<pthread.h>".} +proc pthread_mutexattr_setprioceiling*(a1: ptr Tpthread_mutexattr, a2: cint): cint {.importc, header: "<pthread.h>".} proc pthread_mutexattr_setprotocol*(a1: ptr Tpthread_mutexattr, a2: cint): cint {.importc, header: "<pthread.h>".} proc pthread_mutexattr_setpshared*(a1: ptr Tpthread_mutexattr, a2: cint): cint {.importc, header: "<pthread.h>".} proc pthread_mutexattr_settype*(a1: ptr Tpthread_mutexattr, a2: cint): cint {.importc, header: "<pthread.h>".} @@ -2069,7 +2069,7 @@ proc pthread_testcancel*() {.importc, header: "<pthread.h>".} proc access*(a1: cstring, a2: cint): cint {.importc, header: "<unistd.h>".} proc alarm*(a1: cint): cint {.importc, header: "<unistd.h>".} proc chdir*(a1: cstring): cint {.importc, header: "<unistd.h>".} -proc chown*(a1: cstring, a2: Tuid, a3: Tgid): cint {.importc, header: "<unistd.h>".} +proc chown*(a1: cstring, a2: Tuid, a3: TGid): cint {.importc, header: "<unistd.h>".} proc close*(a1: cint | TSocketHandle): cint {.importc, header: "<unistd.h>".} proc confstr*(a1: cint, a2: cstring, a3: int): int {.importc, header: "<unistd.h>".} proc crypt*(a1, a2: cstring): cstring {.importc, header: "<unistd.h>".} @@ -2085,19 +2085,19 @@ proc execv*(a1: cstring, a2: cstringArray): cint {.importc, header: "<unistd.h>" proc execve*(a1: cstring, a2, a3: cstringArray): cint {. importc, header: "<unistd.h>".} proc execvp*(a1: cstring, a2: cstringArray): cint {.importc, header: "<unistd.h>".} -proc fchown*(a1: cint, a2: Tuid, a3: Tgid): cint {.importc, header: "<unistd.h>".} +proc fchown*(a1: cint, a2: Tuid, a3: TGid): cint {.importc, header: "<unistd.h>".} proc fchdir*(a1: cint): cint {.importc, header: "<unistd.h>".} proc fdatasync*(a1: cint): cint {.importc, header: "<unistd.h>".} -proc fork*(): Tpid {.importc, header: "<unistd.h>".} +proc fork*(): TPid {.importc, header: "<unistd.h>".} proc fpathconf*(a1, a2: cint): int {.importc, header: "<unistd.h>".} proc fsync*(a1: cint): cint {.importc, header: "<unistd.h>".} -proc ftruncate*(a1: cint, a2: Toff): cint {.importc, header: "<unistd.h>".} +proc ftruncate*(a1: cint, a2: TOff): cint {.importc, header: "<unistd.h>".} proc getcwd*(a1: cstring, a2: int): cstring {.importc, header: "<unistd.h>".} proc getegid*(): TGid {.importc, header: "<unistd.h>".} -proc geteuid*(): TUid {.importc, header: "<unistd.h>".} +proc geteuid*(): Tuid {.importc, header: "<unistd.h>".} proc getgid*(): TGid {.importc, header: "<unistd.h>".} -proc getgroups*(a1: cint, a2: ptr array[0..255, Tgid]): cint {. +proc getgroups*(a1: cint, a2: ptr array[0..255, TGid]): cint {. importc, header: "<unistd.h>".} proc gethostid*(): int {.importc, header: "<unistd.h>".} proc gethostname*(a1: cstring, a2: int): cint {.importc, header: "<unistd.h>".} @@ -2106,105 +2106,105 @@ proc getlogin_r*(a1: cstring, a2: int): cint {.importc, header: "<unistd.h>".} proc getopt*(a1: cint, a2: cstringArray, a3: cstring): cint {. importc, header: "<unistd.h>".} -proc getpgid*(a1: Tpid): Tpid {.importc, header: "<unistd.h>".} -proc getpgrp*(): Tpid {.importc, header: "<unistd.h>".} -proc getpid*(): Tpid {.importc, header: "<unistd.h>".} -proc getppid*(): Tpid {.importc, header: "<unistd.h>".} -proc getsid*(a1: Tpid): Tpid {.importc, header: "<unistd.h>".} +proc getpgid*(a1: TPid): TPid {.importc, header: "<unistd.h>".} +proc getpgrp*(): TPid {.importc, header: "<unistd.h>".} +proc getpid*(): TPid {.importc, header: "<unistd.h>".} +proc getppid*(): TPid {.importc, header: "<unistd.h>".} +proc getsid*(a1: TPid): TPid {.importc, header: "<unistd.h>".} proc getuid*(): Tuid {.importc, header: "<unistd.h>".} proc getwd*(a1: cstring): cstring {.importc, header: "<unistd.h>".} proc isatty*(a1: cint): cint {.importc, header: "<unistd.h>".} -proc lchown*(a1: cstring, a2: Tuid, a3: Tgid): cint {.importc, header: "<unistd.h>".} +proc lchown*(a1: cstring, a2: Tuid, a3: TGid): cint {.importc, header: "<unistd.h>".} proc link*(a1, a2: cstring): cint {.importc, header: "<unistd.h>".} -proc lockf*(a1, a2: cint, a3: Toff): cint {.importc, header: "<unistd.h>".} -proc lseek*(a1: cint, a2: Toff, a3: cint): Toff {.importc, header: "<unistd.h>".} +proc lockf*(a1, a2: cint, a3: TOff): cint {.importc, header: "<unistd.h>".} +proc lseek*(a1: cint, a2: TOff, a3: cint): TOff {.importc, header: "<unistd.h>".} proc nice*(a1: cint): cint {.importc, header: "<unistd.h>".} proc pathconf*(a1: cstring, a2: cint): int {.importc, header: "<unistd.h>".} proc pause*(): cint {.importc, header: "<unistd.h>".} proc pipe*(a: array[0..1, cint]): cint {.importc, header: "<unistd.h>".} -proc pread*(a1: cint, a2: pointer, a3: int, a4: Toff): int {. +proc pread*(a1: cint, a2: pointer, a3: int, a4: TOff): int {. importc, header: "<unistd.h>".} -proc pwrite*(a1: cint, a2: pointer, a3: int, a4: Toff): int {. +proc pwrite*(a1: cint, a2: pointer, a3: int, a4: TOff): int {. importc, header: "<unistd.h>".} proc read*(a1: cint, a2: pointer, a3: int): int {.importc, header: "<unistd.h>".} proc readlink*(a1, a2: cstring, a3: int): int {.importc, header: "<unistd.h>".} proc rmdir*(a1: cstring): cint {.importc, header: "<unistd.h>".} -proc setegid*(a1: Tgid): cint {.importc, header: "<unistd.h>".} +proc setegid*(a1: TGid): cint {.importc, header: "<unistd.h>".} proc seteuid*(a1: Tuid): cint {.importc, header: "<unistd.h>".} -proc setgid*(a1: Tgid): cint {.importc, header: "<unistd.h>".} +proc setgid*(a1: TGid): cint {.importc, header: "<unistd.h>".} -proc setpgid*(a1, a2: Tpid): cint {.importc, header: "<unistd.h>".} -proc setpgrp*(): Tpid {.importc, header: "<unistd.h>".} -proc setregid*(a1, a2: Tgid): cint {.importc, header: "<unistd.h>".} +proc setpgid*(a1, a2: TPid): cint {.importc, header: "<unistd.h>".} +proc setpgrp*(): TPid {.importc, header: "<unistd.h>".} +proc setregid*(a1, a2: TGid): cint {.importc, header: "<unistd.h>".} proc setreuid*(a1, a2: Tuid): cint {.importc, header: "<unistd.h>".} -proc setsid*(): Tpid {.importc, header: "<unistd.h>".} +proc setsid*(): TPid {.importc, header: "<unistd.h>".} proc setuid*(a1: Tuid): cint {.importc, header: "<unistd.h>".} proc sleep*(a1: cint): cint {.importc, header: "<unistd.h>".} proc swab*(a1, a2: pointer, a3: int) {.importc, header: "<unistd.h>".} proc symlink*(a1, a2: cstring): cint {.importc, header: "<unistd.h>".} proc sync*() {.importc, header: "<unistd.h>".} proc sysconf*(a1: cint): int {.importc, header: "<unistd.h>".} -proc tcgetpgrp*(a1: cint): tpid {.importc, header: "<unistd.h>".} -proc tcsetpgrp*(a1: cint, a2: Tpid): cint {.importc, header: "<unistd.h>".} -proc truncate*(a1: cstring, a2: Toff): cint {.importc, header: "<unistd.h>".} +proc tcgetpgrp*(a1: cint): TPid {.importc, header: "<unistd.h>".} +proc tcsetpgrp*(a1: cint, a2: TPid): cint {.importc, header: "<unistd.h>".} +proc truncate*(a1: cstring, a2: TOff): cint {.importc, header: "<unistd.h>".} proc ttyname*(a1: cint): cstring {.importc, header: "<unistd.h>".} proc ttyname_r*(a1: cint, a2: cstring, a3: int): cint {. importc, header: "<unistd.h>".} proc ualarm*(a1, a2: Tuseconds): Tuseconds {.importc, header: "<unistd.h>".} proc unlink*(a1: cstring): cint {.importc, header: "<unistd.h>".} proc usleep*(a1: Tuseconds): cint {.importc, header: "<unistd.h>".} -proc vfork*(): tpid {.importc, header: "<unistd.h>".} +proc vfork*(): TPid {.importc, header: "<unistd.h>".} proc write*(a1: cint, a2: pointer, a3: int): int {.importc, header: "<unistd.h>".} -proc sem_close*(a1: ptr Tsem): cint {.importc, header: "<semaphore.h>".} -proc sem_destroy*(a1: ptr Tsem): cint {.importc, header: "<semaphore.h>".} -proc sem_getvalue*(a1: ptr Tsem, a2: var cint): cint {. +proc sem_close*(a1: ptr TSem): cint {.importc, header: "<semaphore.h>".} +proc sem_destroy*(a1: ptr TSem): cint {.importc, header: "<semaphore.h>".} +proc sem_getvalue*(a1: ptr TSem, a2: var cint): cint {. importc, header: "<semaphore.h>".} -proc sem_init*(a1: ptr Tsem, a2: cint, a3: cint): cint {. +proc sem_init*(a1: ptr TSem, a2: cint, a3: cint): cint {. importc, header: "<semaphore.h>".} proc sem_open*(a1: cstring, a2: cint): ptr TSem {. varargs, importc, header: "<semaphore.h>".} -proc sem_post*(a1: ptr Tsem): cint {.importc, header: "<semaphore.h>".} -proc sem_timedwait*(a1: ptr Tsem, a2: ptr Ttimespec): cint {. +proc sem_post*(a1: ptr TSem): cint {.importc, header: "<semaphore.h>".} +proc sem_timedwait*(a1: ptr TSem, a2: ptr Ttimespec): cint {. importc, header: "<semaphore.h>".} -proc sem_trywait*(a1: ptr Tsem): cint {.importc, header: "<semaphore.h>".} +proc sem_trywait*(a1: ptr TSem): cint {.importc, header: "<semaphore.h>".} proc sem_unlink*(a1: cstring): cint {.importc, header: "<semaphore.h>".} -proc sem_wait*(a1: ptr Tsem): cint {.importc, header: "<semaphore.h>".} +proc sem_wait*(a1: ptr TSem): cint {.importc, header: "<semaphore.h>".} -proc ftok*(a1: cstring, a2: cint): Tkey {.importc, header: "<sys/ipc.h>".} +proc ftok*(a1: cstring, a2: cint): TKey {.importc, header: "<sys/ipc.h>".} -proc statvfs*(a1: cstring, a2: var Tstatvfs): cint {. +proc statvfs*(a1: cstring, a2: var TStatvfs): cint {. importc, header: "<sys/statvfs.h>".} -proc fstatvfs*(a1: cint, a2: var Tstatvfs): cint {. +proc fstatvfs*(a1: cint, a2: var TStatvfs): cint {. importc, header: "<sys/statvfs.h>".} proc chmod*(a1: cstring, a2: TMode): cint {.importc, header: "<sys/stat.h>".} proc fchmod*(a1: cint, a2: TMode): cint {.importc, header: "<sys/stat.h>".} -proc fstat*(a1: cint, a2: var Tstat): cint {.importc, header: "<sys/stat.h>".} -proc lstat*(a1: cstring, a2: var Tstat): cint {.importc, header: "<sys/stat.h>".} +proc fstat*(a1: cint, a2: var TStat): cint {.importc, header: "<sys/stat.h>".} +proc lstat*(a1: cstring, a2: var TStat): cint {.importc, header: "<sys/stat.h>".} proc mkdir*(a1: cstring, a2: TMode): cint {.importc, header: "<sys/stat.h>".} proc mkfifo*(a1: cstring, a2: TMode): cint {.importc, header: "<sys/stat.h>".} -proc mknod*(a1: cstring, a2: TMode, a3: Tdev): cint {. +proc mknod*(a1: cstring, a2: TMode, a3: TDev): cint {. importc, header: "<sys/stat.h>".} -proc stat*(a1: cstring, a2: var Tstat): cint {.importc, header: "<sys/stat.h>".} -proc umask*(a1: Tmode): TMode {.importc, header: "<sys/stat.h>".} +proc stat*(a1: cstring, a2: var TStat): cint {.importc, header: "<sys/stat.h>".} +proc umask*(a1: TMode): TMode {.importc, header: "<sys/stat.h>".} -proc S_ISBLK*(m: Tmode): bool {.importc, header: "<sys/stat.h>".} +proc S_ISBLK*(m: TMode): bool {.importc, header: "<sys/stat.h>".} ## Test for a block special file. -proc S_ISCHR*(m: Tmode): bool {.importc, header: "<sys/stat.h>".} +proc S_ISCHR*(m: TMode): bool {.importc, header: "<sys/stat.h>".} ## Test for a character special file. -proc S_ISDIR*(m: Tmode): bool {.importc, header: "<sys/stat.h>".} +proc S_ISDIR*(m: TMode): bool {.importc, header: "<sys/stat.h>".} ## Test for a directory. -proc S_ISFIFO*(m: Tmode): bool {.importc, header: "<sys/stat.h>".} +proc S_ISFIFO*(m: TMode): bool {.importc, header: "<sys/stat.h>".} ## Test for a pipe or FIFO special file. -proc S_ISREG*(m: Tmode): bool {.importc, header: "<sys/stat.h>".} +proc S_ISREG*(m: TMode): bool {.importc, header: "<sys/stat.h>".} ## Test for a regular file. -proc S_ISLNK*(m: Tmode): bool {.importc, header: "<sys/stat.h>".} +proc S_ISLNK*(m: TMode): bool {.importc, header: "<sys/stat.h>".} ## Test for a symbolic link. -proc S_ISSOCK*(m: Tmode): bool {.importc, header: "<sys/stat.h>".} +proc S_ISSOCK*(m: TMode): bool {.importc, header: "<sys/stat.h>".} ## Test for a socket. proc S_TYPEISMQ*(buf: var TStat): bool {.importc, header: "<sys/stat.h>".} @@ -2219,7 +2219,7 @@ proc S_TYPEISTMO*(buf: var TStat): bool {.importc, header: "<sys/stat.h>".} proc mlock*(a1: pointer, a2: int): cint {.importc, header: "<sys/mman.h>".} proc mlockall*(a1: cint): cint {.importc, header: "<sys/mman.h>".} -proc mmap*(a1: pointer, a2: int, a3, a4, a5: cint, a6: Toff): pointer {. +proc mmap*(a1: pointer, a2: int, a3, a4, a5: cint, a6: TOff): pointer {. importc, header: "<sys/mman.h>".} proc mprotect*(a1: pointer, a2: int, a3: cint): cint {. importc, header: "<sys/mman.h>".} @@ -2229,75 +2229,75 @@ proc munlockall*(): cint {.importc, header: "<sys/mman.h>".} proc munmap*(a1: pointer, a2: int): cint {.importc, header: "<sys/mman.h>".} proc posix_madvise*(a1: pointer, a2: int, a3: cint): cint {. importc, header: "<sys/mman.h>".} -proc posix_mem_offset*(a1: pointer, a2: int, a3: var Toff, +proc posix_mem_offset*(a1: pointer, a2: int, a3: var TOff, a4: var int, a5: var cint): cint {.importc, header: "<sys/mman.h>".} proc posix_typed_mem_get_info*(a1: cint, a2: var Tposix_typed_mem_info): cint {.importc, header: "<sys/mman.h>".} proc posix_typed_mem_open*(a1: cstring, a2, a3: cint): cint {. importc, header: "<sys/mman.h>".} -proc shm_open*(a1: cstring, a2: cint, a3: Tmode): cint {. +proc shm_open*(a1: cstring, a2: cint, a3: TMode): cint {. importc, header: "<sys/mman.h>".} proc shm_unlink*(a1: cstring): cint {.importc, header: "<sys/mman.h>".} -proc asctime*(a1: var ttm): cstring{.importc, header: "<time.h>".} +proc asctime*(a1: var Ttm): cstring{.importc, header: "<time.h>".} -proc asctime_r*(a1: var ttm, a2: cstring): cstring {.importc, header: "<time.h>".} -proc clock*(): Tclock {.importc, header: "<time.h>".} -proc clock_getcpuclockid*(a1: tpid, a2: var Tclockid): cint {. +proc asctime_r*(a1: var Ttm, a2: cstring): cstring {.importc, header: "<time.h>".} +proc clock*(): TClock {.importc, header: "<time.h>".} +proc clock_getcpuclockid*(a1: TPid, a2: var TClockId): cint {. importc, header: "<time.h>".} -proc clock_getres*(a1: Tclockid, a2: var Ttimespec): cint {. +proc clock_getres*(a1: TClockId, a2: var Ttimespec): cint {. importc, header: "<time.h>".} -proc clock_gettime*(a1: Tclockid, a2: var Ttimespec): cint {. +proc clock_gettime*(a1: TClockId, a2: var Ttimespec): cint {. importc, header: "<time.h>".} -proc clock_nanosleep*(a1: Tclockid, a2: cint, a3: var Ttimespec, +proc clock_nanosleep*(a1: TClockId, a2: cint, a3: var Ttimespec, a4: var Ttimespec): cint {.importc, header: "<time.h>".} -proc clock_settime*(a1: Tclockid, a2: var Ttimespec): cint {. +proc clock_settime*(a1: TClockId, a2: var Ttimespec): cint {. importc, header: "<time.h>".} -proc ctime*(a1: var Ttime): cstring {.importc, header: "<time.h>".} -proc ctime_r*(a1: var Ttime, a2: cstring): cstring {.importc, header: "<time.h>".} -proc difftime*(a1, a2: Ttime): cdouble {.importc, header: "<time.h>".} -proc getdate*(a1: cstring): ptr ttm {.importc, header: "<time.h>".} +proc ctime*(a1: var TTime): cstring {.importc, header: "<time.h>".} +proc ctime_r*(a1: var TTime, a2: cstring): cstring {.importc, header: "<time.h>".} +proc difftime*(a1, a2: TTime): cdouble {.importc, header: "<time.h>".} +proc getdate*(a1: cstring): ptr Ttm {.importc, header: "<time.h>".} -proc gmtime*(a1: var ttime): ptr ttm {.importc, header: "<time.h>".} -proc gmtime_r*(a1: var ttime, a2: var ttm): ptr ttm {.importc, header: "<time.h>".} -proc localtime*(a1: var ttime): ptr ttm {.importc, header: "<time.h>".} -proc localtime_r*(a1: var ttime, a2: var ttm): ptr ttm {.importc, header: "<time.h>".} -proc mktime*(a1: var ttm): ttime {.importc, header: "<time.h>".} +proc gmtime*(a1: var TTime): ptr Ttm {.importc, header: "<time.h>".} +proc gmtime_r*(a1: var TTime, a2: var Ttm): ptr Ttm {.importc, header: "<time.h>".} +proc localtime*(a1: var TTime): ptr Ttm {.importc, header: "<time.h>".} +proc localtime_r*(a1: var TTime, a2: var Ttm): ptr Ttm {.importc, header: "<time.h>".} +proc mktime*(a1: var Ttm): TTime {.importc, header: "<time.h>".} proc nanosleep*(a1, a2: var Ttimespec): cint {.importc, header: "<time.h>".} proc strftime*(a1: cstring, a2: int, a3: cstring, - a4: var ttm): int {.importc, header: "<time.h>".} -proc strptime*(a1, a2: cstring, a3: var ttm): cstring {.importc, header: "<time.h>".} -proc time*(a1: var Ttime): ttime {.importc, header: "<time.h>".} -proc timer_create*(a1: var Tclockid, a2: var Tsigevent, + a4: var Ttm): int {.importc, header: "<time.h>".} +proc strptime*(a1, a2: cstring, a3: var Ttm): cstring {.importc, header: "<time.h>".} +proc time*(a1: var TTime): TTime {.importc, header: "<time.h>".} +proc timer_create*(a1: var TClockId, a2: var TsigEvent, a3: var Ttimer): cint {.importc, header: "<time.h>".} proc timer_delete*(a1: var Ttimer): cint {.importc, header: "<time.h>".} -proc timer_gettime*(a1: Ttimer, a2: var Titimerspec): cint {. +proc timer_gettime*(a1: Ttimer, a2: var titimerspec): cint {. importc, header: "<time.h>".} proc timer_getoverrun*(a1: Ttimer): cint {.importc, header: "<time.h>".} -proc timer_settime*(a1: Ttimer, a2: cint, a3: var Titimerspec, +proc timer_settime*(a1: Ttimer, a2: cint, a3: var titimerspec, a4: var titimerspec): cint {.importc, header: "<time.h>".} proc tzset*() {.importc, header: "<time.h>".} -proc wait*(a1: var cint): tpid {.importc, header: "<sys/wait.h>".} -proc waitid*(a1: cint, a2: tid, a3: var Tsiginfo, a4: cint): cint {. +proc wait*(a1: var cint): TPid {.importc, header: "<sys/wait.h>".} +proc waitid*(a1: cint, a2: Tid, a3: var TsigInfo, a4: cint): cint {. importc, header: "<sys/wait.h>".} -proc waitpid*(a1: tpid, a2: var cint, a3: cint): tpid {. +proc waitpid*(a1: TPid, a2: var cint, a3: cint): TPid {. importc, header: "<sys/wait.h>".} proc bsd_signal*(a1: cint, a2: proc (x: pointer) {.noconv.}) {. importc, header: "<signal.h>".} -proc kill*(a1: Tpid, a2: cint): cint {.importc, header: "<signal.h>".} -proc killpg*(a1: Tpid, a2: cint): cint {.importc, header: "<signal.h>".} -proc pthread_kill*(a1: tpthread, a2: cint): cint {.importc, header: "<signal.h>".} +proc kill*(a1: TPid, a2: cint): cint {.importc, header: "<signal.h>".} +proc killpg*(a1: TPid, a2: cint): cint {.importc, header: "<signal.h>".} +proc pthread_kill*(a1: Tpthread, a2: cint): cint {.importc, header: "<signal.h>".} proc pthread_sigmask*(a1: cint, a2, a3: var Tsigset): cint {. importc, header: "<signal.h>".} proc `raise`*(a1: cint): cint {.importc, header: "<signal.h>".} -proc sigaction*(a1: cint, a2, a3: var Tsigaction): cint {. +proc sigaction*(a1: cint, a2, a3: var TSigaction): cint {. importc, header: "<signal.h>".} proc sigaddset*(a1: var Tsigset, a2: cint): cint {.importc, header: "<signal.h>".} -proc sigaltstack*(a1, a2: var Tstack): cint {.importc, header: "<signal.h>".} +proc sigaltstack*(a1, a2: var TStack): cint {.importc, header: "<signal.h>".} proc sigdelset*(a1: var Tsigset, a2: cint): cint {.importc, header: "<signal.h>".} proc sigemptyset*(a1: var Tsigset): cint {.importc, header: "<signal.h>".} proc sigfillset*(a1: var Tsigset): cint {.importc, header: "<signal.h>".} @@ -2308,20 +2308,20 @@ proc sigismember*(a1: var Tsigset, a2: cint): cint {.importc, header: "<signal.h proc signal*(a1: cint, a2: proc (x: cint) {.noconv.}) {. importc, header: "<signal.h>".} proc sigpause*(a1: cint): cint {.importc, header: "<signal.h>".} -proc sigpending*(a1: var tsigset): cint {.importc, header: "<signal.h>".} -proc sigprocmask*(a1: cint, a2, a3: var tsigset): cint {. +proc sigpending*(a1: var Tsigset): cint {.importc, header: "<signal.h>".} +proc sigprocmask*(a1: cint, a2, a3: var Tsigset): cint {. importc, header: "<signal.h>".} -proc sigqueue*(a1: tpid, a2: cint, a3: Tsigval): cint {. +proc sigqueue*(a1: TPid, a2: cint, a3: TsigVal): cint {. importc, header: "<signal.h>".} proc sigrelse*(a1: cint): cint {.importc, header: "<signal.h>".} proc sigset*(a1: int, a2: proc (x: cint) {.noconv.}) {. importc, header: "<signal.h>".} proc sigsuspend*(a1: var Tsigset): cint {.importc, header: "<signal.h>".} -proc sigtimedwait*(a1: var Tsigset, a2: var tsiginfo, - a3: var ttimespec): cint {.importc, header: "<signal.h>".} +proc sigtimedwait*(a1: var Tsigset, a2: var TsigInfo, + a3: var Ttimespec): cint {.importc, header: "<signal.h>".} proc sigwait*(a1: var Tsigset, a2: var cint): cint {. importc, header: "<signal.h>".} -proc sigwaitinfo*(a1: var Tsigset, a2: var tsiginfo): cint {. +proc sigwaitinfo*(a1: var Tsigset, a2: var TsigInfo): cint {. importc, header: "<signal.h>".} @@ -2333,81 +2333,81 @@ proc catopen*(a1: cstring, a2: cint): Tnl_catd {. proc sched_get_priority_max*(a1: cint): cint {.importc, header: "<sched.h>".} proc sched_get_priority_min*(a1: cint): cint {.importc, header: "<sched.h>".} -proc sched_getparam*(a1: tpid, a2: var Tsched_param): cint {. +proc sched_getparam*(a1: TPid, a2: var Tsched_param): cint {. importc, header: "<sched.h>".} -proc sched_getscheduler*(a1: tpid): cint {.importc, header: "<sched.h>".} -proc sched_rr_get_interval*(a1: tpid, a2: var Ttimespec): cint {. +proc sched_getscheduler*(a1: TPid): cint {.importc, header: "<sched.h>".} +proc sched_rr_get_interval*(a1: TPid, a2: var Ttimespec): cint {. importc, header: "<sched.h>".} -proc sched_setparam*(a1: tpid, a2: var Tsched_param): cint {. +proc sched_setparam*(a1: TPid, a2: var Tsched_param): cint {. importc, header: "<sched.h>".} -proc sched_setscheduler*(a1: tpid, a2: cint, a3: var tsched_param): cint {. +proc sched_setscheduler*(a1: TPid, a2: cint, a3: var Tsched_param): cint {. importc, header: "<sched.h>".} proc sched_yield*(): cint {.importc, header: "<sched.h>".} proc strerror*(errnum: cint): cstring {.importc, header: "<string.h>".} proc hstrerror*(herrnum: cint): cstring {.importc, header: "<netdb.h>".} -proc FD_CLR*(a1: cint, a2: var Tfd_set) {.importc, header: "<sys/select.h>".} -proc FD_ISSET*(a1: cint | TSocketHandle, a2: var Tfd_set): cint {. +proc FD_CLR*(a1: cint, a2: var TFdSet) {.importc, header: "<sys/select.h>".} +proc FD_ISSET*(a1: cint | TSocketHandle, a2: var TFdSet): cint {. importc, header: "<sys/select.h>".} -proc FD_SET*(a1: cint | TSocketHandle, a2: var Tfd_set) {.importc, header: "<sys/select.h>".} -proc FD_ZERO*(a1: var Tfd_set) {.importc, header: "<sys/select.h>".} +proc FD_SET*(a1: cint | TSocketHandle, a2: var TFdSet) {.importc, header: "<sys/select.h>".} +proc FD_ZERO*(a1: var TFdSet) {.importc, header: "<sys/select.h>".} -proc pselect*(a1: cint, a2, a3, a4: ptr Tfd_set, a5: ptr ttimespec, +proc pselect*(a1: cint, a2, a3, a4: ptr TFdSet, a5: ptr Ttimespec, a6: var Tsigset): cint {.importc, header: "<sys/select.h>".} -proc select*(a1: cint, a2, a3, a4: ptr Tfd_set, a5: ptr ttimeval): cint {. +proc select*(a1: cint, a2, a3, a4: ptr TFdSet, a5: ptr Ttimeval): cint {. importc, header: "<sys/select.h>".} when hasSpawnH: - proc posix_spawn*(a1: var tpid, a2: cstring, + proc posix_spawn*(a1: var TPid, a2: cstring, a3: var Tposix_spawn_file_actions, a4: var Tposix_spawnattr, a5, a6: cstringArray): cint {.importc, header: "<spawn.h>".} - proc posix_spawn_file_actions_addclose*(a1: var tposix_spawn_file_actions, + proc posix_spawn_file_actions_addclose*(a1: var Tposix_spawn_file_actions, a2: cint): cint {.importc, header: "<spawn.h>".} - proc posix_spawn_file_actions_adddup2*(a1: var tposix_spawn_file_actions, + proc posix_spawn_file_actions_adddup2*(a1: var Tposix_spawn_file_actions, a2, a3: cint): cint {.importc, header: "<spawn.h>".} - proc posix_spawn_file_actions_addopen*(a1: var tposix_spawn_file_actions, - a2: cint, a3: cstring, a4: cint, a5: tmode): cint {. + proc posix_spawn_file_actions_addopen*(a1: var Tposix_spawn_file_actions, + a2: cint, a3: cstring, a4: cint, a5: TMode): cint {. importc, header: "<spawn.h>".} proc posix_spawn_file_actions_destroy*( - a1: var tposix_spawn_file_actions): cint {.importc, header: "<spawn.h>".} + a1: var Tposix_spawn_file_actions): cint {.importc, header: "<spawn.h>".} proc posix_spawn_file_actions_init*( - a1: var tposix_spawn_file_actions): cint {.importc, header: "<spawn.h>".} - proc posix_spawnattr_destroy*(a1: var tposix_spawnattr): cint {. + a1: var Tposix_spawn_file_actions): cint {.importc, header: "<spawn.h>".} + proc posix_spawnattr_destroy*(a1: var Tposix_spawnattr): cint {. importc, header: "<spawn.h>".} - proc posix_spawnattr_getsigdefault*(a1: var tposix_spawnattr, + proc posix_spawnattr_getsigdefault*(a1: var Tposix_spawnattr, a2: var Tsigset): cint {.importc, header: "<spawn.h>".} - proc posix_spawnattr_getflags*(a1: var tposix_spawnattr, + proc posix_spawnattr_getflags*(a1: var Tposix_spawnattr, a2: var cshort): cint {.importc, header: "<spawn.h>".} - proc posix_spawnattr_getpgroup*(a1: var tposix_spawnattr, - a2: var tpid): cint {.importc, header: "<spawn.h>".} - proc posix_spawnattr_getschedparam*(a1: var tposix_spawnattr, - a2: var tsched_param): cint {.importc, header: "<spawn.h>".} - proc posix_spawnattr_getschedpolicy*(a1: var tposix_spawnattr, + proc posix_spawnattr_getpgroup*(a1: var Tposix_spawnattr, + a2: var TPid): cint {.importc, header: "<spawn.h>".} + proc posix_spawnattr_getschedparam*(a1: var Tposix_spawnattr, + a2: var Tsched_param): cint {.importc, header: "<spawn.h>".} + proc posix_spawnattr_getschedpolicy*(a1: var Tposix_spawnattr, a2: var cint): cint {.importc, header: "<spawn.h>".} - proc posix_spawnattr_getsigmask*(a1: var tposix_spawnattr, - a2: var tsigset): cint {.importc, header: "<spawn.h>".} + proc posix_spawnattr_getsigmask*(a1: var Tposix_spawnattr, + a2: var Tsigset): cint {.importc, header: "<spawn.h>".} - proc posix_spawnattr_init*(a1: var tposix_spawnattr): cint {. + proc posix_spawnattr_init*(a1: var Tposix_spawnattr): cint {. importc, header: "<spawn.h>".} - proc posix_spawnattr_setsigdefault*(a1: var tposix_spawnattr, - a2: var tsigset): cint {.importc, header: "<spawn.h>".} - proc posix_spawnattr_setflags*(a1: var tposix_spawnattr, a2: cint): cint {. + proc posix_spawnattr_setsigdefault*(a1: var Tposix_spawnattr, + a2: var Tsigset): cint {.importc, header: "<spawn.h>".} + proc posix_spawnattr_setflags*(a1: var Tposix_spawnattr, a2: cint): cint {. importc, header: "<spawn.h>".} - proc posix_spawnattr_setpgroup*(a1: var tposix_spawnattr, a2: tpid): cint {. + proc posix_spawnattr_setpgroup*(a1: var Tposix_spawnattr, a2: TPid): cint {. importc, header: "<spawn.h>".} - proc posix_spawnattr_setschedparam*(a1: var tposix_spawnattr, - a2: var tsched_param): cint {.importc, header: "<spawn.h>".} - proc posix_spawnattr_setschedpolicy*(a1: var tposix_spawnattr, + proc posix_spawnattr_setschedparam*(a1: var Tposix_spawnattr, + a2: var Tsched_param): cint {.importc, header: "<spawn.h>".} + proc posix_spawnattr_setschedpolicy*(a1: var Tposix_spawnattr, a2: cint): cint {. importc, header: "<spawn.h>".} - proc posix_spawnattr_setsigmask*(a1: var tposix_spawnattr, - a2: var tsigset): cint {.importc, header: "<spawn.h>".} - proc posix_spawnp*(a1: var tpid, a2: cstring, - a3: var tposix_spawn_file_actions, - a4: var tposix_spawnattr, + proc posix_spawnattr_setsigmask*(a1: var Tposix_spawnattr, + a2: var Tsigset): cint {.importc, header: "<spawn.h>".} + proc posix_spawnp*(a1: var TPid, a2: cstring, + a3: var Tposix_spawn_file_actions, + a4: var Tposix_spawnattr, a5, a6: cstringArray): cint {.importc, header: "<spawn.h>".} proc getcontext*(a1: var Tucontext): cint {.importc, header: "<ucontext.h>".} @@ -2424,10 +2424,10 @@ proc writev*(a1: cint, a2: ptr TIOVec, a3: cint): int {. proc CMSG_DATA*(cmsg: ptr Tcmsghdr): cstring {. importc, header: "<sys/socket.h>".} -proc CMSG_NXTHDR*(mhdr: ptr TMsgHdr, cmsg: ptr TCMsgHdr): ptr TCmsgHdr {. +proc CMSG_NXTHDR*(mhdr: ptr Tmsghdr, cmsg: ptr Tcmsghdr): ptr Tcmsghdr {. importc, header: "<sys/socket.h>".} -proc CMSG_FIRSTHDR*(mhdr: ptr TMsgHdr): ptr TCMsgHdr {. +proc CMSG_FIRSTHDR*(mhdr: ptr Tmsghdr): ptr Tcmsghdr {. importc, header: "<sys/socket.h>".} const @@ -2435,21 +2435,21 @@ const proc `==`*(x, y: TSocketHandle): bool {.borrow.} -proc accept*(a1: TSocketHandle, a2: ptr Tsockaddr, a3: ptr Tsocklen): TSocketHandle {. +proc accept*(a1: TSocketHandle, a2: ptr TSockAddr, a3: ptr TSocklen): TSocketHandle {. importc, header: "<sys/socket.h>".} -proc bindSocket*(a1: TSocketHandle, a2: ptr Tsockaddr, a3: Tsocklen): cint {. +proc bindSocket*(a1: TSocketHandle, a2: ptr TSockAddr, a3: TSocklen): cint {. importc: "bind", header: "<sys/socket.h>".} ## is Posix's ``bind``, because ``bind`` is a reserved word -proc connect*(a1: TSocketHandle, a2: ptr Tsockaddr, a3: Tsocklen): cint {. +proc connect*(a1: TSocketHandle, a2: ptr TSockAddr, a3: TSocklen): cint {. importc, header: "<sys/socket.h>".} -proc getpeername*(a1: TSocketHandle, a2: ptr Tsockaddr, a3: ptr Tsocklen): cint {. +proc getpeername*(a1: TSocketHandle, a2: ptr TSockAddr, a3: ptr TSocklen): cint {. importc, header: "<sys/socket.h>".} -proc getsockname*(a1: TSocketHandle, a2: ptr Tsockaddr, a3: ptr Tsocklen): cint {. +proc getsockname*(a1: TSocketHandle, a2: ptr TSockAddr, a3: ptr TSocklen): cint {. importc, header: "<sys/socket.h>".} -proc getsockopt*(a1: TSocketHandle, a2, a3: cint, a4: pointer, a5: ptr Tsocklen): cint {. +proc getsockopt*(a1: TSocketHandle, a2, a3: cint, a4: pointer, a5: ptr TSocklen): cint {. importc, header: "<sys/socket.h>".} proc listen*(a1: TSocketHandle, a2: cint): cint {. @@ -2457,7 +2457,7 @@ proc listen*(a1: TSocketHandle, a2: cint): cint {. proc recv*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint): int {. importc, header: "<sys/socket.h>".} proc recvfrom*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint, - a5: ptr Tsockaddr, a6: ptr Tsocklen): int {. + a5: ptr TSockAddr, a6: ptr TSocklen): int {. importc, header: "<sys/socket.h>".} proc recvmsg*(a1: TSocketHandle, a2: ptr Tmsghdr, a3: cint): int {. importc, header: "<sys/socket.h>".} @@ -2465,10 +2465,10 @@ proc send*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint): int {. importc, header: "<sys/socket.h>".} proc sendmsg*(a1: TSocketHandle, a2: ptr Tmsghdr, a3: cint): int {. importc, header: "<sys/socket.h>".} -proc sendto*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint, a5: ptr Tsockaddr, - a6: Tsocklen): int {. +proc sendto*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint, a5: ptr TSockAddr, + a6: TSocklen): int {. importc, header: "<sys/socket.h>".} -proc setsockopt*(a1: TSocketHandle, a2, a3: cint, a4: pointer, a5: Tsocklen): cint {. +proc setsockopt*(a1: TSocketHandle, a2, a3: cint, a4: pointer, a5: TSocklen): cint {. importc, header: "<sys/socket.h>".} proc shutdown*(a1: TSocketHandle, a2: cint): cint {. importc, header: "<sys/socket.h>".} @@ -2530,21 +2530,21 @@ proc freeaddrinfo*(a1: ptr Taddrinfo) {.importc, header: "<netdb.h>".} proc gai_strerror*(a1: cint): cstring {.importc, header: "<netdb.h>".} -proc getaddrinfo*(a1, a2: cstring, a3: ptr TAddrInfo, - a4: var ptr TAddrInfo): cint {.importc, header: "<netdb.h>".} +proc getaddrinfo*(a1, a2: cstring, a3: ptr Taddrinfo, + a4: var ptr Taddrinfo): cint {.importc, header: "<netdb.h>".} -proc gethostbyaddr*(a1: pointer, a2: Tsocklen, a3: cint): ptr THostent {. +proc gethostbyaddr*(a1: pointer, a2: TSocklen, a3: cint): ptr Thostent {. importc, header: "<netdb.h>".} -proc gethostbyname*(a1: cstring): ptr THostent {.importc, header: "<netdb.h>".} -proc gethostent*(): ptr THostent {.importc, header: "<netdb.h>".} +proc gethostbyname*(a1: cstring): ptr Thostent {.importc, header: "<netdb.h>".} +proc gethostent*(): ptr Thostent {.importc, header: "<netdb.h>".} -proc getnameinfo*(a1: ptr Tsockaddr, a2: Tsocklen, - a3: cstring, a4: Tsocklen, a5: cstring, - a6: Tsocklen, a7: cint): cint {.importc, header: "<netdb.h>".} +proc getnameinfo*(a1: ptr TSockAddr, a2: TSocklen, + a3: cstring, a4: TSocklen, a5: cstring, + a6: TSocklen, a7: cint): cint {.importc, header: "<netdb.h>".} -proc getnetbyaddr*(a1: int32, a2: cint): ptr TNetent {.importc, header: "<netdb.h>".} -proc getnetbyname*(a1: cstring): ptr TNetent {.importc, header: "<netdb.h>".} -proc getnetent*(): ptr TNetent {.importc, header: "<netdb.h>".} +proc getnetbyaddr*(a1: int32, a2: cint): ptr Tnetent {.importc, header: "<netdb.h>".} +proc getnetbyname*(a1: cstring): ptr Tnetent {.importc, header: "<netdb.h>".} +proc getnetent*(): ptr Tnetent {.importc, header: "<netdb.h>".} proc getprotobyname*(a1: cstring): ptr TProtoent {.importc, header: "<netdb.h>".} proc getprotobynumber*(a1: cint): ptr TProtoent {.importc, header: "<netdb.h>".} @@ -2560,10 +2560,10 @@ proc setnetent*(a1: cint) {.importc, header: "<netdb.h>".} proc setprotoent*(a1: cint) {.importc, header: "<netdb.h>".} proc setservent*(a1: cint) {.importc, header: "<netdb.h>".} -proc poll*(a1: ptr Tpollfd, a2: Tnfds, a3: int): cint {. +proc poll*(a1: ptr TPollfd, a2: Tnfds, a3: int): cint {. importc, header: "<poll.h>".} -proc realpath*(name, resolved: CString): CString {. +proc realpath*(name, resolved: cstring): cstring {. importc: "realpath", header: "<stdlib.h>".} diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index 8b44e69d9..df7ae6d17 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -34,7 +34,7 @@ proc reverse*[T](a: var openArray[T]) = ## reverses the array `a`. reverse(a, 0, a.high) -proc binarySearch*[T](a: openarray[T], key: T): int = +proc binarySearch*[T](a: openArray[T], key: T): int = ## binary search for `key` in `a`. Returns -1 if not found. var b = len(a) while result < b: @@ -79,7 +79,7 @@ proc merge[T](a, b: var openArray[T], lo, m, hi: int, inc(bb) inc(j) else: - CopyMem(addr(b[0]), addr(a[j]), sizeof(T)*(m-j+1)) + copyMem(addr(b[0]), addr(a[j]), sizeof(T)*(m-j+1)) j = m+1 var i = 0 var k = lo diff --git a/lib/pure/browsers.nim b/lib/pure/browsers.nim index b44f406c5..3a8429f81 100644 --- a/lib/pure/browsers.nim +++ b/lib/pure/browsers.nim @@ -29,9 +29,9 @@ proc openDefaultBrowser*(url: string) = when useWinUnicode: var o = newWideCString("open") var u = newWideCString(url) - discard ShellExecuteW(0'i32, o, u, nil, nil, SW_SHOWNORMAL) + discard shellExecuteW(0'i32, o, u, nil, nil, SW_SHOWNORMAL) else: - discard ShellExecuteA(0'i32, "open", url, nil, nil, SW_SHOWNORMAL) + discard shellExecuteA(0'i32, "open", url, nil, nil, SW_SHOWNORMAL) elif defined(macosx): discard execShellCmd("open " & quoteShell(url)) else: @@ -45,4 +45,4 @@ proc openDefaultBrowser*(url: string) = discard startProcess(command=b, args=[url], options={poUseShell}) return except EOS: - nil + discard diff --git a/lib/pure/collections/LockFreeHash.nim b/lib/pure/collections/LockFreeHash.nim index d3a91763a..b94b542ff 100644 --- a/lib/pure/collections/LockFreeHash.nim +++ b/lib/pure/collections/LockFreeHash.nim @@ -23,7 +23,8 @@ elif sizeof(int) == 8: # 64bit TRaw = range[0..4611686018427387903] ## The range of uint values that can be stored directly in a value slot ## when on a 64 bit platform -else: echo("unsupported platform") +else: + {.error: "unsupported platform".} type TEntry = tuple diff --git a/lib/pure/collections/intsets.nim b/lib/pure/collections/intsets.nim index 2a8d7eec2..f1e67fc0e 100644 --- a/lib/pure/collections/intsets.nim +++ b/lib/pure/collections/intsets.nim @@ -50,7 +50,7 @@ proc mustRehash(length, counter: int): bool {.inline.} = proc nextTry(h, maxHash: THash): THash {.inline.} = result = ((5 * h) + 1) and maxHash -proc IntSetGet(t: TIntSet, key: int): PTrunk = +proc intSetGet(t: TIntSet, key: int): PTrunk = var h = key and t.max while t.data[h] != nil: if t.data[h].key == key: @@ -58,7 +58,7 @@ proc IntSetGet(t: TIntSet, key: int): PTrunk = h = nextTry(h, t.max) result = nil -proc IntSetRawInsert(t: TIntSet, data: var TTrunkSeq, desc: PTrunk) = +proc intSetRawInsert(t: TIntSet, data: var TTrunkSeq, desc: PTrunk) = var h = desc.key and t.max while data[h] != nil: assert(data[h] != desc) @@ -66,22 +66,22 @@ proc IntSetRawInsert(t: TIntSet, data: var TTrunkSeq, desc: PTrunk) = assert(data[h] == nil) data[h] = desc -proc IntSetEnlarge(t: var TIntSet) = +proc intSetEnlarge(t: var TIntSet) = var n: TTrunkSeq var oldMax = t.max t.max = ((t.max + 1) * 2) - 1 newSeq(n, t.max + 1) - for i in countup(0, oldmax): - if t.data[i] != nil: IntSetRawInsert(t, n, t.data[i]) + for i in countup(0, oldMax): + if t.data[i] != nil: intSetRawInsert(t, n, t.data[i]) swap(t.data, n) -proc IntSetPut(t: var TIntSet, key: int): PTrunk = +proc intSetPut(t: var TIntSet, key: int): PTrunk = var h = key and t.max while t.data[h] != nil: if t.data[h].key == key: return t.data[h] h = nextTry(h, t.max) - if mustRehash(t.max + 1, t.counter): IntSetEnlarge(t) + if mustRehash(t.max + 1, t.counter): intSetEnlarge(t) inc(t.counter) h = key and t.max while t.data[h] != nil: h = nextTry(h, t.max) @@ -94,7 +94,7 @@ proc IntSetPut(t: var TIntSet, key: int): PTrunk = proc contains*(s: TIntSet, key: int): bool = ## returns true iff `key` is in `s`. - var t = IntSetGet(s, `shr`(key, TrunkShift)) + var t = intSetGet(s, `shr`(key, TrunkShift)) if t != nil: var u = key and TrunkMask result = (t.bits[`shr`(u, IntShift)] and `shl`(1, u and IntMask)) != 0 @@ -103,14 +103,14 @@ proc contains*(s: TIntSet, key: int): bool = proc incl*(s: var TIntSet, key: int) = ## includes an element `key` in `s`. - var t = IntSetPut(s, `shr`(key, TrunkShift)) + var t = intSetPut(s, `shr`(key, TrunkShift)) var u = key and TrunkMask t.bits[`shr`(u, IntShift)] = t.bits[`shr`(u, IntShift)] or `shl`(1, u and IntMask) proc excl*(s: var TIntSet, key: int) = ## excludes `key` from the set `s`. - var t = IntSetGet(s, `shr`(key, TrunkShift)) + var t = intSetGet(s, `shr`(key, TrunkShift)) if t != nil: var u = key and TrunkMask t.bits[`shr`(u, IntShift)] = t.bits[`shr`(u, IntShift)] and @@ -119,7 +119,7 @@ proc excl*(s: var TIntSet, key: int) = proc containsOrIncl*(s: var TIntSet, key: int): bool = ## returns true if `s` contains `key`, otherwise `key` is included in `s` ## and false is returned. - var t = IntSetGet(s, `shr`(key, TrunkShift)) + var t = intSetGet(s, `shr`(key, TrunkShift)) if t != nil: var u = key and TrunkMask result = (t.bits[`shr`(u, IntShift)] and `shl`(1, u and IntMask)) != 0 diff --git a/lib/pure/collections/lists.nim b/lib/pure/collections/lists.nim index ad8eca6a9..b8f8d20b5 100644 --- a/lib/pure/collections/lists.nim +++ b/lib/pure/collections/lists.nim @@ -41,19 +41,19 @@ type proc initSinglyLinkedList*[T](): TSinglyLinkedList[T] = ## creates a new singly linked list that is empty. - nil + discard proc initDoublyLinkedList*[T](): TDoublyLinkedList[T] = ## creates a new doubly linked list that is empty. - nil + discard proc initSinglyLinkedRing*[T](): TSinglyLinkedRing[T] = ## creates a new singly linked ring that is empty. - nil + discard proc initDoublyLinkedRing*[T](): TDoublyLinkedRing[T] = ## creates a new doubly linked ring that is empty. - nil + discard proc newDoublyLinkedNode*[T](value: T): PDoublyLinkedNode[T] = ## creates a new doubly linked node with the given `value`. diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim index 3a009a8cb..3993f1ccc 100644 --- a/lib/pure/collections/sequtils.nim +++ b/lib/pure/collections/sequtils.nim @@ -136,7 +136,7 @@ proc delete*[T](s: var seq[T], first=0, last=0) = s[i].shallowCopy(s[j]) inc(i) inc(j) - setlen(s, newLen) + setLen(s, newLen) proc insert*[T](dest: var seq[T], src: openArray[T], pos=0) = ## Inserts items from `src` into `dest` at position `pos`. This modifies diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim index 42b77d427..7259772aa 100644 --- a/lib/pure/collections/sets.nim +++ b/lib/pure/collections/sets.nim @@ -65,38 +65,38 @@ template rawInsertImpl() {.dirty.} = data[h].key = key data[h].slot = seFilled -proc RawGet[A](s: TSet[A], key: A): int = +proc rawGet[A](s: TSet[A], key: A): int = rawGetImpl() proc contains*[A](s: TSet[A], key: A): bool = ## returns true iff `key` is in `s`. - var index = RawGet(s, key) + var index = rawGet(s, key) result = index >= 0 -proc RawInsert[A](s: var TSet[A], data: var TKeyValuePairSeq[A], key: A) = +proc rawInsert[A](s: var TSet[A], data: var TKeyValuePairSeq[A], key: A) = rawInsertImpl() -proc Enlarge[A](s: var TSet[A]) = +proc enlarge[A](s: var TSet[A]) = var n: TKeyValuePairSeq[A] newSeq(n, len(s.data) * growthFactor) for i in countup(0, high(s.data)): - if s.data[i].slot == seFilled: RawInsert(s, n, s.data[i].key) + if s.data[i].slot == seFilled: rawInsert(s, n, s.data[i].key) swap(s.data, n) template inclImpl() {.dirty.} = - var index = RawGet(s, key) + var index = rawGet(s, key) if index < 0: - if mustRehash(len(s.data), s.counter): Enlarge(s) - RawInsert(s, s.data, key) + if mustRehash(len(s.data), s.counter): enlarge(s) + rawInsert(s, s.data, key) inc(s.counter) template containsOrInclImpl() {.dirty.} = - var index = RawGet(s, key) + var index = rawGet(s, key) if index >= 0: result = true else: - if mustRehash(len(s.data), s.counter): Enlarge(s) - RawInsert(s, s.data, key) + if mustRehash(len(s.data), s.counter): enlarge(s) + rawInsert(s, s.data, key) inc(s.counter) proc incl*[A](s: var TSet[A], key: A) = @@ -105,7 +105,7 @@ proc incl*[A](s: var TSet[A], key: A) = proc excl*[A](s: var TSet[A], key: A) = ## excludes `key` from the set `s`. - var index = RawGet(s, key) + var index = rawGet(s, key) if index >= 0: s.data[index].slot = seDeleted dec(s.counter) @@ -122,7 +122,7 @@ proc initSet*[A](initialSize=64): TSet[A] = result.counter = 0 newSeq(result.data, initialSize) -proc toSet*[A](keys: openarray[A]): TSet[A] = +proc toSet*[A](keys: openArray[A]): TSet[A] = ## creates a new hash set that contains the given `keys`. result = initSet[A](nextPowerOfTwo(keys.len+10)) for key in items(keys): result.incl(key) @@ -169,15 +169,15 @@ iterator items*[A](s: TOrderedSet[A]): A = forAllOrderedPairs: yield s.data[h].key -proc RawGet[A](s: TOrderedSet[A], key: A): int = +proc rawGet[A](s: TOrderedSet[A], key: A): int = rawGetImpl() proc contains*[A](s: TOrderedSet[A], key: A): bool = ## returns true iff `key` is in `s`. - var index = RawGet(s, key) + var index = rawGet(s, key) result = index >= 0 -proc RawInsert[A](s: var TOrderedSet[A], +proc rawInsert[A](s: var TOrderedSet[A], data: var TOrderedKeyValuePairSeq[A], key: A) = rawInsertImpl() data[h].next = -1 @@ -185,7 +185,7 @@ proc RawInsert[A](s: var TOrderedSet[A], if s.last >= 0: data[s.last].next = h s.last = h -proc Enlarge[A](s: var TOrderedSet[A]) = +proc enlarge[A](s: var TOrderedSet[A]) = var n: TOrderedKeyValuePairSeq[A] newSeq(n, len(s.data) * growthFactor) var h = s.first @@ -194,7 +194,7 @@ proc Enlarge[A](s: var TOrderedSet[A]) = while h >= 0: var nxt = s.data[h].next if s.data[h].slot == seFilled: - RawInsert(s, n, s.data[h].key) + rawInsert(s, n, s.data[h].key) h = nxt swap(s.data, n) @@ -216,7 +216,7 @@ proc initOrderedSet*[A](initialSize=64): TOrderedSet[A] = result.last = -1 newSeq(result.data, initialSize) -proc toOrderedSet*[A](keys: openarray[A]): TOrderedSet[A] = +proc toOrderedSet*[A](keys: openArray[A]): TOrderedSet[A] = ## creates a new ordered hash set that contains the given `keys`. result = initOrderedSet[A](nextPowerOfTwo(keys.len+10)) for key in items(keys): result.incl(key) @@ -224,5 +224,3 @@ proc toOrderedSet*[A](keys: openarray[A]): TOrderedSet[A] = proc `$`*[A](s: TOrderedSet[A]): string = ## The `$` operator for ordered hash sets. dollarImpl() - - diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 02d099c1f..73da274b9 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -85,7 +85,7 @@ template rawInsertImpl() {.dirty.} = data[h].val = val data[h].slot = seFilled -proc RawGet[A, B](t: TTable[A, B], key: A): int = +proc rawGet[A, B](t: TTable[A, B], key: A): int = rawGetImpl() proc `[]`*[A, B](t: TTable[A, B], key: A): B = @@ -93,13 +93,13 @@ proc `[]`*[A, B](t: TTable[A, B], key: A): B = ## default empty value for the type `B` is returned ## and no exception is raised. One can check with ``hasKey`` whether the key ## exists. - var index = RawGet(t, key) + var index = rawGet(t, key) if index >= 0: result = t.data[index].val proc mget*[A, B](t: var TTable[A, B], key: A): var B = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. - var index = RawGet(t, key) + var index = rawGet(t, key) if index >= 0: result = t.data[index].val else: raise newException(EInvalidKey, "key not found: " & $key) @@ -107,39 +107,39 @@ proc hasKey*[A, B](t: TTable[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 -proc RawInsert[A, B](t: var TTable[A, B], data: var TKeyValuePairSeq[A, B], +proc rawInsert[A, B](t: var TTable[A, B], data: var TKeyValuePairSeq[A, B], key: A, val: B) = rawInsertImpl() -proc Enlarge[A, B](t: var TTable[A, B]) = +proc enlarge[A, B](t: var TTable[A, B]) = var n: TKeyValuePairSeq[A, B] newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): - if t.data[i].slot == seFilled: RawInsert(t, n, t.data[i].key, t.data[i].val) + if t.data[i].slot == seFilled: rawInsert(t, n, t.data[i].key, t.data[i].val) swap(t.data, n) -template AddImpl() {.dirty.} = - if mustRehash(len(t.data), t.counter): Enlarge(t) - RawInsert(t, t.data, key, val) +template addImpl() {.dirty.} = + if mustRehash(len(t.data), t.counter): enlarge(t) + rawInsert(t, t.data, key, val) inc(t.counter) -template PutImpl() {.dirty.} = - var index = RawGet(t, key) +template putImpl() {.dirty.} = + var index = rawGet(t, key) if index >= 0: t.data[index].val = val else: - AddImpl() + addImpl() when false: # not yet used: - template HasKeyOrPutImpl() {.dirty.} = - var index = RawGet(t, key) + template hasKeyOrPutImpl() {.dirty.} = + var index = rawGet(t, key) if index >= 0: t.data[index].val = val result = true else: - if mustRehash(len(t.data), t.counter): Enlarge(t) - RawInsert(t, t.data, key, val) + if mustRehash(len(t.data), t.counter): enlarge(t) + rawInsert(t, t.data, key, val) inc(t.counter) result = false @@ -149,11 +149,11 @@ proc `[]=`*[A, B](t: var TTable[A, B], key: A, val: B) = proc add*[A, B](t: var TTable[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. - AddImpl() + addImpl() proc del*[A, B](t: var TTable[A, B], key: A) = ## deletes `key` from hash table `t`. - var index = RawGet(t, key) + let index = rawGet(t, key) if index >= 0: t.data[index].slot = seDeleted dec(t.counter) @@ -168,7 +168,7 @@ proc initTable*[A, B](initialSize=64): TTable[A, B] = result.counter = 0 newSeq(result.data, initialSize) -proc toTable*[A, B](pairs: openarray[tuple[key: A, +proc toTable*[A, B](pairs: openArray[tuple[key: A, val: B]]): TTable[A, B] = ## creates a new hash table that contains the given `pairs`. result = initTable[A, B](nextPowerOfTwo(pairs.len+10)) @@ -240,7 +240,7 @@ iterator mvalues*[A, B](t: var TOrderedTable[A, B]): var B = forAllOrderedPairs: yield t.data[h].val -proc RawGet[A, B](t: TOrderedTable[A, B], key: A): int = +proc rawGet[A, B](t: TOrderedTable[A, B], key: A): int = rawGetImpl() proc `[]`*[A, B](t: TOrderedTable[A, B], key: A): B = @@ -248,13 +248,13 @@ proc `[]`*[A, B](t: TOrderedTable[A, B], key: A): B = ## default empty value for the type `B` is returned ## and no exception is raised. One can check with ``hasKey`` whether the key ## exists. - var index = RawGet(t, key) + var index = rawGet(t, key) if index >= 0: result = t.data[index].val proc mget*[A, B](t: var TOrderedTable[A, B], key: A): var B = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. - var index = RawGet(t, key) + var index = rawGet(t, key) if index >= 0: result = t.data[index].val else: raise newException(EInvalidKey, "key not found: " & $key) @@ -262,7 +262,7 @@ proc hasKey*[A, B](t: TOrderedTable[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 -proc RawInsert[A, B](t: var TOrderedTable[A, B], +proc rawInsert[A, B](t: var TOrderedTable[A, B], data: var TOrderedKeyValuePairSeq[A, B], key: A, val: B) = rawInsertImpl() @@ -271,7 +271,7 @@ proc RawInsert[A, B](t: var TOrderedTable[A, B], if t.last >= 0: data[t.last].next = h t.last = h -proc Enlarge[A, B](t: var TOrderedTable[A, B]) = +proc enlarge[A, B](t: var TOrderedTable[A, B]) = var n: TOrderedKeyValuePairSeq[A, B] newSeq(n, len(t.data) * growthFactor) var h = t.first @@ -280,7 +280,7 @@ proc Enlarge[A, B](t: var TOrderedTable[A, B]) = while h >= 0: var nxt = t.data[h].next if t.data[h].slot == seFilled: - RawInsert(t, n, t.data[h].key, t.data[h].val) + rawInsert(t, n, t.data[h].key, t.data[h].val) h = nxt swap(t.data, n) @@ -290,7 +290,7 @@ proc `[]=`*[A, B](t: var TOrderedTable[A, B], key: A, val: B) = proc add*[A, B](t: var TOrderedTable[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. - AddImpl() + addImpl() proc initOrderedTable*[A, B](initialSize=64): TOrderedTable[A, B] = ## creates a new ordered hash table that is empty. @@ -304,7 +304,7 @@ proc initOrderedTable*[A, B](initialSize=64): TOrderedTable[A, B] = result.last = -1 newSeq(result.data, initialSize) -proc toOrderedTable*[A, B](pairs: openarray[tuple[key: A, +proc toOrderedTable*[A, B](pairs: openArray[tuple[key: A, val: B]]): TOrderedTable[A, B] = ## creates a new ordered hash table that contains the given `pairs`. result = initOrderedTable[A, B](nextPowerOfTwo(pairs.len+10)) @@ -398,7 +398,7 @@ iterator mvalues*[A](t: TCountTable[A]): var int = for h in 0..high(t.data): if t.data[h].val != 0: yield t.data[h].val -proc RawGet[A](t: TCountTable[A], key: A): int = +proc rawGet[A](t: TCountTable[A], key: A): int = var h: THash = hash(key) and high(t.data) # start with real hash value while t.data[h].val != 0: if t.data[h].key == key: return h @@ -409,13 +409,13 @@ proc `[]`*[A](t: TCountTable[A], key: A): int = ## retrieves the value at ``t[key]``. If `key` is not in `t`, ## 0 is returned. One can check with ``hasKey`` whether the key ## exists. - var index = RawGet(t, key) + var index = rawGet(t, key) if index >= 0: result = t.data[index].val proc mget*[A](t: var TCountTable[A], key: A): var int = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. - var index = RawGet(t, key) + var index = rawGet(t, key) if index >= 0: result = t.data[index].val else: raise newException(EInvalidKey, "key not found: " & $key) @@ -423,24 +423,24 @@ proc hasKey*[A](t: TCountTable[A], key: A): bool = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 -proc RawInsert[A](t: TCountTable[A], data: var seq[tuple[key: A, val: int]], +proc rawInsert[A](t: TCountTable[A], data: var seq[tuple[key: A, val: int]], key: A, val: int) = var h: THash = hash(key) and high(data) while data[h].val != 0: h = nextTry(h, high(data)) data[h].key = key data[h].val = val -proc Enlarge[A](t: var TCountTable[A]) = +proc enlarge[A](t: var TCountTable[A]) = var n: seq[tuple[key: A, val: int]] newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): - if t.data[i].val != 0: RawInsert(t, n, t.data[i].key, t.data[i].val) + if t.data[i].val != 0: rawInsert(t, n, t.data[i].key, t.data[i].val) swap(t.data, n) proc `[]=`*[A](t: var TCountTable[A], key: A, val: int) = ## puts a (key, value)-pair into `t`. `val` has to be positive. assert val > 0 - PutImpl() + putImpl() proc initCountTable*[A](initialSize=64): TCountTable[A] = ## creates a new count table that is empty. @@ -463,15 +463,15 @@ proc `$`*[A](t: TCountTable[A]): string = proc inc*[A](t: var TCountTable[A], key: A, val = 1) = ## increments `t[key]` by `val`. - var index = RawGet(t, key) + var index = rawGet(t, key) if index >= 0: inc(t.data[index].val, val) else: - if mustRehash(len(t.data), t.counter): Enlarge(t) - RawInsert(t, t.data, key, val) + if mustRehash(len(t.data), t.counter): enlarge(t) + rawInsert(t, t.data, key, val) inc(t.counter) -proc Smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] = +proc smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] = ## returns the largest (key,val)-pair. Efficiency: O(n) assert t.len > 0 var minIdx = 0 @@ -480,7 +480,7 @@ proc Smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] = result.key = t.data[minIdx].key result.val = t.data[minIdx].val -proc Largest*[A](t: TCountTable[A]): tuple[key: A, val: int] = +proc largest*[A](t: TCountTable[A]): tuple[key: A, val: int] = ## returns the (key,val)-pair with the largest `val`. Efficiency: O(n) assert t.len > 0 var maxIdx = 0 diff --git a/lib/pure/encodings.nim b/lib/pure/encodings.nim index ce4238409..94d21ed4e 100644 --- a/lib/pure/encodings.nim +++ b/lib/pure/encodings.nim @@ -1,7 +1,7 @@ # # # Nimrod's Runtime Library -# (c) Copyright 2012 Andreas Rumpf +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -14,21 +14,21 @@ import os, parseutils, strutils when not defined(windows): type - TConverter = object {.pure, final.} + TConverter = object PConverter* = ptr TConverter ## can convert between two character sets - + else: type TCodePage = distinct int32 - PConverter* = object {.pure.} + PConverter* = object dest, src: TCodePage - + type EInvalidEncoding* = object of EInvalidValue ## exception that is raised ## for encoding errors when defined(windows): - proc EqEncodingNames(a, b: string): bool = + proc eqEncodingNames(a, b: string): bool = var i = 0 var j = 0 while i < a.len and j < b.len: @@ -208,31 +208,31 @@ when defined(windows): when false: # not needed yet: type - TCpInfo = object {.pure.} - MaxCharSize: int32 - DefaultChar: array[0..1, char] - LeadByte: array[0..12-1, char] + TCpInfo = object + maxCharSize: int32 + defaultChar: array[0..1, char] + leadByte: array[0..12-1, char] - proc GetCPInfo(CodePage: TCodePage, lpCPInfo: var TCpInfo): int32 {. + proc getCPInfo(codePage: TCodePage, lpCPInfo: var TCpInfo): int32 {. stdcall, importc: "GetCPInfo", dynlib: "kernel32".} proc nameToCodePage(name: string): TCodePage = var nameAsInt: int if parseInt(name, nameAsInt) == 0: nameAsInt = -1 for no, na in items(winEncodings): - if no == nameAsInt or EqEncodingNames(na, name): return TCodePage(no) + if no == nameAsInt or eqEncodingNames(na, name): return TCodePage(no) result = TCodePage(-1) proc codePageToName(c: TCodePage): string = for no, na in items(winEncodings): - if no == int(c): + if no == int(c): return if na.len != 0: na else: $no result = "" - proc GetACP(): TCodePage {.stdcall, importc: "GetACP", dynlib: "kernel32".} + proc getACP(): TCodePage {.stdcall, importc: "GetACP", dynlib: "kernel32".} - proc MultiByteToWideChar( - CodePage: TCodePage, + proc multiByteToWideChar( + codePage: TCodePage, dwFlags: int32, lpMultiByteStr: cstring, cbMultiByte: cint, @@ -240,8 +240,8 @@ when defined(windows): cchWideChar: cint): cint {. stdcall, importc: "MultiByteToWideChar", dynlib: "kernel32".} - proc WideCharToMultiByte( - CodePage: TCodePage, + proc wideCharToMultiByte( + codePage: TCodePage, dwFlags: int32, lpWideCharStr: cstring, cchWideChar: cint, @@ -321,7 +321,6 @@ proc close*(c: PConverter) = iconvClose(c) when defined(windows): - proc convert*(c: PConverter, s: string): string = ## converts `s` to `destEncoding` that was given to the converter `c`. It ## assumed that `s` is in `srcEncoding`. @@ -333,26 +332,26 @@ when defined(windows): var cap = s.len + s.len shr 2 result = newStringOfCap(cap*2) # convert to utf-16 LE - var m = MultiByteToWideChar(CodePage = c.src, dwFlags = 0'i32, + var m = multiByteToWideChar(codePage = c.src, dwFlags = 0'i32, lpMultiByteStr = cstring(s), cbMultiByte = cint(s.len), lpWideCharStr = cstring(result), cchWideChar = cint(cap)) if m == 0: # try again; ask for capacity: - cap = MultiByteToWideChar(CodePage = c.src, dwFlags = 0'i32, + cap = multiByteToWideChar(codePage = c.src, dwFlags = 0'i32, lpMultiByteStr = cstring(s), cbMultiByte = cint(s.len), lpWideCharStr = nil, cchWideChar = cint(0)) # and do the conversion properly: result = newStringOfCap(cap*2) - m = MultiByteToWideChar(CodePage = c.src, dwFlags = 0'i32, + m = multiByteToWideChar(codePage = c.src, dwFlags = 0'i32, lpMultiByteStr = cstring(s), cbMultiByte = cint(s.len), lpWideCharStr = cstring(result), cchWideChar = cint(cap)) - if m == 0: OSError() + if m == 0: osError(osLastError()) setLen(result, m*2) elif m <= cap: setLen(result, m*2) @@ -364,8 +363,8 @@ when defined(windows): # otherwise the fun starts again: cap = s.len + s.len shr 2 var res = newStringOfCap(cap) - m = WideCharToMultiByte( - CodePage = c.dest, + m = wideCharToMultiByte( + codePage = c.dest, dwFlags = 0'i32, lpWideCharStr = cstring(result), cchWideChar = cint(result.len div 2), @@ -373,8 +372,8 @@ when defined(windows): cbMultiByte = cap.cint) if m == 0: # try again; ask for capacity: - cap = WideCharToMultiByte( - CodePage = c.dest, + cap = wideCharToMultiByte( + codePage = c.dest, dwFlags = 0'i32, lpWideCharStr = cstring(result), cchWideChar = cint(result.len div 2), @@ -382,14 +381,14 @@ when defined(windows): cbMultiByte = cint(0)) # and do the conversion properly: res = newStringOfCap(cap) - m = WideCharToMultiByte( - CodePage = c.dest, + m = wideCharToMultiByte( + codePage = c.dest, dwFlags = 0'i32, lpWideCharStr = cstring(result), cchWideChar = cint(result.len div 2), lpMultiByteStr = cstring(res), cbMultiByte = cap.cint) - if m == 0: OSError() + if m == 0: osError(osLastError()) setLen(res, m) result = res elif m <= cap: @@ -399,15 +398,14 @@ when defined(windows): assert(false) # cannot happen else: - proc convert*(c: PConverter, s: string): string = result = newString(s.len) - var inLen = len(S) + var inLen = len(s) var outLen = len(result) - var src = cstring(S) + var src = cstring(s) var dst = cstring(result) var iconvres: int - while InLen > 0: + while inLen > 0: iconvres = iconv(c, src, inLen, dst, outLen) if iconvres == -1: var lerr = errno @@ -425,11 +423,11 @@ else: dst = cast[cstring](cast[int](cstring(result)) + offset) outLen = len(result) - offset else: - OSError() + osError(lerr.TOSErrorCode) # iconv has a buffer that needs flushing, specially if the last char is # not '\0' discard iconv(c, nil, nil, dst, outlen) - if iconvres == Cint(-1) and errno == E2BIG: + if iconvres == cint(-1) and errno == E2BIG: var offset = cast[int](dst) - cast[int](cstring(result)) setLen(result, len(result)+inLen*2+5) # 5 is minimally one utf-8 char @@ -450,7 +448,7 @@ proc convert*(s: string, destEncoding = "UTF-8", finally: close(c) -when IsMainModule: +when isMainModule: let orig = "öäüß" cp1252 = convert(orig, "CP1252", "UTF-8") diff --git a/lib/pure/hashes.nim b/lib/pure/hashes.nim index 8a3135f89..ee05ad7e2 100644 --- a/lib/pure/hashes.nim +++ b/lib/pure/hashes.nim @@ -32,26 +32,26 @@ proc `!$`*(h: THash): THash {.inline.} = result = result xor (result shr 11) result = result +% result shl 15 -proc hashData*(Data: Pointer, Size: int): THash = +proc hashData*(data: pointer, size: int): THash = ## hashes an array of bytes of size `size` var h: THash = 0 when defined(js): var p: cstring asm """`p` = `Data`;""" else: - var p = cast[cstring](Data) + var p = cast[cstring](data) var i = 0 var s = size while s > 0: h = h !& ord(p[i]) - Inc(i) - Dec(s) + inc(i) + dec(s) result = !$h when defined(js): var objectID = 0 -proc hash*(x: Pointer): THash {.inline.} = +proc hash*(x: pointer): THash {.inline.} = ## efficient hashing of pointers when defined(js): asm """ @@ -126,6 +126,6 @@ proc hash*(x: float): THash {.inline.} = var y = x + 1.0 result = cast[ptr THash](addr(y))[] -proc hash*[A](x: openarray[A]): THash = +proc hash*[A](x: openArray[A]): THash = for it in items(x): result = result !& hash(it) result = !$result diff --git a/lib/pure/htmlgen.nim b/lib/pure/htmlgen.nim index 8d90f8589..63737d583 100644 --- a/lib/pure/htmlgen.nim +++ b/lib/pure/htmlgen.nim @@ -88,7 +88,7 @@ proc xmlCheckedTag*(e: PNimrodNode, tag: string, result.add(newStrLitNode("</")) result.add(newStrLitNode(tag)) result.add(newStrLitNode(">")) - result = NestList(!"&", result) + result = nestList(!"&", result) macro a*(e: expr): expr {.immediate.} = diff --git a/lib/pure/json.nim b/lib/pure/json.nim index df20bd852..360a3a5e7 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -135,7 +135,7 @@ proc str*(my: TJsonParser): string {.inline.} = assert(my.kind in {jsonInt, jsonFloat, jsonString}) return my.a -proc getInt*(my: TJsonParser): biggestInt {.inline.} = +proc getInt*(my: TJsonParser): BiggestInt {.inline.} = ## returns the number for the event: ``jsonInt`` assert(my.kind == jsonInt) return parseBiggestInt(my.a) @@ -151,11 +151,11 @@ proc kind*(my: TJsonParser): TJsonEventKind {.inline.} = proc getColumn*(my: TJsonParser): int {.inline.} = ## get the current column the parser has arrived at. - result = getColNumber(my, my.bufPos) + result = getColNumber(my, my.bufpos) proc getLine*(my: TJsonParser): int {.inline.} = ## get the current line the parser has arrived at. - result = my.linenumber + result = my.lineNumber proc getFilename*(my: TJsonParser): string {.inline.} = ## get the filename of the file that the parser processes. @@ -173,7 +173,7 @@ proc errorMsgExpected*(my: TJsonParser, e: string): string = result = "$1($2, $3) Error: $4" % [ my.filename, $getLine(my), $getColumn(my), e & " expected"] -proc handleHexChar(c: Char, x: var int): bool = +proc handleHexChar(c: char, x: var int): bool = result = true # Success case c of '0'..'9': x = (x shl 4) or (ord(c) - ord('0')) @@ -227,11 +227,11 @@ proc parseString(my: var TJsonParser): TTokKind = add(my.a, buf[pos]) inc(pos) of '\c': - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf add(my.a, '\c') of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf add(my.a, '\L') else: @@ -253,11 +253,11 @@ proc skip(my: var TJsonParser) = of '\0': break of '\c': - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf break of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf break else: @@ -271,10 +271,10 @@ proc skip(my: var TJsonParser) = my.err = errEOC_Expected break of '\c': - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf of '*': inc(pos) @@ -286,12 +286,12 @@ proc skip(my: var TJsonParser) = else: break of ' ', '\t': - Inc(pos) + inc(pos) of '\c': - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf else: break @@ -517,7 +517,7 @@ type of JString: str*: string of JInt: - num*: biggestInt + num*: BiggestInt of JFloat: fnum*: float of JBool: @@ -535,30 +535,30 @@ proc raiseParseErr*(p: TJsonParser, msg: string) {.noinline, noreturn.} = ## raises an `EJsonParsingError` exception. raise newException(EJsonParsingError, errorMsgExpected(p, msg)) -proc newJString*(s: String): PJsonNode = +proc newJString*(s: string): PJsonNode = ## Creates a new `JString PJsonNode`. new(result) result.kind = JString result.str = s -proc newJStringMove(s: String): PJsonNode = +proc newJStringMove(s: string): PJsonNode = new(result) result.kind = JString shallowCopy(result.str, s) -proc newJInt*(n: biggestInt): PJsonNode = +proc newJInt*(n: BiggestInt): PJsonNode = ## Creates a new `JInt PJsonNode`. new(result) result.kind = JInt result.num = n -proc newJFloat*(n: Float): PJsonNode = +proc newJFloat*(n: float): PJsonNode = ## Creates a new `JFloat PJsonNode`. new(result) result.kind = JFloat result.fnum = n -proc newJBool*(b: Bool): PJsonNode = +proc newJBool*(b: bool): PJsonNode = ## Creates a new `JBool PJsonNode`. new(result) result.kind = JBool @@ -587,7 +587,7 @@ proc `%`*(s: string): PJsonNode = result.kind = JString result.str = s -proc `%`*(n: biggestInt): PJsonNode = +proc `%`*(n: BiggestInt): PJsonNode = ## Generic constructor for JSON data. Creates a new `JInt PJsonNode`. new(result) result.kind = JInt @@ -612,7 +612,7 @@ proc `%`*(keyVals: openArray[tuple[key: string, val: PJsonNode]]): PJsonNode = newSeq(result.fields, keyVals.len) for i, p in pairs(keyVals): result.fields[i] = p -proc `%`*(elements: openArray[PJSonNode]): PJsonNode = +proc `%`*(elements: openArray[PJsonNode]): PJsonNode = ## Generic constructor for JSON data. Creates a new `JArray PJsonNode` new(result) result.kind = JArray @@ -628,7 +628,7 @@ proc len*(n: PJsonNode): int = of JObject: result = n.fields.len else: nil -proc `[]`*(node: PJsonNode, name: String): PJsonNode = +proc `[]`*(node: PJsonNode, name: string): PJsonNode = ## Gets a field from a `JObject`. Returns nil if the key is not found. assert(node.kind == JObject) for key, item in items(node.fields): @@ -636,17 +636,17 @@ proc `[]`*(node: PJsonNode, name: String): PJsonNode = return item return nil -proc `[]`*(node: PJsonNode, index: Int): PJsonNode = +proc `[]`*(node: PJsonNode, index: int): PJsonNode = ## Gets the node at `index` in an Array. assert(node.kind == JArray) return node.elems[index] -proc hasKey*(node: PJsonNode, key: String): Bool = +proc hasKey*(node: PJsonNode, key: string): bool = ## Checks if `key` exists in `node`. assert(node.kind == JObject) for k, item in items(node.fields): - if k == key: return True -proc existsKey*(node: PJsonNode, key: String): Bool {.deprecated.} = node.hasKey(key) + if k == key: return true +proc existsKey*(node: PJsonNode, key: string): bool {.deprecated.} = node.hasKey(key) ## Deprecated for `hasKey` proc add*(father, child: PJsonNode) = @@ -661,7 +661,7 @@ proc add*(obj: PJsonNode, key: string, val: PJsonNode) = assert obj.kind == JObject obj.fields.add((key, val)) -proc `[]=`*(obj: PJsonNode, key: String, val: PJsonNode) = +proc `[]=`*(obj: PJsonNode, key: string, val: PJsonNode) = ## Sets a field from a `JObject`. Performs a check for duplicate keys. assert(obj.kind == JObject) for i in 0..obj.fields.len-1: @@ -706,7 +706,7 @@ proc copy*(p: PJsonNode): PJsonNode = proc indent(s: var string, i: int) = s.add(repeatChar(i)) -proc newIndent(curr, indent: int, ml: bool): Int = +proc newIndent(curr, indent: int, ml: bool): int = if ml: return curr + indent else: return indent @@ -730,8 +730,8 @@ proc escapeJson*(s: string): string = result.add(toHex(r, 4)) result.add("\"") -proc toPretty(result: var string, node: PJsonNode, indent = 2, ml = True, - lstArr = False, currIndent = 0) = +proc toPretty(result: var string, node: PJsonNode, indent = 2, ml = true, + lstArr = false, currIndent = 0) = case node.kind of JObject: if currIndent != 0 and not lstArr: result.nl(ml) @@ -747,7 +747,7 @@ proc toPretty(result: var string, node: PJsonNode, indent = 2, ml = True, result.indent(newIndent(currIndent, indent, ml)) result.add(escapeJson(node.fields[i].key)) result.add(": ") - toPretty(result, node.fields[i].val, indent, ml, False, + toPretty(result, node.fields[i].val, indent, ml, false, newIndent(currIndent, indent, ml)) result.nl(ml) result.indent(currIndent) # indent the same as { @@ -776,7 +776,7 @@ proc toPretty(result: var string, node: PJsonNode, indent = 2, ml = True, result.add(", ") result.nl(ml) # New Line toPretty(result, node.elems[i], indent, ml, - True, newIndent(currIndent, indent, ml)) + true, newIndent(currIndent, indent, ml)) result.nl(ml) result.indent(currIndent) result.add("]") @@ -785,18 +785,18 @@ proc toPretty(result: var string, node: PJsonNode, indent = 2, ml = True, if lstArr: result.indent(currIndent) result.add("null") -proc pretty*(node: PJsonNode, indent = 2): String = +proc pretty*(node: PJsonNode, indent = 2): string = ## Converts `node` to its JSON Representation, with indentation and ## on multiple lines. result = "" toPretty(result, node, indent) -proc `$`*(node: PJsonNode): String = +proc `$`*(node: PJsonNode): string = ## Converts `node` to its JSON Representation on one line. result = "" - toPretty(result, node, 1, False) + toPretty(result, node, 1, false) -iterator items*(node: PJsonNode): PJSonNode = +iterator items*(node: PJsonNode): PJsonNode = ## Iterator for the items of `node`. `node` has to be a JArray. assert node.kind == JArray for i in items(node.elems): diff --git a/lib/pure/lexbase.nim b/lib/pure/lexbase.nim index 2756290d8..eee95e2e6 100644 --- a/lib/pure/lexbase.nim +++ b/lib/pure/lexbase.nim @@ -31,7 +31,7 @@ type buf*: cstring ## the buffer itself bufLen*: int ## length of buffer in characters input: PStream ## the input stream - LineNumber*: int ## the current line number + lineNumber*: int ## the current line number sentinel: int lineStart: int # index of last line start in buffer fileOpened: bool @@ -48,11 +48,11 @@ proc getCurrentLine*(L: TBaseLexer, marker: bool = true): string proc getColNumber*(L: TBaseLexer, pos: int): int ## retrieves the current column. -proc HandleCR*(L: var TBaseLexer, pos: int): int +proc handleCR*(L: var TBaseLexer, pos: int): int ## Call this if you scanned over '\c' in the buffer; it returns the the ## position to continue the scanning from. `pos` must be the position ## of the '\c'. -proc HandleLF*(L: var TBaseLexer, pos: int): int +proc handleLF*(L: var TBaseLexer, pos: int): int ## Call this if you scanned over '\L' in the buffer; it returns the the ## position to continue the scanning from. `pos` must be the position ## of the '\L'. @@ -66,7 +66,7 @@ proc close(L: var TBaseLexer) = dealloc(L.buf) close(L.input) -proc FillBuffer(L: var TBaseLexer) = +proc fillBuffer(L: var TBaseLexer) = var charsRead, toCopy, s: int # all are in characters, # not bytes (in case this @@ -75,10 +75,10 @@ proc FillBuffer(L: var TBaseLexer) = # we know here that pos == L.sentinel, but not if this proc # is called the first time by initBaseLexer() assert(L.sentinel < L.bufLen) - toCopy = L.BufLen - L.sentinel - 1 + toCopy = L.bufLen - L.sentinel - 1 assert(toCopy >= 0) if toCopy > 0: - MoveMem(L.buf, addr(L.buf[L.sentinel + 1]), toCopy * chrSize) + moveMem(L.buf, addr(L.buf[L.sentinel + 1]), toCopy * chrSize) # "moveMem" handles overlapping regions charsRead = readData(L.input, addr(L.buf[toCopy]), (L.sentinel + 1) * chrSize) div chrSize @@ -91,7 +91,7 @@ proc FillBuffer(L: var TBaseLexer) = dec(s) # BUGFIX (valgrind) while true: assert(s < L.bufLen) - while (s >= 0) and not (L.buf[s] in NewLines): Dec(s) + while (s >= 0) and not (L.buf[s] in NewLines): dec(s) if s >= 0: # we found an appropriate character for a sentinel: L.sentinel = s @@ -99,11 +99,11 @@ proc FillBuffer(L: var TBaseLexer) = else: # rather than to give up here because the line is too long, # double the buffer's size and try again: - oldBufLen = L.BufLen - L.bufLen = L.BufLen * 2 + oldBufLen = L.bufLen + L.bufLen = L.bufLen * 2 L.buf = cast[cstring](realloc(L.buf, L.bufLen * chrSize)) - assert(L.bufLen - oldBuflen == oldBufLen) - charsRead = ReadData(L.input, addr(L.buf[oldBufLen]), + assert(L.bufLen - oldBufLen == oldBufLen) + charsRead = readData(L.input, addr(L.buf[oldBufLen]), oldBufLen * chrSize) div chrSize if charsRead < oldBufLen: L.buf[oldBufLen + charsRead] = EndOfFile @@ -121,19 +121,19 @@ proc fillBaseLexer(L: var TBaseLexer, pos: int): int = result = 0 L.lineStart = result -proc HandleCR(L: var TBaseLexer, pos: int): int = +proc handleCR(L: var TBaseLexer, pos: int): int = assert(L.buf[pos] == '\c') - inc(L.linenumber) + inc(L.lineNumber) result = fillBaseLexer(L, pos) if L.buf[result] == '\L': result = fillBaseLexer(L, result) -proc HandleLF(L: var TBaseLexer, pos: int): int = +proc handleLF(L: var TBaseLexer, pos: int): int = assert(L.buf[pos] == '\L') - inc(L.linenumber) + inc(L.lineNumber) result = fillBaseLexer(L, pos) #L.lastNL := result-1; // BUGFIX: was: result; -proc skip_UTF_8_BOM(L: var TBaseLexer) = +proc skipUtf8Bom(L: var TBaseLexer) = if (L.buf[0] == '\xEF') and (L.buf[1] == '\xBB') and (L.buf[2] == '\xBF'): inc(L.bufpos, 3) inc(L.lineStart, 3) @@ -147,9 +147,9 @@ proc open(L: var TBaseLexer, input: PStream, bufLen: int = 8192) = L.buf = cast[cstring](alloc(bufLen * chrSize)) L.sentinel = bufLen - 1 L.lineStart = 0 - L.linenumber = 1 # lines start at 1 + L.lineNumber = 1 # lines start at 1 fillBuffer(L) - skip_UTF_8_BOM(L) + skipUtf8Bom(L) proc getColNumber(L: TBaseLexer, pos: int): int = result = abs(pos - L.lineStart) @@ -163,5 +163,5 @@ proc getCurrentLine(L: TBaseLexer, marker: bool = true): string = inc(i) add(result, "\n") if marker: - add(result, RepeatChar(getColNumber(L, L.bufpos)) & "^\n") + add(result, repeatChar(getColNumber(L, L.bufpos)) & "^\n") diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 35b9607e0..062cfae25 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -94,7 +94,7 @@ proc nextPowerOfTwo*(x: int): int = result = result or (result shr 4) result = result or (result shr 2) result = result or (result shr 1) - Inc(result) + inc(result) proc countBits32*(n: int32): int {.noSideEffect.} = ## counts the set bits in `n`. @@ -103,17 +103,17 @@ proc countBits32*(n: int32): int {.noSideEffect.} = v = (v and 0x33333333'i32) +% ((v shr 2'i32) and 0x33333333'i32) result = ((v +% (v shr 4'i32) and 0xF0F0F0F'i32) *% 0x1010101'i32) shr 24'i32 -proc sum*[T](x: openarray[T]): T {.noSideEffect.} = +proc sum*[T](x: openArray[T]): T {.noSideEffect.} = ## computes the sum of the elements in `x`. ## If `x` is empty, 0 is returned. for i in items(x): result = result + i -proc mean*(x: openarray[float]): float {.noSideEffect.} = +proc mean*(x: openArray[float]): float {.noSideEffect.} = ## computes the mean of the elements in `x`. ## If `x` is empty, NaN is returned. result = sum(x) / toFloat(len(x)) -proc variance*(x: openarray[float]): float {.noSideEffect.} = +proc variance*(x: openArray[float]): float {.noSideEffect.} = ## computes the variance of the elements in `x`. ## If `x` is empty, NaN is returned. result = 0.0 diff --git a/lib/pure/md5.nim b/lib/pure/md5.nim index e75f80b4c..0328932fd 100644 --- a/lib/pure/md5.nim +++ b/lib/pure/md5.nim @@ -16,9 +16,9 @@ type MD5Digest* = array[0..15, int8] MD5Buffer = array[0..63, int8] MD5Context* {.final.} = object - State: MD5State - Count: array[0..1, int32] - Buffer: MD5Buffer + state: MD5State + count: array[0..1, int32] + buffer: MD5Buffer const padding: cstring = "\x80\0\0\0" & @@ -32,16 +32,16 @@ const "\0\0\0\0" proc F(x, y, z: int32): int32 {.inline.} = - Result = (x and y) or ((not x) and z) + result = (x and y) or ((not x) and z) proc G(x, y, z: int32): int32 {.inline.} = - Result = (x and z) or (y and (not z)) + result = (x and z) or (y and (not z)) proc H(x, y, z: int32): int32 {.inline.} = - Result = x xor y xor z + result = x xor y xor z proc I(x, y, z: int32): int32 {.inline.} = - Result = y xor (x or (not z)) + result = y xor (x or (not z)) proc rot(x: var int32, n: int8) {.inline.} = x = toU32(x shl ze(n)) or (x shr toU32(32 -% ze(n))) @@ -75,7 +75,7 @@ proc encode(dest: var MD5Block, src: cstring) = ord(src[j+3]) shl 24) inc(j, 4) -proc decode(dest: var openarray[int8], src: openarray[int32]) = +proc decode(dest: var openArray[int8], src: openArray[int32]) = var i = 0 for j in 0..high(src): dest[i] = toU8(src[j] and 0xff'i32) @@ -87,7 +87,7 @@ proc decode(dest: var openarray[int8], src: openarray[int32]) = proc transform(Buffer: pointer, State: var MD5State) = var myBlock: MD5Block - encode(myBlock, cast[cstring](buffer)) + encode(myBlock, cast[cstring](Buffer)) var a = State[0] var b = State[1] var c = State[2] @@ -161,7 +161,7 @@ proc transform(Buffer: pointer, State: var MD5State) = State[2] = State[2] +% c State[3] = State[3] +% d -proc MD5Init*(c: var MD5Context) = +proc md5Init*(c: var MD5Context) = ## initializes a MD5Context c.State[0] = 0x67452301'i32 c.State[1] = 0xEFCDAB89'i32 @@ -169,64 +169,64 @@ proc MD5Init*(c: var MD5Context) = c.State[3] = 0x10325476'i32 c.Count[0] = 0'i32 c.Count[1] = 0'i32 - ZeroMem(addr(c.Buffer), SizeOf(MD5Buffer)) + zeroMem(addr(c.Buffer), sizeof(MD5Buffer)) -proc MD5Update*(c: var MD5Context, input: cstring, len: int) = +proc md5Update*(c: var MD5Context, input: cstring, len: int) = ## updates the MD5Context with the `input` data of length `len` var input = input - var Index = (c.Count[0] shr 3) and 0x3F + var Index = (c.count[0] shr 3) and 0x3F c.Count[0] = c.count[0] +% toU32(len shl 3) if c.Count[0] < (len shl 3): c.Count[1] = c.count[1] +% 1'i32 c.Count[1] = c.count[1] +% toU32(len shr 29) var PartLen = 64 - Index if len >= PartLen: - CopyMem(addr(c.Buffer[Index]), Input, PartLen) + copyMem(addr(c.Buffer[Index]), input, PartLen) transform(addr(c.Buffer), c.State) var i = PartLen while i + 63 < len: - Transform(addr(Input[I]), c.State) + transform(addr(input[i]), c.State) inc(i, 64) - CopyMem(addr(c.Buffer[0]), addr(Input[i]), len-i) + copyMem(addr(c.Buffer[0]), addr(input[i]), len-i) else: - CopyMem(addr(c.Buffer[Index]), addr(Input[0]), len) + copyMem(addr(c.Buffer[Index]), addr(input[0]), len) -proc MD5Final*(c: var MD5Context, digest: var MD5Digest) = +proc md5Final*(c: var MD5Context, digest: var MD5Digest) = ## finishes the MD5Context and stores the result in `digest` var Bits: MD5CBits PadLen: int - decode(bits, c.Count) + decode(Bits, c.Count) var Index = (c.Count[0] shr 3) and 0x3F if Index < 56: PadLen = 56 - Index else: PadLen = 120 - Index - MD5Update(c, padding, PadLen) - MD5Update(c, cast[cstring](addr(Bits)), 8) + md5Update(c, padding, PadLen) + md5Update(c, cast[cstring](addr(Bits)), 8) decode(digest, c.State) - ZeroMem(addr(c), SizeOf(MD5Context)) + zeroMem(addr(c), sizeof(MD5Context)) proc toMD5*(s: string): MD5Digest = ## computes the MD5Digest value for a string `s` var c: MD5Context - MD5Init(c) - MD5Update(c, cstring(s), len(s)) - MD5Final(c, result) + md5Init(c) + md5Update(c, cstring(s), len(s)) + md5Final(c, result) proc `$`*(D: MD5Digest): string = ## converts a MD5Digest value into its string representation const digits = "0123456789abcdef" result = "" for i in 0..15: - add(result, Digits[(D[I] shr 4) and 0xF]) - add(result, Digits[D[I] and 0xF]) + add(result, Digits[(D[i] shr 4) and 0xF]) + add(result, Digits[D[i] and 0xF]) proc getMD5*(s: string): string = ## computes an MD5 value of `s` and returns its string representation var c: MD5Context d: MD5Digest - MD5Init(c) - MD5Update(c, cstring(s), len(s)) - MD5Final(c, d) + md5Init(c) + md5Update(c, cstring(s), len(s)) + md5Final(c, d) result = $d proc `==`*(D1, D2: MD5Digest): bool = diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index 9f4094b40..8c404abe8 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -52,9 +52,9 @@ proc open*(filename: string, mode: TFileMode = fmRead, when defined(windows): template fail(errCode: TOSErrorCode, msg: expr) = rollback() - if result.fHandle != 0: discard CloseHandle(result.fHandle) - if result.mapHandle != 0: discard CloseHandle(result.mapHandle) - OSError(errCode) + if result.fHandle != 0: discard closeHandle(result.fHandle) + if result.mapHandle != 0: discard closeHandle(result.mapHandle) + osError(errCode) # return false #raise newException(EIO, msg) @@ -69,36 +69,36 @@ proc open*(filename: string, mode: TFileMode = fmRead, 0) when useWinUnicode: - result.fHandle = callCreateFile(CreateFileW, newWideCString(filename)) + result.fHandle = callCreateFile(createFileW, newWideCString(filename)) else: result.fHandle = callCreateFile(CreateFileA, filename) if result.fHandle == INVALID_HANDLE_VALUE: - fail(OSLastError(), "error opening file") + fail(osLastError(), "error opening file") if newFileSize != -1: var sizeHigh = int32(newFileSize shr 32) sizeLow = int32(newFileSize and 0xffffffff) - var status = SetFilePointer(result.fHandle, sizeLow, addr(sizeHigh), + var status = setFilePointer(result.fHandle, sizeLow, addr(sizeHigh), FILE_BEGIN) - let lastErr = OSLastError() + let lastErr = osLastError() if (status == INVALID_SET_FILE_POINTER and lastErr.int32 != NO_ERROR) or - (SetEndOfFile(result.fHandle) == 0): + (setEndOfFile(result.fHandle) == 0): fail(lastErr, "error setting file size") # since the strings are always 'nil', we simply always call # CreateFileMappingW which should be slightly faster anyway: - result.mapHandle = CreateFileMappingW( + result.mapHandle = createFileMappingW( result.fHandle, nil, if readonly: PAGE_READONLY else: PAGE_READWRITE, 0, 0, nil) if result.mapHandle == 0: - fail(OSLastError(), "error creating mapping") + fail(osLastError(), "error creating mapping") - result.mem = MapViewOfFileEx( + result.mem = mapViewOfFileEx( result.mapHandle, if readonly: FILE_MAP_READ else: FILE_MAP_WRITE, int32(offset shr 32), @@ -107,12 +107,12 @@ proc open*(filename: string, mode: TFileMode = fmRead, nil) if result.mem == nil: - fail(OSLastError(), "error mapping view") + fail(osLastError(), "error mapping view") var hi, low: int32 - low = GetFileSize(result.fHandle, addr(hi)) + low = getFileSize(result.fHandle, addr(hi)) if low == INVALID_FILE_SIZE: - fail(OSLastError(), "error getting file size") + fail(osLastError(), "error getting file size") else: var fileSize = (int64(hi) shr 32) or low if mappedSize != -1: result.size = min(fileSize, mappedSize).int @@ -122,7 +122,7 @@ proc open*(filename: string, mode: TFileMode = fmRead, template fail(errCode: TOSErrorCode, msg: expr) = rollback() if result.handle != 0: discard close(result.handle) - OSError(errCode) + osError(errCode) var flags = if readonly: O_RDONLY else: O_RDWR @@ -133,22 +133,22 @@ proc open*(filename: string, mode: TFileMode = fmRead, if result.handle == -1: # XXX: errno is supposed to be set here # Is there an exception that wraps it? - fail(OSLastError(), "error opening file") + fail(osLastError(), "error opening file") if newFileSize != -1: if ftruncate(result.handle, newFileSize) == -1: - fail(OSLastError(), "error setting file size") + fail(osLastError(), "error setting file size") if mappedSize != -1: result.size = mappedSize else: - var stat: Tstat + var stat: TStat if fstat(result.handle, stat) != -1: # XXX: Hmm, this could be unsafe # Why is mmap taking int anyway? result.size = int(stat.st_size) else: - fail(OSLastError(), "error getting file size") + fail(osLastError(), "error getting file size") result.mem = mmap( nil, @@ -159,7 +159,7 @@ proc open*(filename: string, mode: TFileMode = fmRead, offset) if result.mem == cast[pointer](MAP_FAILED): - fail(OSLastError(), "file mapping failed") + fail(osLastError(), "file mapping failed") proc close*(f: var TMemFile) = ## closes the memory mapped file `f`. All changes are written back to the @@ -170,13 +170,13 @@ proc close*(f: var TMemFile) = when defined(windows): if f.fHandle != INVALID_HANDLE_VALUE: - lastErr = OSLastError() - error = UnmapViewOfFile(f.mem) == 0 - error = (CloseHandle(f.mapHandle) == 0) or error - error = (CloseHandle(f.fHandle) == 0) or error + lastErr = osLastError() + error = unmapViewOfFile(f.mem) == 0 + error = (closeHandle(f.mapHandle) == 0) or error + error = (closeHandle(f.fHandle) == 0) or error else: if f.handle != 0: - lastErr = OSLastError() + lastErr = osLastError() error = munmap(f.mem, f.size) != 0 error = (close(f.handle) != 0) or error @@ -189,5 +189,5 @@ proc close*(f: var TMemFile) = else: f.handle = 0 - if error: OSError(lastErr) + if error: osError(lastErr) diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 7a8722ab4..448ecc1e3 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -93,11 +93,11 @@ when defined(Nimdoc): # only for proper documentation: elif defined(macos): const - curdir* = ':' - pardir* = "::" - dirsep* = ':' - altsep* = dirsep - pathsep* = ',' + CurDir* = ':' + ParDir* = "::" + DirSep* = ':' + AltSep* = Dirsep + PathSep* = ',' FileSystemCaseSensitive* = false ExeExt* = "" ScriptExt* = "" @@ -123,57 +123,61 @@ elif defined(macos): # grandparent etc. elif doslike: const - curdir* = '.' - pardir* = ".." - dirsep* = '\\' # seperator within paths - altsep* = '/' - pathSep* = ';' # seperator between paths + CurDir* = '.' + ParDir* = ".." + DirSep* = '\\' # seperator within paths + AltSep* = '/' + PathSep* = ';' # seperator between paths FileSystemCaseSensitive* = false ExeExt* = "exe" ScriptExt* = "bat" DynlibFormat* = "$1.dll" elif defined(PalmOS) or defined(MorphOS): const - dirsep* = '/' - altsep* = dirsep + DirSep* = '/' + AltSep* = Dirsep PathSep* = ';' - pardir* = ".." + ParDir* = ".." FileSystemCaseSensitive* = false ExeExt* = "" ScriptExt* = "" DynlibFormat* = "$1.prc" elif defined(RISCOS): const - dirsep* = '.' - altsep* = '.' - pardir* = ".." # is this correct? - pathSep* = ',' + DirSep* = '.' + AltSep* = '.' + ParDir* = ".." # is this correct? + PathSep* = ',' FileSystemCaseSensitive* = true ExeExt* = "" ScriptExt* = "" DynlibFormat* = "lib$1.so" else: # UNIX-like operating system const - curdir* = '.' - pardir* = ".." - dirsep* = '/' - altsep* = dirsep - pathSep* = ':' + CurDir* = '.' + ParDir* = ".." + DirSep* = '/' + AltSep* = DirSep + PathSep* = ':' FileSystemCaseSensitive* = true ExeExt* = "" ScriptExt* = "" DynlibFormat* = when defined(macosx): "lib$1.dylib" else: "lib$1.so" when defined(posix): - var - pathMax {.importc: "PATH_MAX", header: "<stdlib.h>".}: cint + when NoFakeVars: + const pathMax = 5000 # doesn't matter really. The concept of PATH_MAX + # doesn't work anymore on modern OSes. + else: + var + pathMax {.importc: "PATH_MAX", header: "<stdlib.h>".}: cint const ExtSep* = '.' ## The character which separates the base filename from the extension; ## for example, the '.' in ``os.nim``. -proc OSErrorMsg*(): string {.rtl, extern: "nos$1", deprecated.} = +proc osErrorMsg*(): string {.rtl, extern: "nos$1", deprecated.} = ## Retrieves the operating system's error flag, ``errno``. ## On Windows ``GetLastError`` is checked before ``errno``. ## Returns "" if no error occured. @@ -182,25 +186,25 @@ proc OSErrorMsg*(): string {.rtl, extern: "nos$1", deprecated.} = result = "" when defined(Windows): - var err = GetLastError() + var err = getLastError() if err != 0'i32: when useWinUnicode: - var msgbuf: widecstring - if FormatMessageW(0x00000100 or 0x00001000 or 0x00000200, + var msgbuf: WideCString + if formatMessageW(0x00000100 or 0x00001000 or 0x00000200, nil, err, 0, addr(msgbuf), 0, nil) != 0'i32: result = $msgbuf - if msgbuf != nil: LocalFree(cast[pointer](msgbuf)) + if msgbuf != nil: localFree(cast[pointer](msgbuf)) else: var msgbuf: cstring - if FormatMessageA(0x00000100 or 0x00001000 or 0x00000200, + if formatMessageA(0x00000100 or 0x00001000 or 0x00000200, nil, err, 0, addr(msgbuf), 0, nil) != 0'i32: result = $msgbuf - if msgbuf != nil: LocalFree(msgbuf) + if msgbuf != nil: localFree(msgbuf) if errno != 0'i32: result = $os.strerror(errno) {.push warning[deprecated]: off.} -proc OSError*(msg: string = "") {.noinline, rtl, extern: "nos$1", deprecated.} = +proc osError*(msg: string = "") {.noinline, rtl, extern: "nos$1", deprecated.} = ## raises an EOS exception with the given message ``msg``. ## If ``msg == ""``, the operating system's error flag ## (``errno``) is converted to a readable error message. On Windows @@ -209,7 +213,7 @@ proc OSError*(msg: string = "") {.noinline, rtl, extern: "nos$1", deprecated.} = ## ## **Deprecated since version 0.9.4**: use the other ``OSError`` proc. if len(msg) == 0: - var m = OSErrorMsg() + var m = osErrorMsg() raise newException(EOS, if m.len > 0: m else: "unknown OS error") else: raise newException(EOS, msg) @@ -218,7 +222,7 @@ proc OSError*(msg: string = "") {.noinline, rtl, extern: "nos$1", deprecated.} = proc `==`*(err1, err2: TOSErrorCode): bool {.borrow.} proc `$`*(err: TOSErrorCode): string {.borrow.} -proc OSErrorMsg*(errorCode: TOSErrorCode): string = +proc osErrorMsg*(errorCode: TOSErrorCode): string = ## Converts an OS error code into a human readable string. ## ## The error code can be retrieved using the ``OSLastError`` proc. @@ -233,22 +237,22 @@ proc OSErrorMsg*(errorCode: TOSErrorCode): string = when defined(Windows): if errorCode != TOSErrorCode(0'i32): when useWinUnicode: - var msgbuf: widecstring - if FormatMessageW(0x00000100 or 0x00001000 or 0x00000200, + var msgbuf: WideCString + if formatMessageW(0x00000100 or 0x00001000 or 0x00000200, nil, errorCode.int32, 0, addr(msgbuf), 0, nil) != 0'i32: result = $msgbuf - if msgbuf != nil: LocalFree(cast[pointer](msgbuf)) + if msgbuf != nil: localFree(cast[pointer](msgbuf)) else: var msgbuf: cstring - if FormatMessageA(0x00000100 or 0x00001000 or 0x00000200, + if formatMessageA(0x00000100 or 0x00001000 or 0x00000200, nil, errorCode.int32, 0, addr(msgbuf), 0, nil) != 0'i32: result = $msgbuf - if msgbuf != nil: LocalFree(msgbuf) + if msgbuf != nil: localFree(msgbuf) else: if errorCode != TOSErrorCode(0'i32): result = $os.strerror(errorCode.int32) -proc OSError*(errorCode: TOSErrorCode) = +proc osError*(errorCode: TOSErrorCode) = ## Raises an ``EOS`` exception. The ``errorCode`` will determine the ## message, ``OSErrorMsg`` will be used to get this message. ## @@ -256,14 +260,14 @@ proc OSError*(errorCode: TOSErrorCode) = ## ## If the error code is ``0`` or an error message could not be retrieved, ## the message ``unknown OS error`` will be used. - let msg = OSErrorMsg(errorCode) + let msg = osErrorMsg(errorCode) if msg == "": raise newException(EOS, "unknown OS error") else: raise newException(EOS, msg) {.push stackTrace:off.} -proc OSLastError*(): TOSErrorCode = +proc osLastError*(): TOSErrorCode = ## Retrieves the last operating system error code. ## ## This procedure is useful in the event when an OS call fails. In that case @@ -278,12 +282,12 @@ proc OSLastError*(): TOSErrorCode = ## immediately after an OS call fails. On POSIX systems this is not a problem. when defined(windows): - result = TOSErrorCode(GetLastError()) + result = TOSErrorCode(getLastError()) else: result = TOSErrorCode(errno) {.pop.} -proc UnixToNativePath*(path: string): string {. +proc unixToNativePath*(path: string): string {. noSideEffect, rtl, extern: "nos$1".} = ## Converts an UNIX-like path to a native one. ## @@ -300,11 +304,11 @@ proc UnixToNativePath*(path: string): string {. elif defined(macos): result = "" # must not start with ':' else: - result = $dirSep + result = $DirSep start = 1 elif path[0] == '.' and path[1] == '/': # current directory - result = $curdir + result = $CurDir start = 2 else: result = "" @@ -318,12 +322,12 @@ proc UnixToNativePath*(path: string): string {. if result[high(result)] == ':': add result, ':' else: - add result, pardir + add result, ParDir else: - add result, pardir & dirSep + add result, ParDir & DirSep inc(i, 3) elif path[i] == '/': - add result, dirSep + add result, DirSep inc(i) else: add result, path[i] @@ -336,48 +340,33 @@ when defined(windows): template wrapBinary(varname, winApiProc, arg, arg2: expr) {.immediate.} = var varname = winApiProc(newWideCString(arg), arg2) - proc FindFirstFile(a: string, b: var TWIN32_FIND_DATA): THandle = - result = FindFirstFileW(newWideCString(a), b) - template FindNextFile(a, b: expr): expr = FindNextFileW(a, b) + proc findFirstFile(a: string, b: var TWIN32_FIND_DATA): THandle = + result = findFirstFileW(newWideCString(a), b) + template findNextFile(a, b: expr): expr = findNextFileW(a, b) template getCommandLine(): expr = getCommandLineW() - proc skipFindData(f: TWIN32_FIND_DATA): bool {.inline.} = - let - nul = 0 - dot = ord('.') - result = (f.cFilename[0].int == dot) - if result: - result = (f.cFilename[1].int in {dot, nul}) - if result: - result = (f.cFilename[2].int == nul) - template getFilename(f: expr): expr = $cast[WideCString](addr(f.cFilename[0])) else: - template FindFirstFile(a, b: expr): expr = FindFirstFileA(a, b) - template FindNextFile(a, b: expr): expr = FindNextFileA(a, b) + template findFirstFile(a, b: expr): expr = findFirstFileA(a, b) + template findNextFile(a, b: expr): expr = findNextFileA(a, b) template getCommandLine(): expr = getCommandLineA() - proc skipFindData(f: TWIN32_FIND_DATA): bool {.inline.} = - let - nul = '\0' - dot = '.' - result = (f.cFilename[0] == dot) - if result: - result = (f.cFilename[1] in {dot, nul}) - if result: - result = (f.cFilename[2] == nul) - template getFilename(f: expr): expr = $f.cFilename + proc skipFindData(f: TWIN32_FIND_DATA): bool {.inline.} = + const dot = ord('.') + result = f.cFileName[0].int == dot and(f.cFileName[1].int == 0 or + f.cFileName[1].int == dot and f.cFileName[2].int == 0) + proc existsFile*(filename: string): bool {.rtl, extern: "nos$1", tags: [FReadDir].} = ## Returns true if the file exists, false otherwise. when defined(windows): when useWinUnicode: - wrapUnary(a, GetFileAttributesW, filename) + wrapUnary(a, getFileAttributesW, filename) else: - var a = GetFileAttributesA(filename) + var a = getFileAttributesA(filename) if a != -1'i32: result = (a and FILE_ATTRIBUTE_DIRECTORY) == 0'i32 else: @@ -389,9 +378,9 @@ proc existsDir*(dir: string): bool {.rtl, extern: "nos$1", tags: [FReadDir].} = ## is returned. when defined(windows): when useWinUnicode: - wrapUnary(a, GetFileAttributesW, dir) + wrapUnary(a, getFileAttributesW, dir) else: - var a = GetFileAttributesA(dir) + var a = getFileAttributesA(dir) if a != -1'i32: result = (a and FILE_ATTRIBUTE_DIRECTORY) != 0'i32 else: @@ -410,40 +399,40 @@ proc getLastModificationTime*(file: string): TTime {.rtl, extern: "nos$1".} = ## Returns the `file`'s last modification time. when defined(posix): var res: TStat - if stat(file, res) < 0'i32: OSError(OSLastError()) + if stat(file, res) < 0'i32: osError(osLastError()) return res.st_mtime else: - var f: TWIN32_Find_Data - var h = findfirstFile(file, f) - if h == -1'i32: OSError(OSLastError()) + var f: TWIN32_FIND_DATA + var h = findFirstFile(file, f) + if h == -1'i32: osError(osLastError()) result = winTimeToUnixTime(rdFileTime(f.ftLastWriteTime)) - findclose(h) + findClose(h) proc getLastAccessTime*(file: string): TTime {.rtl, extern: "nos$1".} = ## Returns the `file`'s last read or write access time. when defined(posix): var res: TStat - if stat(file, res) < 0'i32: OSError(OSLastError()) + if stat(file, res) < 0'i32: osError(osLastError()) return res.st_atime else: - var f: TWIN32_Find_Data - var h = findfirstFile(file, f) - if h == -1'i32: OSError(OSLastError()) + var f: TWIN32_FIND_DATA + var h = findFirstFile(file, f) + if h == -1'i32: osError(osLastError()) result = winTimeToUnixTime(rdFileTime(f.ftLastAccessTime)) - findclose(h) + findClose(h) proc getCreationTime*(file: string): TTime {.rtl, extern: "nos$1".} = ## Returns the `file`'s creation time. when defined(posix): var res: TStat - if stat(file, res) < 0'i32: OSError(OSLastError()) + if stat(file, res) < 0'i32: osError(osLastError()) return res.st_ctime else: - var f: TWIN32_Find_Data - var h = findfirstFile(file, f) - if h == -1'i32: OSError(OSLastError()) + var f: TWIN32_FIND_DATA + var h = findFirstFile(file, f) + if h == -1'i32: osError(osLastError()) result = winTimeToUnixTime(rdFileTime(f.ftCreationTime)) - findclose(h) + findClose(h) proc fileNewer*(a, b: string): bool {.rtl, extern: "nos$1".} = ## Returns true if the file `a` is newer than file `b`, i.e. if `a`'s @@ -456,40 +445,41 @@ proc getCurrentDir*(): string {.rtl, extern: "nos$1", tags: [].} = when defined(windows): when useWinUnicode: var res = newWideCString("", bufsize) - var L = GetCurrentDirectoryW(bufsize, res) - if L == 0'i32: OSError(OSLastError()) + var L = getCurrentDirectoryW(bufsize, res) + if L == 0'i32: osError(osLastError()) result = res$L else: result = newString(bufsize) - var L = GetCurrentDirectoryA(bufsize, result) - if L == 0'i32: OSError(OSLastError()) + var L = getCurrentDirectoryA(bufsize, result) + if L == 0'i32: osError(osLastError()) setLen(result, L) else: result = newString(bufsize) if getcwd(result, bufsize) != nil: - setlen(result, c_strlen(result)) + setLen(result, c_strlen(result)) else: - OSError(OSLastError()) + osError(osLastError()) proc setCurrentDir*(newDir: string) {.inline, tags: [].} = ## Sets the `current working directory`:idx:; `EOS` is raised if ## `newDir` cannot been set. when defined(Windows): when useWinUnicode: - if SetCurrentDirectoryW(newWideCString(newDir)) == 0'i32: OSError(OSLastError()) + if setCurrentDirectoryW(newWideCString(newDir)) == 0'i32: + osError(osLastError()) else: - if SetCurrentDirectoryA(newDir) == 0'i32: OSError(OSLastError()) + if setCurrentDirectoryA(newDir) == 0'i32: osError(osLastError()) else: - if chdir(newDir) != 0'i32: OSError(OSLastError()) + if chdir(newDir) != 0'i32: osError(osLastError()) -proc JoinPath*(head, tail: string): string {. +proc joinPath*(head, tail: string): string {. noSideEffect, rtl, extern: "nos$1".} = ## Joins two directory names to one. ## ## For example on Unix: ## ## .. code-block:: nimrod - ## JoinPath("usr", "lib") + ## joinPath("usr", "lib") ## ## results in: ## @@ -503,10 +493,10 @@ proc JoinPath*(head, tail: string): string {. ## examples on Unix: ## ## .. code-block:: nimrod - ## assert JoinPath("usr", "") == "usr/" - ## assert JoinPath("", "lib") == "lib" - ## assert JoinPath("", "/lib") == "/lib" - ## assert JoinPath("usr/", "/lib") == "usr/lib" + ## assert joinPath("usr", "") == "usr/" + ## assert joinPath("", "lib") == "lib" + ## assert joinPath("", "/lib") == "/lib" + ## assert joinPath("usr/", "/lib") == "usr/lib" if len(head) == 0: result = tail elif head[len(head)-1] in {DirSep, AltSep}: @@ -520,17 +510,17 @@ proc JoinPath*(head, tail: string): string {. else: result = head & DirSep & tail -proc JoinPath*(parts: varargs[string]): string {.noSideEffect, +proc joinPath*(parts: varargs[string]): string {.noSideEffect, rtl, extern: "nos$1OpenArray".} = - ## The same as `JoinPath(head, tail)`, but works with any number of directory + ## The same as `joinPath(head, tail)`, but works with any number of directory ## parts. You need to pass at least one element or the proc will assert in ## debug builds and crash on release builds. result = parts[0] for i in 1..high(parts): - result = JoinPath(result, parts[i]) + result = joinPath(result, parts[i]) proc `/` * (head, tail: string): string {.noSideEffect.} = - ## The same as ``JoinPath(head, tail)`` + ## The same as ``joinPath(head, tail)`` ## ## Here are some examples for Unix: ## @@ -539,24 +529,24 @@ proc `/` * (head, tail: string): string {.noSideEffect.} = ## assert "" / "lib" == "lib" ## assert "" / "/lib" == "/lib" ## assert "usr/" / "/lib" == "usr/lib" - return JoinPath(head, tail) + return joinPath(head, tail) -proc SplitPath*(path: string): tuple[head, tail: string] {. +proc splitPath*(path: string): tuple[head, tail: string] {. noSideEffect, rtl, extern: "nos$1".} = ## Splits a directory into (head, tail), so that - ## ``JoinPath(head, tail) == path``. + ## ``joinPath(head, tail) == path``. ## ## Examples: ## ## .. code-block:: nimrod - ## SplitPath("usr/local/bin") -> ("usr/local", "bin") - ## SplitPath("usr/local/bin/") -> ("usr/local/bin", "") - ## SplitPath("bin") -> ("", "bin") - ## SplitPath("/bin") -> ("", "bin") - ## SplitPath("") -> ("", "") + ## splitPath("usr/local/bin") -> ("usr/local", "bin") + ## splitPath("usr/local/bin/") -> ("usr/local/bin", "") + ## splitPath("bin") -> ("", "bin") + ## splitPath("/bin") -> ("", "bin") + ## splitPath("") -> ("", "") var sepPos = -1 for i in countdown(len(path)-1, 0): - if path[i] in {dirsep, altsep}: + if path[i] in {DirSep, AltSep}: sepPos = i break if sepPos >= 0: @@ -568,9 +558,9 @@ proc SplitPath*(path: string): tuple[head, tail: string] {. proc parentDirPos(path: string): int = var q = 1 - if path[len(path)-1] in {dirsep, altsep}: q = 2 + if path[len(path)-1] in {DirSep, AltSep}: q = 2 for i in countdown(len(path)-q, 0): - if path[i] in {dirsep, altsep}: return i + if path[i] in {DirSep, AltSep}: return i result = -1 proc parentDir*(path: string): string {. @@ -611,8 +601,8 @@ iterator parentDirs*(path: string, fromRoot=false, inclusive=true): string = else: for i in countup(0, path.len - 2): # ignore the last / # deal with non-normalized paths such as /foo//bar//baz - if path[i] in {dirsep, altsep} and - (i == 0 or path[i-1] notin {dirsep, altsep}): + if path[i] in {DirSep, AltSep} and + (i == 0 or path[i-1] notin {DirSep, AltSep}): yield path.substr(0, i) if inclusive: yield path @@ -627,17 +617,17 @@ proc `/../` * (head, tail: string): string {.noSideEffect.} = result = head / tail proc normExt(ext: string): string = - if ext == "" or ext[0] == extSep: result = ext # no copy needed here - else: result = extSep & ext + if ext == "" or ext[0] == ExtSep: result = ext # no copy needed here + else: result = ExtSep & ext proc searchExtPos(s: string): int = # BUGFIX: do not search until 0! .DS_Store is no file extension! result = -1 for i in countdown(len(s)-1, 1): - if s[i] == extsep: + if s[i] == ExtSep: result = i break - elif s[i] in {dirsep, altsep}: + elif s[i] in {DirSep, AltSep}: break # do not skip over path proc splitFile*(path: string): tuple[dir, name, ext: string] {. @@ -657,7 +647,7 @@ proc splitFile*(path: string): tuple[dir, name, ext: string] {. ## If `path` has no extension, `ext` is the empty string. ## If `path` has no directory component, `dir` is the empty string. ## If `path` has no filename component, `name` and `ext` are empty strings. - if path.len == 0 or path[path.len-1] in {dirSep, altSep}: + if path.len == 0 or path[path.len-1] in {DirSep, AltSep}: result = (path, "", "") else: var sepPos = -1 @@ -665,8 +655,8 @@ proc splitFile*(path: string): tuple[dir, name, ext: string] {. for i in countdown(len(path)-1, 0): if path[i] == ExtSep: if dotPos == path.len and i > 0 and - path[i-1] notin {dirsep, altsep}: dotPos = i - elif path[i] in {dirsep, altsep}: + path[i-1] notin {DirSep, AltSep}: dotPos = i + elif path[i] in {DirSep, AltSep}: sepPos = i break result.dir = substr(path, 0, sepPos-1) @@ -677,7 +667,7 @@ proc extractFilename*(path: string): string {. noSideEffect, rtl, extern: "nos$1".} = ## Extracts the filename of a given `path`. This is the same as ## ``name & ext`` from ``splitFile(path)``. - if path.len == 0 or path[path.len-1] in {dirSep, altSep}: + if path.len == 0 or path[path.len-1] in {DirSep, AltSep}: result = "" else: result = splitPath(path).tail @@ -688,26 +678,26 @@ proc expandFilename*(filename: string): string {.rtl, extern: "nos$1", when defined(windows): const bufsize = 3072'i32 when useWinUnicode: - var unused: widecstring + var unused: WideCString var res = newWideCString("", bufsize div 2) - var L = GetFullPathNameW(newWideCString(filename), bufsize, res, unused) + var L = getFullPathNameW(newWideCString(filename), bufsize, res, unused) if L <= 0'i32 or L >= bufsize: - OSError(OSLastError()) + osError(osLastError()) result = res$L else: var unused: cstring result = newString(bufsize) - var L = GetFullPathNameA(filename, bufsize, result, unused) - if L <= 0'i32 or L >= bufsize: OSError(OSLastError()) + var L = getFullPathNameA(filename, bufsize, result, unused) + if L <= 0'i32 or L >= bufsize: osError(osLastError()) setLen(result, L) else: # careful, realpath needs to take an allocated buffer according to Posix: result = newString(pathMax) var r = realpath(filename, result) - if r.isNil: OSError(OSLastError()) - setlen(result, c_strlen(result)) + if r.isNil: osError(osLastError()) + setLen(result, c_strlen(result)) -proc ChangeFileExt*(filename, ext: string): string {. +proc changeFileExt*(filename, ext: string): string {. noSideEffect, rtl, extern: "nos$1".} = ## Changes the file extension to `ext`. ## @@ -776,47 +766,47 @@ proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1", when useWinUnicode: var p1 = newWideCString(path1) var p2 = newWideCString(path2) - template OpenHandle(path: expr): expr = - CreateFileW(path, 0'i32, FILE_SHARE_DELETE or FILE_SHARE_READ or + template openHandle(path: expr): expr = + createFileW(path, 0'i32, FILE_SHARE_DELETE or FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS or FILE_ATTRIBUTE_NORMAL, 0) - var f1 = OpenHandle(p1) - var f2 = OpenHandle(p2) + var f1 = openHandle(p1) + var f2 = openHandle(p2) else: - template OpenHandle(path: expr): expr = - CreateFileA(path, 0'i32, FILE_SHARE_DELETE or FILE_SHARE_READ or + template openHandle(path: expr): expr = + createFileA(path, 0'i32, FILE_SHARE_DELETE or FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS or FILE_ATTRIBUTE_NORMAL, 0) - var f1 = OpenHandle(path1) - var f2 = OpenHandle(path2) + var f1 = openHandle(path1) + var f2 = openHandle(path2) var lastErr: TOSErrorCode if f1 != INVALID_HANDLE_VALUE and f2 != INVALID_HANDLE_VALUE: var fi1, fi2: TBY_HANDLE_FILE_INFORMATION - if GetFileInformationByHandle(f1, addr(fi1)) != 0 and - GetFileInformationByHandle(f2, addr(fi2)) != 0: + if getFileInformationByHandle(f1, addr(fi1)) != 0 and + getFileInformationByHandle(f2, addr(fi2)) != 0: result = fi1.dwVolumeSerialNumber == fi2.dwVolumeSerialNumber and fi1.nFileIndexHigh == fi2.nFileIndexHigh and fi1.nFileIndexLow == fi2.nFileIndexLow else: - lastErr = OSLastError() + lastErr = osLastError() success = false else: - lastErr = OSLastError() + lastErr = osLastError() success = false - discard CloseHandle(f1) - discard CloseHandle(f2) + discard closeHandle(f1) + discard closeHandle(f2) - if not success: OSError(lastErr) + if not success: osError(lastErr) else: var a, b: TStat if stat(path1, a) < 0'i32 or stat(path2, b) < 0'i32: - OSError(OSLastError()) + osError(osLastError()) else: result = a.st_dev == b.st_dev and a.st_ino == b.st_ino @@ -832,11 +822,11 @@ proc sameFileContent*(path1, path2: string): bool {.rtl, extern: "nos$1", if not open(b, path2): close(a) return false - var bufA = alloc(bufsize) - var bufB = alloc(bufsize) - while True: - var readA = readBuffer(a, bufA, bufsize) - var readB = readBuffer(b, bufB, bufsize) + var bufA = alloc(bufSize) + var bufB = alloc(bufSize) + while true: + var readA = readBuffer(a, bufA, bufSize) + var readB = readBuffer(b, bufB, bufSize) if readA != readB: result = false break @@ -870,7 +860,7 @@ proc getFilePermissions*(filename: string): set[TFilePermission] {. ## permission is available in any case. when defined(posix): var a: TStat - if stat(filename, a) < 0'i32: OSError(OSLastError()) + if stat(filename, a) < 0'i32: osError(osLastError()) result = {} if (a.st_mode and S_IRUSR) != 0'i32: result.incl(fpUserRead) if (a.st_mode and S_IWUSR) != 0'i32: result.incl(fpUserWrite) @@ -885,10 +875,10 @@ proc getFilePermissions*(filename: string): set[TFilePermission] {. if (a.st_mode and S_IXOTH) != 0'i32: result.incl(fpOthersExec) else: when useWinUnicode: - wrapUnary(res, GetFileAttributesW, filename) + wrapUnary(res, getFileAttributesW, filename) else: - var res = GetFileAttributesA(filename) - if res == -1'i32: OSError(OSLastError()) + var res = getFileAttributesA(filename) + if res == -1'i32: osError(osLastError()) if (res and FILE_ATTRIBUTE_READONLY) != 0'i32: result = {fpUserExec, fpUserRead, fpGroupExec, fpGroupRead, fpOthersExec, fpOthersRead} @@ -914,22 +904,22 @@ proc setFilePermissions*(filename: string, permissions: set[TFilePermission]) {. if fpOthersWrite in permissions: p = p or S_IWOTH if fpOthersExec in permissions: p = p or S_IXOTH - if chmod(filename, p) != 0: OSError(OSLastError()) + if chmod(filename, p) != 0: osError(osLastError()) else: when useWinUnicode: - wrapUnary(res, GetFileAttributesW, filename) + wrapUnary(res, getFileAttributesW, filename) else: - var res = GetFileAttributesA(filename) - if res == -1'i32: OSError(OSLastError()) + var res = getFileAttributesA(filename) + if res == -1'i32: osError(osLastError()) if fpUserWrite in permissions: res = res and not FILE_ATTRIBUTE_READONLY else: res = res or FILE_ATTRIBUTE_READONLY when useWinUnicode: - wrapBinary(res2, SetFileAttributesW, filename, res) + wrapBinary(res2, setFileAttributesW, filename, res) else: - var res2 = SetFileAttributesA(filename, res) - if res2 == - 1'i32: OSError(OSLastError()) + var res2 = setFileAttributesA(filename, res) + if res2 == - 1'i32: osError(osLastError()) proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", tags: [FReadIO, FWriteIO].} = @@ -946,27 +936,27 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", when useWinUnicode: let s = newWideCString(source) let d = newWideCString(dest) - if CopyFileW(s, d, 0'i32) == 0'i32: OSError(OSLastError()) + if copyFileW(s, d, 0'i32) == 0'i32: osError(osLastError()) else: - if CopyFileA(source, dest, 0'i32) == 0'i32: OSError(OSLastError()) + if copyFileA(source, dest, 0'i32) == 0'i32: osError(osLastError()) else: # generic version of copyFile which works for any platform: const bufSize = 8000 # better for memory manager var d, s: TFile - if not open(s, source): OSError(OSLastError()) + if not open(s, source): osError(osLastError()) if not open(d, dest, fmWrite): close(s) - OSError(OSLastError()) - var buf = alloc(bufsize) - while True: - var bytesread = readBuffer(s, buf, bufsize) + osError(osLastError()) + var buf = alloc(bufSize) + while true: + var bytesread = readBuffer(s, buf, bufSize) if bytesread > 0: var byteswritten = writeBuffer(d, buf, bytesread) - if bytesread != bytesWritten: + if bytesread != byteswritten: dealloc(buf) close(s) close(d) - OSError(OSLastError()) + osError(osLastError()) if bytesread != bufSize: break dealloc(buf) close(s) @@ -975,21 +965,24 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", proc moveFile*(source, dest: string) {.rtl, extern: "nos$1", tags: [FReadIO, FWriteIO].} = ## Moves a file from `source` to `dest`. If this fails, `EOS` is raised. - if crename(source, dest) != 0'i32: + if c_rename(source, dest) != 0'i32: raise newException(EOS, $strerror(errno)) when not defined(ENOENT) and not defined(Windows): - var ENOENT {.importc, header: "<errno.h>".}: cint + when NoFakeVars: + const ENOENT = cint(2) # 2 on most systems including Solaris + else: + var ENOENT {.importc, header: "<errno.h>".}: cint when defined(Windows): when useWinUnicode: - template DeleteFile(file: expr): expr {.immediate.} = DeleteFileW(file) - template SetFileAttributes(file, attrs: expr): expr {.immediate.} = - SetFileAttributesW(file, attrs) + template deleteFile(file: expr): expr {.immediate.} = deleteFileW(file) + template setFileAttributes(file, attrs: expr): expr {.immediate.} = + setFileAttributesW(file, attrs) else: - template DeleteFile(file: expr): expr {.immediate.} = DeleteFileA(file) - template SetFileAttributes(file, attrs: expr): expr {.immediate.} = - SetFileAttributesA(file, attrs) + template deleteFile(file: expr): expr {.immediate.} = deleteFileA(file) + template setFileAttributes(file, attrs: expr): expr {.immediate.} = + setFileAttributesA(file, attrs) proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = ## Removes the `file`. If this fails, `EOS` is raised. This does not fail @@ -1000,14 +993,14 @@ proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = let f = newWideCString(file) else: let f = file - if DeleteFile(f) == 0: - if GetLastError() == ERROR_ACCESS_DENIED: - if SetFileAttributes(f, FILE_ATTRIBUTE_NORMAL) == 0: - OSError(OSLastError()) - if DeleteFile(f) == 0: - OSError(OSLastError()) + if deleteFile(f) == 0: + if getLastError() == ERROR_ACCESS_DENIED: + if setFileAttributes(f, FILE_ATTRIBUTE_NORMAL) == 0: + osError(osLastError()) + if deleteFile(f) == 0: + osError(osLastError()) else: - if cremove(file) != 0'i32 and errno != ENOENT: + if c_remove(file) != 0'i32 and errno != ENOENT: raise newException(EOS, $strerror(errno)) proc execShellCmd*(command: string): int {.rtl, extern: "nos$1", @@ -1020,7 +1013,7 @@ proc execShellCmd*(command: string): int {.rtl, extern: "nos$1", ## the process has finished. To execute a program without having a ## shell involved, use the `execProcess` proc of the `osproc` ## module. - result = csystem(command) + result = c_system(command) # Environment handling cannot be put into RTL, because the ``envPairs`` # iterator depends on ``environment``. @@ -1033,10 +1026,10 @@ when defined(windows): # because we support Windows GUI applications, things get really # messy here... when useWinUnicode: - proc strEnd(cstr: wideCString, c = 0'i32): wideCString {. + proc strEnd(cstr: WideCString, c = 0'i32): WideCString {. importc: "wcschr", header: "<string.h>".} else: - proc strEnd(cstr: CString, c = 0'i32): CString {. + proc strEnd(cstr: cstring, c = 0'i32): cstring {. importc: "strchr", header: "<string.h>".} proc getEnvVarsC() = @@ -1047,18 +1040,18 @@ when defined(windows): env = getEnvironmentStringsW() e = env if e == nil: return # an error occured - while True: + while true: var eend = strEnd(e) add(environment, $e) - e = cast[wideCString](cast[TAddress](eend)+2) + e = cast[WideCString](cast[TAddress](eend)+2) if eend[1].int == 0: break - discard FreeEnvironmentStringsW(env) + discard freeEnvironmentStringsW(env) else: var env = getEnvironmentStringsA() e = env if e == nil: return # an error occured - while True: + while true: var eend = strEnd(e) add(environment, $e) e = cast[CString](cast[TAddress](eend)+1) @@ -1091,7 +1084,7 @@ else: when useNSGetEnviron: var gEnv = NSGetEnviron()[] var i = 0 - while True: + while true: if gEnv[i] == nil: break add environment, $gEnv[i] inc(i) @@ -1114,14 +1107,14 @@ proc getEnv*(key: string): TaintedString {.tags: [FReadEnv].} = if i >= 0: return TaintedString(substr(environment[i], find(environment[i], '=')+1)) else: - var env = cgetenv(key) + var env = c_getenv(key) if env == nil: return TaintedString("") result = TaintedString($env) proc existsEnv*(key: string): bool {.tags: [FReadEnv].} = ## Checks whether the environment variable named `key` exists. ## Returns true if it exists, false otherwise. - if cgetenv(key) != nil: return true + if c_getenv(key) != nil: return true else: return findEnvVar(key) >= 0 proc putEnv*(key, val: string) {.tags: [FWriteEnv].} = @@ -1139,15 +1132,15 @@ proc putEnv*(key, val: string) {.tags: [FWriteEnv].} = add environment, (key & '=' & val) indx = high(environment) when defined(unix): - if cputenv(environment[indx]) != 0'i32: - OSError(OSLastError()) + if c_putenv(environment[indx]) != 0'i32: + osError(osLastError()) else: when useWinUnicode: var k = newWideCString(key) var v = newWideCString(val) - if SetEnvironmentVariableW(k, v) == 0'i32: OSError(OSLastError()) + if setEnvironmentVariableW(k, v) == 0'i32: osError(osLastError()) else: - if SetEnvironmentVariableA(key, val) == 0'i32: OSError(OSLastError()) + if setEnvironmentVariableA(key, val) == 0'i32: osError(osLastError()) iterator envPairs*(): tuple[key, value: TaintedString] {.tags: [FReadEnv].} = ## Iterate over all `environments variables`:idx:. In the first component @@ -1167,15 +1160,15 @@ iterator walkFiles*(pattern: string): string {.tags: [FReadDir].} = ## notation is supported. when defined(windows): var - f: TWin32FindData + f: TWIN32_FIND_DATA res: int - res = findfirstFile(pattern, f) + res = findFirstFile(pattern, f) if res != -1: while true: if not skipFindData(f): yield splitFile(pattern).dir / extractFilename(getFilename(f)) - if findnextFile(res, f) == 0'i32: break - findclose(res) + if findNextFile(res, f) == 0'i32: break + findClose(res) else: # here we use glob var f: TGlob @@ -1220,8 +1213,8 @@ iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] {. ## dirA/fileA1.txt ## dirA/fileA2.txt when defined(windows): - var f: TWIN32_Find_Data - var h = findfirstFile(dir / "*", f) + var f: TWIN32_FIND_DATA + var h = findFirstFile(dir / "*", f) if h != -1: while true: var k = pcFile @@ -1229,13 +1222,13 @@ iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] {. if (f.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) != 0'i32: k = pcDir yield (k, dir / extractFilename(getFilename(f))) - if findnextFile(h, f) == 0'i32: break - findclose(h) + if findNextFile(h, f) == 0'i32: break + findClose(h) else: - var d = openDir(dir) + var d = opendir(dir) if d != nil: while true: - var x = readDir(d) + var x = readdir(d) if x == nil: break var y = $x.d_name if y != "." and y != "..": @@ -1246,7 +1239,7 @@ iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] {. if S_ISDIR(s.st_mode): k = pcDir if S_ISLNK(s.st_mode): k = succ(k) yield (k, y) - discard closeDir(d) + discard closedir(d) iterator walkDirRec*(dir: string, filter={pcFile, pcDir}): string {. tags: [FReadDir].} = @@ -1274,15 +1267,15 @@ iterator walkDirRec*(dir: string, filter={pcFile, pcDir}): string {. proc rawRemoveDir(dir: string) = when defined(windows): when useWinUnicode: - wrapUnary(res, RemoveDirectoryW, dir) + wrapUnary(res, removeDirectoryW, dir) else: - var res = RemoveDirectoryA(dir) - let lastError = OSLastError() + var res = removeDirectoryA(dir) + let lastError = osLastError() if res == 0'i32 and lastError.int32 != 3'i32 and lastError.int32 != 18'i32 and lastError.int32 != 2'i32: - OSError(lastError) + osError(lastError) else: - if rmdir(dir) != 0'i32 and errno != ENOENT: OSError(OSLastError()) + if rmdir(dir) != 0'i32 and errno != ENOENT: osError(osLastError()) proc removeDir*(dir: string) {.rtl, extern: "nos$1", tags: [ FWriteDir, FReadDir].} = @@ -1300,17 +1293,17 @@ proc removeDir*(dir: string) {.rtl, extern: "nos$1", tags: [ proc rawCreateDir(dir: string) = when defined(solaris): if mkdir(dir, 0o711) != 0'i32 and errno != EEXIST and errno != ENOSYS: - OSError(OSLastError()) + osError(osLastError()) elif defined(unix): if mkdir(dir, 0o711) != 0'i32 and errno != EEXIST: - OSError(OSLastError()) + osError(osLastError()) else: when useWinUnicode: - wrapUnary(res, CreateDirectoryW, dir) + wrapUnary(res, createDirectoryW, dir) else: - var res = CreateDirectoryA(dir) - if res == 0'i32 and GetLastError() != 183'i32: - OSError(OSLastError()) + var res = createDirectoryA(dir) + if res == 0'i32 and getLastError() != 183'i32: + osError(osLastError()) proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = ## Creates the `directory`:idx: `dir`. @@ -1323,7 +1316,7 @@ proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = when defined(doslike): omitNext = isAbsolute(dir) for i in 1.. dir.len-1: - if dir[i] in {dirsep, altsep}: + if dir[i] in {DirSep, AltSep}: if omitNext: omitNext = false else: @@ -1341,7 +1334,7 @@ proc copyDir*(source, dest: string) {.rtl, extern: "nos$1", copyFile(path, dest / noSource) of pcDir: copyDir(path, dest / noSource) - else: nil + else: discard proc parseCmdLine*(c: string): seq[string] {. noSideEffect, rtl, extern: "nos$1".} = @@ -1539,7 +1532,7 @@ when defined(linux) or defined(solaris) or defined(bsd) or defined(aix): if len > 256: result = newString(len+1) len = readlink(procPath, result, len) - setlen(result, len) + setLen(result, len) when defined(macosx): type @@ -1568,7 +1561,7 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [FReadIO].} = # /proc/<pid>/file when defined(windows): when useWinUnicode: - var buf = cast[wideCString](alloc(256*2)) + var buf = cast[WideCString](alloc(256*2)) var len = getModuleFileNameW(0, buf, 256) result = buf$len else: @@ -1599,8 +1592,8 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [FReadIO].} = if len(result) > 0 and result[0] != DirSep: # not an absolute path? # iterate over any path in the $PATH environment variable for p in split(string(getEnv("PATH")), {PathSep}): - var x = JoinPath(p, result) - if ExistsFile(x): return x + var x = joinPath(p, result) + if existsFile(x): return x proc getApplicationFilename*(): string {.rtl, extern: "nos$1", deprecated.} = ## Returns the filename of the application's executable. @@ -1629,33 +1622,33 @@ proc sleep*(milsecs: int) {.rtl, extern: "nos$1", tags: [FTime].} = a.tv_nsec = (milsecs mod 1000) * 1000 * 1000 discard posix.nanosleep(a, b) -proc getFileSize*(file: string): biggestInt {.rtl, extern: "nos$1", +proc getFileSize*(file: string): BiggestInt {.rtl, extern: "nos$1", tags: [FReadIO].} = ## returns the file size of `file`. Can raise ``EOS``. when defined(windows): - var a: TWin32FindData - var resA = findfirstFile(file, a) - if resA == -1: OSError(OSLastError()) + var a: TWIN32_FIND_DATA + var resA = findFirstFile(file, a) + if resA == -1: osError(osLastError()) result = rdFileSize(a) - findclose(resA) + findClose(resA) else: var f: TFile if open(f, file): result = getFileSize(f) close(f) - else: OSError(OSLastError()) + else: osError(osLastError()) proc findExe*(exe: string): string {.tags: [FReadDir, FReadEnv].} = ## Searches for `exe` in the current working directory and then ## in directories listed in the ``PATH`` environment variable. ## Returns "" if the `exe` cannot be found. On DOS-like platforms, `exe` ## is added an ``.exe`` file extension if it has no extension. - result = addFileExt(exe, os.exeExt) - if ExistsFile(result): return + result = addFileExt(exe, os.ExeExt) + if existsFile(result): return var path = string(os.getEnv("PATH")) - for candidate in split(path, pathSep): + for candidate in split(path, PathSep): var x = candidate / result - if ExistsFile(x): return x + if existsFile(x): return x result = "" proc expandTilde*(path: string): string = diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 61b940ce8..fe4303d8a 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -23,7 +23,7 @@ else: type TProcess = object of TObject when defined(windows): - FProcessHandle: Thandle + fProcessHandle: THandle inHandle, outHandle, errHandle: TFileHandle id: THandle else: @@ -108,7 +108,7 @@ proc execCmd*(command: string): int {.rtl, extern: "nosp$1", tags: [FExecIO].} proc startProcess*(command: string, workingDir: string = "", - args: openarray[string] = [], + args: openArray[string] = [], env: PStringTable = nil, options: set[TProcessOption] = {poStdErrToStdOut}): PProcess {.rtl, extern: "nosp$1", tags: [FExecIO, FReadEnv].} @@ -219,7 +219,7 @@ proc countProcessors*(): int {.rtl, extern: "nosp$1".} = ## returns the numer of the processors/cores the machine has. ## Returns 0 if it cannot be detected. when defined(windows): - var x = getenv("NUMBER_OF_PROCESSORS") + var x = getEnv("NUMBER_OF_PROCESSORS") if x.len > 0: result = parseInt(x.string) elif defined(macosx) or defined(bsd): var @@ -336,11 +336,11 @@ when defined(Windows) and not defined(useNimRtl): var s = PFileHandleStream(s) if s.atTheEnd: return 0 var br: int32 - var a = winlean.ReadFile(s.handle, buffer, bufLen.cint, br, nil) + var a = winlean.readFile(s.handle, buffer, bufLen.cint, br, nil) # TRUE and zero bytes returned (EOF). # TRUE and n (>0) bytes returned (good data). # FALSE and bytes returned undefined (system error). - if a == 0 and br != 0: OSError(OSLastError()) + if a == 0 and br != 0: osError(osLastError()) s.atTheEnd = br < bufLen result = br @@ -348,7 +348,7 @@ when defined(Windows) and not defined(useNimRtl): var s = PFileHandleStream(s) var bytesWritten: int32 var a = winlean.writeFile(s.handle, buffer, bufLen.cint, bytesWritten, nil) - if a == 0: OSError(OSLastError()) + if a == 0: osError(osLastError()) proc newFileHandleStream(handle: THandle): PFileHandleStream = new(result) @@ -358,7 +358,7 @@ when defined(Windows) and not defined(useNimRtl): result.readDataImpl = hsReadData result.writeDataImpl = hsWriteData - proc buildCommandLine(a: string, args: openarray[string]): cstring = + proc buildCommandLine(a: string, args: openArray[string]): cstring = var res = quoteShell(a) for i in 0..high(args): res.add(' ') @@ -383,45 +383,45 @@ when defined(Windows) and not defined(useNimRtl): # O_WRONLY {.importc: "_O_WRONLY", header: "<fcntl.h>".}: int # O_RDONLY {.importc: "_O_RDONLY", header: "<fcntl.h>".}: int - proc CreatePipeHandles(Rdhandle, WrHandle: var THandle) = - var piInheritablePipe: TSecurityAttributes - piInheritablePipe.nlength = SizeOF(TSecurityAttributes).cint + proc createPipeHandles(rdHandle, wrHandle: var THandle) = + var piInheritablePipe: TSECURITY_ATTRIBUTES + piInheritablePipe.nLength = sizeof(TSECURITY_ATTRIBUTES).cint piInheritablePipe.lpSecurityDescriptor = nil - piInheritablePipe.Binherithandle = 1 - if CreatePipe(Rdhandle, Wrhandle, piInheritablePipe, 1024) == 0'i32: - OSError(OSLastError()) + piInheritablePipe.bInheritHandle = 1 + if createPipe(rdHandle, wrHandle, piInheritablePipe, 1024) == 0'i32: + osError(osLastError()) proc fileClose(h: THandle) {.inline.} = - if h > 4: discard CloseHandle(h) + if h > 4: discard closeHandle(h) proc startProcess(command: string, workingDir: string = "", - args: openarray[string] = [], + args: openArray[string] = [], env: PStringTable = nil, options: set[TProcessOption] = {poStdErrToStdOut}): PProcess = var - SI: TStartupInfo - ProcInfo: TProcessInformation + si: TSTARTUPINFO + procInfo: TPROCESS_INFORMATION success: int hi, ho, he: THandle new(result) - SI.cb = SizeOf(SI).cint + si.cb = sizeof(si).cint if poParentStreams notin options: - SI.dwFlags = STARTF_USESTDHANDLES # STARTF_USESHOWWINDOW or - CreatePipeHandles(SI.hStdInput, HI) - CreatePipeHandles(HO, Si.hStdOutput) + si.dwFlags = STARTF_USESTDHANDLES # STARTF_USESHOWWINDOW or + createPipeHandles(si.hStdInput, hi) + createPipeHandles(ho, si.hStdOutput) if poStdErrToStdOut in options: - SI.hStdError = SI.hStdOutput - HE = HO + si.hStdError = si.hStdOutput + he = ho else: - CreatePipeHandles(HE, Si.hStdError) + createPipeHandles(he, si.hStdError) result.inHandle = TFileHandle(hi) result.outHandle = TFileHandle(ho) result.errHandle = TFileHandle(he) else: - SI.hStdError = GetStdHandle(STD_ERROR_HANDLE) - SI.hStdInput = GetStdHandle(STD_INPUT_HANDLE) - SI.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE) + si.hStdError = getStdHandle(STD_ERROR_HANDLE) + si.hStdInput = getStdHandle(STD_INPUT_HANDLE) + si.hStdOutput = getStdHandle(STD_OUTPUT_HANDLE) result.inHandle = TFileHandle(si.hStdInput) result.outHandle = TFileHandle(si.hStdOutput) result.errHandle = TFileHandle(si.hStdError) @@ -440,64 +440,64 @@ when defined(Windows) and not defined(useNimRtl): var tmp = newWideCString(cmdl) var ee = newWideCString(e) var wwd = newWideCString(wd) - success = winlean.CreateProcessW(nil, + success = winlean.createProcessW(nil, tmp, nil, nil, 1, NORMAL_PRIORITY_CLASS or CREATE_UNICODE_ENVIRONMENT, - ee, wwd, SI, ProcInfo) + ee, wwd, si, procInfo) else: - success = winlean.CreateProcessA(nil, + success = winlean.createProcessA(nil, cmdl, nil, nil, 1, NORMAL_PRIORITY_CLASS, e, wd, SI, ProcInfo) - let lastError = OSLastError() + let lastError = osLastError() if poParentStreams notin options: - FileClose(si.hStdInput) - FileClose(si.hStdOutput) + fileClose(si.hStdInput) + fileClose(si.hStdOutput) if poStdErrToStdOut notin options: - FileClose(si.hStdError) + fileClose(si.hStdError) if e != nil: dealloc(e) dealloc(cmdl) - if success == 0: OSError(lastError) + if success == 0: osError(lastError) # Close the handle now so anyone waiting is woken: discard closeHandle(procInfo.hThread) - result.FProcessHandle = procInfo.hProcess - result.id = procInfo.dwProcessID + result.fProcessHandle = procInfo.hProcess + result.id = procInfo.dwProcessId proc close(p: PProcess) = when false: # somehow this does not work on Windows: - discard CloseHandle(p.inHandle) - discard CloseHandle(p.outHandle) - discard CloseHandle(p.errHandle) - discard CloseHandle(p.FProcessHandle) + discard closeHandle(p.inHandle) + discard closeHandle(p.outHandle) + discard closeHandle(p.errHandle) + discard closeHandle(p.FProcessHandle) proc suspend(p: PProcess) = - discard SuspendThread(p.FProcessHandle) + discard suspendThread(p.fProcessHandle) proc resume(p: PProcess) = - discard ResumeThread(p.FProcessHandle) + discard resumeThread(p.fProcessHandle) proc running(p: PProcess): bool = - var x = waitForSingleObject(p.FProcessHandle, 50) + var x = waitForSingleObject(p.fProcessHandle, 50) return x == WAIT_TIMEOUT proc terminate(p: PProcess) = if running(p): - discard TerminateProcess(p.FProcessHandle, 0) + discard terminateProcess(p.fProcessHandle, 0) proc waitForExit(p: PProcess, timeout: int = -1): int = - discard WaitForSingleObject(p.FProcessHandle, timeout.int32) + discard waitForSingleObject(p.fProcessHandle, timeout.int32) var res: int32 - discard GetExitCodeProcess(p.FProcessHandle, res) + discard getExitCodeProcess(p.fProcessHandle, res) result = res - discard CloseHandle(p.FProcessHandle) + discard closeHandle(p.fProcessHandle) proc peekExitCode(p: PProcess): int = - var b = waitForSingleObject(p.FProcessHandle, 50) == WAIT_TIMEOUT + var b = waitForSingleObject(p.fProcessHandle, 50) == WAIT_TIMEOUT if b: result = -1 else: var res: int32 - discard GetExitCodeProcess(p.FProcessHandle, res) + discard getExitCodeProcess(p.fProcessHandle, res) return res proc inputStream(p: PProcess): PStream = @@ -511,38 +511,38 @@ when defined(Windows) and not defined(useNimRtl): proc execCmd(command: string): int = var - SI: TStartupInfo - ProcInfo: TProcessInformation + si: TSTARTUPINFO + procInfo: TPROCESS_INFORMATION process: THandle L: int32 - SI.cb = SizeOf(SI).cint - SI.hStdError = GetStdHandle(STD_ERROR_HANDLE) - SI.hStdInput = GetStdHandle(STD_INPUT_HANDLE) - SI.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE) + si.cb = sizeof(si).cint + si.hStdError = getStdHandle(STD_ERROR_HANDLE) + si.hStdInput = getStdHandle(STD_INPUT_HANDLE) + si.hStdOutput = getStdHandle(STD_OUTPUT_HANDLE) when useWinUnicode: var c = newWideCString(command) - var res = winlean.CreateProcessW(nil, c, nil, nil, 0, - NORMAL_PRIORITY_CLASS, nil, nil, SI, ProcInfo) + var res = winlean.createProcessW(nil, c, nil, nil, 0, + NORMAL_PRIORITY_CLASS, nil, nil, si, procInfo) else: - var res = winlean.CreateProcessA(nil, command, nil, nil, 0, + var res = winlean.createProcessA(nil, command, nil, nil, 0, NORMAL_PRIORITY_CLASS, nil, nil, SI, ProcInfo) if res == 0: - OSError(OSLastError()) + osError(osLastError()) else: - Process = ProcInfo.hProcess - discard CloseHandle(ProcInfo.hThread) - if WaitForSingleObject(Process, INFINITE) != -1: - discard GetExitCodeProcess(Process, L) + process = procInfo.hProcess + discard closeHandle(procInfo.hThread) + if waitForSingleObject(process, INFINITE) != -1: + discard getExitCodeProcess(process, L) result = int(L) else: result = -1 - discard CloseHandle(Process) + discard closeHandle(process) proc select(readfds: var seq[PProcess], timeout = 500): int = assert readfds.len <= MAXIMUM_WAIT_OBJECTS var rfds: TWOHandleArray for i in 0..readfds.len()-1: - rfds[i] = readfds[i].FProcessHandle + rfds[i] = readfds[i].fProcessHandle var ret = waitForMultipleObjects(readfds.len.int32, addr(rfds), 0'i32, timeout.int32) @@ -550,7 +550,7 @@ when defined(Windows) and not defined(useNimRtl): of WAIT_TIMEOUT: return 0 of WAIT_FAILED: - OSError(OSLastError()) + osError(osLastError()) else: var i = ret - WAIT_OBJECT_0 readfds.del(i) @@ -561,13 +561,13 @@ elif not defined(useNimRtl): readIdx = 0 writeIdx = 1 - proc addCmdArgs(command: string, args: openarray[string]): string = + proc addCmdArgs(command: string, args: openArray[string]): string = result = quoteShell(command) for i in 0 .. high(args): add(result, " ") add(result, quoteShell(args[i])) - proc toCStringArray(b, a: openarray[string]): cstringArray = + proc toCStringArray(b, a: openArray[string]): cstringArray = result = cast[cstringArray](alloc0((a.len + b.len + 1) * sizeof(cstring))) for i in 0..high(b): result[i] = cast[cstring](alloc(b[i].len+1)) @@ -576,7 +576,7 @@ elif not defined(useNimRtl): result[i+b.len] = cast[cstring](alloc(a[i].len+1)) copyMem(result[i+b.len], cstring(a[i]), a[i].len+1) - proc ToCStringArray(t: PStringTable): cstringArray = + proc toCStringArray(t: PStringTable): cstringArray = result = cast[cstringArray](alloc0((t.len + 1) * sizeof(cstring))) var i = 0 for key, val in pairs(t): @@ -585,7 +585,7 @@ elif not defined(useNimRtl): copyMem(result[i], addr(x[0]), x.len+1) inc(i) - proc EnvToCStringArray(): cstringArray = + proc envToCStringArray(): cstringArray = var counter = 0 for key, val in envPairs(): inc counter result = cast[cstringArray](alloc0((counter + 1) * sizeof(cstring))) @@ -598,17 +598,17 @@ elif not defined(useNimRtl): proc startProcess(command: string, workingDir: string = "", - args: openarray[string] = [], + args: openArray[string] = [], env: PStringTable = nil, options: set[TProcessOption] = {poStdErrToStdOut}): PProcess = var - p_stdin, p_stdout, p_stderr: array [0..1, cint] + pStdin, pStdout, pStderr: array [0..1, cint] new(result) result.exitCode = -3 # for ``waitForExit`` if poParentStreams notin options: - if pipe(p_stdin) != 0'i32 or pipe(p_stdout) != 0'i32 or - pipe(p_stderr) != 0'i32: - OSError(OSLastError()) + if pipe(pStdin) != 0'i32 or pipe(pStdout) != 0'i32 or + pipe(pStderr) != 0'i32: + osError(osLastError()) var pid: TPid when defined(posix_spawn) and not defined(useFork): @@ -616,7 +616,7 @@ elif not defined(useNimRtl): var fops: Tposix_spawn_file_actions template chck(e: expr) = - if e != 0'i32: OSError(OSLastError()) + if e != 0'i32: osError(osLastError()) chck posix_spawn_file_actions_init(fops) chck posix_spawnattr_init(attr) @@ -631,17 +631,17 @@ elif not defined(useNimRtl): POSIX_SPAWN_SETPGROUP) if poParentStreams notin options: - chck posix_spawn_file_actions_addclose(fops, p_stdin[writeIdx]) - chck posix_spawn_file_actions_adddup2(fops, p_stdin[readIdx], readIdx) - chck posix_spawn_file_actions_addclose(fops, p_stdout[readIdx]) - chck posix_spawn_file_actions_adddup2(fops, p_stdout[writeIdx], writeIdx) - chck posix_spawn_file_actions_addclose(fops, p_stderr[readIdx]) + chck posix_spawn_file_actions_addclose(fops, pStdin[writeIdx]) + chck posix_spawn_file_actions_adddup2(fops, pStdin[readIdx], readIdx) + chck posix_spawn_file_actions_addclose(fops, pStdout[readIdx]) + chck posix_spawn_file_actions_adddup2(fops, pStdout[writeIdx], writeIdx) + chck posix_spawn_file_actions_addclose(fops, pStderr[readIdx]) if poStdErrToStdOut in options: - chck posix_spawn_file_actions_adddup2(fops, p_stdout[writeIdx], 2) + chck posix_spawn_file_actions_adddup2(fops, pStdout[writeIdx], 2) else: - chck posix_spawn_file_actions_adddup2(fops, p_stderr[writeIdx], 2) + chck posix_spawn_file_actions_adddup2(fops, pStderr[writeIdx], 2) - var e = if env == nil: EnvToCStringArray() else: ToCStringArray(env) + var e = if env == nil: envToCStringArray() else: toCStringArray(env) var a: cstringArray var res: cint if workingDir.len > 0: os.setCurrentDir(workingDir) @@ -661,20 +661,20 @@ elif not defined(useNimRtl): else: Pid = fork() - if Pid < 0: OSError(OSLastError()) + if Pid < 0: osError(osLastError()) if pid == 0: ## child process: if poParentStreams notin options: discard close(p_stdin[writeIdx]) - if dup2(p_stdin[readIdx], readIdx) < 0: OSError(OSLastError()) + if dup2(p_stdin[readIdx], readIdx) < 0: osError(osLastError()) discard close(p_stdout[readIdx]) - if dup2(p_stdout[writeIdx], writeIdx) < 0: OSError(OSLastError()) + if dup2(p_stdout[writeIdx], writeIdx) < 0: osError(osLastError()) discard close(p_stderr[readIdx]) if poStdErrToStdOut in options: - if dup2(p_stdout[writeIdx], 2) < 0: OSError(OSLastError()) + if dup2(p_stdout[writeIdx], 2) < 0: osError(osLastError()) else: - if dup2(p_stderr[writeIdx], 2) < 0: OSError(OSLastError()) + if dup2(p_stderr[writeIdx], 2) < 0: osError(osLastError()) # Create a new process group if setpgid(0, 0) == -1: quit("setpgid call failed: " & $strerror(errno)) @@ -709,16 +709,16 @@ elif not defined(useNimRtl): else: result.errHandle = 2 else: - result.inHandle = p_stdin[writeIdx] - result.outHandle = p_stdout[readIdx] + result.inHandle = pStdin[writeIdx] + result.outHandle = pStdout[readIdx] if poStdErrToStdOut in options: result.errHandle = result.outHandle - discard close(p_stderr[readIdx]) + discard close(pStderr[readIdx]) else: - result.errHandle = p_stderr[readIdx] - discard close(p_stderr[writeIdx]) - discard close(p_stdin[readIdx]) - discard close(p_stdout[writeIdx]) + result.errHandle = pStderr[readIdx] + discard close(pStderr[writeIdx]) + discard close(pStdin[readIdx]) + discard close(pStdout[writeIdx]) proc close(p: PProcess) = if p.inStream != nil: close(p.inStream) @@ -729,21 +729,21 @@ elif not defined(useNimRtl): discard close(p.errHandle) proc suspend(p: PProcess) = - if kill(-p.id, SIGSTOP) != 0'i32: OSError(OSLastError()) + if kill(-p.id, SIGSTOP) != 0'i32: osError(osLastError()) proc resume(p: PProcess) = - if kill(-p.id, SIGCONT) != 0'i32: OSError(OSLastError()) + if kill(-p.id, SIGCONT) != 0'i32: osError(osLastError()) proc running(p: PProcess): bool = - var ret = waitPid(p.id, p.exitCode, WNOHANG) + var ret = waitpid(p.id, p.exitCode, WNOHANG) if ret == 0: return true # Can't establish status. Assume running. result = ret == int(p.id) proc terminate(p: PProcess) = if kill(-p.id, SIGTERM) == 0'i32: if p.running(): - if kill(-p.id, SIGKILL) != 0'i32: OSError(OSLastError()) - else: OSError(OSLastError()) + if kill(-p.id, SIGKILL) != 0'i32: osError(osLastError()) + else: osError(osLastError()) proc waitForExit(p: PProcess, timeout: int = -1): int = #if waitPid(p.id, p.exitCode, 0) == int(p.id): @@ -751,14 +751,14 @@ elif not defined(useNimRtl): # ``running`` probably set ``p.exitCode`` for us. Since ``p.exitCode`` is # initialized with -3, wrong success exit codes are prevented. if p.exitCode != -3: return p.exitCode - if waitPid(p.id, p.exitCode, 0) < 0: + if waitpid(p.id, p.exitCode, 0) < 0: p.exitCode = -3 - OSError(OSLastError()) + osError(osLastError()) result = int(p.exitCode) shr 8 proc peekExitCode(p: PProcess): int = if p.exitCode != -3: return p.exitCode - var ret = waitPid(p.id, p.exitCode, WNOHANG) + var ret = waitpid(p.id, p.exitCode, WNOHANG) var b = ret == int(p.id) if b: result = -1 if p.exitCode == -3: result = -1 @@ -767,7 +767,7 @@ elif not defined(useNimRtl): proc createStream(stream: var PStream, handle: var TFileHandle, fileMode: TFileMode) = var f: TFile - if not open(f, handle, fileMode): OSError(OSLastError()) + if not open(f, handle, fileMode): osError(osLastError()) stream = newFileStream(f) proc inputStream(p: PProcess): PStream = @@ -808,7 +808,7 @@ elif not defined(useNimRtl): setLen(s, L) proc select(readfds: var seq[PProcess], timeout = 500): int = - var tv: TTimeVal + var tv: Ttimeval tv.tv_sec = 0 tv.tv_usec = timeout * 1000 diff --git a/lib/pure/parsecfg.nim b/lib/pure/parsecfg.nim index e8014cece..f3249b107 100644 --- a/lib/pure/parsecfg.nim +++ b/lib/pure/parsecfg.nim @@ -82,7 +82,7 @@ proc open*(c: var TCfgParser, input: PStream, filename: string, c.filename = filename c.tok.kind = tkInvalid c.tok.literal = "" - inc(c.linenumber, lineOffset) + inc(c.lineNumber, lineOffset) rawGetTok(c, c.tok) proc close*(c: var TCfgParser) {.rtl, extern: "npc$1".} = @@ -91,11 +91,11 @@ proc close*(c: var TCfgParser) {.rtl, extern: "npc$1".} = proc getColumn*(c: TCfgParser): int {.rtl, extern: "npc$1".} = ## get the current column the parser has arrived at. - result = getColNumber(c, c.bufPos) + result = getColNumber(c, c.bufpos) proc getLine*(c: TCfgParser): int {.rtl, extern: "npc$1".} = ## get the current line the parser has arrived at. - result = c.linenumber + result = c.lineNumber proc getFilename*(c: TCfgParser): string {.rtl, extern: "npc$1".} = ## get the filename of the file that the parser processes. @@ -113,7 +113,7 @@ proc handleHexChar(c: var TCfgParser, xi: var int) = xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('A') + 10) inc(c.bufpos) else: - nil + discard proc handleDecChars(c: var TCfgParser, xi: var int) = while c.buf[c.bufpos] in {'0'..'9'}: @@ -125,74 +125,74 @@ proc getEscapedChar(c: var TCfgParser, tok: var TToken) = case c.buf[c.bufpos] of 'n', 'N': add(tok.literal, "\n") - Inc(c.bufpos) + inc(c.bufpos) of 'r', 'R', 'c', 'C': add(tok.literal, '\c') - Inc(c.bufpos) + inc(c.bufpos) of 'l', 'L': add(tok.literal, '\L') - Inc(c.bufpos) + inc(c.bufpos) of 'f', 'F': add(tok.literal, '\f') inc(c.bufpos) of 'e', 'E': add(tok.literal, '\e') - Inc(c.bufpos) + inc(c.bufpos) of 'a', 'A': add(tok.literal, '\a') - Inc(c.bufpos) + inc(c.bufpos) of 'b', 'B': add(tok.literal, '\b') - Inc(c.bufpos) + inc(c.bufpos) of 'v', 'V': add(tok.literal, '\v') - Inc(c.bufpos) + inc(c.bufpos) of 't', 'T': add(tok.literal, '\t') - Inc(c.bufpos) + inc(c.bufpos) of '\'', '"': add(tok.literal, c.buf[c.bufpos]) - Inc(c.bufpos) + inc(c.bufpos) of '\\': add(tok.literal, '\\') - Inc(c.bufpos) + inc(c.bufpos) of 'x', 'X': inc(c.bufpos) var xi = 0 handleHexChar(c, xi) handleHexChar(c, xi) - add(tok.literal, Chr(xi)) + add(tok.literal, chr(xi)) of '0'..'9': var xi = 0 handleDecChars(c, xi) - if (xi <= 255): add(tok.literal, Chr(xi)) + if (xi <= 255): add(tok.literal, chr(xi)) else: tok.kind = tkInvalid else: tok.kind = tkInvalid -proc HandleCRLF(c: var TCfgParser, pos: int): int = +proc handleCRLF(c: var TCfgParser, pos: int): int = case c.buf[pos] - of '\c': result = lexbase.HandleCR(c, pos) - of '\L': result = lexbase.HandleLF(c, pos) + of '\c': result = lexbase.handleCR(c, pos) + of '\L': result = lexbase.handleLF(c, pos) else: result = pos proc getString(c: var TCfgParser, tok: var TToken, rawMode: bool) = - var pos = c.bufPos + 1 # skip " + var pos = c.bufpos + 1 # skip " var buf = c.buf # put `buf` in a register tok.kind = tkSymbol if (buf[pos] == '"') and (buf[pos + 1] == '"'): # long string literal: inc(pos, 2) # skip "" # skip leading newline: - pos = HandleCRLF(c, pos) + pos = handleCRLF(c, pos) buf = c.buf while true: case buf[pos] of '"': if (buf[pos + 1] == '"') and (buf[pos + 2] == '"'): break add(tok.literal, '"') - Inc(pos) + inc(pos) of '\c', '\L': - pos = HandleCRLF(c, pos) + pos = handleCRLF(c, pos) buf = c.buf add(tok.literal, "\n") of lexbase.EndOfFile: @@ -200,7 +200,7 @@ proc getString(c: var TCfgParser, tok: var TToken, rawMode: bool) = break else: add(tok.literal, buf[pos]) - Inc(pos) + inc(pos) c.bufpos = pos + 3 # skip the three """ else: # ordinary string literal @@ -213,12 +213,12 @@ proc getString(c: var TCfgParser, tok: var TToken, rawMode: bool) = tok.kind = tkInvalid break if (ch == '\\') and not rawMode: - c.bufPos = pos + c.bufpos = pos getEscapedChar(c, tok) - pos = c.bufPos + pos = c.bufpos else: add(tok.literal, ch) - Inc(pos) + inc(pos) c.bufpos = pos proc getSymbol(c: var TCfgParser, tok: var TToken) = @@ -226,7 +226,7 @@ proc getSymbol(c: var TCfgParser, tok: var TToken) = var buf = c.buf while true: add(tok.literal, buf[pos]) - Inc(pos) + inc(pos) if not (buf[pos] in SymChars): break c.bufpos = pos tok.kind = tkSymbol @@ -237,11 +237,11 @@ proc skip(c: var TCfgParser) = while true: case buf[pos] of ' ', '\t': - Inc(pos) + inc(pos) of '#', ';': while not (buf[pos] in {'\c', '\L', lexbase.EndOfFile}): inc(pos) of '\c', '\L': - pos = HandleCRLF(c, pos) + pos = handleCRLF(c, pos) buf = c.buf else: break # EndOfFile also leaves the loop @@ -249,7 +249,7 @@ proc skip(c: var TCfgParser) = proc rawGetTok(c: var TCfgParser, tok: var TToken) = tok.kind = tkInvalid - setlen(tok.literal, 0) + setLen(tok.literal, 0) skip(c) case c.buf[c.bufpos] of '=': @@ -257,8 +257,8 @@ proc rawGetTok(c: var TCfgParser, tok: var TToken) = inc(c.bufpos) tok.literal = "=" of '-': - inc(c.bufPos) - if c.buf[c.bufPos] == '-': inc(c.bufPos) + inc(c.bufpos) + if c.buf[c.bufpos] == '-': inc(c.bufpos) tok.kind = tkDashDash tok.literal = "--" of ':': @@ -266,8 +266,8 @@ proc rawGetTok(c: var TCfgParser, tok: var TToken) = inc(c.bufpos) tok.literal = ":" of 'r', 'R': - if c.buf[c.bufPos + 1] == '\"': - Inc(c.bufPos) + if c.buf[c.bufpos + 1] == '\"': + inc(c.bufpos) getString(c, tok, true) else: getSymbol(c, tok) @@ -277,7 +277,7 @@ proc rawGetTok(c: var TCfgParser, tok: var TToken) = tok.literal = "]" of ']': tok.kind = tkBracketRi - Inc(c.bufpos) + inc(c.bufpos) tok.literal = "]" of '"': getString(c, tok, false) diff --git a/lib/pure/parseopt.nim b/lib/pure/parseopt.nim index fa704bbce..68ae537c7 100644 --- a/lib/pure/parseopt.nim +++ b/lib/pure/parseopt.nim @@ -11,8 +11,8 @@ ## It supports one convenience iterator over all command line options and some ## lower-level features. ## -## DEPRECATED. Use parseopt2 instead as this version has issues with spaces -## in arguments. +## **Deprecated since version 0.9.3:** Use the `parseopt2 <parseopt2.html>`_ +## module instead as this version has issues with spaces in arguments. {.deprecated.} {.push debugger: off.} @@ -37,7 +37,7 @@ type ## or the argument, ``value`` is not "" if ## the option was given a value -when defined(os.ParamCount): +when defined(os.paramCount): # we cannot provide this for NimRtl creation on Posix, because we can't # access the command line arguments then! @@ -50,7 +50,7 @@ when defined(os.ParamCount): result.cmd = cmdline else: result.cmd = "" - for i in countup(1, ParamCount()): + for i in countup(1, paramCount()): result.cmd = result.cmd & quoteIfContainsWhite(paramStr(i).string) & ' ' result.kind = cmdEnd result.key = TaintedString"" @@ -94,8 +94,8 @@ proc next*(p: var TOptParser) {. var i = p.pos while p.cmd[i] in {'\x09', ' '}: inc(i) p.pos = i - setlen(p.key.string, 0) - setlen(p.val.string, 0) + setLen(p.key.string, 0) + setLen(p.val.string, 0) if p.inShortState: handleShortOption(p) return @@ -105,7 +105,7 @@ proc next*(p: var TOptParser) {. of '-': inc(i) if p.cmd[i] == '-': - p.kind = cmdLongOption + p.kind = cmdLongoption inc(i) i = parseWord(p.cmd, i, p.key.string, {'\0', ' ', '\x09', ':', '='}) while p.cmd[i] in {'\x09', ' '}: inc(i) diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim index c11265bfd..6423b3ab0 100644 --- a/lib/pure/parseutils.nim +++ b/lib/pure/parseutils.nim @@ -51,7 +51,7 @@ proc parseHex*(s: string, number: var int, start = 0): int {. elif s[i] == '#': inc(i) while true: case s[i] - of '_': nil + of '_': discard of '0'..'9': number = number shl 4 or (ord(s[i]) - ord('0')) foundDigit = true @@ -74,7 +74,7 @@ proc parseOct*(s: string, number: var int, start = 0): int {. if s[i] == '0' and (s[i+1] == 'o' or s[i+1] == 'O'): inc(i, 2) while true: case s[i] - of '_': nil + of '_': discard of '0'..'7': number = number shl 3 or (ord(s[i]) - ord('0')) foundDigit = true @@ -189,7 +189,7 @@ proc captureBetween*(s: string, first: char, second = '\0', start = 0): string = {.push overflowChecks: on.} # this must be compiled with overflow checking turned on: -proc rawParseInt(s: string, b: var biggestInt, start = 0): int = +proc rawParseInt(s: string, b: var BiggestInt, start = 0): int = var sign: BiggestInt = -1 i = start @@ -207,12 +207,12 @@ proc rawParseInt(s: string, b: var biggestInt, start = 0): int = result = i - start {.pop.} # overflowChecks -proc parseBiggestInt*(s: string, number: var biggestInt, start = 0): int {. +proc parseBiggestInt*(s: string, number: var BiggestInt, start = 0): int {. rtl, extern: "npuParseBiggestInt", noSideEffect.} = ## parses an integer starting at `start` and stores the value into `number`. ## Result is the number of processed chars or 0 if there is no integer. ## `EOverflow` is raised if an overflow occurs. - var res: biggestInt + var res: BiggestInt # use 'res' for exception safety (don't write to 'number' in case of an # overflow exception: result = rawParseInt(s, res, start) @@ -223,7 +223,7 @@ proc parseInt*(s: string, number: var int, start = 0): int {. ## parses an integer starting at `start` and stores the value into `number`. ## Result is the number of processed chars or 0 if there is no integer. ## `EOverflow` is raised if an overflow occurs. - var res: biggestInt + var res: BiggestInt result = parseBiggestInt(s, res, start) if (sizeof(int) <= 4) and ((res < low(int)) or (res > high(int))): @@ -231,7 +231,7 @@ proc parseInt*(s: string, number: var int, start = 0): int {. else: number = int(res) -proc tenToThePowerOf(b: int): biggestFloat = +proc tenToThePowerOf(b: int): BiggestFloat = var b = b var a = 10.0 result = 1.0 @@ -242,7 +242,7 @@ proc tenToThePowerOf(b: int): biggestFloat = if b == 0: break a *= a -proc parseBiggestFloat*(s: string, number: var biggestFloat, start = 0): int {. +proc parseBiggestFloat*(s: string, number: var BiggestFloat, start = 0): int {. rtl, extern: "npuParseBiggestFloat", noSideEffect.} = ## parses a float starting at `start` and stores the value into `number`. ## Result is the number of processed chars or 0 if there occured a parsing @@ -319,7 +319,7 @@ proc parseFloat*(s: string, number: var float, start = 0): int {. ## parses a float starting at `start` and stores the value into `number`. ## Result is the number of processed chars or 0 if there occured a parsing ## error. - var bf: biggestFloat + var bf: BiggestFloat result = parseBiggestFloat(s, bf, start) number = bf diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim index d8fed845a..a6147a96c 100644 --- a/lib/pure/pegs.nim +++ b/lib/pure/pegs.nim @@ -249,23 +249,23 @@ proc newLine*: TPeg {.inline.} = ## constructs the PEG `newline`:idx: (``\n``) result.kind = pkNewline -proc UnicodeLetter*: TPeg {.inline.} = +proc unicodeLetter*: TPeg {.inline.} = ## constructs the PEG ``\letter`` which matches any Unicode letter. result.kind = pkLetter -proc UnicodeLower*: TPeg {.inline.} = +proc unicodeLower*: TPeg {.inline.} = ## constructs the PEG ``\lower`` which matches any Unicode lowercase letter. result.kind = pkLower -proc UnicodeUpper*: TPeg {.inline.} = +proc unicodeUpper*: TPeg {.inline.} = ## constructs the PEG ``\upper`` which matches any Unicode uppercase letter. result.kind = pkUpper -proc UnicodeTitle*: TPeg {.inline.} = +proc unicodeTitle*: TPeg {.inline.} = ## constructs the PEG ``\title`` which matches any Unicode title letter. result.kind = pkTitle -proc UnicodeWhitespace*: TPeg {.inline.} = +proc unicodeWhitespace*: TPeg {.inline.} = ## constructs the PEG ``\white`` which matches any Unicode ## whitespace character. result.kind = pkWhitespace @@ -340,28 +340,28 @@ proc newNonTerminal*(name: string, line, column: int): PNonTerminal {. template letters*: expr = ## expands to ``charset({'A'..'Z', 'a'..'z'})`` - charset({'A'..'Z', 'a'..'z'}) + charSet({'A'..'Z', 'a'..'z'}) template digits*: expr = ## expands to ``charset({'0'..'9'})`` - charset({'0'..'9'}) + charSet({'0'..'9'}) template whitespace*: expr = ## expands to ``charset({' ', '\9'..'\13'})`` - charset({' ', '\9'..'\13'}) + charSet({' ', '\9'..'\13'}) template identChars*: expr = ## expands to ``charset({'a'..'z', 'A'..'Z', '0'..'9', '_'})`` - charset({'a'..'z', 'A'..'Z', '0'..'9', '_'}) + charSet({'a'..'z', 'A'..'Z', '0'..'9', '_'}) template identStartChars*: expr = ## expands to ``charset({'A'..'Z', 'a'..'z', '_'})`` - charset({'a'..'z', 'A'..'Z', '_'}) + charSet({'a'..'z', 'A'..'Z', '_'}) template ident*: expr = ## same as ``[a-zA-Z_][a-zA-z_0-9]*``; standard identifier - sequence(charset({'a'..'z', 'A'..'Z', '_'}), - *charset({'a'..'z', 'A'..'Z', '0'..'9', '_'})) + sequence(charSet({'a'..'z', 'A'..'Z', '_'}), + *charSet({'a'..'z', 'A'..'Z', '0'..'9', '_'})) template natural*: expr = ## same as ``\d+`` @@ -385,7 +385,7 @@ proc esc(c: char, reserved = {'\0'..'\255'}): string = elif c in reserved: result = '\\' & c else: result = $c -proc singleQuoteEsc(c: Char): string = return "'" & esc(c, {'\''}) & "'" +proc singleQuoteEsc(c: char): string = return "'" & esc(c, {'\''}) & "'" proc singleQuoteEsc(str: string): string = result = "'" @@ -409,11 +409,11 @@ proc charSetEscAux(cc: set[char]): string = c1 = c2 inc(c1) -proc CharSetEsc(cc: set[char]): string = +proc charSetEsc(cc: set[char]): string = if card(cc) >= 128+64: - result = "[^" & CharSetEscAux({'\1'..'\xFF'} - cc) & ']' + result = "[^" & charSetEscAux({'\1'..'\xFF'} - cc) & ']' else: - result = '[' & CharSetEscAux(cc) & ']' + result = '[' & charSetEscAux(cc) & ']' proc toStrAux(r: TPeg, res: var string) = case r.kind @@ -590,7 +590,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. var a: TRune result = start fastRuneAt(s, result, a) - if isWhitespace(a): dec(result, start) + if isWhiteSpace(a): dec(result, start) else: result = -1 else: result = -1 @@ -747,7 +747,7 @@ template fillMatches(s, caps, c: expr) = for k in 0..c.ml-1: caps[k] = substr(s, c.matches[k][0], c.matches[k][1]) -proc match*(s: string, pattern: TPeg, matches: var openarray[string], +proc match*(s: string, pattern: TPeg, matches: var openArray[string], start = 0): bool {.nosideEffect, rtl, extern: "npegs$1Capture".} = ## returns ``true`` if ``s[start..]`` matches the ``pattern`` and ## the captured substrings in the array ``matches``. If it does not @@ -765,7 +765,7 @@ proc match*(s: string, pattern: TPeg, c.origStart = start result = rawMatch(s, pattern, start, c) == len(s)-start -proc matchLen*(s: string, pattern: TPeg, matches: var openarray[string], +proc matchLen*(s: string, pattern: TPeg, matches: var openArray[string], start = 0): int {.nosideEffect, rtl, extern: "npegs$1Capture".} = ## the same as ``match``, but it returns the length of the match, ## if there is no match, -1 is returned. Note that a match length @@ -786,7 +786,7 @@ proc matchLen*(s: string, pattern: TPeg, c.origStart = start result = rawMatch(s, pattern, start, c) -proc find*(s: string, pattern: TPeg, matches: var openarray[string], +proc find*(s: string, pattern: TPeg, matches: var openArray[string], start = 0): int {.nosideEffect, rtl, extern: "npegs$1Capture".} = ## returns the starting position of ``pattern`` in ``s`` and the captured ## substrings in the array ``matches``. If it does not match, nothing @@ -801,7 +801,7 @@ proc find*(s: string, pattern: TPeg, matches: var openarray[string], return -1 # could also use the pattern here: (!P .)* P -proc findBounds*(s: string, pattern: TPeg, matches: var openarray[string], +proc findBounds*(s: string, pattern: TPeg, matches: var openArray[string], start = 0): tuple[first, last: int] {. nosideEffect, rtl, extern: "npegs$1Capture".} = ## returns the starting position and end position of ``pattern`` in ``s`` @@ -869,7 +869,7 @@ template `=~`*(s: string, pattern: TPeg): bool = ## bind maxSubpatterns when not definedInScope(matches): - var matches {.inject.}: array[0..maxSubpatterns-1, string] + var matches {.inject.}: array[0..MaxSubpatterns-1, string] match(s, pattern, matches) # ------------------------- more string handling ------------------------------ @@ -1074,14 +1074,14 @@ const "@", "built-in", "escaped", "$", "$", "^" ] -proc HandleCR(L: var TPegLexer, pos: int): int = +proc handleCR(L: var TPegLexer, pos: int): int = assert(L.buf[pos] == '\c') inc(L.linenumber) result = pos+1 if L.buf[result] == '\L': inc(result) L.lineStart = result -proc HandleLF(L: var TPegLexer, pos: int): int = +proc handleLF(L: var TPegLexer, pos: int): int = assert(L.buf[pos] == '\L') inc(L.linenumber) result = pos+1 @@ -1124,38 +1124,38 @@ proc getEscapedChar(c: var TPegLexer, tok: var TToken) = case c.buf[c.bufpos] of 'r', 'R', 'c', 'C': add(tok.literal, '\c') - Inc(c.bufpos) + inc(c.bufpos) of 'l', 'L': add(tok.literal, '\L') - Inc(c.bufpos) + inc(c.bufpos) of 'f', 'F': add(tok.literal, '\f') inc(c.bufpos) of 'e', 'E': add(tok.literal, '\e') - Inc(c.bufpos) + inc(c.bufpos) of 'a', 'A': add(tok.literal, '\a') - Inc(c.bufpos) + inc(c.bufpos) of 'b', 'B': add(tok.literal, '\b') - Inc(c.bufpos) + inc(c.bufpos) of 'v', 'V': add(tok.literal, '\v') - Inc(c.bufpos) + inc(c.bufpos) of 't', 'T': add(tok.literal, '\t') - Inc(c.bufpos) + inc(c.bufpos) of 'x', 'X': inc(c.bufpos) var xi = 0 handleHexChar(c, xi) handleHexChar(c, xi) if xi == 0: tok.kind = tkInvalid - else: add(tok.literal, Chr(xi)) + else: add(tok.literal, chr(xi)) of '0'..'9': var val = ord(c.buf[c.bufpos]) - ord('0') - Inc(c.bufpos) + inc(c.bufpos) var i = 1 while (i <= 3) and (c.buf[c.bufpos] in {'0'..'9'}): val = val * 10 + ord(c.buf[c.bufpos]) - ord('0') @@ -1169,7 +1169,7 @@ proc getEscapedChar(c: var TPegLexer, tok: var TToken) = tok.kind = tkInvalid else: add(tok.literal, c.buf[c.bufpos]) - Inc(c.bufpos) + inc(c.bufpos) proc skip(c: var TPegLexer) = var pos = c.bufpos @@ -1177,14 +1177,14 @@ proc skip(c: var TPegLexer) = while true: case buf[pos] of ' ', '\t': - Inc(pos) + inc(pos) of '#': while not (buf[pos] in {'\c', '\L', '\0'}): inc(pos) of '\c': - pos = HandleCR(c, pos) + pos = handleCR(c, pos) buf = c.buf of '\L': - pos = HandleLF(c, pos) + pos = handleLF(c, pos) buf = c.buf else: break # EndOfFile also leaves the loop @@ -1209,7 +1209,7 @@ proc getString(c: var TPegLexer, tok: var TToken) = break else: add(tok.literal, buf[pos]) - Inc(pos) + inc(pos) c.bufpos = pos proc getDollar(c: var TPegLexer, tok: var TToken) = @@ -1250,7 +1250,7 @@ proc getCharSet(c: var TPegLexer, tok: var TToken) = break else: ch = buf[pos] - Inc(pos) + inc(pos) incl(tok.charset, ch) if buf[pos] == '-': if buf[pos+1] == ']': @@ -1270,7 +1270,7 @@ proc getCharSet(c: var TPegLexer, tok: var TToken) = break else: ch2 = buf[pos] - Inc(pos) + inc(pos) for i in ord(ch)+1 .. ord(ch2): incl(tok.charset, chr(i)) c.bufpos = pos @@ -1281,7 +1281,7 @@ proc getSymbol(c: var TPegLexer, tok: var TToken) = var buf = c.buf while true: add(tok.literal, buf[pos]) - Inc(pos) + inc(pos) if buf[pos] notin strutils.IdentChars: break c.bufpos = pos tok.kind = tkIdentifier @@ -1298,7 +1298,7 @@ proc getBuiltin(c: var TPegLexer, tok: var TToken) = proc getTok(c: var TPegLexer, tok: var TToken) = tok.kind = tkInvalid tok.modifier = modNone - setlen(tok.literal, 0) + setLen(tok.literal, 0) skip(c) case c.buf[c.bufpos] of '{': @@ -1315,14 +1315,14 @@ proc getTok(c: var TPegLexer, tok: var TToken) = inc(c.bufpos) add(tok.literal, '}') of '[': - getCharset(c, tok) + getCharSet(c, tok) of '(': tok.kind = tkParLe - Inc(c.bufpos) + inc(c.bufpos) add(tok.literal, '(') of ')': tok.kind = tkParRi - Inc(c.bufpos) + inc(c.bufpos) add(tok.literal, ')') of '.': tok.kind = tkAny @@ -1452,28 +1452,28 @@ proc modifiedTerm(s: string, m: TModifier): TPeg = proc modifiedBackref(s: int, m: TModifier): TPeg = case m - of modNone, modVerbatim: result = backRef(s) - of modIgnoreCase: result = backRefIgnoreCase(s) - of modIgnoreStyle: result = backRefIgnoreStyle(s) + of modNone, modVerbatim: result = backref(s) + of modIgnoreCase: result = backrefIgnoreCase(s) + of modIgnoreStyle: result = backrefIgnoreStyle(s) proc builtin(p: var TPegParser): TPeg = # do not use "y", "skip" or "i" as these would be ambiguous case p.tok.literal of "n": result = newLine() - of "d": result = charset({'0'..'9'}) - of "D": result = charset({'\1'..'\xff'} - {'0'..'9'}) - of "s": result = charset({' ', '\9'..'\13'}) - of "S": result = charset({'\1'..'\xff'} - {' ', '\9'..'\13'}) - of "w": result = charset({'a'..'z', 'A'..'Z', '_', '0'..'9'}) - of "W": result = charset({'\1'..'\xff'} - {'a'..'z','A'..'Z','_','0'..'9'}) - of "a": result = charset({'a'..'z', 'A'..'Z'}) - of "A": result = charset({'\1'..'\xff'} - {'a'..'z', 'A'..'Z'}) + of "d": result = charSet({'0'..'9'}) + of "D": result = charSet({'\1'..'\xff'} - {'0'..'9'}) + of "s": result = charSet({' ', '\9'..'\13'}) + of "S": result = charSet({'\1'..'\xff'} - {' ', '\9'..'\13'}) + of "w": result = charSet({'a'..'z', 'A'..'Z', '_', '0'..'9'}) + of "W": result = charSet({'\1'..'\xff'} - {'a'..'z','A'..'Z','_','0'..'9'}) + of "a": result = charSet({'a'..'z', 'A'..'Z'}) + of "A": result = charSet({'\1'..'\xff'} - {'a'..'z', 'A'..'Z'}) of "ident": result = pegs.ident - of "letter": result = UnicodeLetter() - of "upper": result = UnicodeUpper() - of "lower": result = UnicodeLower() - of "title": result = UnicodeTitle() - of "white": result = UnicodeWhitespace() + of "letter": result = unicodeLetter() + of "upper": result = unicodeUpper() + of "lower": result = unicodeLower() + of "title": result = unicodeTitle() + of "white": result = unicodeWhitespace() else: pegError(p, "unknown built-in: " & p.tok.literal) proc token(terminal: TPeg, p: TPegParser): TPeg = @@ -1505,7 +1505,7 @@ proc primary(p: var TPegParser): TPeg = elif not arrowIsNextTok(p): var nt = getNonTerminal(p, p.tok.literal) incl(nt.flags, ntUsed) - result = nonTerminal(nt).token(p) + result = nonterminal(nt).token(p) getTok(p) else: pegError(p, "expression expected, but found: " & p.tok.literal) @@ -1517,7 +1517,7 @@ proc primary(p: var TPegParser): TPeg = of tkCharSet: if '\0' in p.tok.charset: pegError(p, "binary zero ('\\0') not allowed in character class") - result = charset(p.tok.charset).token(p) + result = charSet(p.tok.charset).token(p) getTok(p) of tkParLe: getTok(p) @@ -1549,7 +1549,7 @@ proc primary(p: var TPegParser): TPeg = of tkBackref: var m = p.tok.modifier if m == modNone: m = p.modifier - result = modifiedBackRef(p.tok.index, m).token(p) + result = modifiedBackref(p.tok.index, m).token(p) if p.tok.index < 0 or p.tok.index > p.captures: pegError(p, "invalid back reference index: " & $p.tok.index) getTok(p) diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 66bb1e6a9..de445dd36 100644 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -26,7 +26,7 @@ {.deadCodeElim: on.} -when hostos == "solaris": +when hostOS == "solaris": {.passl: "-lsocket -lnsl".} import os, parseutils @@ -132,17 +132,17 @@ type ETimeout* = object of ESynch let - InvalidSocket*: TSocket = nil ## invalid socket + invalidSocket*: TSocket = nil ## invalid socket when defined(windows): let - OSInvalidSocket = winlean.INVALID_SOCKET + osInvalidSocket = winlean.INVALID_SOCKET else: let - OSInvalidSocket = posix.INVALID_SOCKET + osInvalidSocket = posix.INVALID_SOCKET proc newTSocket(fd: TSocketHandle, isBuff: bool): TSocket = - if fd == OSInvalidSocket: + if fd == osInvalidSocket: return nil new(result) result.fd = fd @@ -187,14 +187,14 @@ proc htons*(x: int16): int16 = result = sockets.ntohs(x) when defined(Posix): - proc ToInt(domain: TDomain): cint = + proc toInt(domain: TDomain): cint = case domain of AF_UNIX: result = posix.AF_UNIX of AF_INET: result = posix.AF_INET of AF_INET6: result = posix.AF_INET6 else: nil - proc ToInt(typ: TType): cint = + proc toInt(typ: TType): cint = case typ of SOCK_STREAM: result = posix.SOCK_STREAM of SOCK_DGRAM: result = posix.SOCK_DGRAM @@ -202,7 +202,7 @@ when defined(Posix): of SOCK_RAW: result = posix.SOCK_RAW else: nil - proc ToInt(p: TProtocol): cint = + proc toInt(p: TProtocol): cint = case p of IPPROTO_TCP: result = posix.IPPROTO_TCP of IPPROTO_UDP: result = posix.IPPROTO_UDP @@ -216,10 +216,10 @@ else: proc toInt(domain: TDomain): cint = result = toU16(ord(domain)) - proc ToInt(typ: TType): cint = + proc toInt(typ: TType): cint = result = cint(ord(typ)) - proc ToInt(p: TProtocol): cint = + proc toInt(p: TProtocol): cint = result = cint(ord(p)) proc socket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, @@ -230,7 +230,7 @@ proc socket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, when defined(Windows): result = newTSocket(winlean.socket(ord(domain), ord(typ), ord(protocol)), buffered) else: - result = newTSocket(posix.socket(ToInt(domain), ToInt(typ), ToInt(protocol)), buffered) + result = newTSocket(posix.socket(toInt(domain), toInt(typ), toInt(protocol)), buffered) when defined(ssl): CRYPTO_malloc_init() @@ -333,7 +333,7 @@ when defined(ssl): if SSLSetFd(socket.sslHandle, socket.fd) != 1: SSLError() -proc SocketError*(socket: TSocket, err: int = -1, async = false) = +proc socketError*(socket: TSocket, err: int = -1, async = false) = ## Raises proper errors based on return values of ``recv`` functions. ## ## If ``async`` is ``True`` no error will be thrown in the case when the @@ -362,28 +362,28 @@ proc SocketError*(socket: TSocket, err: int = -1, async = false) = else: SSLError("Unknown Error") if err == -1 and not (when defined(ssl): socket.isSSL else: false): - let lastError = OSLastError() + let lastError = osLastError() if async: when defined(windows): if lastError.int32 == WSAEWOULDBLOCK: return - else: OSError(lastError) + else: osError(lastError) else: if lastError.int32 == EAGAIN or lastError.int32 == EWOULDBLOCK: return - else: OSError(lastError) - else: OSError(lastError) + else: osError(lastError) + else: osError(lastError) proc listen*(socket: TSocket, backlog = SOMAXCONN) {.tags: [FReadIO].} = ## Marks ``socket`` as accepting connections. ## ``Backlog`` specifies the maximum length of the ## queue of pending connections. - if listen(socket.fd, cint(backlog)) < 0'i32: OSError(OSLastError()) + if listen(socket.fd, cint(backlog)) < 0'i32: osError(osLastError()) proc invalidIp4(s: string) {.noreturn, noinline.} = raise newException(EInvalidValue, "invalid ip4 address: " & s) -proc parseIp4*(s: string): biggestInt = +proc parseIp4*(s: string): BiggestInt = ## parses an IP version 4 in dotted decimal form like "a.b.c.d". ## ## This is equivalent to `inet_ntoa`:idx:. @@ -410,14 +410,14 @@ proc parseIp4*(s: string): biggestInt = if j <= 0: invalidIp4(s) inc(i, j) if s[i] != '\0': invalidIp4(s) - result = biggestInt(a shl 24 or b shl 16 or c shl 8 or d) + result = BiggestInt(a shl 24 or b shl 16 or c shl 8 or d) template gaiNim(a, p, h, list: expr): stmt = block: - var gaiResult = getAddrInfo(a, $p, addr(h), list) + var gaiResult = getaddrinfo(a, $p, addr(h), list) if gaiResult != 0'i32: when defined(windows): - OSError(OSLastError()) + osError(osLastError()) else: raise newException(EOS, $gai_strerror(gaiResult)) @@ -436,17 +436,17 @@ proc bindAddr*(socket: TSocket, port = TPort(0), address = "") {. name.sin_port = sockets.htons(int16(port)) name.sin_addr.s_addr = sockets.htonl(INADDR_ANY) if bindSocket(socket.fd, cast[ptr TSockAddr](addr(name)), - sizeof(name).TSockLen) < 0'i32: - OSError(OSLastError()) + sizeof(name).TSocklen) < 0'i32: + osError(osLastError()) else: - var hints: TAddrInfo - var aiList: ptr TAddrInfo = nil + var hints: Taddrinfo + var aiList: ptr Taddrinfo = nil hints.ai_family = toInt(AF_INET) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) gaiNim(address, port, hints, aiList) - if bindSocket(socket.fd, aiList.ai_addr, aiList.ai_addrLen.TSockLen) < 0'i32: - OSError(OSLastError()) + if bindSocket(socket.fd, aiList.ai_addr, aiList.ai_addrlen.TSocklen) < 0'i32: + osError(osLastError()) proc getSockName*(socket: TSocket): TPort = ## returns the socket's associated port number. @@ -457,40 +457,40 @@ proc getSockName*(socket: TSocket): TPort = name.sin_family = posix.AF_INET #name.sin_port = htons(cint16(port)) #name.sin_addr.s_addr = htonl(INADDR_ANY) - var namelen = sizeof(name).TSockLen + var namelen = sizeof(name).TSocklen if getsockname(socket.fd, cast[ptr TSockAddr](addr(name)), addr(namelen)) == -1'i32: - OSError(OSLastError()) + osError(osLastError()) result = TPort(sockets.ntohs(name.sin_port)) template acceptAddrPlain(noClientRet, successRet: expr, sslImplementation: stmt): stmt {.immediate.} = assert(client != nil) var sockAddress: Tsockaddr_in - var addrLen = sizeof(sockAddress).TSockLen + var addrLen = sizeof(sockAddress).TSocklen var sock = accept(server.fd, cast[ptr TSockAddr](addr(sockAddress)), addr(addrLen)) - if sock == OSInvalidSocket: - let err = OSLastError() + if sock == osInvalidSocket: + let err = osLastError() when defined(windows): if err.int32 == WSAEINPROGRESS: - client = InvalidSocket + client = invalidSocket address = "" when noClientRet.int == -1: return else: return noClientRet - else: OSError(err) + else: osError(err) else: if err.int32 == EAGAIN or err.int32 == EWOULDBLOCK: - client = InvalidSocket + client = invalidSocket address = "" when noClientRet.int == -1: return else: return noClientRet - else: OSError(err) + else: osError(err) else: client.fd = sock client.isBuffered = server.isBuffered @@ -628,7 +628,7 @@ proc accept*(server: TSocket): TSocket {.deprecated, tags: [FReadIO].} = proc close*(socket: TSocket) = ## closes a socket. when defined(windows): - discard winlean.closeSocket(socket.fd) + discard winlean.closesocket(socket.fd) else: discard posix.close(socket.fd) # TODO: These values should not be discarded. An EOS should be raised. @@ -669,7 +669,7 @@ proc getServByPort*(port: TPort, proto: string): TServent {.tags: [FReadIO].} = result.port = TPort(s.s_port) result.proto = $s.s_proto -proc getHostByAddr*(ip: string): THostEnt {.tags: [FReadIO].} = +proc getHostByAddr*(ip: string): Thostent {.tags: [FReadIO].} = ## This function will lookup the hostname of an IP Address. var myaddr: TInAddr myaddr.s_addr = inet_addr(ip) @@ -677,43 +677,43 @@ proc getHostByAddr*(ip: string): THostEnt {.tags: [FReadIO].} = when defined(windows): var s = winlean.gethostbyaddr(addr(myaddr), sizeof(myaddr).cuint, cint(sockets.AF_INET)) - if s == nil: OSError(OSLastError()) + if s == nil: osError(osLastError()) else: - var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).TSockLen, + var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).TSocklen, cint(posix.AF_INET)) if s == nil: - raise newException(EOS, $hStrError(h_errno)) + raise newException(EOS, $hstrerror(h_errno)) result.name = $s.h_name result.aliases = cstringArrayToSeq(s.h_aliases) when defined(windows): - result.addrType = TDomain(s.h_addrtype) + result.addrtype = TDomain(s.h_addrtype) else: if s.h_addrtype == posix.AF_INET: - result.addrType = AF_INET + result.addrtype = AF_INET elif s.h_addrtype == posix.AF_INET6: - result.addrType = AF_INET6 + result.addrtype = AF_INET6 else: raise newException(EOS, "unknown h_addrtype") result.addrList = cstringArrayToSeq(s.h_addr_list) result.length = int(s.h_length) -proc getHostByName*(name: string): THostEnt {.tags: [FReadIO].} = +proc getHostByName*(name: string): Thostent {.tags: [FReadIO].} = ## This function will lookup the IP address of a hostname. when defined(Windows): var s = winlean.gethostbyname(name) else: var s = posix.gethostbyname(name) - if s == nil: OSError(OSLastError()) + if s == nil: osError(osLastError()) result.name = $s.h_name result.aliases = cstringArrayToSeq(s.h_aliases) when defined(windows): - result.addrType = TDomain(s.h_addrtype) + result.addrtype = TDomain(s.h_addrtype) else: if s.h_addrtype == posix.AF_INET: - result.addrType = AF_INET + result.addrtype = AF_INET elif s.h_addrtype == posix.AF_INET6: - result.addrType = AF_INET6 + result.addrtype = AF_INET6 else: raise newException(EOS, "unknown h_addrtype") result.addrList = cstringArrayToSeq(s.h_addr_list) @@ -723,10 +723,10 @@ proc getSockOptInt*(socket: TSocket, level, optname: int): int {. tags: [FReadIO].} = ## getsockopt for integer options. var res: cint - var size = sizeof(res).TSockLen + var size = sizeof(res).TSocklen if getsockopt(socket.fd, cint(level), cint(optname), addr(res), addr(size)) < 0'i32: - OSError(OSLastError()) + osError(osLastError()) result = int(res) proc setSockOptInt*(socket: TSocket, level, optname, optval: int) {. @@ -734,8 +734,8 @@ proc setSockOptInt*(socket: TSocket, level, optname, optval: int) {. ## setsockopt for integer options. var value = cint(optval) if setsockopt(socket.fd, cint(level), cint(optname), addr(value), - sizeof(value).TSockLen) < 0'i32: - OSError(OSLastError()) + sizeof(value).TSocklen) < 0'i32: + osError(osLastError()) proc toCInt(opt: TSOBool): cint = case opt @@ -751,10 +751,10 @@ proc getSockOpt*(socket: TSocket, opt: TSOBool, level = SOL_SOCKET): bool {. tags: [FReadIO].} = ## Retrieves option ``opt`` as a boolean value. var res: cint - var size = sizeof(res).TSockLen + var size = sizeof(res).TSocklen if getsockopt(socket.fd, cint(level), toCInt(opt), addr(res), addr(size)) < 0'i32: - OSError(OSLastError()) + osError(osLastError()) result = res != 0 proc setSockOpt*(socket: TSocket, opt: TSOBool, value: bool, level = SOL_SOCKET) {. @@ -762,8 +762,8 @@ proc setSockOpt*(socket: TSocket, opt: TSOBool, value: bool, level = SOL_SOCKET) ## Sets option ``opt`` to a boolean value specified by ``value``. var valuei = cint(if value: 1 else: 0) if setsockopt(socket.fd, cint(level), toCInt(opt), addr(valuei), - sizeof(valuei).TSockLen) < 0'i32: - OSError(OSLastError()) + sizeof(valuei).TSocklen) < 0'i32: + osError(osLastError()) proc connect*(socket: TSocket, address: string, port = TPort(0), af: TDomain = AF_INET) {.tags: [FReadIO].} = @@ -773,8 +773,8 @@ proc connect*(socket: TSocket, address: string, port = TPort(0), ## not do it. ## ## If ``socket`` is an SSL socket a handshake will be automatically performed. - var hints: TAddrInfo - var aiList: ptr TAddrInfo = nil + var hints: Taddrinfo + var aiList: ptr Taddrinfo = nil hints.ai_family = toInt(af) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) @@ -784,14 +784,14 @@ proc connect*(socket: TSocket, address: string, port = TPort(0), var lastError: TOSErrorCode var it = aiList while it != nil: - if connect(socket.fd, it.ai_addr, it.ai_addrlen.TSockLen) == 0'i32: + if connect(socket.fd, it.ai_addr, it.ai_addrlen.TSocklen) == 0'i32: success = true break - else: lastError = OSLastError() + else: lastError = osLastError() it = it.ai_next freeaddrinfo(aiList) - if not success: OSError(lastError) + if not success: osError(lastError) when defined(ssl): if socket.isSSL: @@ -836,8 +836,8 @@ proc connectAsync*(socket: TSocket, name: string, port = TPort(0), ## ## **Note**: For SSL sockets, the ``handshake`` procedure must be called ## whenever the socket successfully connects to a server. - var hints: TAddrInfo - var aiList: ptr TAddrInfo = nil + var hints: Taddrinfo + var aiList: ptr Taddrinfo = nil hints.ai_family = toInt(af) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) @@ -847,12 +847,12 @@ proc connectAsync*(socket: TSocket, name: string, port = TPort(0), var lastError: TOSErrorCode var it = aiList while it != nil: - var ret = connect(socket.fd, it.ai_addr, it.ai_addrlen.TSockLen) + var ret = connect(socket.fd, it.ai_addr, it.ai_addrlen.TSocklen) if ret == 0'i32: success = true break else: - lastError = OSLastError() + lastError = osLastError() when defined(windows): # Windows EINTR doesn't behave same as POSIX. if lastError.int32 == WSAEWOULDBLOCK: @@ -866,7 +866,7 @@ proc connectAsync*(socket: TSocket, name: string, port = TPort(0), it = it.ai_next freeaddrinfo(aiList) - if not success: OSError(lastError) + if not success: osError(lastError) when defined(ssl): if socket.isSSL: socket.sslNoHandshake = true @@ -912,7 +912,7 @@ when defined(ssl): else: SSLError("Socket is not an SSL socket.") -proc timeValFromMilliseconds(timeout = 500): TTimeVal = +proc timeValFromMilliseconds(timeout = 500): Ttimeval = if timeout != -1: var seconds = timeout div 1000 result.tv_sec = seconds.int32 @@ -970,7 +970,7 @@ proc select*(readfds, writefds, exceptfds: var seq[TSocket], if buffersFilled > 0: return buffersFilled - var tv {.noInit.}: TTimeVal = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) var rd, wr, ex: TFdSet var m = 0 @@ -993,7 +993,7 @@ proc select*(readfds, writefds: var seq[TSocket], let buffersFilled = checkBuffer(readfds) if buffersFilled > 0: return buffersFilled - var tv {.noInit.}: TTimeVal = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) var rd, wr: TFdSet var m = 0 @@ -1017,7 +1017,7 @@ proc selectWrite*(writefds: var seq[TSocket], ## ## ``timeout`` is specified in miliseconds and ``-1`` can be specified for ## an unlimited time. - var tv {.noInit.}: TTimeVal = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) var wr: TFdSet var m = 0 @@ -1035,7 +1035,7 @@ proc select*(readfds: var seq[TSocket], timeout = 500): int = let buffersFilled = checkBuffer(readfds) if buffersFilled > 0: return buffersFilled - var tv {.noInit.}: TTimeVal = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) var rd: TFdSet var m = 0 @@ -1058,7 +1058,7 @@ proc readIntoBuf(socket: TSocket, flags: int32): int = else: result = recv(socket.fd, addr(socket.buffer), cint(socket.buffer.high), flags) if result <= 0: - socket.buflen = 0 + socket.bufLen = 0 socket.currPos = 0 return result socket.bufLen = result @@ -1142,7 +1142,7 @@ proc waitFor(socket: TSocket, waited: var float, timeout, size: int, var s = @[socket] var startTime = epochTime() let selRet = select(s, timeout - int(waited * 1000.0)) - if selRet < 0: OSError(OSLastError()) + if selRet < 0: osError(osLastError()) if selRet != 1: raise newException(ETimeout, "Call to '" & funcName & "' timed out.") waited += (epochTime() - startTime) @@ -1180,7 +1180,7 @@ proc recv*(socket: TSocket, data: var string, size: int, timeout = -1): int = result = recv(socket, cstring(data), size, timeout) if result < 0: data.setLen(0) - socket.SocketError(result) + socket.socketError(result) data.setLen(result) proc recvAsync*(socket: TSocket, data: var string, size: int): int = @@ -1194,7 +1194,7 @@ proc recvAsync*(socket: TSocket, data: var string, size: int): int = result = recv(socket, cstring(data), size) if result < 0: data.setLen(0) - socket.SocketError(async = true) + socket.socketError(async = true) result = -1 data.setLen(result) @@ -1258,10 +1258,10 @@ proc recvLine*(socket: TSocket, line: var TaintedString, timeout = -1): bool {. if n > 0 and c == '\L': discard recv(socket, addr(c), 1) elif n <= 0: return false - addNlIfEmpty() + addNLIfEmpty() return true elif c == '\L': - addNlIfEmpty() + addNLIfEmpty() return true add(line.string, c) @@ -1291,18 +1291,18 @@ proc readLine*(socket: TSocket, line: var TaintedString, timeout = -1) {. var c: char discard waitFor(socket, waited, timeout, 1, "readLine") var n = recv(socket, addr(c), 1) - if n < 0: OSError(OSLastError()) + if n < 0: osError(osLastError()) elif n == 0: return if c == '\r': discard waitFor(socket, waited, timeout, 1, "readLine") n = peekChar(socket, c) if n > 0 and c == '\L': discard recv(socket, addr(c), 1) - elif n <= 0: OSError(OSLastError()) - addNlIfEmpty() + elif n <= 0: osError(osLastError()) + addNLIfEmpty() return elif c == '\L': - addNlIfEmpty() + addNLIfEmpty() return add(line.string, c) @@ -1352,7 +1352,7 @@ proc readLineAsync*(socket: TSocket, setLen(line.string, 0) template errorOrNone = - socket.SocketError(async = true) + socket.socketError(async = true) return ReadNone while true: @@ -1385,7 +1385,7 @@ proc recv*(socket: TSocket): TaintedString {.tags: [FReadIO], deprecated.} = var pos = 0 while true: var bytesRead = recv(socket, addr(string(result)[pos]), bufSize-1) - if bytesRead == -1: OSError(OSLastError()) + if bytesRead == -1: osError(osLastError()) setLen(result.string, pos + bytesRead) if bytesRead != bufSize-1: break # increase capacity: @@ -1454,22 +1454,22 @@ proc recvAsync*(socket: TSocket, s: var TaintedString): bool {. else: SSLError("Unknown Error") if bytesRead == -1 and not (when defined(ssl): socket.isSSL else: false): - let err = OSLastError() + let err = osLastError() when defined(windows): if err.int32 == WSAEWOULDBLOCK: - return False - else: OSError(err) + return false + else: osError(err) else: if err.int32 == EAGAIN or err.int32 == EWOULDBLOCK: - return False - else: OSError(err) + return false + else: osError(err) setLen(s.string, pos + bytesRead) if bytesRead != bufSize-1: break # increase capacity: setLen(s.string, s.string.len + bufSize) inc(pos, bytesRead) - result = True + result = true proc recvFrom*(socket: TSocket, data: var string, length: int, address: var string, port: var TPort, flags = 0'i32): int {. @@ -1488,8 +1488,8 @@ proc recvFrom*(socket: TSocket, data: var string, length: int, # TODO: Buffered sockets data.setLen(length) var sockAddress: Tsockaddr_in - var addrLen = sizeof(sockAddress).TSockLen - result = recvFrom(socket.fd, cstring(data), length.cint, flags.cint, + var addrLen = sizeof(sockAddress).TSocklen + result = recvfrom(socket.fd, cstring(data), length.cint, flags.cint, cast[ptr TSockAddr](addr(sockAddress)), addr(addrLen)) if result != -1: @@ -1497,7 +1497,7 @@ proc recvFrom*(socket: TSocket, data: var string, length: int, address = $inet_ntoa(sockAddress.sin_addr) port = ntohs(sockAddress.sin_port).TPort -proc recvFromAsync*(socket: TSocket, data: var String, length: int, +proc recvFromAsync*(socket: TSocket, data: var string, length: int, address: var string, port: var TPort, flags = 0'i32): bool {.tags: [FReadIO].} = ## Variant of ``recvFrom`` for non-blocking sockets. Unlike ``recvFrom``, @@ -1507,15 +1507,15 @@ proc recvFromAsync*(socket: TSocket, data: var String, length: int, result = true var callRes = recvFrom(socket, data, length, address, port, flags) if callRes < 0: - let err = OSLastError() + let err = osLastError() when defined(windows): if err.int32 == WSAEWOULDBLOCK: - return False - else: OSError(err) + return false + else: osError(err) else: if err.int32 == EAGAIN or err.int32 == EWOULDBLOCK: - return False - else: OSError(err) + return false + else: osError(err) proc skip*(socket: TSocket) {.tags: [FReadIO], deprecated.} = ## skips all the data that is pending for the socket @@ -1565,7 +1565,7 @@ proc send*(socket: TSocket, data: string) {.tags: [FWriteIO].} = if socket.isSSL: SSLError() - OSError(OSLastError()) + osError(osLastError()) if sent != data.len: raise newException(EOS, "Could not send all data.") @@ -1598,15 +1598,15 @@ proc sendAsync*(socket: TSocket, data: string): int {.tags: [FWriteIO].} = else: return if result == -1: - let err = OSLastError() + let err = osLastError() when defined(windows): if err.int32 == WSAEINPROGRESS: return 0 - else: OSError(err) + else: osError(err) else: if err.int32 == EAGAIN or err.int32 == EWOULDBLOCK: return 0 - else: OSError(err) + else: osError(err) proc trySend*(socket: TSocket, data: string): bool {.tags: [FWriteIO].} = @@ -1622,8 +1622,8 @@ proc sendTo*(socket: TSocket, address: string, port: TPort, data: pointer, ## this function will try each IP of that hostname. ## ## **Note:** This proc is not available for SSL sockets. - var hints: TAddrInfo - var aiList: ptr TAddrInfo = nil + var hints: Taddrinfo + var aiList: ptr Taddrinfo = nil hints.ai_family = toInt(af) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) @@ -1633,8 +1633,8 @@ proc sendTo*(socket: TSocket, address: string, port: TPort, data: pointer, var success = false var it = aiList while it != nil: - result = sendTo(socket.fd, data, size.cint, flags.cint, it.ai_addr, - it.ai_addrlen.TSockLen) + result = sendto(socket.fd, data, size.cint, flags.cint, it.ai_addr, + it.ai_addrlen.TSocklen) if result != -1'i32: success = true break @@ -1661,16 +1661,16 @@ when defined(Windows): proc setBlocking(s: TSocket, blocking: bool) = when defined(Windows): var mode = clong(ord(not blocking)) # 1 for non-blocking, 0 for blocking - if ioctlsocket(TSocketHandle(s.fd), FIONBIO, addr(mode)) == -1: - OSError(OSLastError()) + if ioctlsocket(s.fd, FIONBIO, addr(mode)) == -1: + osError(osLastError()) else: # BSD sockets var x: int = fcntl(s.fd, F_GETFL, 0) if x == -1: - OSError(OSLastError()) + osError(osLastError()) else: var mode = if blocking: x and not O_NONBLOCK else: x or O_NONBLOCK if fcntl(s.fd, F_SETFL, mode) == -1: - OSError(OSLastError()) + osError(osLastError()) s.nonblocking = not blocking discard """ proc setReuseAddr*(s: TSocket) = @@ -1709,7 +1709,7 @@ proc isBlocking*(socket: TSocket): bool = not socket.nonblocking ## Determines whether ``socket`` is blocking. when defined(Windows): - var wsa: TWSADATA - if WSAStartup(0x0101'i16, addr wsa) != 0: OSError(OSLastError()) + var wsa: TWSAData + if wsaStartup(0x0101'i16, addr wsa) != 0: osError(osLastError()) diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index 764471b78..302742eb4 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -249,7 +249,7 @@ proc fsClose(s: PStream) = close(PFileStream(s).f) PFileStream(s).f = nil proc fsFlush(s: PStream) = flushFile(PFileStream(s).f) -proc fsAtEnd(s: PStream): bool = return EndOfFile(PFileStream(s).f) +proc fsAtEnd(s: PStream): bool = return endOfFile(PFileStream(s).f) proc fsSetPosition(s: PStream, pos: int) = setFilePos(PFileStream(s).f, pos) proc fsGetPosition(s: PStream): int = return int(getFilePos(PFileStream(s).f)) @@ -277,7 +277,7 @@ proc newFileStream*(filename: string, mode: TFileMode): PFileStream = ## If the file cannot be opened, nil is returned. See the `system ## <system.html>`_ module for a list of available TFileMode enums. var f: TFile - if Open(f, filename, mode): result = newFileStream(f) + if open(f, filename, mode): result = newFileStream(f) when true: diff --git a/lib/pure/strtabs.nim b/lib/pure/strtabs.nim index 77b463fc0..7003acfcf 100644 --- a/lib/pure/strtabs.nim +++ b/lib/pure/strtabs.nim @@ -88,10 +88,10 @@ proc mustRehash(length, counter: int): bool = proc nextTry(h, maxHash: THash): THash {.inline.} = result = ((5 * h) + 1) and maxHash -proc RawGet(t: PStringTable, key: string): int = +proc rawGet(t: PStringTable, key: string): int = var h: THash = myhash(t, key) and high(t.data) # start with real hash value while not isNil(t.data[h].key): - if mycmp(t, t.data[h].key, key): + if myCmp(t, t.data[h].key, key): return h h = nextTry(h, high(t.data)) result = - 1 @@ -100,7 +100,7 @@ proc `[]`*(t: PStringTable, key: string): string {.rtl, extern: "nstGet".} = ## retrieves the value at ``t[key]``. If `key` is not in `t`, "" is returned ## and no exception is raised. One can check with ``hasKey`` whether the key ## exists. - var index = RawGet(t, key) + var index = rawGet(t, key) if index >= 0: result = t.data[index].val else: result = "" @@ -108,7 +108,7 @@ proc mget*(t: PStringTable, key: string): var string {. rtl, extern: "nstTake".} = ## retrieves the location at ``t[key]``. If `key` is not in `t`, the ## ``EInvalidKey`` exception is raised. - var index = RawGet(t, key) + var index = rawGet(t, key) if index >= 0: result = t.data[index].val else: raise newException(EInvalidKey, "key does not exist: " & key) @@ -116,31 +116,31 @@ proc hasKey*(t: PStringTable, key: string): bool {.rtl, extern: "nst$1".} = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 -proc RawInsert(t: PStringTable, data: var TKeyValuePairSeq, key, val: string) = +proc rawInsert(t: PStringTable, data: var TKeyValuePairSeq, key, val: string) = var h: THash = myhash(t, key) and high(data) while not isNil(data[h].key): h = nextTry(h, high(data)) data[h].key = key data[h].val = val -proc Enlarge(t: PStringTable) = +proc enlarge(t: PStringTable) = var n: TKeyValuePairSeq newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): - if not isNil(t.data[i].key): RawInsert(t, n, t.data[i].key, t.data[i].val) + if not isNil(t.data[i].key): rawInsert(t, n, t.data[i].key, t.data[i].val) swap(t.data, n) proc `[]=`*(t: PStringTable, key, val: string) {.rtl, extern: "nstPut".} = ## puts a (key, value)-pair into `t`. - var index = RawGet(t, key) + var index = rawGet(t, key) if index >= 0: t.data[index].val = val else: - if mustRehash(len(t.data), t.counter): Enlarge(t) - RawInsert(t, t.data, key, val) + if mustRehash(len(t.data), t.counter): enlarge(t) + rawInsert(t, t.data, key, val) inc(t.counter) -proc RaiseFormatException(s: string) = +proc raiseFormatException(s: string) = var e: ref EInvalidValue new(e) e.msg = "format string: key not found: " & s @@ -184,7 +184,7 @@ proc newStringTable*(keyValuePairs: varargs[tuple[key, val: string]], ## var mytab = newStringTable({"key1": "val1", "key2": "val2"}, ## modeCaseInsensitive) result = newStringTable(mode) - for key, val in items(keyvaluePairs): result[key] = val + for key, val in items(keyValuePairs): result[key] = val proc `%`*(f: string, t: PStringTable, flags: set[TFormatFlag] = {}): string {. rtl, extern: "nstFormat".} = diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index fe71cb77b..20109cfa2 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -1,170 +1,170 @@ -# -# -# Nimrod's Runtime Library -# (c) Copyright 2012 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## This module contains various string utility routines. -## See the module `re <re.html>`_ for regular expression support. -## See the module `pegs <pegs.html>`_ for PEG support. - -import parseutils - -{.deadCodeElim: on.} - -{.push debugger:off .} # the user does not want to trace a part - # of the standard library! - -include "system/inclrtl" - -type - TCharSet* = set[char] # for compatibility with Nim - -const - Whitespace* = {' ', '\t', '\v', '\r', '\l', '\f'} - ## All the characters that count as whitespace. - - Letters* = {'A'..'Z', 'a'..'z'} - ## the set of letters - - Digits* = {'0'..'9'} - ## the set of digits - - HexDigits* = {'0'..'9', 'A'..'F', 'a'..'f'} - ## the set of hexadecimal digits - - IdentChars* = {'a'..'z', 'A'..'Z', '0'..'9', '_'} - ## the set of characters an identifier can consist of - - IdentStartChars* = {'a'..'z', 'A'..'Z', '_'} - ## the set of characters an identifier can start with - - NewLines* = {'\13', '\10'} - ## the set of characters a newline terminator can start with - -proc toLower*(c: Char): Char {.noSideEffect, procvar, - rtl, extern: "nsuToLowerChar".} = - ## Converts `c` into lower case. This works only for the letters A-Z. - ## See `unicode.toLower` for a version that works for any Unicode character. - if c in {'A'..'Z'}: - result = chr(ord(c) + (ord('a') - ord('A'))) - else: - result = c - -proc toLower*(s: string): string {.noSideEffect, procvar, - rtl, extern: "nsuToLowerStr".} = - ## Converts `s` into lower case. This works only for the letters A-Z. - ## See `unicode.toLower` for a version that works for any Unicode character. - result = newString(len(s)) - for i in 0..len(s) - 1: - result[i] = toLower(s[i]) - -proc toUpper*(c: Char): Char {.noSideEffect, procvar, - rtl, extern: "nsuToUpperChar".} = - ## Converts `c` into upper case. This works only for the letters a-z. - ## See `unicode.toUpper` for a version that works for any Unicode character. - if c in {'a'..'z'}: - result = Chr(Ord(c) - (Ord('a') - Ord('A'))) - else: - result = c - -proc toUpper*(s: string): string {.noSideEffect, procvar, - rtl, extern: "nsuToUpperStr".} = - ## Converts `s` into upper case. This works only for the letters a-z. - ## See `unicode.toUpper` for a version that works for any Unicode character. - result = newString(len(s)) - for i in 0..len(s) - 1: - result[i] = toUpper(s[i]) - -proc capitalize*(s: string): string {.noSideEffect, procvar, - rtl, extern: "nsuCapitalize".} = - ## Converts the first character of `s` into upper case. - ## This works only for the letters a-z. - result = toUpper(s[0]) & substr(s, 1) - -proc normalize*(s: string): string {.noSideEffect, procvar, - rtl, extern: "nsuNormalize".} = - ## Normalizes the string `s`. That means to convert it to lower case and - ## remove any '_'. This is needed for Nimrod identifiers for example. - result = newString(s.len) - var j = 0 - for i in 0..len(s) - 1: - if s[i] in {'A'..'Z'}: - result[j] = Chr(Ord(s[i]) + (Ord('a') - Ord('A'))) - inc j - elif s[i] != '_': - result[j] = s[i] - inc j - if j != s.len: setLen(result, j) - -proc cmpIgnoreCase*(a, b: string): int {.noSideEffect, - rtl, extern: "nsuCmpIgnoreCase", procvar, operator: 4.} = - ## Compares two strings in a case insensitive manner. Returns: - ## - ## | 0 iff a == b - ## | < 0 iff a < b - ## | > 0 iff a > b - var i = 0 - var m = min(a.len, b.len) - while i < m: - result = ord(toLower(a[i])) - ord(toLower(b[i])) - if result != 0: return - inc(i) - result = a.len - b.len - -{.push checks: off, line_trace: off .} # this is a hot-spot in the compiler! - # thus we compile without checks here - -proc cmpIgnoreStyle*(a, b: string): int {.noSideEffect, - rtl, extern: "nsuCmpIgnoreStyle", procvar, operator: 3.} = - ## Compares two strings normalized (i.e. case and - ## underscores do not matter). Returns: - ## - ## | 0 iff a == b - ## | < 0 iff a < b - ## | > 0 iff a > b - var i = 0 - var j = 0 - while True: - while a[i] == '_': inc(i) - while b[j] == '_': inc(j) # BUGFIX: typo - var aa = toLower(a[i]) - var bb = toLower(b[j]) - result = ord(aa) - ord(bb) - if result != 0 or aa == '\0': break - inc(i) - inc(j) - -{.pop.} - -proc strip*(s: string, leading = true, trailing = true): string {.noSideEffect, - rtl, extern: "nsuStrip", operator: 5.} = - ## Strips whitespace from `s` and returns the resulting string. - ## If `leading` is true, leading whitespace is stripped. - ## If `trailing` is true, trailing whitespace is stripped. - const - chars: set[Char] = Whitespace - var - first = 0 - last = len(s)-1 - if leading: - while s[first] in chars: inc(first) - if trailing: - while last >= 0 and s[last] in chars: dec(last) - result = substr(s, first, last) - -proc toOctal*(c: char): string {.noSideEffect, rtl, extern: "nsuToOctal".} = - ## Converts a character `c` to its octal representation. The resulting - ## string may not have a leading zero. Its length is always exactly 3. - result = newString(3) - var val = ord(c) - for i in countdown(2, 0): - result[i] = Chr(val mod 8 + ord('0')) - val = val div 8 - +# +# +# Nimrod's Runtime Library +# (c) Copyright 2012 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module contains various string utility routines. +## See the module `re <re.html>`_ for regular expression support. +## See the module `pegs <pegs.html>`_ for PEG support. + +import parseutils + +{.deadCodeElim: on.} + +{.push debugger:off .} # the user does not want to trace a part + # of the standard library! + +include "system/inclrtl" + +type + TCharSet* = set[char] # for compatibility with Nim + +const + Whitespace* = {' ', '\t', '\v', '\r', '\l', '\f'} + ## All the characters that count as whitespace. + + Letters* = {'A'..'Z', 'a'..'z'} + ## the set of letters + + Digits* = {'0'..'9'} + ## the set of digits + + HexDigits* = {'0'..'9', 'A'..'F', 'a'..'f'} + ## the set of hexadecimal digits + + IdentChars* = {'a'..'z', 'A'..'Z', '0'..'9', '_'} + ## the set of characters an identifier can consist of + + IdentStartChars* = {'a'..'z', 'A'..'Z', '_'} + ## the set of characters an identifier can start with + + NewLines* = {'\13', '\10'} + ## the set of characters a newline terminator can start with + +proc toLower*(c: char): char {.noSideEffect, procvar, + rtl, extern: "nsuToLowerChar".} = + ## Converts `c` into lower case. This works only for the letters A-Z. + ## See `unicode.toLower` for a version that works for any Unicode character. + if c in {'A'..'Z'}: + result = chr(ord(c) + (ord('a') - ord('A'))) + else: + result = c + +proc toLower*(s: string): string {.noSideEffect, procvar, + rtl, extern: "nsuToLowerStr".} = + ## Converts `s` into lower case. This works only for the letters A-Z. + ## See `unicode.toLower` for a version that works for any Unicode character. + result = newString(len(s)) + for i in 0..len(s) - 1: + result[i] = toLower(s[i]) + +proc toUpper*(c: char): char {.noSideEffect, procvar, + rtl, extern: "nsuToUpperChar".} = + ## Converts `c` into upper case. This works only for the letters a-z. + ## See `unicode.toUpper` for a version that works for any Unicode character. + if c in {'a'..'z'}: + result = chr(ord(c) - (ord('a') - ord('A'))) + else: + result = c + +proc toUpper*(s: string): string {.noSideEffect, procvar, + rtl, extern: "nsuToUpperStr".} = + ## Converts `s` into upper case. This works only for the letters a-z. + ## See `unicode.toUpper` for a version that works for any Unicode character. + result = newString(len(s)) + for i in 0..len(s) - 1: + result[i] = toUpper(s[i]) + +proc capitalize*(s: string): string {.noSideEffect, procvar, + rtl, extern: "nsuCapitalize".} = + ## Converts the first character of `s` into upper case. + ## This works only for the letters a-z. + result = toUpper(s[0]) & substr(s, 1) + +proc normalize*(s: string): string {.noSideEffect, procvar, + rtl, extern: "nsuNormalize".} = + ## Normalizes the string `s`. That means to convert it to lower case and + ## remove any '_'. This is needed for Nimrod identifiers for example. + result = newString(s.len) + var j = 0 + for i in 0..len(s) - 1: + if s[i] in {'A'..'Z'}: + result[j] = chr(ord(s[i]) + (ord('a') - ord('A'))) + inc j + elif s[i] != '_': + result[j] = s[i] + inc j + if j != s.len: setLen(result, j) + +proc cmpIgnoreCase*(a, b: string): int {.noSideEffect, + rtl, extern: "nsuCmpIgnoreCase", procvar, operator: 4.} = + ## Compares two strings in a case insensitive manner. Returns: + ## + ## | 0 iff a == b + ## | < 0 iff a < b + ## | > 0 iff a > b + var i = 0 + var m = min(a.len, b.len) + while i < m: + result = ord(toLower(a[i])) - ord(toLower(b[i])) + if result != 0: return + inc(i) + result = a.len - b.len + +{.push checks: off, line_trace: off .} # this is a hot-spot in the compiler! + # thus we compile without checks here + +proc cmpIgnoreStyle*(a, b: string): int {.noSideEffect, + rtl, extern: "nsuCmpIgnoreStyle", procvar, operator: 3.} = + ## Compares two strings normalized (i.e. case and + ## underscores do not matter). Returns: + ## + ## | 0 iff a == b + ## | < 0 iff a < b + ## | > 0 iff a > b + var i = 0 + var j = 0 + while true: + while a[i] == '_': inc(i) + while b[j] == '_': inc(j) # BUGFIX: typo + var aa = toLower(a[i]) + var bb = toLower(b[j]) + result = ord(aa) - ord(bb) + if result != 0 or aa == '\0': break + inc(i) + inc(j) + +{.pop.} + +proc strip*(s: string, leading = true, trailing = true): string {.noSideEffect, + rtl, extern: "nsuStrip", operator: 5.} = + ## Strips whitespace from `s` and returns the resulting string. + ## If `leading` is true, leading whitespace is stripped. + ## If `trailing` is true, trailing whitespace is stripped. + const + chars: set[char] = Whitespace + var + first = 0 + last = len(s)-1 + if leading: + while s[first] in chars: inc(first) + if trailing: + while last >= 0 and s[last] in chars: dec(last) + result = substr(s, first, last) + +proc toOctal*(c: char): string {.noSideEffect, rtl, extern: "nsuToOctal".} = + ## Converts a character `c` to its octal representation. The resulting + ## string may not have a leading zero. Its length is always exactly 3. + result = newString(3) + var val = ord(c) + for i in countdown(2, 0): + result[i] = chr(val mod 8 + ord('0')) + val = val div 8 + iterator split*(s: string, seps: set[char] = Whitespace): string = ## Splits the string `s` into substrings using a group of separators. ## @@ -209,199 +209,199 @@ iterator split*(s: string, seps: set[char] = Whitespace): string = ## "08" ## "08.398990" ## - var last = 0 - assert(not ('\0' in seps)) - while last < len(s): - while s[last] in seps: inc(last) - var first = last - while last < len(s) and s[last] not_in seps: inc(last) # BUGFIX! - if first <= last-1: - yield substr(s, first, last-1) - -iterator split*(s: string, sep: char): string = - ## Splits the string `s` into substrings using a single separator. - ## - ## Substrings are separated by the character `sep`. - ## Unlike the version of the iterator which accepts a set of separator - ## characters, this proc will not coalesce groups of the - ## separator, returning a string for each found character. The code: - ## - ## .. code-block:: nimrod - ## for word in split(";;this;is;an;;example;;;", ';'): - ## writeln(stdout, word) - ## - ## Results in: - ## - ## .. code-block:: - ## "" - ## "" - ## "this" - ## "is" - ## "an" - ## "" - ## "example" - ## "" - ## "" - ## "" - ## - var last = 0 - assert('\0' != sep) - if len(s) > 0: - # `<=` is correct here for the edge cases! - while last <= len(s): - var first = last - while last < len(s) and s[last] != sep: inc(last) - yield substr(s, first, last-1) - inc(last) - -iterator splitLines*(s: string): string = - ## Splits the string `s` into its containing lines. Every newline - ## combination (CR, LF, CR-LF) is supported. The result strings contain - ## no trailing ``\n``. - ## - ## Example: - ## - ## .. code-block:: nimrod - ## for line in splitLines("\nthis\nis\nan\n\nexample\n"): - ## writeln(stdout, line) - ## - ## Results in: - ## - ## .. code-block:: nimrod - ## "" - ## "this" - ## "is" - ## "an" - ## "" - ## "example" - ## "" - var first = 0 - var last = 0 - while true: - while s[last] notin {'\0', '\c', '\l'}: inc(last) - yield substr(s, first, last-1) - # skip newlines: - if s[last] == '\l': inc(last) - elif s[last] == '\c': - inc(last) - if s[last] == '\l': inc(last) - else: break # was '\0' - first = last - -proc splitLines*(s: string): seq[string] {.noSideEffect, - rtl, extern: "nsuSplitLines".} = - ## The same as the `splitLines` iterator, but is a proc that returns a - ## sequence of substrings. - accumulateResult(splitLines(s)) - -proc countLines*(s: string): int {.noSideEffect, - rtl, extern: "nsuCountLines".} = - ## same as ``len(splitLines(s))``, but much more efficient. - var i = 0 - while i < s.len: - case s[i] - of '\c': - if s[i+1] == '\l': inc i - inc result - of '\l': inc result - else: nil - inc i - -proc split*(s: string, seps: set[char] = Whitespace): seq[string] {. - noSideEffect, rtl, extern: "nsuSplitCharSet".} = - ## The same as the `split` iterator, but is a proc that returns a - ## sequence of substrings. - accumulateResult(split(s, seps)) - -proc split*(s: string, sep: char): seq[string] {.noSideEffect, - rtl, extern: "nsuSplitChar".} = - ## The same as the `split` iterator, but is a proc that returns a sequence - ## of substrings. - accumulateResult(split(s, sep)) - -proc toHex*(x: BiggestInt, len: int): string {.noSideEffect, - rtl, extern: "nsuToHex".} = - ## Converts `x` to its hexadecimal representation. The resulting string - ## will be exactly `len` characters long. No prefix like ``0x`` - ## is generated. `x` is treated as an unsigned value. - const - HexChars = "0123456789ABCDEF" - var - shift: BiggestInt - result = newString(len) - for j in countdown(len-1, 0): - result[j] = HexChars[toU32(x shr shift) and 0xF'i32] - shift = shift + 4 - -proc intToStr*(x: int, minchars: int = 1): string {.noSideEffect, - rtl, extern: "nsuIntToStr".} = - ## Converts `x` to its decimal representation. The resulting string - ## will be minimally `minchars` characters long. This is achieved by - ## adding leading zeros. - result = $abs(x) - for i in 1 .. minchars - len(result): - result = '0' & result - if x < 0: - result = '-' & result - -proc ParseInt*(s: string): int {.noSideEffect, procvar, - rtl, extern: "nsuParseInt".} = - ## Parses a decimal integer value contained in `s`. If `s` is not - ## a valid integer, `EInvalidValue` is raised. - var L = parseutils.parseInt(s, result, 0) - if L != s.len or L == 0: - raise newException(EInvalidValue, "invalid integer: " & s) - -proc ParseBiggestInt*(s: string): biggestInt {.noSideEffect, procvar, - rtl, extern: "nsuParseBiggestInt".} = - ## Parses a decimal integer value contained in `s`. If `s` is not - ## a valid integer, `EInvalidValue` is raised. - var L = parseutils.parseBiggestInt(s, result, 0) - if L != s.len or L == 0: - raise newException(EInvalidValue, "invalid integer: " & s) - -proc ParseFloat*(s: string): float {.noSideEffect, procvar, - rtl, extern: "nsuParseFloat".} = - ## Parses a decimal floating point value contained in `s`. If `s` is not - ## a valid floating point number, `EInvalidValue` is raised. ``NAN``, - ## ``INF``, ``-INF`` are also supported (case insensitive comparison). - var L = parseutils.parseFloat(s, result, 0) - if L != s.len or L == 0: - raise newException(EInvalidValue, "invalid float: " & s) - -proc ParseHexInt*(s: string): int {.noSideEffect, procvar, - rtl, extern: "nsuParseHexInt".} = - ## Parses a hexadecimal integer value contained in `s`. If `s` is not - ## a valid integer, `EInvalidValue` is raised. `s` can have one of the - ## following optional prefixes: ``0x``, ``0X``, ``#``. - ## Underscores within `s` are ignored. - var i = 0 - if s[i] == '0' and (s[i+1] == 'x' or s[i+1] == 'X'): inc(i, 2) - elif s[i] == '#': inc(i) - while true: - case s[i] - of '_': inc(i) - of '0'..'9': - result = result shl 4 or (ord(s[i]) - ord('0')) - inc(i) - of 'a'..'f': - result = result shl 4 or (ord(s[i]) - ord('a') + 10) - inc(i) - of 'A'..'F': - result = result shl 4 or (ord(s[i]) - ord('A') + 10) - inc(i) - of '\0': break - else: raise newException(EInvalidValue, "invalid integer: " & s) - -proc parseBool*(s: string): bool = - ## Parses a value into a `bool`. If ``s`` is one of the following values: - ## ``y, yes, true, 1, on``, then returns `true`. If ``s`` is one of the - ## following values: ``n, no, false, 0, off``, then returns `false`. - ## If ``s`` is something else a ``EInvalidValue`` exception is raised. - case normalize(s) - of "y", "yes", "true", "1", "on": result = true - of "n", "no", "false", "0", "off": result = false - else: raise newException(EInvalidValue, "cannot interpret as a bool: " & s) + var last = 0 + assert(not ('\0' in seps)) + while last < len(s): + while s[last] in seps: inc(last) + var first = last + while last < len(s) and s[last] notin seps: inc(last) # BUGFIX! + if first <= last-1: + yield substr(s, first, last-1) + +iterator split*(s: string, sep: char): string = + ## Splits the string `s` into substrings using a single separator. + ## + ## Substrings are separated by the character `sep`. + ## Unlike the version of the iterator which accepts a set of separator + ## characters, this proc will not coalesce groups of the + ## separator, returning a string for each found character. The code: + ## + ## .. code-block:: nimrod + ## for word in split(";;this;is;an;;example;;;", ';'): + ## writeln(stdout, word) + ## + ## Results in: + ## + ## .. code-block:: + ## "" + ## "" + ## "this" + ## "is" + ## "an" + ## "" + ## "example" + ## "" + ## "" + ## "" + ## + var last = 0 + assert('\0' != sep) + if len(s) > 0: + # `<=` is correct here for the edge cases! + while last <= len(s): + var first = last + while last < len(s) and s[last] != sep: inc(last) + yield substr(s, first, last-1) + inc(last) + +iterator splitLines*(s: string): string = + ## Splits the string `s` into its containing lines. Every newline + ## combination (CR, LF, CR-LF) is supported. The result strings contain + ## no trailing ``\n``. + ## + ## Example: + ## + ## .. code-block:: nimrod + ## for line in splitLines("\nthis\nis\nan\n\nexample\n"): + ## writeln(stdout, line) + ## + ## Results in: + ## + ## .. code-block:: nimrod + ## "" + ## "this" + ## "is" + ## "an" + ## "" + ## "example" + ## "" + var first = 0 + var last = 0 + while true: + while s[last] notin {'\0', '\c', '\l'}: inc(last) + yield substr(s, first, last-1) + # skip newlines: + if s[last] == '\l': inc(last) + elif s[last] == '\c': + inc(last) + if s[last] == '\l': inc(last) + else: break # was '\0' + first = last + +proc splitLines*(s: string): seq[string] {.noSideEffect, + rtl, extern: "nsuSplitLines".} = + ## The same as the `splitLines` iterator, but is a proc that returns a + ## sequence of substrings. + accumulateResult(splitLines(s)) + +proc countLines*(s: string): int {.noSideEffect, + rtl, extern: "nsuCountLines".} = + ## same as ``len(splitLines(s))``, but much more efficient. + var i = 0 + while i < s.len: + case s[i] + of '\c': + if s[i+1] == '\l': inc i + inc result + of '\l': inc result + else: nil + inc i + +proc split*(s: string, seps: set[char] = Whitespace): seq[string] {. + noSideEffect, rtl, extern: "nsuSplitCharSet".} = + ## The same as the `split` iterator, but is a proc that returns a + ## sequence of substrings. + accumulateResult(split(s, seps)) + +proc split*(s: string, sep: char): seq[string] {.noSideEffect, + rtl, extern: "nsuSplitChar".} = + ## The same as the `split` iterator, but is a proc that returns a sequence + ## of substrings. + accumulateResult(split(s, sep)) + +proc toHex*(x: BiggestInt, len: int): string {.noSideEffect, + rtl, extern: "nsuToHex".} = + ## Converts `x` to its hexadecimal representation. The resulting string + ## will be exactly `len` characters long. No prefix like ``0x`` + ## is generated. `x` is treated as an unsigned value. + const + HexChars = "0123456789ABCDEF" + var + shift: BiggestInt + result = newString(len) + for j in countdown(len-1, 0): + result[j] = HexChars[toU32(x shr shift) and 0xF'i32] + shift = shift + 4 + +proc intToStr*(x: int, minchars: int = 1): string {.noSideEffect, + rtl, extern: "nsuIntToStr".} = + ## Converts `x` to its decimal representation. The resulting string + ## will be minimally `minchars` characters long. This is achieved by + ## adding leading zeros. + result = $abs(x) + for i in 1 .. minchars - len(result): + result = '0' & result + if x < 0: + result = '-' & result + +proc parseInt*(s: string): int {.noSideEffect, procvar, + rtl, extern: "nsuParseInt".} = + ## Parses a decimal integer value contained in `s`. If `s` is not + ## a valid integer, `EInvalidValue` is raised. + var L = parseutils.parseInt(s, result, 0) + if L != s.len or L == 0: + raise newException(EInvalidValue, "invalid integer: " & s) + +proc parseBiggestInt*(s: string): BiggestInt {.noSideEffect, procvar, + rtl, extern: "nsuParseBiggestInt".} = + ## Parses a decimal integer value contained in `s`. If `s` is not + ## a valid integer, `EInvalidValue` is raised. + var L = parseutils.parseBiggestInt(s, result, 0) + if L != s.len or L == 0: + raise newException(EInvalidValue, "invalid integer: " & s) + +proc parseFloat*(s: string): float {.noSideEffect, procvar, + rtl, extern: "nsuParseFloat".} = + ## Parses a decimal floating point value contained in `s`. If `s` is not + ## a valid floating point number, `EInvalidValue` is raised. ``NAN``, + ## ``INF``, ``-INF`` are also supported (case insensitive comparison). + var L = parseutils.parseFloat(s, result, 0) + if L != s.len or L == 0: + raise newException(EInvalidValue, "invalid float: " & s) + +proc parseHexInt*(s: string): int {.noSideEffect, procvar, + rtl, extern: "nsuParseHexInt".} = + ## Parses a hexadecimal integer value contained in `s`. If `s` is not + ## a valid integer, `EInvalidValue` is raised. `s` can have one of the + ## following optional prefixes: ``0x``, ``0X``, ``#``. + ## Underscores within `s` are ignored. + var i = 0 + if s[i] == '0' and (s[i+1] == 'x' or s[i+1] == 'X'): inc(i, 2) + elif s[i] == '#': inc(i) + while true: + case s[i] + of '_': inc(i) + of '0'..'9': + result = result shl 4 or (ord(s[i]) - ord('0')) + inc(i) + of 'a'..'f': + result = result shl 4 or (ord(s[i]) - ord('a') + 10) + inc(i) + of 'A'..'F': + result = result shl 4 or (ord(s[i]) - ord('A') + 10) + inc(i) + of '\0': break + else: raise newException(EInvalidValue, "invalid integer: " & s) + +proc parseBool*(s: string): bool = + ## Parses a value into a `bool`. If ``s`` is one of the following values: + ## ``y, yes, true, 1, on``, then returns `true`. If ``s`` is one of the + ## following values: ``n, no, false, 0, off``, then returns `false`. + ## If ``s`` is something else a ``EInvalidValue`` exception is raised. + case normalize(s) + of "y", "yes", "true", "1", "on": result = true + of "n", "no", "false", "0", "off": result = false + else: raise newException(EInvalidValue, "cannot interpret as a bool: " & s) proc parseEnum*[T: enum](s: string): T = ## parses an enum ``T``. Raises ``EInvalidValue`` for an invalid value in @@ -418,30 +418,30 @@ proc parseEnum*[T: enum](s: string, default: T): T = if cmpIgnoreStyle(s, $e) == 0: return e result = default - -proc repeatChar*(count: int, c: Char = ' '): string {.noSideEffect, - rtl, extern: "nsuRepeatChar".} = - ## Returns a string of length `count` consisting only of - ## the character `c`. You can use this proc to left align strings. Example: - ## - ## .. code-block:: nimrod - ## let - ## width = 15 - ## text1 = "Hello user!" - ## text2 = "This is a very long string" - ## echo text1 & repeatChar(max(0, width - text1.len)) & "|" - ## echo text2 & repeatChar(max(0, width - text2.len)) & "|" - result = newString(count) - for i in 0..count-1: result[i] = c - -proc repeatStr*(count: int, s: string): string {.noSideEffect, - rtl, extern: "nsuRepeatStr".} = - ## Returns `s` concatenated `count` times. - result = newStringOfCap(count*s.len) - for i in 0..count-1: result.add(s) - -proc align*(s: string, count: int, padding = ' '): string {. - noSideEffect, rtl, extern: "nsuAlignString".} = + +proc repeatChar*(count: int, c: char = ' '): string {.noSideEffect, + rtl, extern: "nsuRepeatChar".} = + ## Returns a string of length `count` consisting only of + ## the character `c`. You can use this proc to left align strings. Example: + ## + ## .. code-block:: nimrod + ## let + ## width = 15 + ## text1 = "Hello user!" + ## text2 = "This is a very long string" + ## echo text1 & repeatChar(max(0, width - text1.len)) & "|" + ## echo text2 & repeatChar(max(0, width - text2.len)) & "|" + result = newString(count) + for i in 0..count-1: result[i] = c + +proc repeatStr*(count: int, s: string): string {.noSideEffect, + rtl, extern: "nsuRepeatStr".} = + ## Returns `s` concatenated `count` times. + result = newStringOfCap(count*s.len) + for i in 0..count-1: result.add(s) + +proc align*(s: string, count: int, padding = ' '): string {. + noSideEffect, rtl, extern: "nsuAlignString".} = ## Aligns a string `s` with `padding`, so that is of length `count`. ## `padding` characters (by default spaces) are added before `s` resulting in ## right alignment. If ``s.len >= count``, no spaces are added and `s` is @@ -453,247 +453,247 @@ proc align*(s: string, count: int, padding = ' '): string {. ## assert align("a", 0) == "a" ## assert align("1232", 6) == " 1232" ## assert align("1232", 6, '#') == "##1232" - if s.len < count: - result = newString(count) - var spaces = count - s.len - for i in 0..spaces-1: result[i] = padding - for i in spaces..count-1: result[i] = s[i-spaces] - else: - result = s - -iterator tokenize*(s: string, seps: set[char] = Whitespace): tuple[ - token: string, isSep: bool] = - ## Tokenizes the string `s` into substrings. - ## - ## Substrings are separated by a substring containing only `seps`. - ## Examples: - ## - ## .. code-block:: nimrod - ## for word in tokenize(" this is an example "): - ## writeln(stdout, word) - ## - ## Results in: - ## - ## .. code-block:: nimrod - ## (" ", true) - ## ("this", false) - ## (" ", true) - ## ("is", false) - ## (" ", true) - ## ("an", false) - ## (" ", true) - ## ("example", false) - ## (" ", true) - var i = 0 - while true: - var j = i - var isSep = s[j] in seps - while j < s.len and (s[j] in seps) == isSep: inc(j) - if j > i: - yield (substr(s, i, j-1), isSep) - else: - break - i = j - -proc wordWrap*(s: string, maxLineWidth = 80, - splitLongWords = true, - seps: set[char] = whitespace, - newLine = "\n"): string {. - noSideEffect, rtl, extern: "nsuWordWrap".} = - ## word wraps `s`. - result = newStringOfCap(s.len + s.len shr 6) - var SpaceLeft = maxLineWidth - for word, isSep in tokenize(s, seps): - if len(word) > SpaceLeft: - if splitLongWords and len(word) > maxLineWidth: - result.add(substr(word, 0, spaceLeft-1)) - var w = spaceLeft+1 - var wordLeft = len(word) - spaceLeft - while wordLeft > 0: - result.add(newLine) - var L = min(maxLineWidth, wordLeft) - SpaceLeft = maxLineWidth - L - result.add(substr(word, w, w+L-1)) - inc(w, L) - dec(wordLeft, L) - else: - SpaceLeft = maxLineWidth - len(Word) - result.add(newLine) - result.add(word) - else: - SpaceLeft = SpaceLeft - len(Word) - result.add(word) - -proc unindent*(s: string, eatAllIndent = false): string {. - noSideEffect, rtl, extern: "nsuUnindent".} = - ## unindents `s`. - result = newStringOfCap(s.len) - var i = 0 - var pattern = true - var indent = 0 - while s[i] == ' ': inc i - var level = if i == 0: -1 else: i - while i < s.len: - if s[i] == ' ': - if i > 0 and s[i-1] in {'\l', '\c'}: - pattern = true - indent = 0 - if pattern: - inc(indent) - if indent > level and not eatAllIndent: - result.add(s[i]) - if level < 0: level = indent - else: - # a space somewhere: do not delete - result.add(s[i]) - else: - pattern = false - result.add(s[i]) - inc i - -proc startsWith*(s, prefix: string): bool {.noSideEffect, - rtl, extern: "nsuStartsWith".} = - ## Returns true iff ``s`` starts with ``prefix``. - ## If ``prefix == ""`` true is returned. - var i = 0 - while true: - if prefix[i] == '\0': return true - if s[i] != prefix[i]: return false - inc(i) - -proc endsWith*(s, suffix: string): bool {.noSideEffect, - rtl, extern: "nsuEndsWith".} = - ## Returns true iff ``s`` ends with ``suffix``. - ## If ``suffix == ""`` true is returned. - var i = 0 - var j = len(s) - len(suffix) - while i+j <% s.len: - if s[i+j] != suffix[i]: return false - inc(i) - if suffix[i] == '\0': return true + if s.len < count: + result = newString(count) + let spaces = count - s.len + for i in 0..spaces-1: result[i] = padding + for i in spaces..count-1: result[i] = s[i-spaces] + else: + result = s + +iterator tokenize*(s: string, seps: set[char] = Whitespace): tuple[ + token: string, isSep: bool] = + ## Tokenizes the string `s` into substrings. + ## + ## Substrings are separated by a substring containing only `seps`. + ## Examples: + ## + ## .. code-block:: nimrod + ## for word in tokenize(" this is an example "): + ## writeln(stdout, word) + ## + ## Results in: + ## + ## .. code-block:: nimrod + ## (" ", true) + ## ("this", false) + ## (" ", true) + ## ("is", false) + ## (" ", true) + ## ("an", false) + ## (" ", true) + ## ("example", false) + ## (" ", true) + var i = 0 + while true: + var j = i + var isSep = s[j] in seps + while j < s.len and (s[j] in seps) == isSep: inc(j) + if j > i: + yield (substr(s, i, j-1), isSep) + else: + break + i = j + +proc wordWrap*(s: string, maxLineWidth = 80, + splitLongWords = true, + seps: set[char] = Whitespace, + newLine = "\n"): string {. + noSideEffect, rtl, extern: "nsuWordWrap".} = + ## word wraps `s`. + result = newStringOfCap(s.len + s.len shr 6) + var spaceLeft = maxLineWidth + for word, isSep in tokenize(s, seps): + if len(word) > spaceLeft: + if splitLongWords and len(word) > maxLineWidth: + result.add(substr(word, 0, spaceLeft-1)) + var w = spaceLeft+1 + var wordLeft = len(word) - spaceLeft + while wordLeft > 0: + result.add(newLine) + var L = min(maxLineWidth, wordLeft) + spaceLeft = maxLineWidth - L + result.add(substr(word, w, w+L-1)) + inc(w, L) + dec(wordLeft, L) + else: + spaceLeft = maxLineWidth - len(word) + result.add(newLine) + result.add(word) + else: + spaceLeft = spaceLeft - len(word) + result.add(word) + +proc unindent*(s: string, eatAllIndent = false): string {. + noSideEffect, rtl, extern: "nsuUnindent".} = + ## unindents `s`. + result = newStringOfCap(s.len) + var i = 0 + var pattern = true + var indent = 0 + while s[i] == ' ': inc i + var level = if i == 0: -1 else: i + while i < s.len: + if s[i] == ' ': + if i > 0 and s[i-1] in {'\l', '\c'}: + pattern = true + indent = 0 + if pattern: + inc(indent) + if indent > level and not eatAllIndent: + result.add(s[i]) + if level < 0: level = indent + else: + # a space somewhere: do not delete + result.add(s[i]) + else: + pattern = false + result.add(s[i]) + inc i + +proc startsWith*(s, prefix: string): bool {.noSideEffect, + rtl, extern: "nsuStartsWith".} = + ## Returns true iff ``s`` starts with ``prefix``. + ## If ``prefix == ""`` true is returned. + var i = 0 + while true: + if prefix[i] == '\0': return true + if s[i] != prefix[i]: return false + inc(i) + +proc endsWith*(s, suffix: string): bool {.noSideEffect, + rtl, extern: "nsuEndsWith".} = + ## Returns true iff ``s`` ends with ``suffix``. + ## If ``suffix == ""`` true is returned. + var i = 0 + var j = len(s) - len(suffix) + while i+j <% s.len: + if s[i+j] != suffix[i]: return false + inc(i) + if suffix[i] == '\0': return true proc continuesWith*(s, substr: string, start: int): bool {.noSideEffect, rtl, extern: "nsuContinuesWith".} = - ## Returns true iff ``s`` continues with ``substr`` at position ``start``. - ## If ``substr == ""`` true is returned. - var i = 0 - while true: - if substr[i] == '\0': return true - if s[i+start] != substr[i]: return false - inc(i) - -proc addSep*(dest: var string, sep = ", ", startLen = 0) {.noSideEffect, - inline.} = - ## A shorthand for: - ## - ## .. code-block:: nimrod - ## if dest.len > startLen: add(dest, sep) - ## - ## This is often useful for generating some code where the items need to - ## be *separated* by `sep`. `sep` is only added if `dest` is longer than - ## `startLen`. The following example creates a string describing - ## an array of integers: - ## - ## .. code-block:: nimrod - ## var arr = "[" - ## for x in items([2, 3, 5, 7, 11]): - ## addSep(arr, startLen=len("[")) - ## add(arr, $x) - ## add(arr, "]") - if dest.len > startLen: add(dest, sep) - -proc allCharsInSet*(s: string, theSet: TCharSet): bool = - ## returns true iff each character of `s` is in the set `theSet`. - for c in items(s): - if c notin theSet: return false - return true - -proc abbrev*(s: string, possibilities: openarray[string]): int = - ## returns the index of the first item in `possibilities` if not - ## ambiguous; -1 if no item has been found; -2 if multiple items - ## match. - result = -1 # none found - for i in 0..possibilities.len-1: - if possibilities[i].startsWith(s): - if possibilities[i] == s: - # special case: exact match shouldn't be ambiguous - return i - if result >= 0: return -2 # ambiguous - result = i - -# --------------------------------------------------------------------------- - -proc join*(a: openArray[string], sep: string): string {. - noSideEffect, rtl, extern: "nsuJoinSep".} = - ## concatenates all strings in `a` separating them with `sep`. - if len(a) > 0: - var L = sep.len * (a.len-1) - for i in 0..high(a): inc(L, a[i].len) - result = newStringOfCap(L) - add(result, a[0]) - for i in 1..high(a): - add(result, sep) - add(result, a[i]) - else: - result = "" - -proc join*(a: openArray[string]): string {. - noSideEffect, rtl, extern: "nsuJoin".} = - ## concatenates all strings in `a`. - if len(a) > 0: - var L = 0 - for i in 0..high(a): inc(L, a[i].len) - result = newStringOfCap(L) - for i in 0..high(a): add(result, a[i]) - else: - result = "" - -type - TSkipTable = array[Char, int] - -proc preprocessSub(sub: string, a: var TSkipTable) = - var m = len(sub) - for i in 0..0xff: a[chr(i)] = m+1 - for i in 0..m-1: a[sub[i]] = m-i - -proc findAux(s, sub: string, start: int, a: TSkipTable): int = - # fast "quick search" algorithm: - var - m = len(sub) - n = len(s) - # search: - var j = start - while j <= n - m: - block match: - for k in 0..m-1: - if sub[k] != s[k+j]: break match - return j - inc(j, a[s[j+m]]) - return -1 - -proc find*(s, sub: string, start: int = 0): int {.noSideEffect, - rtl, extern: "nsuFindStr", operator: 6.} = - ## Searches for `sub` in `s` starting at position `start`. Searching is - ## case-sensitive. If `sub` is not in `s`, -1 is returned. - var a {.noinit.}: TSkipTable - preprocessSub(sub, a) - result = findAux(s, sub, start, a) - -proc find*(s: string, sub: char, start: int = 0): int {.noSideEffect, - rtl, extern: "nsuFindChar".} = - ## Searches for `sub` in `s` starting at position `start`. Searching is - ## case-sensitive. If `sub` is not in `s`, -1 is returned. - for i in start..len(s)-1: - if sub == s[i]: return i - return -1 - -proc find*(s: string, chars: set[char], start: int = 0): int {.noSideEffect, - rtl, extern: "nsuFindCharSet".} = - ## Searches for `chars` in `s` starting at position `start`. If `s` contains - ## none of the characters in `chars`, -1 is returned. - for i in start..s.len-1: - if s[i] in chars: return i - return -1 + ## Returns true iff ``s`` continues with ``substr`` at position ``start``. + ## If ``substr == ""`` true is returned. + var i = 0 + while true: + if substr[i] == '\0': return true + if s[i+start] != substr[i]: return false + inc(i) + +proc addSep*(dest: var string, sep = ", ", startLen = 0) {.noSideEffect, + inline.} = + ## A shorthand for: + ## + ## .. code-block:: nimrod + ## if dest.len > startLen: add(dest, sep) + ## + ## This is often useful for generating some code where the items need to + ## be *separated* by `sep`. `sep` is only added if `dest` is longer than + ## `startLen`. The following example creates a string describing + ## an array of integers: + ## + ## .. code-block:: nimrod + ## var arr = "[" + ## for x in items([2, 3, 5, 7, 11]): + ## addSep(arr, startLen=len("[")) + ## add(arr, $x) + ## add(arr, "]") + if dest.len > startLen: add(dest, sep) + +proc allCharsInSet*(s: string, theSet: TCharSet): bool = + ## returns true iff each character of `s` is in the set `theSet`. + for c in items(s): + if c notin theSet: return false + return true + +proc abbrev*(s: string, possibilities: openArray[string]): int = + ## returns the index of the first item in `possibilities` if not + ## ambiguous; -1 if no item has been found; -2 if multiple items + ## match. + result = -1 # none found + for i in 0..possibilities.len-1: + if possibilities[i].startsWith(s): + if possibilities[i] == s: + # special case: exact match shouldn't be ambiguous + return i + if result >= 0: return -2 # ambiguous + result = i + +# --------------------------------------------------------------------------- + +proc join*(a: openArray[string], sep: string): string {. + noSideEffect, rtl, extern: "nsuJoinSep".} = + ## concatenates all strings in `a` separating them with `sep`. + if len(a) > 0: + var L = sep.len * (a.len-1) + for i in 0..high(a): inc(L, a[i].len) + result = newStringOfCap(L) + add(result, a[0]) + for i in 1..high(a): + add(result, sep) + add(result, a[i]) + else: + result = "" + +proc join*(a: openArray[string]): string {. + noSideEffect, rtl, extern: "nsuJoin".} = + ## concatenates all strings in `a`. + if len(a) > 0: + var L = 0 + for i in 0..high(a): inc(L, a[i].len) + result = newStringOfCap(L) + for i in 0..high(a): add(result, a[i]) + else: + result = "" + +type + TSkipTable = array[char, int] + +proc preprocessSub(sub: string, a: var TSkipTable) = + var m = len(sub) + for i in 0..0xff: a[chr(i)] = m+1 + for i in 0..m-1: a[sub[i]] = m-i + +proc findAux(s, sub: string, start: int, a: TSkipTable): int = + # fast "quick search" algorithm: + var + m = len(sub) + n = len(s) + # search: + var j = start + while j <= n - m: + block match: + for k in 0..m-1: + if sub[k] != s[k+j]: break match + return j + inc(j, a[s[j+m]]) + return -1 + +proc find*(s, sub: string, start: int = 0): int {.noSideEffect, + rtl, extern: "nsuFindStr", operator: 6.} = + ## Searches for `sub` in `s` starting at position `start`. Searching is + ## case-sensitive. If `sub` is not in `s`, -1 is returned. + var a {.noinit.}: TSkipTable + preprocessSub(sub, a) + result = findAux(s, sub, start, a) + +proc find*(s: string, sub: char, start: int = 0): int {.noSideEffect, + rtl, extern: "nsuFindChar".} = + ## Searches for `sub` in `s` starting at position `start`. Searching is + ## case-sensitive. If `sub` is not in `s`, -1 is returned. + for i in start..len(s)-1: + if sub == s[i]: return i + return -1 + +proc find*(s: string, chars: set[char], start: int = 0): int {.noSideEffect, + rtl, extern: "nsuFindCharSet".} = + ## Searches for `chars` in `s` starting at position `start`. If `s` contains + ## none of the characters in `chars`, -1 is returned. + for i in start..s.len-1: + if s[i] in chars: return i + return -1 proc rfind*(s, sub: string, start: int = -1): int {.noSideEffect.} = ## Searches for `sub` in `s` in reverse, starting at `start` and going @@ -708,180 +708,180 @@ proc rfind*(s, sub: string, start: int = -1): int {.noSideEffect.} = break if result != -1: return return -1 - + proc quoteIfContainsWhite*(s: string): string {.deprecated.} = - ## returns ``'"' & s & '"'`` if `s` contains a space and does not - ## start with a quote, else returns `s` + ## returns ``'"' & s & '"'`` if `s` contains a space and does not + ## start with a quote, else returns `s` ## DEPRECATED as it was confused for shell quoting function. ## For this application use osproc.quoteShell. - if find(s, {' ', '\t'}) >= 0 and s[0] != '"': - result = '"' & s & '"' - else: - result = s - -proc contains*(s: string, c: char): bool {.noSideEffect.} = - ## Same as ``find(s, c) >= 0``. - return find(s, c) >= 0 - -proc contains*(s, sub: string): bool {.noSideEffect.} = - ## Same as ``find(s, sub) >= 0``. - return find(s, sub) >= 0 - -proc contains*(s: string, chars: set[char]): bool {.noSideEffect.} = - ## Same as ``find(s, chars) >= 0``. - return find(s, chars) >= 0 - -proc replace*(s, sub: string, by = ""): string {.noSideEffect, - rtl, extern: "nsuReplaceStr", operator: 1.} = - ## Replaces `sub` in `s` by the string `by`. - var a {.noinit.}: TSkipTable - result = "" - preprocessSub(sub, a) - var i = 0 - while true: - var j = findAux(s, sub, i, a) - if j < 0: break - add result, substr(s, i, j - 1) - add result, by - i = j + len(sub) - # copy the rest: - add result, substr(s, i) - -proc replace*(s: string, sub, by: char): string {.noSideEffect, - rtl, extern: "nsuReplaceChar".} = - ## optimized version for characters. - result = newString(s.len) - var i = 0 - while i < s.len: - if s[i] == sub: result[i] = by - else: result[i] = s[i] - inc(i) - -proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect, - rtl, extern: "nsuReplaceWord".} = - ## Replaces `sub` in `s` by the string `by`. Each occurance of `sub` - ## has to be surrounded by word boundaries (comparable to ``\\w`` in - ## regular expressions), otherwise it is not replaced. - const wordChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'} - var a {.noinit.}: TSkipTable - result = "" - preprocessSub(sub, a) - var i = 0 - while true: - var j = findAux(s, sub, i, a) - if j < 0: break - # word boundary? - if (j == 0 or s[j-1] notin wordChars) and - (j+sub.len >= s.len or s[j+sub.len] notin wordChars): - add result, substr(s, i, j - 1) - add result, by - i = j + len(sub) - else: - add result, substr(s, i, j) - i = j + 1 - # copy the rest: - add result, substr(s, i) - -proc delete*(s: var string, first, last: int) {.noSideEffect, - rtl, extern: "nsuDelete".} = - ## Deletes in `s` the characters at position `first` .. `last`. This modifies - ## `s` itself, it does not return a copy. - var i = first - var j = last+1 - var newLen = len(s)-j+i - while i < newLen: - s[i] = s[j] - inc(i) - inc(j) - setlen(s, newLen) - -proc ParseOctInt*(s: string): int {.noSideEffect, - rtl, extern: "nsuParseOctInt".} = - ## Parses an octal integer value contained in `s`. If `s` is not - ## a valid integer, `EInvalidValue` is raised. `s` can have one of the - ## following optional prefixes: ``0o``, ``0O``. - ## Underscores within `s` are ignored. - var i = 0 - if s[i] == '0' and (s[i+1] == 'o' or s[i+1] == 'O'): inc(i, 2) - while true: - case s[i] - of '_': inc(i) - of '0'..'7': - result = result shl 3 or (ord(s[i]) - ord('0')) - inc(i) - of '\0': break - else: raise newException(EInvalidValue, "invalid integer: " & s) - -proc toOct*(x: BiggestInt, len: int): string {.noSideEffect, - rtl, extern: "nsuToOct".} = - ## converts `x` into its octal representation. The resulting string is - ## always `len` characters long. No leading ``0o`` prefix is generated. - var - mask: BiggestInt = 7 - shift: BiggestInt = 0 - assert(len > 0) - result = newString(len) - for j in countdown(len-1, 0): - result[j] = chr(int((x and mask) shr shift) + ord('0')) - shift = shift + 3 - mask = mask shl 3 - -proc toBin*(x: BiggestInt, len: int): string {.noSideEffect, - rtl, extern: "nsuToBin".} = - ## converts `x` into its binary representation. The resulting string is - ## always `len` characters long. No leading ``0b`` prefix is generated. - var - mask: BiggestInt = 1 - shift: BiggestInt = 0 - assert(len > 0) - result = newString(len) - for j in countdown(len-1, 0): - result[j] = chr(int((x and mask) shr shift) + ord('0')) - shift = shift + 1 - mask = mask shl 1 - -proc insertSep*(s: string, sep = '_', digits = 3): string {.noSideEffect, - rtl, extern: "nsuInsertSep".} = - ## inserts the separator `sep` after `digits` digits from right to left. - ## Even though the algorithm works with any string `s`, it is only useful - ## if `s` contains a number. - ## Example: ``insertSep("1000000") == "1_000_000"`` - var L = (s.len-1) div digits + s.len - result = newString(L) - var j = 0 - dec(L) - for i in countdown(len(s)-1, 0): - if j == digits: - result[L] = sep - dec(L) - j = 0 - result[L] = s[i] - inc(j) - dec(L) - -proc escape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, - rtl, extern: "nsuEscape".} = - ## Escapes a string `s`. This does these operations (at the same time): - ## * replaces any ``\`` by ``\\`` - ## * replaces any ``'`` by ``\'`` - ## * replaces any ``"`` by ``\"`` - ## * replaces any other character in the set ``{'\0'..'\31', '\128'..'\255'}`` - ## by ``\xHH`` where ``HH`` is its hexadecimal value. - ## The procedure has been designed so that its output is usable for many - ## different common syntaxes. The resulting string is prefixed with - ## `prefix` and suffixed with `suffix`. Both may be empty strings. - result = newStringOfCap(s.len + s.len shr 2) - result.add(prefix) - for c in items(s): - case c - of '\0'..'\31', '\128'..'\255': - add(result, "\\x") - add(result, toHex(ord(c), 2)) - of '\\': add(result, "\\\\") - of '\'': add(result, "\\'") - of '\"': add(result, "\\\"") - else: add(result, c) - add(result, suffix) + if find(s, {' ', '\t'}) >= 0 and s[0] != '"': + result = '"' & s & '"' + else: + result = s + +proc contains*(s: string, c: char): bool {.noSideEffect.} = + ## Same as ``find(s, c) >= 0``. + return find(s, c) >= 0 + +proc contains*(s, sub: string): bool {.noSideEffect.} = + ## Same as ``find(s, sub) >= 0``. + return find(s, sub) >= 0 + +proc contains*(s: string, chars: set[char]): bool {.noSideEffect.} = + ## Same as ``find(s, chars) >= 0``. + return find(s, chars) >= 0 + +proc replace*(s, sub: string, by = ""): string {.noSideEffect, + rtl, extern: "nsuReplaceStr", operator: 1.} = + ## Replaces `sub` in `s` by the string `by`. + var a {.noinit.}: TSkipTable + result = "" + preprocessSub(sub, a) + var i = 0 + while true: + var j = findAux(s, sub, i, a) + if j < 0: break + add result, substr(s, i, j - 1) + add result, by + i = j + len(sub) + # copy the rest: + add result, substr(s, i) + +proc replace*(s: string, sub, by: char): string {.noSideEffect, + rtl, extern: "nsuReplaceChar".} = + ## optimized version for characters. + result = newString(s.len) + var i = 0 + while i < s.len: + if s[i] == sub: result[i] = by + else: result[i] = s[i] + inc(i) + +proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect, + rtl, extern: "nsuReplaceWord".} = + ## Replaces `sub` in `s` by the string `by`. Each occurance of `sub` + ## has to be surrounded by word boundaries (comparable to ``\\w`` in + ## regular expressions), otherwise it is not replaced. + const wordChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'} + var a {.noinit.}: TSkipTable + result = "" + preprocessSub(sub, a) + var i = 0 + while true: + var j = findAux(s, sub, i, a) + if j < 0: break + # word boundary? + if (j == 0 or s[j-1] notin wordChars) and + (j+sub.len >= s.len or s[j+sub.len] notin wordChars): + add result, substr(s, i, j - 1) + add result, by + i = j + len(sub) + else: + add result, substr(s, i, j) + i = j + 1 + # copy the rest: + add result, substr(s, i) + +proc delete*(s: var string, first, last: int) {.noSideEffect, + rtl, extern: "nsuDelete".} = + ## Deletes in `s` the characters at position `first` .. `last`. This modifies + ## `s` itself, it does not return a copy. + var i = first + var j = last+1 + var newLen = len(s)-j+i + while i < newLen: + s[i] = s[j] + inc(i) + inc(j) + setLen(s, newLen) + +proc parseOctInt*(s: string): int {.noSideEffect, + rtl, extern: "nsuParseOctInt".} = + ## Parses an octal integer value contained in `s`. If `s` is not + ## a valid integer, `EInvalidValue` is raised. `s` can have one of the + ## following optional prefixes: ``0o``, ``0O``. + ## Underscores within `s` are ignored. + var i = 0 + if s[i] == '0' and (s[i+1] == 'o' or s[i+1] == 'O'): inc(i, 2) + while true: + case s[i] + of '_': inc(i) + of '0'..'7': + result = result shl 3 or (ord(s[i]) - ord('0')) + inc(i) + of '\0': break + else: raise newException(EInvalidValue, "invalid integer: " & s) + +proc toOct*(x: BiggestInt, len: int): string {.noSideEffect, + rtl, extern: "nsuToOct".} = + ## converts `x` into its octal representation. The resulting string is + ## always `len` characters long. No leading ``0o`` prefix is generated. + var + mask: BiggestInt = 7 + shift: BiggestInt = 0 + assert(len > 0) + result = newString(len) + for j in countdown(len-1, 0): + result[j] = chr(int((x and mask) shr shift) + ord('0')) + shift = shift + 3 + mask = mask shl 3 + +proc toBin*(x: BiggestInt, len: int): string {.noSideEffect, + rtl, extern: "nsuToBin".} = + ## converts `x` into its binary representation. The resulting string is + ## always `len` characters long. No leading ``0b`` prefix is generated. + var + mask: BiggestInt = 1 + shift: BiggestInt = 0 + assert(len > 0) + result = newString(len) + for j in countdown(len-1, 0): + result[j] = chr(int((x and mask) shr shift) + ord('0')) + shift = shift + 1 + mask = mask shl 1 + +proc insertSep*(s: string, sep = '_', digits = 3): string {.noSideEffect, + rtl, extern: "nsuInsertSep".} = + ## inserts the separator `sep` after `digits` digits from right to left. + ## Even though the algorithm works with any string `s`, it is only useful + ## if `s` contains a number. + ## Example: ``insertSep("1000000") == "1_000_000"`` + var L = (s.len-1) div digits + s.len + result = newString(L) + var j = 0 + dec(L) + for i in countdown(len(s)-1, 0): + if j == digits: + result[L] = sep + dec(L) + j = 0 + result[L] = s[i] + inc(j) + dec(L) + +proc escape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, + rtl, extern: "nsuEscape".} = + ## Escapes a string `s`. This does these operations (at the same time): + ## * replaces any ``\`` by ``\\`` + ## * replaces any ``'`` by ``\'`` + ## * replaces any ``"`` by ``\"`` + ## * replaces any other character in the set ``{'\0'..'\31', '\128'..'\255'}`` + ## by ``\xHH`` where ``HH`` is its hexadecimal value. + ## The procedure has been designed so that its output is usable for many + ## different common syntaxes. The resulting string is prefixed with + ## `prefix` and suffixed with `suffix`. Both may be empty strings. + result = newStringOfCap(s.len + s.len shr 2) + result.add(prefix) + for c in items(s): + case c + of '\0'..'\31', '\128'..'\255': + add(result, "\\x") + add(result, toHex(ord(c), 2)) + of '\\': add(result, "\\\\") + of '\'': add(result, "\\'") + of '\"': add(result, "\\\"") + else: add(result, c) + add(result, suffix) proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, rtl, extern: "nsuUnescape".} = @@ -896,7 +896,7 @@ proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, raise newException(EInvalidValue, "String does not start with a prefix of: " & prefix) i.inc() - while True: + while true: if i == s.len-suffix.len: break case s[i] of '\\': @@ -920,323 +920,323 @@ proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, if s[i .. -1] != suffix: raise newException(EInvalidValue, "String does not end with a suffix of: " & suffix) - -proc validIdentifier*(s: string): bool {.noSideEffect, - rtl, extern: "nsuValidIdentifier".} = - ## returns true if `s` is a valid identifier. A valid identifier starts - ## with a character of the set `IdentStartChars` and is followed by any - ## number of characters of the set `IdentChars`. - if s[0] in IdentStartChars: - for i in 1..s.len-1: - if s[i] notin IdentChars: return false - return true - -proc editDistance*(a, b: string): int {.noSideEffect, - rtl, extern: "nsuEditDistance".} = - ## returns the edit distance between `a` and `b`. This uses the - ## `Levenshtein`:idx: distance algorithm with only a linear memory overhead. - ## This implementation is highly optimized! - var len1 = a.len - var len2 = b.len - if len1 > len2: - # make `b` the longer string - return editDistance(b, a) - - # strip common prefix: - var s = 0 - while a[s] == b[s] and a[s] != '\0': - inc(s) - dec(len1) - dec(len2) - # strip common suffix: - while len1 > 0 and len2 > 0 and a[s+len1-1] == b[s+len2-1]: - dec(len1) - dec(len2) - # trivial cases: - if len1 == 0: return len2 - if len2 == 0: return len1 - - # another special case: - if len1 == 1: - for j in s..len2-1: - if a[s] == b[j]: return len2 - 1 - return len2 - - inc(len1) - inc(len2) - var half = len1 shr 1 - # initalize first row: - #var row = cast[ptr array[0..high(int) div 8, int]](alloc(len2*sizeof(int))) - var row: seq[int] - newSeq(row, len2) - var e = s + len2 - 1 # end marker - for i in 1..len2 - half - 1: row[i] = i - row[0] = len1 - half - 1 - for i in 1 .. len1 - 1: - var char1 = a[i + s - 1] - var char2p: int - var D, x: int - var p: int - if i >= len1 - half: - # skip the upper triangle: - var offset = i - len1 + half - char2p = offset - p = offset - var c3 = row[p] + ord(char1 != b[s + char2p]) - inc(p) - inc(char2p) - x = row[p] + 1 - D = x - if x > c3: x = c3 - row[p] = x - inc(p) - else: - p = 1 - char2p = 0 - D = i - x = i - if i <= half + 1: - # skip the lower triangle: - e = len2 + i - half - 2 - # main: - while p <= e: - dec(D) - var c3 = D + ord(char1 != b[char2p + s]) - inc(char2p) - inc(x) - if x > c3: x = c3 - D = row[p] + 1 - if x > D: x = D - row[p] = x - inc(p) - # lower triangle sentinel: - if i <= half: - dec(D) - var c3 = D + ord(char1 != b[char2p + s]) - inc(x) - if x > c3: x = c3 - row[p] = x - result = row[e] - #dealloc(row) - - -# floating point formating: - -proc c_sprintf(buf, frmt: CString) {.nodecl, importc: "sprintf", varargs, - noSideEffect.} - -type - TFloatFormat* = enum ## the different modes of floating point formating - ffDefault, ## use the shorter floating point notation - ffDecimal, ## use decimal floating point notation - ffScientific ## use scientific notation (using ``e`` character) - -proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault, + +proc validIdentifier*(s: string): bool {.noSideEffect, + rtl, extern: "nsuValidIdentifier".} = + ## returns true if `s` is a valid identifier. A valid identifier starts + ## with a character of the set `IdentStartChars` and is followed by any + ## number of characters of the set `IdentChars`. + if s[0] in IdentStartChars: + for i in 1..s.len-1: + if s[i] notin IdentChars: return false + return true + +proc editDistance*(a, b: string): int {.noSideEffect, + rtl, extern: "nsuEditDistance".} = + ## returns the edit distance between `a` and `b`. This uses the + ## `Levenshtein`:idx: distance algorithm with only a linear memory overhead. + ## This implementation is highly optimized! + var len1 = a.len + var len2 = b.len + if len1 > len2: + # make `b` the longer string + return editDistance(b, a) + + # strip common prefix: + var s = 0 + while a[s] == b[s] and a[s] != '\0': + inc(s) + dec(len1) + dec(len2) + # strip common suffix: + while len1 > 0 and len2 > 0 and a[s+len1-1] == b[s+len2-1]: + dec(len1) + dec(len2) + # trivial cases: + if len1 == 0: return len2 + if len2 == 0: return len1 + + # another special case: + if len1 == 1: + for j in s..len2-1: + if a[s] == b[j]: return len2 - 1 + return len2 + + inc(len1) + inc(len2) + var half = len1 shr 1 + # initalize first row: + #var row = cast[ptr array[0..high(int) div 8, int]](alloc(len2*sizeof(int))) + var row: seq[int] + newSeq(row, len2) + var e = s + len2 - 1 # end marker + for i in 1..len2 - half - 1: row[i] = i + row[0] = len1 - half - 1 + for i in 1 .. len1 - 1: + var char1 = a[i + s - 1] + var char2p: int + var D, x: int + var p: int + if i >= len1 - half: + # skip the upper triangle: + var offset = i - len1 + half + char2p = offset + p = offset + var c3 = row[p] + ord(char1 != b[s + char2p]) + inc(p) + inc(char2p) + x = row[p] + 1 + D = x + if x > c3: x = c3 + row[p] = x + inc(p) + else: + p = 1 + char2p = 0 + D = i + x = i + if i <= half + 1: + # skip the lower triangle: + e = len2 + i - half - 2 + # main: + while p <= e: + dec(D) + var c3 = D + ord(char1 != b[char2p + s]) + inc(char2p) + inc(x) + if x > c3: x = c3 + D = row[p] + 1 + if x > D: x = D + row[p] = x + inc(p) + # lower triangle sentinel: + if i <= half: + dec(D) + var c3 = D + ord(char1 != b[char2p + s]) + inc(x) + if x > c3: x = c3 + row[p] = x + result = row[e] + #dealloc(row) + + +# floating point formating: + +proc c_sprintf(buf, frmt: cstring) {.header: "<stdio.h>", importc: "sprintf", + varargs, noSideEffect.} + +type + TFloatFormat* = enum ## the different modes of floating point formating + ffDefault, ## use the shorter floating point notation + ffDecimal, ## use decimal floating point notation + ffScientific ## use scientific notation (using ``e`` character) + +proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault, precision: range[0..32] = 16): string {. - noSideEffect, operator: 2, rtl, extern: "nsu$1".} = - ## converts a floating point value `f` to a string. - ## - ## If ``format == ffDecimal`` then precision is the number of digits to - ## be printed after the decimal point. - ## If ``format == ffScientific`` then precision is the maximum number - ## of significant digits to be printed. - ## `precision`'s default value is the maximum number of meaningful digits + noSideEffect, operator: 2, rtl, extern: "nsu$1".} = + ## converts a floating point value `f` to a string. + ## + ## If ``format == ffDecimal`` then precision is the number of digits to + ## be printed after the decimal point. + ## If ``format == ffScientific`` then precision is the maximum number + ## of significant digits to be printed. + ## `precision`'s default value is the maximum number of meaningful digits ## after the decimal point for Nimrod's ``biggestFloat`` type. ## - ## If ``precision == 0``, it tries to format it nicely. - const floatFormatToChar: array[TFloatFormat, char] = ['g', 'f', 'e'] - var - frmtstr {.noinit.}: array[0..5, char] - buf {.noinit.}: array[0..2500, char] - frmtstr[0] = '%' - if precision > 0: - frmtstr[1] = '#' - frmtstr[2] = '.' - frmtstr[3] = '*' - frmtstr[4] = floatFormatToChar[format] - frmtstr[5] = '\0' - c_sprintf(buf, frmtstr, precision, f) - else: - frmtstr[1] = floatFormatToChar[format] - frmtstr[2] = '\0' - c_sprintf(buf, frmtstr, f) - result = $buf - -proc formatFloat*(f: float, format: TFloatFormat = ffDefault, + ## If ``precision == 0``, it tries to format it nicely. + const floatFormatToChar: array[TFloatFormat, char] = ['g', 'f', 'e'] + var + frmtstr {.noinit.}: array[0..5, char] + buf {.noinit.}: array[0..2500, char] + frmtstr[0] = '%' + if precision > 0: + frmtstr[1] = '#' + frmtstr[2] = '.' + frmtstr[3] = '*' + frmtstr[4] = floatFormatToChar[format] + frmtstr[5] = '\0' + c_sprintf(buf, frmtstr, precision, f) + else: + frmtstr[1] = floatFormatToChar[format] + frmtstr[2] = '\0' + c_sprintf(buf, frmtstr, f) + result = $buf + +proc formatFloat*(f: float, format: TFloatFormat = ffDefault, precision: range[0..32] = 16): string {. - noSideEffect, operator: 2, rtl, extern: "nsu$1".} = - ## converts a floating point value `f` to a string. - ## - ## If ``format == ffDecimal`` then precision is the number of digits to - ## be printed after the decimal point. - ## If ``format == ffScientific`` then precision is the maximum number - ## of significant digits to be printed. - ## `precision`'s default value is the maximum number of meaningful digits - ## after the decimal point for Nimrod's ``float`` type. - result = formatBiggestFloat(f, format, precision) - -proc formatSize*(bytes: biggestInt, decimalSep = '.'): string = - ## Rounds and formats `bytes`. Examples: - ## - ## .. code-block:: nimrod - ## - ## formatSize(1'i64 shl 31 + 300'i64) == "2.204GB" - ## formatSize(4096) == "4KB" - ## - template frmt(a, b, c: expr): expr = - let bs = $b - insertSep($a) & decimalSep & bs.substr(0, 2) & c - let gigabytes = bytes shr 30 - let megabytes = bytes shr 20 - let kilobytes = bytes shr 10 - if gigabytes != 0: - result = frmt(gigabytes, megabytes, "GB") - elif megabytes != 0: - result = frmt(megabytes, kilobytes, "MB") - elif kilobytes != 0: - result = frmt(kilobytes, bytes, "KB") - else: - result = insertSep($bytes) & "B" - -proc findNormalized(x: string, inArray: openarray[string]): int = - var i = 0 - while i < high(inArray): - if cmpIgnoreStyle(x, inArray[i]) == 0: return i - inc(i, 2) # incrementing by 1 would probably lead to a - # security hole... - return -1 - -proc invalidFormatString() {.noinline.} = - raise newException(EInvalidValue, "invalid format string") - -proc addf*(s: var string, formatstr: string, a: varargs[string, `$`]) {. - noSideEffect, rtl, extern: "nsuAddf".} = - ## The same as ``add(s, formatstr % a)``, but more efficient. - const PatternChars = {'a'..'z', 'A'..'Z', '0'..'9', '\128'..'\255', '_'} - var i = 0 - var num = 0 - while i < len(formatstr): - if formatstr[i] == '$': - case formatstr[i+1] # again we use the fact that strings - # are zero-terminated here - of '#': - if num >% a.high: invalidFormatString() - add s, a[num] - inc i, 2 - inc num - of '$': - add s, '$' - inc(i, 2) - of '1'..'9', '-': - var j = 0 - inc(i) # skip $ - var negative = formatstr[i] == '-' - if negative: inc i - while formatstr[i] in Digits: - j = j * 10 + ord(formatstr[i]) - ord('0') - inc(i) - let idx = if not negative: j-1 else: a.len-j - if idx >% a.high: invalidFormatString() - add s, a[idx] - of '{': - var j = i+1 - while formatstr[j] notin {'\0', '}'}: inc(j) - var x = findNormalized(substr(formatstr, i+2, j-1), a) - if x >= 0 and x < high(a): add s, a[x+1] - else: invalidFormatString() - i = j+1 - of 'a'..'z', 'A'..'Z', '\128'..'\255', '_': - var j = i+1 - while formatstr[j] in PatternChars: inc(j) - var x = findNormalized(substr(formatstr, i+1, j-1), a) - if x >= 0 and x < high(a): add s, a[x+1] - else: invalidFormatString() - i = j - else: - invalidFormatString() - else: - add s, formatstr[i] - inc(i) - -proc `%` *(formatstr: string, a: openarray[string]): string {.noSideEffect, - rtl, extern: "nsuFormatOpenArray".} = - ## The `substitution`:idx: operator performs string substitutions in - ## `formatstr` and returns a modified `formatstr`. This is often called - ## `string interpolation`:idx:. - ## - ## This is best explained by an example: - ## - ## .. code-block:: nimrod - ## "$1 eats $2." % ["The cat", "fish"] - ## - ## Results in: - ## - ## .. code-block:: nimrod - ## "The cat eats fish." - ## - ## The substitution variables (the thing after the ``$``) are enumerated - ## from 1 to ``a.len``. - ## To produce a verbatim ``$``, use ``$$``. - ## The notation ``$#`` can be used to refer to the next substitution - ## variable: - ## - ## .. code-block:: nimrod - ## "$# eats $#." % ["The cat", "fish"] - ## - ## Substitution variables can also be words (that is - ## ``[A-Za-z_]+[A-Za-z0-9_]*``) in which case the arguments in `a` with even - ## indices are keys and with odd indices are the corresponding values. - ## An example: - ## - ## .. code-block:: nimrod - ## "$animal eats $food." % ["animal", "The cat", "food", "fish"] - ## - ## Results in: - ## - ## .. code-block:: nimrod - ## "The cat eats fish." - ## - ## The variables are compared with `cmpIgnoreStyle`. `EInvalidValue` is - ## raised if an ill-formed format string has been passed to the `%` operator. - result = newStringOfCap(formatstr.len + a.len shl 4) - addf(result, formatstr, a) - -proc `%` *(formatstr, a: string): string {.noSideEffect, - rtl, extern: "nsuFormatSingleElem".} = - ## This is the same as ``formatstr % [a]``. - result = newStringOfCap(formatstr.len + a.len) - addf(result, formatstr, [a]) - -proc format*(formatstr: string, a: varargs[string, `$`]): string {.noSideEffect, - rtl, extern: "nsuFormatVarargs".} = + noSideEffect, operator: 2, rtl, extern: "nsu$1".} = + ## converts a floating point value `f` to a string. + ## + ## If ``format == ffDecimal`` then precision is the number of digits to + ## be printed after the decimal point. + ## If ``format == ffScientific`` then precision is the maximum number + ## of significant digits to be printed. + ## `precision`'s default value is the maximum number of meaningful digits + ## after the decimal point for Nimrod's ``float`` type. + result = formatBiggestFloat(f, format, precision) + +proc formatSize*(bytes: BiggestInt, decimalSep = '.'): string = + ## Rounds and formats `bytes`. Examples: + ## + ## .. code-block:: nimrod + ## + ## formatSize(1'i64 shl 31 + 300'i64) == "2.204GB" + ## formatSize(4096) == "4KB" + ## + template frmt(a, b, c: expr): expr = + let bs = $b + insertSep($a) & decimalSep & bs.substr(0, 2) & c + let gigabytes = bytes shr 30 + let megabytes = bytes shr 20 + let kilobytes = bytes shr 10 + if gigabytes != 0: + result = frmt(gigabytes, megabytes, "GB") + elif megabytes != 0: + result = frmt(megabytes, kilobytes, "MB") + elif kilobytes != 0: + result = frmt(kilobytes, bytes, "KB") + else: + result = insertSep($bytes) & "B" + +proc findNormalized(x: string, inArray: openArray[string]): int = + var i = 0 + while i < high(inArray): + if cmpIgnoreStyle(x, inArray[i]) == 0: return i + inc(i, 2) # incrementing by 1 would probably lead to a + # security hole... + return -1 + +proc invalidFormatString() {.noinline.} = + raise newException(EInvalidValue, "invalid format string") + +proc addf*(s: var string, formatstr: string, a: varargs[string, `$`]) {. + noSideEffect, rtl, extern: "nsuAddf".} = + ## The same as ``add(s, formatstr % a)``, but more efficient. + const PatternChars = {'a'..'z', 'A'..'Z', '0'..'9', '\128'..'\255', '_'} + var i = 0 + var num = 0 + while i < len(formatstr): + if formatstr[i] == '$': + case formatstr[i+1] # again we use the fact that strings + # are zero-terminated here + of '#': + if num >% a.high: invalidFormatString() + add s, a[num] + inc i, 2 + inc num + of '$': + add s, '$' + inc(i, 2) + of '1'..'9', '-': + var j = 0 + inc(i) # skip $ + var negative = formatstr[i] == '-' + if negative: inc i + while formatstr[i] in Digits: + j = j * 10 + ord(formatstr[i]) - ord('0') + inc(i) + let idx = if not negative: j-1 else: a.len-j + if idx >% a.high: invalidFormatString() + add s, a[idx] + of '{': + var j = i+1 + while formatstr[j] notin {'\0', '}'}: inc(j) + var x = findNormalized(substr(formatstr, i+2, j-1), a) + if x >= 0 and x < high(a): add s, a[x+1] + else: invalidFormatString() + i = j+1 + of 'a'..'z', 'A'..'Z', '\128'..'\255', '_': + var j = i+1 + while formatstr[j] in PatternChars: inc(j) + var x = findNormalized(substr(formatstr, i+1, j-1), a) + if x >= 0 and x < high(a): add s, a[x+1] + else: invalidFormatString() + i = j + else: + invalidFormatString() + else: + add s, formatstr[i] + inc(i) + +proc `%` *(formatstr: string, a: openArray[string]): string {.noSideEffect, + rtl, extern: "nsuFormatOpenArray".} = + ## The `substitution`:idx: operator performs string substitutions in + ## `formatstr` and returns a modified `formatstr`. This is often called + ## `string interpolation`:idx:. + ## + ## This is best explained by an example: + ## + ## .. code-block:: nimrod + ## "$1 eats $2." % ["The cat", "fish"] + ## + ## Results in: + ## + ## .. code-block:: nimrod + ## "The cat eats fish." + ## + ## The substitution variables (the thing after the ``$``) are enumerated + ## from 1 to ``a.len``. + ## To produce a verbatim ``$``, use ``$$``. + ## The notation ``$#`` can be used to refer to the next substitution + ## variable: + ## + ## .. code-block:: nimrod + ## "$# eats $#." % ["The cat", "fish"] + ## + ## Substitution variables can also be words (that is + ## ``[A-Za-z_]+[A-Za-z0-9_]*``) in which case the arguments in `a` with even + ## indices are keys and with odd indices are the corresponding values. + ## An example: + ## + ## .. code-block:: nimrod + ## "$animal eats $food." % ["animal", "The cat", "food", "fish"] + ## + ## Results in: + ## + ## .. code-block:: nimrod + ## "The cat eats fish." + ## + ## The variables are compared with `cmpIgnoreStyle`. `EInvalidValue` is + ## raised if an ill-formed format string has been passed to the `%` operator. + result = newStringOfCap(formatstr.len + a.len shl 4) + addf(result, formatstr, a) + +proc `%` *(formatstr, a: string): string {.noSideEffect, + rtl, extern: "nsuFormatSingleElem".} = + ## This is the same as ``formatstr % [a]``. + result = newStringOfCap(formatstr.len + a.len) + addf(result, formatstr, [a]) + +proc format*(formatstr: string, a: varargs[string, `$`]): string {.noSideEffect, + rtl, extern: "nsuFormatVarargs".} = ## This is the same as ``formatstr % a`` except that it supports - ## auto stringification. - result = newStringOfCap(formatstr.len + a.len) - addf(result, formatstr, a) - -{.pop.} - -when isMainModule: - doAssert align("abc", 4) == " abc" - doAssert align("a", 0) == "a" - doAssert align("1232", 6) == " 1232" - doAssert align("1232", 6, '#') == "##1232" - echo wordWrap(""" this is a long text -- muchlongerthan10chars and here - it goes""", 10, false) - doAssert formatBiggestFloat(0.00000000001, ffDecimal, 11) == "0.00000000001" - doAssert formatBiggestFloat(0.00000000001, ffScientific, 1) == "1.0e-11" - - doAssert "$# $3 $# $#" % ["a", "b", "c"] == "a c b c" - echo formatSize(1'i64 shl 31 + 300'i64) # == "4,GB" - echo formatSize(1'i64 shl 31) - - doAssert "$animal eats $food." % ["animal", "The cat", "food", "fish"] == - "The cat eats fish." - - doAssert "-ld a-ldz -ld".replaceWord("-ld") == " a-ldz " - doAssert "-lda-ldz -ld abc".replaceWord("-ld") == "-lda-ldz abc" + ## auto stringification. + result = newStringOfCap(formatstr.len + a.len) + addf(result, formatstr, a) + +{.pop.} + +when isMainModule: + doAssert align("abc", 4) == " abc" + doAssert align("a", 0) == "a" + doAssert align("1232", 6) == " 1232" + doAssert align("1232", 6, '#') == "##1232" + echo wordWrap(""" this is a long text -- muchlongerthan10chars and here + it goes""", 10, false) + doAssert formatBiggestFloat(0.00000000001, ffDecimal, 11) == "0.00000000001" + doAssert formatBiggestFloat(0.00000000001, ffScientific, 1) == "1.0e-11" + + doAssert "$# $3 $# $#" % ["a", "b", "c"] == "a c b c" + echo formatSize(1'i64 shl 31 + 300'i64) # == "4,GB" + echo formatSize(1'i64 shl 31) + + doAssert "$animal eats $food." % ["animal", "The cat", "food", "fish"] == + "The cat eats fish." + + doAssert "-ld a-ldz -ld".replaceWord("-ld") == " a-ldz " + doAssert "-lda-ldz -ld abc".replaceWord("-ld") == "-lda-ldz abc" - type TMyEnum = enum enA, enB, enC, enuD, enE - doAssert parseEnum[TMyEnum]("enu_D") == enuD + type TMyEnum = enum enA, enB, enC, enuD, enE + doAssert parseEnum[TMyEnum]("enu_D") == enuD - doAssert parseEnum("invalid enum value", enC) == enC + doAssert parseEnum("invalid enum value", enC) == enC diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index 501184aca..20f1d0695 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -27,15 +27,15 @@ when defined(windows): var hTemp = GetStdHandle(STD_OUTPUT_HANDLE) if DuplicateHandle(GetCurrentProcess(), hTemp, GetCurrentProcess(), addr(conHandle), 0, 1, DUPLICATE_SAME_ACCESS) == 0: - OSError(OSLastError()) + osError(osLastError()) proc getCursorPos(): tuple [x,y: int] = - var c: TCONSOLE_SCREEN_BUFFER_INFO - if GetConsoleScreenBufferInfo(conHandle, addr(c)) == 0: OSError(OSLastError()) + var c: TCONSOLESCREENBUFFERINFO + if GetConsoleScreenBufferInfo(conHandle, addr(c)) == 0: osError(osLastError()) return (int(c.dwCursorPosition.x), int(c.dwCursorPosition.y)) proc getAttributes(): int16 = - var c: TCONSOLE_SCREEN_BUFFER_INFO + var c: TCONSOLESCREENBUFFERINFO # workaround Windows bugs: try several times if GetConsoleScreenBufferInfo(conHandle, addr(c)) != 0: return c.wAttributes @@ -48,10 +48,10 @@ proc setCursorPos*(x, y: int) = ## sets the terminal's cursor to the (x,y) position. (0,0) is the ## upper left of the screen. when defined(windows): - var c: TCoord + var c: TCOORD c.x = int16(x) c.y = int16(y) - if SetConsoleCursorPosition(conHandle, c) == 0: OSError(OSLastError()) + if SetConsoleCursorPosition(conHandle, c) == 0: osError(osLastError()) else: stdout.write("\e[" & $y & ';' & $x & 'f') @@ -59,12 +59,12 @@ proc setCursorXPos*(x: int) = ## sets the terminal's cursor to the x position. The y position is ## not changed. when defined(windows): - var scrbuf: TCONSOLE_SCREEN_BUFFER_INFO + var scrbuf: TCONSOLESCREENBUFFERINFO var hStdout = conHandle - if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: OSError(OSLastError()) + if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: osError(osLastError()) var origin = scrbuf.dwCursorPosition origin.x = int16(x) - if SetConsoleCursorPosition(conHandle, origin) == 0: OSError(OSLastError()) + if SetConsoleCursorPosition(conHandle, origin) == 0: osError(osLastError()) else: stdout.write("\e[" & $x & 'G') @@ -73,16 +73,16 @@ when defined(windows): ## sets the terminal's cursor to the y position. The x position is ## not changed. **Warning**: This is not supported on UNIX! when defined(windows): - var scrbuf: TCONSOLE_SCREEN_BUFFER_INFO + var scrbuf: TCONSOLESCREENBUFFERINFO var hStdout = conHandle - if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: OSError(OSLastError()) + if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: osError(osLastError()) var origin = scrbuf.dwCursorPosition origin.y = int16(y) - if SetConsoleCursorPosition(conHandle, origin) == 0: OSError(OSLastError()) + if SetConsoleCursorPosition(conHandle, origin) == 0: osError(osLastError()) else: - nil + discard -proc CursorUp*(count=1) = +proc cursorUp*(count=1) = ## Moves the cursor up by `count` rows. when defined(windows): var p = getCursorPos() @@ -91,7 +91,7 @@ proc CursorUp*(count=1) = else: stdout.write("\e[" & $count & 'A') -proc CursorDown*(count=1) = +proc cursorDown*(count=1) = ## Moves the cursor down by `count` rows. when defined(windows): var p = getCursorPos() @@ -100,7 +100,7 @@ proc CursorDown*(count=1) = else: stdout.write("\e[" & $count & 'B') -proc CursorForward*(count=1) = +proc cursorForward*(count=1) = ## Moves the cursor forward by `count` columns. when defined(windows): var p = getCursorPos() @@ -109,7 +109,7 @@ proc CursorForward*(count=1) = else: stdout.write("\e[" & $count & 'C') -proc CursorBackward*(count=1) = +proc cursorBackward*(count=1) = ## Moves the cursor backward by `count` columns. when defined(windows): var p = getCursorPos() @@ -119,78 +119,78 @@ proc CursorBackward*(count=1) = stdout.write("\e[" & $count & 'D') when true: - nil + discard else: - proc EraseLineEnd* = + proc eraseLineEnd* = ## Erases from the current cursor position to the end of the current line. when defined(windows): - nil + discard else: stdout.write("\e[K") - proc EraseLineStart* = + proc eraseLineStart* = ## Erases from the current cursor position to the start of the current line. when defined(windows): - nil + discard else: stdout.write("\e[1K") - proc EraseDown* = + proc eraseDown* = ## Erases the screen from the current line down to the bottom of the screen. when defined(windows): - nil + discard else: stdout.write("\e[J") - proc EraseUp* = + proc eraseUp* = ## Erases the screen from the current line up to the top of the screen. when defined(windows): - nil + discard else: stdout.write("\e[1J") -proc EraseLine* = +proc eraseLine* = ## Erases the entire current line. when defined(windows): - var scrbuf: TCONSOLE_SCREEN_BUFFER_INFO + var scrbuf: TCONSOLESCREENBUFFERINFO var numwrote: DWORD var hStdout = conHandle - if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: OSError(OSLastError()) + if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: osError(osLastError()) var origin = scrbuf.dwCursorPosition origin.x = 0'i16 - if SetConsoleCursorPosition(conHandle, origin) == 0: OSError(OSLastError()) + if SetConsoleCursorPosition(conHandle, origin) == 0: osError(osLastError()) var ht = scrbuf.dwSize.Y - origin.Y var wt = scrbuf.dwSize.X - origin.X if FillConsoleOutputCharacter(hStdout,' ', ht*wt, origin, addr(numwrote)) == 0: - OSError(OSLastError()) + osError(osLastError()) if FillConsoleOutputAttribute(hStdout, scrbuf.wAttributes, ht * wt, scrbuf.dwCursorPosition, addr(numwrote)) == 0: - OSError(OSLastError()) + osError(osLastError()) else: stdout.write("\e[2K") setCursorXPos(0) -proc EraseScreen* = +proc eraseScreen* = ## Erases the screen with the background colour and moves the cursor to home. when defined(windows): - var scrbuf: TCONSOLE_SCREEN_BUFFER_INFO + var scrbuf: TCONSOLESCREENBUFFERINFO var numwrote: DWORD - var origin: TCoord # is inititalized to 0, 0 + var origin: TCOORD # is inititalized to 0, 0 var hStdout = conHandle - if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: OSError(OSLastError()) + if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: osError(osLastError()) if FillConsoleOutputCharacter(hStdout, ' ', scrbuf.dwSize.X*scrbuf.dwSize.Y, origin, addr(numwrote)) == 0: - OSError(OSLastError()) + osError(osLastError()) if FillConsoleOutputAttribute(hStdout, scrbuf.wAttributes, scrbuf.dwSize.X * scrbuf.dwSize.Y, origin, addr(numwrote)) == 0: - OSError(OSLastError()) + osError(osLastError()) setCursorXPos(0) else: stdout.write("\e[2J") -proc ResetAttributes* {.noconv.} = +proc resetAttributes* {.noconv.} = ## resets all attributes; it is advisable to register this as a quit proc ## with ``system.addQuitProc(resetAttributes)``. when defined(windows): @@ -227,7 +227,7 @@ proc setStyle*(style: set[TStyle]) = for s in items(style): stdout.write("\e[" & $ord(s) & 'm') -proc WriteStyled*(txt: string, style: set[TStyle] = {styleBright}) = +proc writeStyled*(txt: string, style: set[TStyle] = {styleBright}) = ## writes the text `txt` in a given `style`. when defined(windows): var old = getAttributes() @@ -320,8 +320,8 @@ proc isatty*(f: TFile): bool = proc styledEchoProcessArg(s: string) = write stdout, s proc styledEchoProcessArg(style: TStyle) = setStyle({style}) proc styledEchoProcessArg(style: set[TStyle]) = setStyle style -proc styledEchoProcessArg(color: TForegroundColor) = setForeGroundColor color -proc styledEchoProcessArg(color: TBackgroundColor) = setBackGroundColor color +proc styledEchoProcessArg(color: TForegroundColor) = setForegroundColor color +proc styledEchoProcessArg(color: TBackgroundColor) = setBackgroundColor color macro styledEcho*(m: varargs[expr]): stmt = ## to be documented. @@ -345,4 +345,4 @@ when isMainModule: writeln(stdout, "ordinary text") styledEcho("styled text ", {styleBright, styleBlink, styleUnderscore}) - \ No newline at end of file + diff --git a/lib/pure/times.nim b/lib/pure/times.nim index e967ef683..be3e5d6da 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -146,7 +146,7 @@ proc getGMTime*(t: TTime): TTimeInfo {.tags: [FTime], raises: [].} ## converts the calendar time `t` to broken-down time representation, ## expressed in Coordinated Universal Time (UTC). -proc TimeInfoToTime*(timeInfo: TTimeInfo): TTime {.tags: [].} +proc timeInfoToTime*(timeInfo: TTimeInfo): TTime {.tags: [].} ## converts a broken-down time structure to ## calendar time representation. The function ignores the specified ## contents of the structure members `weekday` and `yearday` and recomputes @@ -256,7 +256,7 @@ proc `+`*(a: TTimeInfo, interval: TTimeInterval): TTimeInfo = ## ## **Note:** This has been only briefly tested and it may not be ## very accurate. - let t = toSeconds(TimeInfoToTime(a)) + let t = toSeconds(timeInfoToTime(a)) let secs = toSeconds(a, interval) if a.tzname == "UTC": result = getGMTime(fromSeconds(t + secs)) @@ -268,7 +268,7 @@ proc `-`*(a: TTimeInfo, interval: TTimeInterval): TTimeInfo = ## ## **Note:** This has been only briefly tested, it is inaccurate especially ## when you subtract so much that you reach the Julian calendar. - let t = toSeconds(TimeInfoToTime(a)) + let t = toSeconds(timeInfoToTime(a)) let secs = toSeconds(a, interval) if a.tzname == "UTC": result = getGMTime(fromSeconds(t - secs)) @@ -297,7 +297,7 @@ when not defined(JS): when not defined(JS): # C wrapper: type - structTM {.importc: "struct tm", final.} = object + StructTM {.importc: "struct tm", final.} = object second {.importc: "tm_sec".}, minute {.importc: "tm_min".}, hour {.importc: "tm_hour".}, @@ -308,7 +308,7 @@ when not defined(JS): yearday {.importc: "tm_yday".}, isdst {.importc: "tm_isdst".}: cint - PTimeInfo = ptr structTM + PTimeInfo = ptr StructTM PTime = ptr TTime TClock {.importc: "clock_t".} = distinct int @@ -319,11 +319,11 @@ when not defined(JS): importc: "gmtime", header: "<time.h>", tags: [].} proc timec(timer: PTime): TTime {. importc: "time", header: "<time.h>", tags: [].} - proc mktime(t: structTM): TTime {. + proc mktime(t: StructTM): TTime {. importc: "mktime", header: "<time.h>", tags: [].} - proc asctime(tblock: structTM): CString {. + proc asctime(tblock: StructTM): cstring {. importc: "asctime", header: "<time.h>", tags: [].} - proc ctime(time: PTime): CString {. + proc ctime(time: PTime): cstring {. importc: "ctime", header: "<time.h>", tags: [].} # strftime(s: CString, maxsize: int, fmt: CString, t: tm): int {. # importc: "strftime", header: "<time.h>".} @@ -335,7 +335,7 @@ when not defined(JS): clocksPerSec {.importc: "CLOCKS_PER_SEC", nodecl.}: int # our own procs on top of that: - proc tmToTimeInfo(tm: structTM, local: bool): TTimeInfo = + proc tmToTimeInfo(tm: StructTM, local: bool): TTimeInfo = const weekDays: array [0..6, TWeekDay] = [ dSun, dMon, dTue, dWed, dThu, dFri, dSat] @@ -345,11 +345,11 @@ when not defined(JS): monthday: int(tm.monthday), month: TMonth(tm.month), year: tm.year + 1900'i32, - weekday: weekDays[int(tm.weekDay)], + weekday: weekDays[int(tm.weekday)], yearday: int(tm.yearday), - isDST: tm.isDST > 0, + isDST: tm.isdst > 0, tzname: if local: - if tm.isDST > 0: + if tm.isdst > 0: getTzname().DST else: getTzname().nonDST @@ -358,7 +358,7 @@ when not defined(JS): timezone: if local: getTimezone() else: 0 ) - proc timeInfoToTM(t: TTimeInfo): structTM = + proc timeInfoToTM(t: TTimeInfo): StructTM = const weekDays: array [TWeekDay, int8] = [1'i8,2'i8,3'i8,4'i8,5'i8,6'i8,0'i8] result.second = t.second @@ -367,7 +367,7 @@ when not defined(JS): result.monthday = t.monthday result.month = ord(t.month) result.year = t.year - 1900 - result.weekday = weekDays[t.weekDay] + result.weekday = weekDays[t.weekday] result.yearday = t.yearday result.isdst = if t.isDST: 1 else: 0 @@ -401,7 +401,7 @@ when not defined(JS): # copying is needed anyway to provide reentrancity; thus # the conversion is not expensive - proc TimeInfoToTime(timeInfo: TTimeInfo): TTime = + proc timeInfoToTime(timeInfo: TTimeInfo): TTime = var cTimeInfo = timeInfo # for C++ we have to make a copy, # because the header of mktime is broken in my version of libc return mktime(timeInfoToTM(cTimeInfo)) @@ -453,7 +453,7 @@ when not defined(JS): result = toFloat(a.tv_sec) + toFloat(a.tv_usec)*0.00_0001 elif defined(windows): var f: winlean.TFiletime - GetSystemTimeAsFileTime(f) + getSystemTimeAsFileTime(f) var i64 = rdFileTime(f) - epochDiff var secs = i64 div rateDiff var subsecs = i64 mod rateDiff @@ -498,7 +498,7 @@ elif defined(JS): result.weekday = weekDays[t.getUTCDay()] result.yearday = 0 - proc TimeInfoToTime*(timeInfo: TTimeInfo): TTime = + proc timeInfoToTime*(timeInfo: TTimeInfo): TTime = result = internGetTime() result.setSeconds(timeInfo.second) result.setMinutes(timeInfo.minute) @@ -532,7 +532,7 @@ proc getDateStr*(): string {.rtl, extern: "nt$1", tags: [FTime].} = ## gets the current date as a string of the format ``YYYY-MM-DD``. var ti = getLocalTime(getTime()) result = $ti.year & '-' & intToStr(ord(ti.month)+1, 2) & - '-' & intToStr(ti.monthDay, 2) + '-' & intToStr(ti.monthday, 2) proc getClockStr*(): string {.rtl, extern: "nt$1", tags: [FTime].} = ## gets the current clock time as a string of the format ``HH:MM:SS``. @@ -593,7 +593,7 @@ proc format*(info: TTimeInfo, f: string): string = result = "" var i = 0 var currentF = "" - while True: + while true: case f[i] of ' ', '-', '/', ':', '\'', '\0', '(', ')', '[', ']', ',': case currentF diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim index f90fc2745..6e73eea3f 100644 --- a/lib/pure/unicode.nim +++ b/lib/pure/unicode.nim @@ -14,8 +14,8 @@ include "system/inclrtl" type - irune = int # underlying type of TRune - TRune* = distinct irune ## type that can hold any Unicode character + IRune = int # underlying type of TRune + TRune* = distinct IRune ## type that can hold any Unicode character TRune16* = distinct int16 ## 16 bit Unicode character proc `<=%`*(a, b: TRune): bool = return int(a) <=% int(b) @@ -109,7 +109,7 @@ proc runeAt*(s: string, i: int): TRune = proc toUTF8*(c: TRune): string {.rtl, extern: "nuc$1".} = ## converts a rune into its UTF8 representation - var i = irune(c) + var i = IRune(c) if i <=% 127: result = newString(1) result[0] = chr(i) @@ -1100,7 +1100,7 @@ const 0x01f1, 501, # 0x01f3, 499] # -proc binarySearch(c: irune, tab: openArray[iRune], len, stride: int): int = +proc binarySearch(c: IRune, tab: openArray[IRune], len, stride: int): int = var n = len var t = 0 while n > 1: @@ -1118,29 +1118,29 @@ proc binarySearch(c: irune, tab: openArray[iRune], len, stride: int): int = proc toLower*(c: TRune): TRune {.rtl, extern: "nuc$1", procvar.} = ## Converts `c` into lower case. This works for any Unicode character. ## If possible, prefer `toLower` over `toUpper`. - var c = irune(c) - var p = binarySearch(c, tolowerRanges, len(toLowerRanges) div 3, 3) + var c = IRune(c) + var p = binarySearch(c, tolowerRanges, len(tolowerRanges) div 3, 3) if p >= 0 and c >= tolowerRanges[p] and c <= tolowerRanges[p+1]: return TRune(c + tolowerRanges[p+2] - 500) - p = binarySearch(c, toLowerSinglets, len(toLowerSinglets) div 2, 2) - if p >= 0 and c == toLowerSinglets[p]: - return TRune(c + toLowerSinglets[p+1] - 500) + p = binarySearch(c, tolowerSinglets, len(tolowerSinglets) div 2, 2) + if p >= 0 and c == tolowerSinglets[p]: + return TRune(c + tolowerSinglets[p+1] - 500) return TRune(c) proc toUpper*(c: TRune): TRune {.rtl, extern: "nuc$1", procvar.} = ## Converts `c` into upper case. This works for any Unicode character. ## If possible, prefer `toLower` over `toUpper`. - var c = irune(c) - var p = binarySearch(c, toUpperRanges, len(toUpperRanges) div 3, 3) - if p >= 0 and c >= toUpperRanges[p] and c <= toUpperRanges[p+1]: - return TRune(c + toUpperRanges[p+2] - 500) - p = binarySearch(c, toUpperSinglets, len(toUpperSinglets) div 2, 2) - if p >= 0 and c == toUpperSinglets[p]: - return TRune(c + toUpperSinglets[p+1] - 500) + var c = IRune(c) + var p = binarySearch(c, toupperRanges, len(toupperRanges) div 3, 3) + if p >= 0 and c >= toupperRanges[p] and c <= toupperRanges[p+1]: + return TRune(c + toupperRanges[p+2] - 500) + p = binarySearch(c, toupperSinglets, len(toupperSinglets) div 2, 2) + if p >= 0 and c == toupperSinglets[p]: + return TRune(c + toupperSinglets[p+1] - 500) return TRune(c) proc toTitle*(c: TRune): TRune {.rtl, extern: "nuc$1", procvar.} = - var c = irune(c) + var c = IRune(c) var p = binarySearch(c, toTitleSinglets, len(toTitleSinglets) div 2, 2) if p >= 0 and c == toTitleSinglets[p]: return TRune(c + toTitleSinglets[p+1] - 500) @@ -1149,32 +1149,32 @@ proc toTitle*(c: TRune): TRune {.rtl, extern: "nuc$1", procvar.} = proc isLower*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = ## returns true iff `c` is a lower case Unicode character ## If possible, prefer `isLower` over `isUpper`. - var c = irune(c) + var c = IRune(c) # Note: toUpperRanges is correct here! - var p = binarySearch(c, toUpperRanges, len(toUpperRanges) div 3, 3) - if p >= 0 and c >= toUpperRanges[p] and c <= toUpperRanges[p+1]: + var p = binarySearch(c, toupperRanges, len(toupperRanges) div 3, 3) + if p >= 0 and c >= toupperRanges[p] and c <= toupperRanges[p+1]: return true - p = binarySearch(c, toUpperSinglets, len(toUpperSinglets) div 2, 2) - if p >= 0 and c == toUpperSinglets[p]: + p = binarySearch(c, toupperSinglets, len(toupperSinglets) div 2, 2) + if p >= 0 and c == toupperSinglets[p]: return true proc isUpper*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = ## returns true iff `c` is a upper case Unicode character ## If possible, prefer `isLower` over `isUpper`. - var c = irune(c) + var c = IRune(c) # Note: toLowerRanges is correct here! - var p = binarySearch(c, toLowerRanges, len(toLowerRanges) div 3, 3) - if p >= 0 and c >= toLowerRanges[p] and c <= toLowerRanges[p+1]: + var p = binarySearch(c, tolowerRanges, len(tolowerRanges) div 3, 3) + if p >= 0 and c >= tolowerRanges[p] and c <= tolowerRanges[p+1]: return true - p = binarySearch(c, toLowerSinglets, len(toLowerSinglets) div 2, 2) - if p >= 0 and c == toLowerSinglets[p]: + p = binarySearch(c, tolowerSinglets, len(tolowerSinglets) div 2, 2) + if p >= 0 and c == tolowerSinglets[p]: return true proc isAlpha*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = ## returns true iff `c` is an *alpha* Unicode character (i.e. a letter) if isUpper(c) or isLower(c): return true - var c = irune(c) + var c = IRune(c) var p = binarySearch(c, alphaRanges, len(alphaRanges) div 2, 2) if p >= 0 and c >= alphaRanges[p] and c <= alphaRanges[p+1]: return true @@ -1187,7 +1187,7 @@ proc isTitle*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = proc isWhiteSpace*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = ## returns true iff `c` is a Unicode whitespace character - var c = irune(c) + var c = IRune(c) var p = binarySearch(c, spaceRanges, len(spaceRanges) div 2, 2) if p >= 0 and c >= spaceRanges[p] and c <= spaceRanges[p+1]: return true @@ -1214,7 +1214,7 @@ proc cmpRunesIgnoreCase*(a, b: string): int {.rtl, extern: "nuc$1", procvar.} = # slow path: fastRuneAt(a, i, ar) fastRuneAt(b, j, br) - result = irune(toLower(ar)) - irune(toLower(br)) + result = IRune(toLower(ar)) - IRune(toLower(br)) if result != 0: return result = a.len - b.len diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index f847d24f4..f5640a1b4 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -37,8 +37,8 @@ var checkpoints: seq[string] = @[] -template TestSetupIMPL*: stmt {.immediate, dirty.} = nil -template TestTeardownIMPL*: stmt {.immediate, dirty.} = nil +template TestSetupIMPL*: stmt {.immediate, dirty.} = discard +template TestTeardownIMPL*: stmt {.immediate, dirty.} = discard proc shouldRun(testName: string): bool = result = true @@ -126,7 +126,7 @@ macro check*(conditions: stmt): stmt {.immediate.} = for i in 1 .. <exp.len: if exp[i].kind notin nnkLiterals: inc counter - var arg = newIdentNode(":p" & ($counter)) + var arg = newIdentNode(":p" & $counter) var argStr = exp[i].toStrLit if exp[i].kind in nnkCallKinds: inspectArgs(exp[i]) argsAsgns.add getAst(asgn(arg, exp[i])) @@ -146,7 +146,8 @@ macro check*(conditions: stmt): stmt {.immediate.} = var checkedStr = checked.toStrLit inspectArgs(checked) - result = getAst(rewrite(checked, checked.lineinfo, checkedStr, argsAsgns, argsPrintOuts)) + result = getAst(rewrite(checked, checked.lineinfo, checkedStr, + argsAsgns, argsPrintOuts)) of nnkStmtList: result = newNimNode(nnkStmtList) @@ -176,7 +177,7 @@ macro expect*(exceptions: varargs[expr], body: stmt): stmt {.immediate.} = checkpoint(lineInfoLit & ": Expect Failed, no exception was thrown.") fail() except errorTypes: - nil + discard var body = exp[exp.len - 1] diff --git a/lib/system.nim b/lib/system.nim index 26109bb97..75bebf702 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -144,7 +144,7 @@ proc reset*[T](obj: var T) {.magic: "Reset", noSideEffect.} ## be called before any possible `object branch transition`:idx:. # for low and high the return type T may not be correct, but -# we handle that with compiler magic in SemLowHigh() +# we handle that with compiler magic in semLowHigh() proc high*[T](x: T): T {.magic: "High", noSideEffect.} ## returns the highest possible index of an array, a sequence, a string or ## the highest possible value of an ordinal value `x`. As a special @@ -159,7 +159,7 @@ type range*{.magic: "Range".}[T] ## Generic type to construct range types. array*{.magic: "Array".}[I, T] ## Generic type to construct ## fixed-length arrays. - openarray*{.magic: "OpenArray".}[T] ## Generic type to construct open arrays. + openArray*{.magic: "OpenArray".}[T] ## Generic type to construct open arrays. ## Open arrays are implemented as a ## pointer to the array data and a ## length field. @@ -186,7 +186,10 @@ proc `..`*[T](b: T): TSlice[T] {.noSideEffect, inline.} = when not defined(niminheritable): {.pragma: inheritable.} -when not defined(JS) and not defined(NimrodVM): +const NoFakeVars* = defined(NimrodVM) ## true if the backend doesn't support \ + ## "fake variables" like 'var EBADF {.importc.}: cint'. + +when not defined(JS): type TGenericSeq {.compilerproc, pure, inheritable.} = object len, reserved: int @@ -195,14 +198,15 @@ when not defined(JS) and not defined(NimrodVM): NimStringDesc {.compilerproc, final.} = object of TGenericSeq data: array[0..100_000_000, char] NimString = ptr NimStringDesc - + +when not defined(JS) and not defined(NimrodVM): template space(s: PGenericSeq): int {.dirty.} = s.reserved and not seqShallowFlag include "system/hti" type - Byte* = uInt8 ## this is an alias for ``uint8``, that is an unsigned + Byte* = uint8 ## this is an alias for ``uint8``, that is an unsigned ## int 8 bits wide. Natural* = range[0..high(int)] @@ -335,13 +339,13 @@ type TResult* = enum Failure, Success -proc sizeof*[T](x: T): natural {.magic: "SizeOf", noSideEffect.} +proc sizeof*[T](x: T): Natural {.magic: "SizeOf", noSideEffect.} ## returns the size of ``x`` in bytes. Since this is a low-level proc, ## its usage is discouraged - using ``new`` for the most cases suffices ## that one never needs to know ``x``'s size. As a special semantic rule, ## ``x`` may also be a type identifier (``sizeof(int)`` is valid). -proc `<`*[T](x: ordinal[T]): T {.magic: "UnaryLt", noSideEffect.} +proc `<`*[T](x: Ordinal[T]): T {.magic: "UnaryLt", noSideEffect.} ## unary ``<`` that can be used for nice looking excluding ranges: ## ## .. code-block:: nimrod @@ -349,22 +353,22 @@ proc `<`*[T](x: ordinal[T]): T {.magic: "UnaryLt", noSideEffect.} ## ## Semantically this is the same as ``pred``. -proc succ*[T](x: ordinal[T], y = 1): T {.magic: "Succ", noSideEffect.} +proc succ*[T](x: Ordinal[T], y = 1): T {.magic: "Succ", noSideEffect.} ## returns the ``y``-th successor of the value ``x``. ``T`` has to be ## an ordinal type. If such a value does not exist, ``EOutOfRange`` is raised ## or a compile time error occurs. -proc pred*[T](x: ordinal[T], y = 1): T {.magic: "Pred", noSideEffect.} +proc pred*[T](x: Ordinal[T], y = 1): T {.magic: "Pred", noSideEffect.} ## returns the ``y``-th predecessor of the value ``x``. ``T`` has to be ## an ordinal type. If such a value does not exist, ``EOutOfRange`` is raised ## or a compile time error occurs. -proc inc*[T](x: var ordinal[T], y = 1) {.magic: "Inc", noSideEffect.} +proc inc*[T](x: var Ordinal[T], y = 1) {.magic: "Inc", noSideEffect.} ## increments the ordinal ``x`` by ``y``. If such a value does not ## exist, ``EOutOfRange`` is raised or a compile time error occurs. This is a ## short notation for: ``x = succ(x, y)``. -proc dec*[T](x: var ordinal[T], y = 1) {.magic: "Dec", noSideEffect.} +proc dec*[T](x: var Ordinal[T], y = 1) {.magic: "Dec", noSideEffect.} ## decrements the ordinal ``x`` by ``y``. If such a value does not ## exist, ``EOutOfRange`` is raised or a compile time error occurs. This is a ## short notation for: ``x = pred(x, y)``. @@ -418,10 +422,18 @@ proc incl*[T](x: var set[T], y: T) {.magic: "Incl", noSideEffect.} ## includes element ``y`` to the set ``x``. This is the same as ## ``x = x + {y}``, but it might be more efficient. +template incl*[T](s: var set[T], flags: set[T]) = + ## includes the set of flags to the set ``x``. + s = s + flags + proc excl*[T](x: var set[T], y: T) {.magic: "Excl", noSideEffect.} ## excludes element ``y`` to the set ``x``. This is the same as ## ``x = x - {y}``, but it might be more efficient. +template excl*[T](s: var set[T], flags: set[T]) = + ## excludes the set of flags to ``x``. + s = s - flags + proc card*[T](x: set[T]): int {.magic: "Card", noSideEffect.} ## returns the cardinality of the set ``x``, i.e. the number of elements ## in the set. @@ -584,46 +596,46 @@ proc `<` *(x, y: int64): bool {.magic: "LtI64", noSideEffect.} ## Returns true iff `x` is less than `y`. type - IntMax32 = bool|int|int8|int16|int32 + IntMax32 = int|int8|int16|int32 proc `+%` *(x, y: IntMax32): IntMax32 {.magic: "AddU", noSideEffect.} -proc `+%` *(x, y: Int64): Int64 {.magic: "AddU", noSideEffect.} +proc `+%` *(x, y: int64): int64 {.magic: "AddU", noSideEffect.} ## treats `x` and `y` as unsigned and adds them. The result is truncated to ## fit into the result. This implements modulo arithmetic. No overflow ## errors are possible. proc `-%` *(x, y: IntMax32): IntMax32 {.magic: "SubU", noSideEffect.} -proc `-%` *(x, y: Int64): Int64 {.magic: "SubU", noSideEffect.} +proc `-%` *(x, y: int64): int64 {.magic: "SubU", noSideEffect.} ## treats `x` and `y` as unsigned and subtracts them. The result is ## truncated to fit into the result. This implements modulo arithmetic. ## No overflow errors are possible. proc `*%` *(x, y: IntMax32): IntMax32 {.magic: "MulU", noSideEffect.} -proc `*%` *(x, y: Int64): Int64 {.magic: "MulU", noSideEffect.} +proc `*%` *(x, y: int64): int64 {.magic: "MulU", noSideEffect.} ## treats `x` and `y` as unsigned and multiplies them. The result is ## truncated to fit into the result. This implements modulo arithmetic. ## No overflow errors are possible. proc `/%` *(x, y: IntMax32): IntMax32 {.magic: "DivU", noSideEffect.} -proc `/%` *(x, y: Int64): Int64 {.magic: "DivU", noSideEffect.} +proc `/%` *(x, y: int64): int64 {.magic: "DivU", noSideEffect.} ## treats `x` and `y` as unsigned and divides them. The result is ## truncated to fit into the result. This implements modulo arithmetic. ## No overflow errors are possible. proc `%%` *(x, y: IntMax32): IntMax32 {.magic: "ModU", noSideEffect.} -proc `%%` *(x, y: Int64): Int64 {.magic: "ModU", noSideEffect.} +proc `%%` *(x, y: int64): int64 {.magic: "ModU", noSideEffect.} ## treats `x` and `y` as unsigned and compute the modulo of `x` and `y`. ## The result is truncated to fit into the result. ## This implements modulo arithmetic. ## No overflow errors are possible. proc `<=%` *(x, y: IntMax32): bool {.magic: "LeU", noSideEffect.} -proc `<=%` *(x, y: Int64): bool {.magic: "LeU64", noSideEffect.} +proc `<=%` *(x, y: int64): bool {.magic: "LeU64", noSideEffect.} ## treats `x` and `y` as unsigned and compares them. ## Returns true iff ``unsigned(x) <= unsigned(y)``. proc `<%` *(x, y: IntMax32): bool {.magic: "LtU", noSideEffect.} -proc `<%` *(x, y: Int64): bool {.magic: "LtU64", noSideEffect.} +proc `<%` *(x, y: int64): bool {.magic: "LtU64", noSideEffect.} ## treats `x` and `y` as unsigned and compares them. ## Returns true iff ``unsigned(x) < unsigned(y)``. @@ -728,10 +740,10 @@ proc contains*[T](s: TSlice[T], value: T): bool {.noSideEffect, inline.} = result = s.a <= value and value <= s.b template `in` * (x, y: expr): expr {.immediate.} = contains(y, x) -template `not_in` * (x, y: expr): expr {.immediate.} = not contains(y, x) +template `notin` * (x, y: expr): expr {.immediate.} = not contains(y, x) proc `is` *[T, S](x: T, y: S): bool {.magic: "Is", noSideEffect.} -template `is_not` *(x, y: expr): expr {.immediate.} = not (x is y) +template `isnot` *(x, y: expr): expr {.immediate.} = not (x is y) proc `of` *[T, S](x: T, y: S): bool {.magic: "Of", noSideEffect.} @@ -933,7 +945,6 @@ template sysAssert(cond: bool, msg: string) = if not cond: echo "[SYSASSERT] ", msg quit 1 - nil include "system/inclrtl" @@ -1061,7 +1072,7 @@ proc toFloat*(i: int): float {. ## fails, `EInvalidValue` is raised. However, on most platforms the ## conversion cannot fail. -proc toBiggestFloat*(i: biggestint): biggestfloat {. +proc toBiggestFloat*(i: BiggestInt): BiggestFloat {. magic: "ToBiggestFloat", noSideEffect, importc: "toBiggestFloat".} ## converts an biggestint `i` into a ``biggestfloat``. If the conversion ## fails, `EInvalidValue` is raised. However, on most platforms the @@ -1073,7 +1084,7 @@ proc toInt*(f: float): int {. ## rounds `f` if it does not contain an integer value. If the conversion ## fails (because `f` is infinite for example), `EInvalidValue` is raised. -proc toBiggestInt*(f: biggestfloat): biggestint {. +proc toBiggestInt*(f: BiggestFloat): BiggestInt {. magic: "ToBiggestInt", noSideEffect, importc: "toBiggestInt".} ## converts a biggestfloat `f` into a ``biggestint``. Conversion ## rounds `f` if it does not contain an integer value. If the conversion @@ -1115,19 +1126,19 @@ proc substr*(s: string, first, last: int): string {. ## or `limit`:idx: a string's length. when not defined(nimrodVM): - proc zeroMem*(p: Pointer, size: int) {.importc, noDecl.} + proc zeroMem*(p: pointer, size: int) {.importc, noDecl.} ## overwrites the contents of the memory at ``p`` with the value 0. ## Exactly ``size`` bytes will be overwritten. Like any procedure ## dealing with raw memory this is *unsafe*. - proc copyMem*(dest, source: Pointer, size: int) {. + proc copyMem*(dest, source: pointer, size: int) {. importc: "memcpy", header: "<string.h>".} ## copies the contents from the memory at ``source`` to the memory ## at ``dest``. Exactly ``size`` bytes will be copied. The memory ## regions may not overlap. Like any procedure dealing with raw ## memory this is *unsafe*. - proc moveMem*(dest, source: Pointer, size: int) {. + proc moveMem*(dest, source: pointer, size: int) {. importc: "memmove", header: "<string.h>".} ## copies the contents from the memory at ``source`` to the memory ## at ``dest``. Exactly ``size`` bytes will be copied. The memory @@ -1135,14 +1146,14 @@ when not defined(nimrodVM): ## and is thus somewhat more safe than ``copyMem``. Like any procedure ## dealing with raw memory this is still *unsafe*, though. - proc equalMem*(a, b: Pointer, size: int): bool {. + proc equalMem*(a, b: pointer, size: int): bool {. importc: "equalMem", noDecl, noSideEffect.} ## compares the memory blocks ``a`` and ``b``. ``size`` bytes will ## be compared. If the blocks are equal, true is returned, false ## otherwise. Like any procedure dealing with raw memory this is ## *unsafe*. - when hostOs != "standalone": + when hostOS != "standalone": proc alloc*(size: int): pointer {.noconv, rtl, tags: [].} ## allocates a new memory block with at least ``size`` bytes. The ## block has to be freed with ``realloc(block, 0)`` or @@ -1157,7 +1168,7 @@ when not defined(nimrodVM): ## containing zero, so it is somewhat safer than ``alloc``. ## The allocated memory belongs to its allocating thread! ## Use `allocShared0` to allocate from a shared heap. - proc realloc*(p: Pointer, newsize: int): pointer {.noconv, rtl, tags: [].} + proc realloc*(p: pointer, newsize: int): pointer {.noconv, rtl, tags: [].} ## grows or shrinks a given memory block. If p is **nil** then a new ## memory block is returned. In either way the block has at least ## ``newsize`` bytes. If ``newsize == 0`` and p is not **nil** @@ -1165,7 +1176,7 @@ when not defined(nimrodVM): ## be freed with ``dealloc``. ## The allocated memory belongs to its allocating thread! ## Use `reallocShared` to reallocate from a shared heap. - proc dealloc*(p: Pointer) {.noconv, rtl, tags: [].} + proc dealloc*(p: pointer) {.noconv, rtl, tags: [].} ## frees the memory allocated with ``alloc``, ``alloc0`` or ## ``realloc``. This procedure is dangerous! If one forgets to ## free the memory a leak occurs; if one tries to access freed @@ -1186,13 +1197,13 @@ when not defined(nimrodVM): ## ``reallocShared(block, 0)`` or ``deallocShared(block)``. ## The block is initialized with all bytes ## containing zero, so it is somewhat safer than ``allocShared``. - proc reallocShared*(p: Pointer, newsize: int): pointer {.noconv, rtl.} + proc reallocShared*(p: pointer, newsize: int): pointer {.noconv, rtl.} ## grows or shrinks a given memory block on the heap. If p is **nil** ## then a new memory block is returned. In either way the block has at least ## ``newsize`` bytes. If ``newsize == 0`` and p is not **nil** ## ``reallocShared`` calls ``deallocShared(p)``. In other cases the ## block has to be freed with ``deallocShared``. - proc deallocShared*(p: Pointer) {.noconv, rtl.} + proc deallocShared*(p: pointer) {.noconv, rtl.} ## frees the memory allocated with ``allocShared``, ``allocShared0`` or ## ``reallocShared``. This procedure is dangerous! If one forgets to ## free the memory a leak occurs; if one tries to access freed @@ -1237,7 +1248,7 @@ proc `$` *(x: char): string {.magic: "CharToStr", noSideEffect.} ## The stingify operator for a character argument. Returns `x` ## converted to a string. -proc `$` *(x: Cstring): string {.magic: "CStrToStr", noSideEffect.} +proc `$` *(x: cstring): string {.magic: "CStrToStr", noSideEffect.} ## The stingify operator for a CString argument. Returns `x` ## converted to a string. @@ -1259,13 +1270,13 @@ proc getRefcount*[T](x: seq[T]): int {.importc: "getRefcount", noSideEffect.} ## retrieves the reference count of an heap-allocated object. The ## value is implementation-dependent. -# new constants: + const - inf* {.magic: "Inf".} = 1.0 / 0.0 + Inf* {.magic: "Inf".} = 1.0 / 0.0 ## contains the IEEE floating point value of positive infinity. - neginf* {.magic: "NegInf".} = -inf + NegInf* {.magic: "NegInf".} = -Inf ## contains the IEEE floating point value of negative infinity. - nan* {.magic: "NaN".} = 0.0 / 0.0 + NaN* {.magic: "NaN".} = 0.0 / 0.0 ## contains an IEEE floating point value of *Not A Number*. Note ## that you cannot compare a floating point value to this value ## and expect a reasonable result - use the `classify` procedure @@ -1372,7 +1383,7 @@ proc clamp*[T](x, a, b: T): T = if x > b: return b return x -iterator items*[T](a: openarray[T]): T {.inline.} = +iterator items*[T](a: openArray[T]): T {.inline.} = ## iterates over each item of `a`. var i = 0 while i < len(a): @@ -1425,7 +1436,7 @@ iterator items*(E: typedesc[enum]): E = for v in low(E)..high(E): yield v -iterator pairs*[T](a: openarray[T]): tuple[key: int, val: T] {.inline.} = +iterator pairs*[T](a: openArray[T]): tuple[key: int, val: T] {.inline.} = ## iterates over each item of `a`. Yields ``(index, a[index])`` pairs. var i = 0 while i < len(a): @@ -1959,20 +1970,20 @@ when not defined(JS): #and not defined(NimrodVM): ## Template which expands to either stdout or stderr depending on ## `useStdoutAsStdmsg` compile-time switch. - proc Open*(f: var TFile, filename: string, - mode: TFileMode = fmRead, bufSize: int = -1): Bool {.tags: [].} + proc open*(f: var TFile, filename: string, + mode: TFileMode = fmRead, bufSize: int = -1): bool {.tags: [].} ## Opens a file named `filename` with given `mode`. ## ## Default mode is readonly. Returns true iff the file could be opened. ## This throws no exception if the file could not be opened. - proc Open*(f: var TFile, filehandle: TFileHandle, - mode: TFileMode = fmRead): Bool {.tags: [].} + proc open*(f: var TFile, filehandle: TFileHandle, + mode: TFileMode = fmRead): bool {.tags: [].} ## Creates a ``TFile`` from a `filehandle` with given `mode`. ## ## Default mode is readonly. Returns true iff the file could be opened. - proc Open*(filename: string, + proc open*(filename: string, mode: TFileMode = fmRead, bufSize: int = -1): TFile = ## Opens a file named `filename` with given `mode`. ## @@ -1989,16 +2000,16 @@ when not defined(JS): #and not defined(NimrodVM): ## ## Default mode is readonly. Returns true iff the file could be reopened. - proc Close*(f: TFile) {.importc: "fclose", header: "<stdio.h>", tags: [].} + proc close*(f: TFile) {.importc: "fclose", header: "<stdio.h>", tags: [].} ## Closes the file. - proc EndOfFile*(f: TFile): Bool {.tags: [].} + proc endOfFile*(f: TFile): bool {.tags: [].} ## Returns true iff `f` is at the end. proc readChar*(f: TFile): char {. importc: "fgetc", header: "<stdio.h>", tags: [FReadIO].} ## Reads a single character from the stream `f`. - proc FlushFile*(f: TFile) {. + proc flushFile*(f: TFile) {. importc: "fflush", header: "<stdio.h>", tags: [FWriteIO].} ## Flushes `f`'s buffer. @@ -2018,10 +2029,10 @@ when not defined(JS): #and not defined(NimrodVM): proc write*(f: TFile, r: float32) {.tags: [FWriteIO].} proc write*(f: TFile, i: int) {.tags: [FWriteIO].} - proc write*(f: TFile, i: biggestInt) {.tags: [FWriteIO].} - proc write*(f: TFile, r: biggestFloat) {.tags: [FWriteIO].} + proc write*(f: TFile, i: BiggestInt) {.tags: [FWriteIO].} + proc write*(f: TFile, r: BiggestFloat) {.tags: [FWriteIO].} proc write*(f: TFile, s: string) {.tags: [FWriteIO].} - proc write*(f: TFile, b: Bool) {.tags: [FWriteIO].} + proc write*(f: TFile, b: bool) {.tags: [FWriteIO].} proc write*(f: TFile, c: char) {.tags: [FWriteIO].} proc write*(f: TFile, c: cstring) {.tags: [FWriteIO].} proc write*(f: TFile, a: varargs[string, `$`]) {.tags: [FWriteIO].} @@ -2047,13 +2058,13 @@ when not defined(JS): #and not defined(NimrodVM): proc getFileSize*(f: TFile): int64 {.tags: [FReadIO].} ## retrieves the file size (in bytes) of `f`. - proc ReadBytes*(f: TFile, a: var openarray[int8], start, len: int): int {. + proc readBytes*(f: TFile, a: var openArray[int8], start, len: int): int {. tags: [FReadIO].} ## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns ## the actual number of bytes that have been read which may be less than ## `len` (if not as many bytes are remaining), but not greater. - proc ReadChars*(f: TFile, a: var openarray[char], start, len: int): int {. + proc readChars*(f: TFile, a: var openArray[char], start, len: int): int {. tags: [FReadIO].} ## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns ## the actual number of bytes that have been read which may be less than @@ -2064,13 +2075,13 @@ when not defined(JS): #and not defined(NimrodVM): ## the actual number of bytes that have been read which may be less than ## `len` (if not as many bytes are remaining), but not greater. - proc writeBytes*(f: TFile, a: openarray[int8], start, len: int): int {. + proc writeBytes*(f: TFile, a: openArray[int8], start, len: int): int {. tags: [FWriteIO].} ## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns ## the number of actual written bytes, which may be less than `len` in case ## of an error. - proc writeChars*(f: tFile, a: openarray[char], start, len: int): int {. + proc writeChars*(f: TFile, a: openArray[char], start, len: int): int {. tags: [FWriteIO].} ## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns ## the number of actual written bytes, which may be less than `len` in case @@ -2192,7 +2203,7 @@ when not defined(JS): #and not defined(NimrodVM): const GenericSeqSize = (2 * sizeof(int)) - proc getDiscriminant(aa: Pointer, n: ptr TNimNode): int = + proc getDiscriminant(aa: pointer, n: ptr TNimNode): int = sysAssert(n.kind == nkCase, "getDiscriminant: node != nkCase") var d: int var a = cast[TAddress](aa) @@ -2203,7 +2214,7 @@ when not defined(JS): #and not defined(NimrodVM): else: sysAssert(false, "getDiscriminant: invalid n.typ.size") return d - proc selectBranch(aa: Pointer, n: ptr TNimNode): ptr TNimNode = + proc selectBranch(aa: pointer, n: ptr TNimNode): ptr TNimNode = var discr = getDiscriminant(aa, n) if discr <% n.len: result = n.sons[discr] @@ -2225,8 +2236,19 @@ when not defined(JS): #and not defined(NimrodVM): when hostOS != "standalone": iterator lines*(filename: string): TaintedString {.tags: [FReadIO].} = - ## Iterate over any line in the file named `filename`. - ## If the file does not exist `EIO` is raised. + ## Iterates over any line in the file named `filename`. + ## + ## If the file does not exist `EIO` is raised. The trailing newline + ## character(s) are removed from the iterated lines. Example: + ## + ## .. code-block:: nimrod + ## import strutils + ## + ## proc transformLetters(filename: string) = + ## var buffer = "" + ## for line in filename.lines: + ## buffer.add(line.replace("a", "0") & '\x0A') + ## writeFile(filename, buffer) var f = open(filename) var res = TaintedString(newStringOfCap(80)) while f.readLine(res): yield res @@ -2234,6 +2256,17 @@ when not defined(JS): #and not defined(NimrodVM): iterator lines*(f: TFile): TaintedString {.tags: [FReadIO].} = ## Iterate over any line in the file `f`. + ## + ## The trailing newline character(s) are removed from the iterated lines. + ## Example: + ## + ## .. code-block:: nimrod + ## proc countZeros(filename: TFile): tuple[lines, zeros: int] = + ## for line in filename.lines: + ## for letter in line: + ## if letter == '0': + ## result.zeros += 1 + ## result.lines += 1 var res = TaintedString(newStringOfCap(80)) while f.readLine(res): yield res @@ -2547,7 +2580,7 @@ proc raiseAssert*(msg: string) {.noinline.} = sysFatal(EAssertionFailed, msg) when true: - proc hiddenRaiseAssert(msg: string) {.raises: [], tags: [].} = + proc failedAssertImpl*(msg: string) {.raises: [], tags: [].} = # trick the compiler to not list ``EAssertionFailed`` when called # by ``assert``. type THide = proc (msg: string) {.noinline, raises: [], noSideEffect, @@ -2560,11 +2593,11 @@ template assert*(cond: bool, msg = "") = ## raises an ``EAssertionFailure`` exception. However, the compiler may ## not generate any code at all for ``assert`` if it is advised to do so. ## Use ``assert`` for debugging purposes only. - bind instantiationInfo, hiddenRaiseAssert + bind instantiationInfo + mixin failedAssertImpl when compileOption("assertions"): {.line.}: - if not cond: - hiddenRaiseAssert(astToStr(cond) & ' ' & msg) + if not cond: failedAssertImpl(astToStr(cond) & ' ' & msg) template doAssert*(cond: bool, msg = "") = ## same as `assert` but is always turned on and not affected by the @@ -2577,9 +2610,9 @@ template doAssert*(cond: bool, msg = "") = when not defined(nimhygiene): {.pragma: inject.} -template onFailedAssert*(msg: expr, code: stmt): stmt = - ## Sets an assertion failure handler that will intercept any assert statements - ## following `onFailedAssert` in the current lexical scope. +template onFailedAssert*(msg: expr, code: stmt): stmt {.dirty, immediate.} = + ## Sets an assertion failure handler that will intercept any assert + ## statements following `onFailedAssert` in the current lexical scope. ## Can be defined multiple times in a single function. ## ## .. code-block:: nimrod @@ -2596,8 +2629,8 @@ template onFailedAssert*(msg: expr, code: stmt): stmt = ## ## assert(...) ## - template raiseAssert(msgIMPL: string): stmt = - let msg {.inject.} = msgIMPL + template failedAssertImpl(msgIMPL: string): stmt {.dirty, immediate.} = + let msg = msgIMPL code proc shallow*[T](s: var seq[T]) {.noSideEffect, inline.} = @@ -2643,7 +2676,7 @@ when hostOS != "standalone": x[j+i] = item[j] inc(j) -proc compiles*(x: expr): bool {.magic: "Compiles", noSideEffect.} = +proc compiles*(x): bool {.magic: "Compiles", noSideEffect.} = ## Special compile-time procedure that checks whether `x` can be compiled ## without any semantic error. ## This can be used to check whether a type supports some operation: @@ -2651,7 +2684,7 @@ proc compiles*(x: expr): bool {.magic: "Compiles", noSideEffect.} = ## .. code-block:: Nimrod ## when not compiles(3 + 4): ## echo "'+' for integers is available" - nil + discard when defined(initDebugger): initDebugger() @@ -2692,4 +2725,13 @@ proc locals*(): TObject {.magic: "Locals", noSideEffect.} = ## # -> name a with value something ## # -> name b with value 4 ## # -> B is 1 - nil + discard + +when not defined(booting): + type + semistatic*[T] = static[T] | T + # indicates a param of proc specialized for each static value, + # but also accepting run-time values + + template isStatic*(x): expr = compiles(static(x)) + # checks whether `x` is a value known at compile-time diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index 17258cf68..954485eb4 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -59,15 +59,16 @@ elif defined(windows): MEM_DECOMMIT = 0x4000 MEM_RELEASE = 0x8000 - proc VirtualAlloc(lpAddress: pointer, dwSize: int, flAllocationType, + proc virtualAlloc(lpAddress: pointer, dwSize: int, flAllocationType, flProtect: int32): pointer {. - header: "<windows.h>", stdcall.} + header: "<windows.h>", stdcall, importc: "VirtualAlloc".} - proc VirtualFree(lpAddress: pointer, dwSize: int, - dwFreeType: int32) {.header: "<windows.h>", stdcall.} + proc virtualFree(lpAddress: pointer, dwSize: int, + dwFreeType: int32) {.header: "<windows.h>", stdcall, + importc: "VirtualFree".} proc osAllocPages(size: int): pointer {.inline.} = - result = VirtualAlloc(nil, size, MEM_RESERVE or MEM_COMMIT, + result = virtualAlloc(nil, size, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE) if result == nil: raiseOutOfMem() @@ -78,7 +79,7 @@ elif defined(windows): # Windows :-(. We have to live with MEM_DECOMMIT instead. # Well that used to be the case but MEM_DECOMMIT fragments the address # space heavily, so we now treat Windows as a strange unmap target. - when reallyOsDealloc: VirtualFree(p, 0, MEM_RELEASE) + when reallyOsDealloc: virtualFree(p, 0, MEM_RELEASE) #VirtualFree(p, size, MEM_DECOMMIT) else: @@ -108,7 +109,7 @@ type data: TTrunkBuckets type - TAlignType = biggestFloat + TAlignType = BiggestFloat TFreeCell {.final, pure.} = object next: ptr TFreeCell # next free cell in chunk (overlaid with refcount) zeroField: int # 0 means cell is not used (overlaid with typ field) @@ -251,36 +252,36 @@ proc llDeallocAll(a: var TMemRegion) = osDeallocPages(it, PageSize) it = next -proc IntSetGet(t: TIntSet, key: int): PTrunk = +proc intSetGet(t: TIntSet, key: int): PTrunk = var it = t.data[key and high(t.data)] while it != nil: if it.key == key: return it it = it.next result = nil -proc IntSetPut(a: var TMemRegion, t: var TIntSet, key: int): PTrunk = - result = IntSetGet(t, key) +proc intSetPut(a: var TMemRegion, t: var TIntSet, key: int): PTrunk = + result = intSetGet(t, key) if result == nil: result = cast[PTrunk](llAlloc(a, sizeof(result[]))) result.next = t.data[key and high(t.data)] t.data[key and high(t.data)] = result result.key = key -proc Contains(s: TIntSet, key: int): bool = - var t = IntSetGet(s, key shr TrunkShift) +proc contains(s: TIntSet, key: int): bool = + var t = intSetGet(s, key shr TrunkShift) if t != nil: var u = key and TrunkMask result = (t.bits[u shr IntShift] and (1 shl (u and IntMask))) != 0 else: result = false -proc Incl(a: var TMemRegion, s: var TIntSet, key: int) = - var t = IntSetPut(a, s, key shr TrunkShift) +proc incl(a: var TMemRegion, s: var TIntSet, key: int) = + var t = intSetPut(a, s, key shr TrunkShift) var u = key and TrunkMask t.bits[u shr IntShift] = t.bits[u shr IntShift] or (1 shl (u and IntMask)) -proc Excl(s: var TIntSet, key: int) = - var t = IntSetGet(s, key shr TrunkShift) +proc excl(s: var TIntSet, key: int) = + var t = intSetGet(s, key shr TrunkShift) if t != nil: var u = key and TrunkMask t.bits[u shr IntShift] = t.bits[u shr IntShift] and not @@ -387,7 +388,7 @@ proc freeOsChunks(a: var TMemRegion, p: pointer, size: int) = #c_fprintf(c_stdout, "[Alloc] back to OS: %ld\n", size) proc isAccessible(a: TMemRegion, p: pointer): bool {.inline.} = - result = Contains(a.chunkStarts, pageIndex(p)) + result = contains(a.chunkStarts, pageIndex(p)) proc contains[T](list, x: T): bool = var it = list @@ -403,7 +404,7 @@ proc writeFreeList(a: TMemRegion) = it, it.next, it.prev) it = it.next -proc ListAdd[T](head: var T, c: T) {.inline.} = +proc listAdd[T](head: var T, c: T) {.inline.} = sysAssert(c notin head, "listAdd 1") sysAssert c.prev == nil, "listAdd 2" sysAssert c.next == nil, "listAdd 3" @@ -413,7 +414,7 @@ proc ListAdd[T](head: var T, c: T) {.inline.} = head.prev = c head = c -proc ListRemove[T](head: var T, c: T) {.inline.} = +proc listRemove[T](head: var T, c: T) {.inline.} = sysAssert(c in head, "listRemove") if c == head: head = c.next @@ -443,7 +444,7 @@ proc freeBigChunk(a: var TMemRegion, c: PBigChunk) = if isAccessible(a, ri) and chunkUnused(ri): sysAssert(not isSmallChunk(ri), "freeBigChunk 3") if not isSmallChunk(ri): - ListRemove(a.freeChunksList, cast[PBigChunk](ri)) + listRemove(a.freeChunksList, cast[PBigChunk](ri)) inc(c.size, ri.size) excl(a.chunkStarts, pageIndex(ri)) when coalescLeft: @@ -453,7 +454,7 @@ proc freeBigChunk(a: var TMemRegion, c: PBigChunk) = if isAccessible(a, le) and chunkUnused(le): sysAssert(not isSmallChunk(le), "freeBigChunk 5") if not isSmallChunk(le): - ListRemove(a.freeChunksList, cast[PBigChunk](le)) + listRemove(a.freeChunksList, cast[PBigChunk](le)) inc(le.size, c.size) excl(a.chunkStarts, pageIndex(c)) c = cast[PBigChunk](le) @@ -461,7 +462,7 @@ proc freeBigChunk(a: var TMemRegion, c: PBigChunk) = if c.size < ChunkOsReturn or weirdUnmap: incl(a, a.chunkStarts, pageIndex(c)) updatePrevSize(a, c, c.size) - ListAdd(a.freeChunksList, c) + listAdd(a.freeChunksList, c) c.used = false else: freeOsChunks(a, c, c.size) @@ -477,7 +478,7 @@ proc splitChunk(a: var TMemRegion, c: PBigChunk, size: int) = updatePrevSize(a, c, rest.size) c.size = size incl(a, a.chunkStarts, pageIndex(rest)) - ListAdd(a.freeChunksList, rest) + listAdd(a.freeChunksList, rest) proc getBigChunk(a: var TMemRegion, size: int): PBigChunk = # use first fit for now: @@ -488,10 +489,10 @@ proc getBigChunk(a: var TMemRegion, size: int): PBigChunk = while result != nil: sysAssert chunkUnused(result), "getBigChunk 3" if result.size == size: - ListRemove(a.freeChunksList, result) + listRemove(a.freeChunksList, result) break search elif result.size > size: - ListRemove(a.freeChunksList, result) + listRemove(a.freeChunksList, result) splitChunk(a, result, size) break search result = result.next @@ -530,7 +531,7 @@ proc allocInv(a: TMemRegion): bool = while it != nil: if it.zeroField != 0: echo "[SYSASSERT] it.zeroField != 0" - cprintf("%ld %p\n", it.zeroField, it) + c_printf("%ld %p\n", it.zeroField, it) return false it = it.next c = c.next @@ -556,7 +557,7 @@ proc rawAlloc(a: var TMemRegion, requestedSize: int): pointer = c.free = SmallChunkSize - smallChunkOverhead() - size c.next = nil c.prev = nil - ListAdd(a.freeSmallChunks[s], c) + listAdd(a.freeSmallChunks[s], c) result = addr(c.data) sysAssert((cast[TAddress](result) and (MemAlign-1)) == 0, "rawAlloc 4") else: @@ -580,7 +581,7 @@ proc rawAlloc(a: var TMemRegion, requestedSize: int): pointer = sysAssert(allocInv(a), "rawAlloc: before c.free < size") if c.free < size: sysAssert(allocInv(a), "rawAlloc: before listRemove test") - ListRemove(a.freeSmallChunks[s], c) + listRemove(a.freeSmallChunks[s], c) sysAssert(allocInv(a), "rawAlloc: end listRemove test") sysAssert(((cast[TAddress](result) and PageMask) - smallChunkOverhead()) %% size == 0, "rawAlloc 21") @@ -627,12 +628,12 @@ proc rawDealloc(a: var TMemRegion, p: pointer) = # check if it is not in the freeSmallChunks[s] list: if c.free < s: # add it to the freeSmallChunks[s] array: - ListAdd(a.freeSmallChunks[s div memAlign], c) + listAdd(a.freeSmallChunks[s div MemAlign], c) inc(c.free, s) else: inc(c.free, s) if c.free == SmallChunkSize-smallChunkOverhead(): - ListRemove(a.freeSmallChunks[s div memAlign], c) + listRemove(a.freeSmallChunks[s div MemAlign], c) c.size = SmallChunkSize freeBigChunk(a, cast[PBigChunk](c)) sysAssert(((cast[TAddress](p) and PageMask) - smallChunkOverhead()) %% @@ -738,7 +739,7 @@ proc realloc(allocator: var TMemRegion, p: pointer, newsize: int): pointer = proc deallocOsPages(a: var TMemRegion) = # we free every 'ordinarily' allocated page by iterating over the page bits: for p in elements(a.chunkStarts): - var page = cast[PChunk](p shl pageShift) + var page = cast[PChunk](p shl PageShift) when not weirdUnmap: var size = if page.size < PageSize: PageSize else: page.size osDeallocPages(page, size) @@ -759,7 +760,7 @@ proc getOccupiedMem(a: TMemRegion): int {.inline.} = # ---------------------- thread memory region ------------------------------- -template InstantiateForRegion(allocator: expr) = +template instantiateForRegion(allocator: expr) = when defined(fulldebug): proc interiorAllocatedPtr*(p: pointer): pointer = result = interiorAllocatedPtr(allocator, p) @@ -801,13 +802,13 @@ template InstantiateForRegion(allocator: expr) = when hasThreadSupport: var sharedHeap: TMemRegion var heapLock: TSysLock - InitSysLock(HeapLock) + initSysLock(heapLock) proc allocShared(size: int): pointer = when hasThreadSupport: - AcquireSys(HeapLock) + acquireSys(heapLock) result = alloc(sharedHeap, size) - ReleaseSys(HeapLock) + releaseSys(heapLock) else: result = alloc(size) @@ -817,17 +818,17 @@ template InstantiateForRegion(allocator: expr) = proc deallocShared(p: pointer) = when hasThreadSupport: - AcquireSys(HeapLock) + acquireSys(heapLock) dealloc(sharedHeap, p) - ReleaseSys(HeapLock) + releaseSys(heapLock) else: dealloc(p) proc reallocShared(p: pointer, newsize: int): pointer = when hasThreadSupport: - AcquireSys(HeapLock) + acquireSys(heapLock) result = realloc(sharedHeap, p, newsize) - ReleaseSys(HeapLock) + releaseSys(heapLock) else: result = realloc(p, newsize) diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim index 13e8496d2..2d33965e3 100644 --- a/lib/system/ansi_c.nim +++ b/lib/system/ansi_c.nim @@ -13,12 +13,12 @@ {.push hints:off} -proc c_strcmp(a, b: CString): cint {.header: "<string.h>", +proc c_strcmp(a, b: cstring): cint {.header: "<string.h>", noSideEffect, importc: "strcmp".} -proc c_memcmp(a, b: CString, size: int): cint {.header: "<string.h>", +proc c_memcmp(a, b: cstring, size: int): cint {.header: "<string.h>", noSideEffect, importc: "memcmp".} -proc c_memcpy(a, b: CString, size: int) {.header: "<string.h>", importc: "memcpy".} -proc c_strlen(a: CString): int {.header: "<string.h>", +proc c_memcpy(a, b: cstring, size: int) {.header: "<string.h>", importc: "memcpy".} +proc c_strlen(a: cstring): int {.header: "<string.h>", noSideEffect, importc: "strlen".} proc c_memset(p: pointer, value: cint, size: int) {. header: "<string.h>", importc: "memset".} @@ -28,8 +28,8 @@ type final, incompleteStruct.} = object C_BinaryFile {.importc: "FILE", header: "<stdio.h>", final, incompleteStruct.} = object - C_TextFileStar = ptr CTextFile - C_BinaryFileStar = ptr CBinaryFile + C_TextFileStar = ptr C_TextFile + C_BinaryFileStar = ptr C_BinaryFile C_JmpBuf {.importc: "jmp_buf", header: "<setjmp.h>".} = object @@ -40,21 +40,40 @@ var # constants faked as variables: when not defined(SIGINT): - var - SIGINT {.importc: "SIGINT", nodecl.}: cint - SIGSEGV {.importc: "SIGSEGV", nodecl.}: cint - SIGABRT {.importc: "SIGABRT", nodecl.}: cint - SIGFPE {.importc: "SIGFPE", nodecl.}: cint - SIGILL {.importc: "SIGILL", nodecl.}: cint + when NoFakeVars: + when defined(windows): + const + SIGABRT = cint(22) + SIGFPE = cint(8) + SIGILL = cint(4) + SIGINT = cint(2) + SIGSEGV = cint(11) + SIGTERM = cint(15) + elif defined(macosx) or defined(linux): + const + SIGABRT = cint(6) + SIGFPE = cint(8) + SIGILL = cint(4) + SIGINT = cint(2) + SIGSEGV = cint(11) + SIGTERM = cint(15) + else: + {.error: "SIGABRT not ported to your platform".} + else: + var + SIGINT {.importc: "SIGINT", nodecl.}: cint + SIGSEGV {.importc: "SIGSEGV", nodecl.}: cint + SIGABRT {.importc: "SIGABRT", nodecl.}: cint + SIGFPE {.importc: "SIGFPE", nodecl.}: cint + SIGILL {.importc: "SIGILL", nodecl.}: cint when defined(macosx): - var - SIGBUS {.importc: "SIGBUS", nodecl.}: cint - # hopefully this does not lead to new bugs + when NoFakeVars: + const SIGBUS = cint(10) + else: + var SIGBUS {.importc: "SIGBUS", nodecl.}: cint else: - var - SIGBUS {.importc: "SIGSEGV", nodecl.}: cint - # only Mac OS X has this shit + template SIGBUS: expr = SIGSEGV proc c_longjmp(jmpb: C_JmpBuf, retval: cint) {. header: "<setjmp.h>", importc: "longjmp".} @@ -73,27 +92,27 @@ proc c_fgetc(stream: C_TextFileStar): int {.importc: "fgetc", header: "<stdio.h>".} proc c_ungetc(c: int, f: C_TextFileStar) {.importc: "ungetc", header: "<stdio.h>".} -proc c_putc(c: Char, stream: C_TextFileStar) {.importc: "putc", +proc c_putc(c: char, stream: C_TextFileStar) {.importc: "putc", header: "<stdio.h>".} -proc c_fprintf(f: C_TextFileStar, frmt: CString) {. +proc c_fprintf(f: C_TextFileStar, frmt: cstring) {. importc: "fprintf", header: "<stdio.h>", varargs.} -proc c_printf(frmt: CString) {. +proc c_printf(frmt: cstring) {. importc: "printf", header: "<stdio.h>", varargs.} proc c_fopen(filename, mode: cstring): C_TextFileStar {. importc: "fopen", header: "<stdio.h>".} proc c_fclose(f: C_TextFileStar) {.importc: "fclose", header: "<stdio.h>".} -proc c_sprintf(buf, frmt: CString) {.header: "<stdio.h>", +proc c_sprintf(buf, frmt: cstring) {.header: "<stdio.h>", importc: "sprintf", varargs, noSideEffect.} # we use it only in a way that cannot lead to security issues -proc c_fread(buf: Pointer, size, n: int, f: C_BinaryFileStar): int {. +proc c_fread(buf: pointer, size, n: int, f: C_BinaryFileStar): int {. importc: "fread", header: "<stdio.h>".} proc c_fseek(f: C_BinaryFileStar, offset: clong, whence: int): int {. importc: "fseek", header: "<stdio.h>".} -proc c_fwrite(buf: Pointer, size, n: int, f: C_BinaryFileStar): int {. +proc c_fwrite(buf: pointer, size, n: int, f: C_BinaryFileStar): int {. importc: "fwrite", header: "<stdio.h>".} proc c_exit(errorcode: cint) {.importc: "exit", header: "<stdlib.h>".} @@ -111,16 +130,22 @@ proc c_realloc(p: pointer, newsize: int): pointer {. when hostOS != "standalone": when not defined(errno): - var errno {.importc, header: "<errno.h>".}: cint ## error variable + when defined(NimrodVM): + var vmErrnoWrapper {.importc.}: ptr cint + template errno: expr = + bind vmErrnoWrapper + vmErrnoWrapper[] + else: + var errno {.importc, header: "<errno.h>".}: cint ## error variable proc strerror(errnum: cint): cstring {.importc, header: "<string.h>".} -proc c_remove(filename: CString): cint {. +proc c_remove(filename: cstring): cint {. importc: "remove", header: "<stdio.h>".} -proc c_rename(oldname, newname: CString): cint {. +proc c_rename(oldname, newname: cstring): cint {. importc: "rename", header: "<stdio.h>".} -proc c_system(cmd: CString): cint {.importc: "system", header: "<stdlib.h>".} -proc c_getenv(env: CString): CString {.importc: "getenv", header: "<stdlib.h>".} -proc c_putenv(env: CString): cint {.importc: "putenv", header: "<stdlib.h>".} +proc c_system(cmd: cstring): cint {.importc: "system", header: "<stdlib.h>".} +proc c_getenv(env: cstring): cstring {.importc: "getenv", header: "<stdlib.h>".} +proc c_putenv(env: cstring): cint {.importc: "putenv", header: "<stdlib.h>".} {.pop} diff --git a/lib/system/assign.nim b/lib/system/assign.nim index 3b43abcd1..bed8820be 100644 --- a/lib/system/assign.nim +++ b/lib/system/assign.nim @@ -7,10 +7,10 @@ # distribution, for details about the copyright. # -proc genericResetAux(dest: Pointer, n: ptr TNimNode) +proc genericResetAux(dest: pointer, n: ptr TNimNode) -proc genericAssignAux(dest, src: Pointer, mt: PNimType, shallow: bool) -proc genericAssignAux(dest, src: Pointer, n: ptr TNimNode, shallow: bool) = +proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) +proc genericAssignAux(dest, src: pointer, n: ptr TNimNode, shallow: bool) = var d = cast[TAddress](dest) s = cast[TAddress](src) @@ -37,37 +37,37 @@ proc genericAssignAux(dest, src: Pointer, n: ptr TNimNode, shallow: bool) = # echo "ugh memory corruption! ", n.kind # quit 1 -proc genericAssignAux(dest, src: Pointer, mt: PNimType, shallow: bool) = +proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) = var d = cast[TAddress](dest) s = cast[TAddress](src) sysAssert(mt != nil, "genericAssignAux 2") - case mt.Kind + case mt.kind of tyString: - var x = cast[ppointer](dest) - var s2 = cast[ppointer](s)[] + var x = cast[PPointer](dest) + var s2 = cast[PPointer](s)[] if s2 == nil or shallow or ( cast[PGenericSeq](s2).reserved and seqShallowFlag) != 0: unsureAsgnRef(x, s2) else: unsureAsgnRef(x, copyString(cast[NimString](s2))) of tySequence: - var s2 = cast[ppointer](src)[] + var s2 = cast[PPointer](src)[] var seq = cast[PGenericSeq](s2) - var x = cast[ppointer](dest) + var x = cast[PPointer](dest) if s2 == nil or shallow or (seq.reserved and seqShallowFlag) != 0: # this can happen! nil sequences are allowed unsureAsgnRef(x, s2) return sysAssert(dest != nil, "genericAssignAux 3") unsureAsgnRef(x, newSeq(mt, seq.len)) - var dst = cast[taddress](cast[ppointer](dest)[]) + var dst = cast[TAddress](cast[PPointer](dest)[]) for i in 0..seq.len-1: genericAssignAux( cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), - cast[pointer](cast[taddress](s2) +% i *% mt.base.size +% + cast[pointer](cast[TAddress](s2) +% i *% mt.base.size +% GenericSeqSize), - mt.Base, shallow) + mt.base, shallow) of tyObject: # we need to copy m_type field for tyObject, as it could be empty for # sequence reallocations: @@ -83,16 +83,16 @@ proc genericAssignAux(dest, src: Pointer, mt: PNimType, shallow: bool) = genericAssignAux(cast[pointer](d +% i*% mt.base.size), cast[pointer](s +% i*% mt.base.size), mt.base, shallow) of tyRef: - unsureAsgnRef(cast[ppointer](dest), cast[ppointer](s)[]) + unsureAsgnRef(cast[PPointer](dest), cast[PPointer](s)[]) else: copyMem(dest, src, mt.size) # copy raw bits -proc genericAssign(dest, src: Pointer, mt: PNimType) {.compilerProc.} = +proc genericAssign(dest, src: pointer, mt: PNimType) {.compilerProc.} = GC_disable() genericAssignAux(dest, src, mt, false) GC_enable() -proc genericShallowAssign(dest, src: Pointer, mt: PNimType) {.compilerProc.} = +proc genericShallowAssign(dest, src: pointer, mt: PNimType) {.compilerProc.} = GC_disable() genericAssignAux(dest, src, mt, true) GC_enable() @@ -126,7 +126,7 @@ when false: cprintf("%s %ld\n", k, t.size) debugNimType(t.base) -proc genericSeqAssign(dest, src: Pointer, mt: PNimType) {.compilerProc.} = +proc genericSeqAssign(dest, src: pointer, mt: PNimType) {.compilerProc.} = var src = src # ugly, but I like to stress the parser sometimes :-) genericAssign(dest, addr(src), mt) @@ -139,12 +139,12 @@ proc genericAssignOpenArray(dest, src: pointer, len: int, genericAssign(cast[pointer](d +% i*% mt.base.size), cast[pointer](s +% i*% mt.base.size), mt.base) -proc objectInit(dest: Pointer, typ: PNimType) {.compilerProc.} -proc objectInitAux(dest: Pointer, n: ptr TNimNode) = +proc objectInit(dest: pointer, typ: PNimType) {.compilerProc.} +proc objectInitAux(dest: pointer, n: ptr TNimNode) = var d = cast[TAddress](dest) case n.kind of nkNone: sysAssert(false, "objectInitAux") - of nkSLot: objectInit(cast[pointer](d +% n.offset), n.typ) + of nkSlot: objectInit(cast[pointer](d +% n.offset), n.typ) of nkList: for i in 0..n.len-1: objectInitAux(dest, n.sons[i]) @@ -152,7 +152,7 @@ proc objectInitAux(dest: Pointer, n: ptr TNimNode) = var m = selectBranch(dest, n) if m != nil: objectInitAux(dest, m) -proc objectInit(dest: Pointer, typ: PNimType) = +proc objectInit(dest: pointer, typ: PNimType) = # the generic init proc that takes care of initialization of complex # objects on the stack or heap var d = cast[TAddress](dest) @@ -168,12 +168,12 @@ proc objectInit(dest: Pointer, typ: PNimType) = of tyArray, tyArrayConstr: for i in 0..(typ.size div typ.base.size)-1: objectInit(cast[pointer](d +% i * typ.base.size), typ.base) - else: nil # nothing to do + else: discard # nothing to do # ---------------------- assign zero ----------------------------------------- when not defined(nimmixin): - proc destroy(x: int) = nil + proc destroy(x: int) = discard proc nimDestroyRange*[T](r: T) = # internal proc used for destroying sequences and arrays for i in countup(0, r.len - 1): destroy(r[i]) @@ -184,8 +184,8 @@ else: mixin destroy for i in countup(0, r.len - 1): destroy(r[i]) -proc genericReset(dest: Pointer, mt: PNimType) {.compilerProc.} -proc genericResetAux(dest: Pointer, n: ptr TNimNode) = +proc genericReset(dest: pointer, mt: PNimType) {.compilerProc.} +proc genericResetAux(dest: pointer, n: ptr TNimNode) = var d = cast[TAddress](dest) case n.kind of nkNone: sysAssert(false, "genericResetAux") @@ -197,12 +197,12 @@ proc genericResetAux(dest: Pointer, n: ptr TNimNode) = if m != nil: genericResetAux(dest, m) zeroMem(cast[pointer](d +% n.offset), n.typ.size) -proc genericReset(dest: Pointer, mt: PNimType) = +proc genericReset(dest: pointer, mt: PNimType) = var d = cast[TAddress](dest) sysAssert(mt != nil, "genericReset 2") - case mt.Kind + case mt.kind of tyString, tyRef, tySequence: - unsureAsgnRef(cast[ppointer](dest), nil) + unsureAsgnRef(cast[PPointer](dest), nil) of tyObject, tyTuple: # we don't need to reset m_type field for tyObject genericResetAux(dest, mt.node) diff --git a/lib/system/atomics.nim b/lib/system/atomics.nim index 36185e0a8..b1a96b209 100644 --- a/lib/system/atomics.nim +++ b/lib/system/atomics.nim @@ -7,62 +7,60 @@ # distribution, for details about the copyright. # -# Atomic operations for Nimrod. +## Atomic operations for Nimrod. -when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport: - +when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport: type AtomMemModel* = enum - ATOMIC_RELAXED, - ## No barriers or synchronization. - ATOMIC_CONSUME, - ## Data dependency only for both barrier and synchronization with another thread. - ATOMIC_ACQUIRE, - ## Barrier to hoisting of code and synchronizes with release (or stronger) - ## semantic stores from another thread. - ATOMIC_RELEASE, - ## Barrier to sinking of code and synchronizes with acquire (or stronger) - ## semantic loads from another thread. - ATOMIC_ACQ_REL, - ## Full barrier in both directions and synchronizes with acquire loads - ## and release stores in another thread. - ATOMIC_SEQ_CST - ## Full barrier in both directions and synchronizes with acquire loads - ## and release stores in all threads. + ATOMIC_RELAXED, ## No barriers or synchronization. + ATOMIC_CONSUME, ## Data dependency only for both barrier and + ## synchronization with another thread. + ATOMIC_ACQUIRE, ## Barrier to hoisting of code and synchronizes with + ## release (or stronger) + ## semantic stores from another thread. + ATOMIC_RELEASE, ## Barrier to sinking of code and synchronizes with + ## acquire (or stronger) + ## semantic loads from another thread. + ATOMIC_ACQ_REL, ## Full barrier in both directions and synchronizes + ## with acquire loads + ## and release stores in another thread. + ATOMIC_SEQ_CST ## Full barrier in both directions and synchronizes + ## with acquire loads + ## and release stores in all threads. TAtomType* = TNumber|pointer|ptr|char - ## Type Class representing valid types for use with atomic procs + ## Type Class representing valid types for use with atomic procs - proc atomic_load_n*[T: TAtomType](p: ptr T, mem: AtomMemModel): T {. + proc atomicLoadN*[T: TAtomType](p: ptr T, mem: AtomMemModel): T {. importc: "__atomic_load_n", nodecl.} ## This proc implements an atomic load operation. It returns the contents at p. ## ATOMIC_RELAXED, ATOMIC_SEQ_CST, ATOMIC_ACQUIRE, ATOMIC_CONSUME. - proc atomic_load*[T: TAtomType](p: ptr T, ret: ptr T, mem: AtomMemModel) {. + proc atomicLoad*[T: TAtomType](p, ret: ptr T, mem: AtomMemModel) {. importc: "__atomic_load", nodecl.} ## This is the generic version of an atomic load. It returns the contents at p in ret. - proc atomic_store_n*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel) {. + proc atomicStoreN*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel) {. importc: "__atomic_store_n", nodecl.} ## This proc implements an atomic store operation. It writes val at p. ## ATOMIC_RELAXED, ATOMIC_SEQ_CST, and ATOMIC_RELEASE. - proc atomic_store*[T: TAtomType](p: ptr T, val: ptr T, mem: AtomMemModel) {. + proc atomicStore*[T: TAtomType](p, val: ptr T, mem: AtomMemModel) {. importc: "__atomic_store", nodecl.} ## This is the generic version of an atomic store. It stores the value of val at p - proc atomic_exchange_n*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. + proc atomicExchangeN*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. importc: "__atomic_exchange_n", nodecl.} ## This proc implements an atomic exchange operation. It writes val at p, ## and returns the previous contents at p. ## ATOMIC_RELAXED, ATOMIC_SEQ_CST, ATOMIC_ACQUIRE, ATOMIC_RELEASE, ATOMIC_ACQ_REL - proc atomic_exchange*[T: TAtomType](p: ptr T, val: ptr T, ret: ptr T, mem: AtomMemModel) {. + proc atomicExchange*[T: TAtomType](p, val, ret: ptr T, mem: AtomMemModel) {. importc: "__atomic_exchange", nodecl.} ## This is the generic version of an atomic exchange. It stores the contents at val at p. ## The original value at p is copied into ret. - proc atomic_compare_exchange_n*[T: TAtomType](p: ptr T, expected: ptr T, desired: T, + proc atomicCompareExchangeN*[T: TAtomType](p, expected: ptr T, desired: T, weak: bool, success_memmodel: AtomMemModel, failure_memmodel: AtomMemModel): bool {. importc: "__atomic_compare_exchange_n ", nodecl.} ## This proc implements an atomic compare and exchange operation. This compares the @@ -78,7 +76,7 @@ when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport: ## cannot be __ATOMIC_RELEASE nor __ATOMIC_ACQ_REL. It also cannot be a stronger model ## than that specified by success_memmodel. - proc atomic_compare_exchange*[T: TAtomType](p: ptr T, expected: ptr T, desired: ptr T, + proc atomicCompareExchange*[T: TAtomType](p, expected, desired: ptr T, weak: bool, success_memmodel: AtomMemModel, failure_memmodel: AtomMemModel): bool {. importc: "__atomic_compare_exchange_n ", nodecl.} ## This proc implements the generic version of atomic_compare_exchange. @@ -86,58 +84,58 @@ when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport: ## value is also a pointer. ## Perform the operation return the new value, all memory models are valid - proc atomic_add_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. + proc atomicAddFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. importc: "__atomic_add_fetch", nodecl.} - proc atomic_sub_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. + proc atomicSubFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. importc: "__atomic_sub_fetch", nodecl.} - proc atomic_or_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. + proc atomicOrFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. importc: "__atomic_or_fetch ", nodecl.} - proc atomic_and_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. + proc atomicAndFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. importc: "__atomic_and_fetch", nodecl.} - proc atomic_xor_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. + proc atomicXorFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. importc: "__atomic_xor_fetch", nodecl.} - proc atomic_nand_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. + proc atomicNandFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. importc: "__atomic_nand_fetch ", nodecl.} ## Perform the operation return the old value, all memory models are valid - proc atomic_fetch_add*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. - importc: "__atomic_fetch_add ", nodecl.} - proc atomic_fetch_sub*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. - importc: "__atomic_fetch_sub ", nodecl.} - proc atomic_fetch_or*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. - importc: "__atomic_fetch_or ", nodecl.} - proc atomic_fetch_and*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. - importc: "__atomic_fetch_and ", nodecl.} - proc atomic_fetch_xor*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. - importc: "__atomic_fetch_xor ", nodecl.} - proc atomic_fetch_nand*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. + proc atomicFetchAdd*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. + importc: "__atomic_fetch_add", nodecl.} + proc atomicFetchSub*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. + importc: "__atomic_fetch_sub", nodecl.} + proc atomicFetchOr*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. + importc: "__atomic_fetch_or", nodecl.} + proc atomicFetchAnd*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. + importc: "__atomic_fetch_and", nodecl.} + proc atomicFetchXor*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. + importc: "__atomic_fetch_xor", nodecl.} + proc atomicFetchNand*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. importc: "__atomic_fetch_nand", nodecl.} - proc atomic_test_and_set*(p: pointer, mem: AtomMemModel): bool {. - importc: "__atomic_test_and_set ", nodecl.} + proc atomicTestAndSet*(p: pointer, mem: AtomMemModel): bool {. + importc: "__atomic_test_and_set", nodecl.} ## This built-in function performs an atomic test-and-set operation on the byte at p. ## The byte is set to some implementation defined nonzero “set” value and the return ## value is true if and only if the previous contents were “set”. ## All memory models are valid. - proc atomic_clear*(p: pointer, mem: AtomMemModel) {. + proc atomicClear*(p: pointer, mem: AtomMemModel) {. importc: "__atomic_clear", nodecl.} ## This built-in function performs an atomic clear operation at p. ## After the operation, at p contains 0. ## ATOMIC_RELAXED, ATOMIC_SEQ_CST, ATOMIC_RELEASE - proc atomic_thread_fence*(mem: AtomMemModel) {. - importc: "__atomic_thread_fence ", nodecl.} + proc atomicThreadFence*(mem: AtomMemModel) {. + importc: "__atomic_thread_fence", nodecl.} ## This built-in function acts as a synchronization fence between threads based ## on the specified memory model. All memory orders are valid. - proc atomic_signal_fence*(mem: AtomMemModel) {. - importc: "__atomic_signal_fence ", nodecl.} + proc atomicSignalFence*(mem: AtomMemModel) {. + importc: "__atomic_signal_fence", nodecl.} ## This built-in function acts as a synchronization fence between a thread and ## signal handlers based in the same thread. All memory orders are valid. - proc atomic_always_lock_free*(size: int, p: pointer): bool {. - importc: "__atomic_always_lock_free ", nodecl.} + proc atomicAlwaysLockFree*(size: int, p: pointer): bool {. + importc: "__atomic_always_lock_free", nodecl.} ## This built-in function returns true if objects of size bytes always generate ## lock free atomic instructions for the target architecture. size must resolve ## to a compile-time constant and the result also resolves to a compile-time constant. @@ -145,8 +143,8 @@ when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport: ## A value of 0 indicates typical alignment should be used. The compiler may also ## ignore this parameter. - proc atomic_is_lock_free*(size: int, p: pointer): bool {. - importc: "__atomic_is_lock_free ", nodecl.} + proc atomicIsLockFree*(size: int, p: pointer): bool {. + importc: "__atomic_is_lock_free", nodecl.} ## This built-in function returns true if objects of size bytes always generate ## lock free atomic instructions for the target architecture. If it is not known ## to be lock free a call is made to a runtime routine named __atomic_is_lock_free. @@ -154,19 +152,14 @@ when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport: ## A value of 0 indicates typical alignment should be used. The compiler may also ## ignore this parameter. - - elif defined(vcc) and hasThreadSupport: - proc add_and_fetch*(p: ptr int, val: int): int {. + proc addAndFetch*(p: ptr int, val: int): int {. importc: "NimXadd", nodecl.} else: - proc add_and_fetch*(p: ptr int, val: int): int {.inline.} = + proc addAndFetch*(p: ptr int, val: int): int {.inline.} = inc(p[], val) result = p[] - - - # atomic compare and swap (CAS) funcitons to implement lock-free algorithms #if defined(windows) and not defined(gcc) and hasThreadSupport: @@ -183,7 +176,7 @@ else: #elif not hasThreadSupport: # proc compareAndSwap*[T](mem: ptr T, -# expected: T, newValue: T): bool {.inline.} = +# expected: T, newValue: T): bool {.inline.} = # ## Returns true if successfully set value at mem to newValue when value # ## at mem == expected # var oldval = mem[] @@ -209,7 +202,4 @@ proc atomicDec*(memLoc: var int, x: int = 1): int = result = atomic_add_fetch(memLoc.addr, -x, ATOMIC_RELAXED) else: dec(memLoc, x) - result = memLoc - - - + result = memLoc diff --git a/lib/system/avltree.nim b/lib/system/avltree.nim index 6a268b453..fc965d6aa 100644 --- a/lib/system/avltree.nim +++ b/lib/system/avltree.nim @@ -9,30 +9,30 @@ # not really an AVL tree anymore, but still balanced ... -template IsBottom(n: PAvlNode): bool = n == bottom +template isBottom(n: PAvlNode): bool = n == bottom proc lowGauge(n: PAvlNode): int = var it = n - while not IsBottom(it): + while not isBottom(it): result = it.key it = it.link[0] proc highGauge(n: PAvlNode): int = result = -1 var it = n - while not IsBottom(it): + while not isBottom(it): result = it.upperBound it = it.link[1] proc find(root: PAvlNode, key: int): PAvlNode = var it = root - while not IsBottom(it): + while not isBottom(it): if it.key == key: return it it = it.link[ord(it.key <% key)] proc inRange(root: PAvlNode, key: int): PAvlNode = var it = root - while not IsBottom(it): + while not isBottom(it): if it.key <=% key and key <% it.upperBound: return it it = it.link[ord(it.key <% key)] diff --git a/lib/system/cellsets.nim b/lib/system/cellsets.nim index 7ad814da4..9a22ed0c5 100644 --- a/lib/system/cellsets.nim +++ b/lib/system/cellsets.nim @@ -43,15 +43,15 @@ type proc contains(s: TCellSeq, c: PCell): bool {.inline.} = for i in 0 .. s.len-1: - if s.d[i] == c: return True - return False + if s.d[i] == c: return true + return false proc add(s: var TCellSeq, c: PCell) {.inline.} = if s.len >= s.cap: s.cap = s.cap * 3 div 2 - var d = cast[PCellArray](Alloc(s.cap * sizeof(PCell))) + var d = cast[PCellArray](alloc(s.cap * sizeof(PCell))) copyMem(d, s.d, s.len * sizeof(PCell)) - Dealloc(s.d) + dealloc(s.d) s.d = d # XXX: realloc? s.d[s.len] = c @@ -60,10 +60,10 @@ proc add(s: var TCellSeq, c: PCell) {.inline.} = proc init(s: var TCellSeq, cap: int = 1024) = s.len = 0 s.cap = cap - s.d = cast[PCellArray](Alloc0(cap * sizeof(PCell))) + s.d = cast[PCellArray](alloc0(cap * sizeof(PCell))) proc deinit(s: var TCellSeq) = - Dealloc(s.d) + dealloc(s.d) s.d = nil s.len = 0 s.cap = 0 @@ -73,20 +73,20 @@ proc deinit(s: var TCellSeq) = const InitCellSetSize = 1024 # must be a power of two! -proc Init(s: var TCellSet) = - s.data = cast[PPageDescArray](Alloc0(InitCellSetSize * sizeof(PPageDesc))) +proc init(s: var TCellSet) = + s.data = cast[PPageDescArray](alloc0(InitCellSetSize * sizeof(PPageDesc))) s.max = InitCellSetSize-1 s.counter = 0 s.head = nil -proc Deinit(s: var TCellSet) = +proc deinit(s: var TCellSet) = var it = s.head while it != nil: var n = it.next - Dealloc(it) + dealloc(it) it = n s.head = nil # play it safe here - Dealloc(s.data) + dealloc(s.data) s.data = nil s.counter = 0 @@ -96,14 +96,14 @@ proc nextTry(h, maxHash: int): int {.inline.} = # generates each int in range(maxHash) exactly once (see any text on # random-number generation for proof). -proc CellSetGet(t: TCellSet, key: TAddress): PPageDesc = +proc cellSetGet(t: TCellSet, key: TAddress): PPageDesc = var h = cast[int](key) and t.max while t.data[h] != nil: if t.data[h].key == key: return t.data[h] h = nextTry(h, t.max) return nil -proc CellSetRawInsert(t: TCellSet, data: PPageDescArray, desc: PPageDesc) = +proc cellSetRawInsert(t: TCellSet, data: PPageDescArray, desc: PPageDesc) = var h = cast[int](desc.key) and t.max while data[h] != nil: sysAssert(data[h] != desc, "CellSetRawInsert 1") @@ -111,17 +111,17 @@ proc CellSetRawInsert(t: TCellSet, data: PPageDescArray, desc: PPageDesc) = sysAssert(data[h] == nil, "CellSetRawInsert 2") data[h] = desc -proc CellSetEnlarge(t: var TCellSet) = +proc cellSetEnlarge(t: var TCellSet) = var oldMax = t.max t.max = ((t.max+1)*2)-1 - var n = cast[PPageDescArray](Alloc0((t.max + 1) * sizeof(PPageDesc))) - for i in 0 .. oldmax: + var n = cast[PPageDescArray](alloc0((t.max + 1) * sizeof(PPageDesc))) + for i in 0 .. oldMax: if t.data[i] != nil: - CellSetRawInsert(t, n, t.data[i]) - Dealloc(t.data) + cellSetRawInsert(t, n, t.data[i]) + dealloc(t.data) t.data = n -proc CellSetPut(t: var TCellSet, key: TAddress): PPageDesc = +proc cellSetPut(t: var TCellSet, key: TAddress): PPageDesc = var h = cast[int](key) and t.max while true: var x = t.data[h] @@ -130,13 +130,13 @@ proc CellSetPut(t: var TCellSet, key: TAddress): PPageDesc = h = nextTry(h, t.max) if ((t.max+1)*2 < t.counter*3) or ((t.max+1)-t.counter < 4): - CellSetEnlarge(t) + cellSetEnlarge(t) inc(t.counter) h = cast[int](key) and t.max while t.data[h] != nil: h = nextTry(h, t.max) sysAssert(t.data[h] == nil, "CellSetPut") # the new page descriptor goes into result - result = cast[PPageDesc](Alloc0(sizeof(TPageDesc))) + result = cast[PPageDesc](alloc0(sizeof(TPageDesc))) result.next = t.head result.key = key t.head = result @@ -146,7 +146,7 @@ proc CellSetPut(t: var TCellSet, key: TAddress): PPageDesc = proc contains(s: TCellSet, cell: PCell): bool = var u = cast[TAddress](cell) - var t = CellSetGet(s, u shr PageShift) + var t = cellSetGet(s, u shr PageShift) if t != nil: u = (u %% PageSize) /% MemAlign result = (t.bits[u shr IntShift] and (1 shl (u and IntMask))) != 0 @@ -155,13 +155,13 @@ proc contains(s: TCellSet, cell: PCell): bool = proc incl(s: var TCellSet, cell: PCell) {.noinline.} = var u = cast[TAddress](cell) - var t = CellSetPut(s, u shr PageShift) + var t = cellSetPut(s, u shr PageShift) u = (u %% PageSize) /% MemAlign t.bits[u shr IntShift] = t.bits[u shr IntShift] or (1 shl (u and IntMask)) proc excl(s: var TCellSet, cell: PCell) = var u = cast[TAddress](cell) - var t = CellSetGet(s, u shr PageShift) + var t = cellSetGet(s, u shr PageShift) if t != nil: u = (u %% PageSize) /% MemAlign t.bits[u shr IntShift] = (t.bits[u shr IntShift] and @@ -169,7 +169,7 @@ proc excl(s: var TCellSet, cell: PCell) = proc containsOrIncl(s: var TCellSet, cell: PCell): bool = var u = cast[TAddress](cell) - var t = CellSetGet(s, u shr PageShift) + var t = cellSetGet(s, u shr PageShift) if t != nil: u = (u %% PageSize) /% MemAlign result = (t.bits[u shr IntShift] and (1 shl (u and IntMask))) != 0 @@ -177,7 +177,7 @@ proc containsOrIncl(s: var TCellSet, cell: PCell): bool = t.bits[u shr IntShift] = t.bits[u shr IntShift] or (1 shl (u and IntMask)) else: - Incl(s, cell) + incl(s, cell) result = false iterator elements(t: TCellSet): PCell {.inline.} = @@ -201,7 +201,7 @@ iterator elements(t: TCellSet): PCell {.inline.} = iterator elementsExcept(t, s: TCellSet): PCell {.inline.} = var r = t.head while r != nil: - let ss = CellSetGet(s, r.key) + let ss = cellSetGet(s, r.key) var i = 0 while i <= high(r.bits): var w = r.bits[i] diff --git a/lib/system/channels.nim b/lib/system/channels.nim index 9c3cc93e0..bf949529b 100644 --- a/lib/system/channels.nim +++ b/lib/system/channels.nim @@ -48,9 +48,9 @@ proc deinitRawChannel(p: pointer) = deinitSys(c.lock) deinitSysCond(c.cond) -proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel, +proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, mode: TLoadStoreMode) -proc storeAux(dest, src: Pointer, n: ptr TNimNode, t: PRawChannel, +proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel, mode: TLoadStoreMode) = var d = cast[TAddress](dest) @@ -67,7 +67,7 @@ proc storeAux(dest, src: Pointer, n: ptr TNimNode, t: PRawChannel, if m != nil: storeAux(dest, src, m, t, mode) of nkNone: sysAssert(false, "storeAux") -proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel, +proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, mode: TLoadStoreMode) = var d = cast[TAddress](dest) @@ -82,7 +82,7 @@ proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel, x[] = nil else: var ss = cast[NimString](s2) - var ns = cast[NimString](Alloc(t.region, ss.len+1 + GenericSeqSize)) + var ns = cast[NimString](alloc(t.region, ss.len+1 + GenericSeqSize)) copyMem(ns, ss, ss.len+1 + GenericSeqSize) x[] = ns else: @@ -92,7 +92,7 @@ proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel, unsureAsgnRef(x, s2) else: unsureAsgnRef(x, copyString(cast[NimString](s2))) - Dealloc(t.region, s2) + dealloc(t.region, s2) of tySequence: var s2 = cast[ppointer](src)[] var seq = cast[PGenericSeq](s2) @@ -105,7 +105,7 @@ proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel, else: sysAssert(dest != nil, "dest == nil") if mode == mStore: - x[] = Alloc(t.region, seq.len *% mt.base.size +% GenericSeqSize) + x[] = alloc(t.region, seq.len *% mt.base.size +% GenericSeqSize) else: unsureAsgnRef(x, newObj(mt, seq.len * mt.base.size + GenericSeqSize)) var dst = cast[taddress](cast[ppointer](dest)[]) @@ -118,7 +118,7 @@ proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel, var dstseq = cast[PGenericSeq](dst) dstseq.len = seq.len dstseq.reserved = seq.len - if mode != mStore: Dealloc(t.region, s2) + if mode != mStore: dealloc(t.region, s2) of tyObject: # copy type field: var pint = cast[ptr PNimType](dest) @@ -143,7 +143,7 @@ proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel, unsureAsgnRef(x, nil) else: if mode == mStore: - x[] = Alloc(t.region, mt.base.size) + x[] = alloc(t.region, mt.base.size) else: # XXX we should use the dynamic type here too, but that is not stored # in the inbox at all --> use source[]'s object type? but how? we need @@ -151,7 +151,7 @@ proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel, var obj = newObj(mt, mt.base.size) unsureAsgnRef(x, obj) storeAux(x[], s, mt.base, t, mode) - if mode != mStore: Dealloc(t.region, s) + if mode != mStore: dealloc(t.region, s) else: copyMem(dest, src, mt.size) # copy raw bits @@ -161,7 +161,7 @@ proc rawSend(q: PRawChannel, data: pointer, typ: PNimType) = if q.count >= cap: # start with capacity for 2 entries in the queue: if cap == 0: cap = 1 - var n = cast[pbytes](Alloc0(q.region, cap*2*typ.size)) + var n = cast[pbytes](alloc0(q.region, cap*2*typ.size)) var z = 0 var i = q.rd var c = q.count @@ -170,7 +170,7 @@ proc rawSend(q: PRawChannel, data: pointer, typ: PNimType) = copyMem(addr(n[z*typ.size]), addr(q.data[i*typ.size]), typ.size) i = (i + 1) and q.mask inc z - if q.data != nil: Dealloc(q.region, q.data) + if q.data != nil: dealloc(q.region, q.data) q.data = n q.mask = cap*2 - 1 q.wr = q.count @@ -200,7 +200,7 @@ template sendImpl(q: expr) {.immediate.} = rawSend(q, addr(m), typ) q.elemType = typ releaseSys(q.lock) - SignalSysCond(q.cond) + signalSysCond(q.cond) proc send*[TMsg](c: var TChannel[TMsg], msg: TMsg) = ## sends a message to a thread. `msg` is deeply copied. @@ -212,7 +212,7 @@ proc llRecv(q: PRawChannel, res: pointer, typ: PNimType) = acquireSys(q.lock) q.ready = true while q.count <= 0: - WaitSysCond(q.cond, q.lock) + waitSysCond(q.cond, q.lock) q.ready = false if typ != q.elemType: releaseSys(q.lock) diff --git a/lib/system/chcks.nim b/lib/system/chcks.nim index e78129483..f29e222e8 100644 --- a/lib/system/chcks.nim +++ b/lib/system/chcks.nim @@ -9,8 +9,8 @@ # Implementation of some runtime checks. -proc raiseRangeError(val: biggestInt) {.compilerproc, noreturn, noinline.} = - when hostOs == "standalone": +proc raiseRangeError(val: BiggestInt) {.compilerproc, noreturn, noinline.} = + when hostOS == "standalone": sysFatal(EOutOfRange, "value out of range") else: sysFatal(EOutOfRange, "value out of range: ", $val) diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim index 6a80369b9..9ef1a99ca 100644 --- a/lib/system/dyncalls.nim +++ b/lib/system/dyncalls.nim @@ -28,7 +28,7 @@ proc nimLoadLibraryError(path: string) = stdout.rawWrite("\n") quit(1) -proc ProcAddrError(name: cstring) {.noinline.} = +proc procAddrError(name: cstring) {.noinline.} = # carefully written to avoid memory allocation: stdout.rawWrite("could not import: ") stdout.write(name) @@ -56,7 +56,7 @@ when defined(posix): RTLD_NOW {.importc: "RTLD_NOW", header: "<dlfcn.h>".}: int proc dlclose(lib: TLibHandle) {.importc, header: "<dlfcn.h>".} - proc dlopen(path: CString, mode: int): TLibHandle {. + proc dlopen(path: cstring, mode: int): TLibHandle {. importc, header: "<dlfcn.h>".} proc dlsym(lib: TLibHandle, name: cstring): TProcAddr {. importc, header: "<dlfcn.h>".} @@ -72,7 +72,7 @@ when defined(posix): proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr = result = dlsym(lib, name) - if result == nil: ProcAddrError(name) + if result == nil: procAddrError(name) elif defined(windows) or defined(dos): # @@ -83,21 +83,22 @@ elif defined(windows) or defined(dos): type THINSTANCE {.importc: "HINSTANCE".} = pointer - proc FreeLibrary(lib: THINSTANCE) {.importc, header: "<windows.h>", stdcall.} + proc freeLibrary(lib: THINSTANCE) {. + importc: "FreeLibrary", header: "<windows.h>", stdcall.} proc winLoadLibrary(path: cstring): THINSTANCE {. importc: "LoadLibraryA", header: "<windows.h>", stdcall.} - proc GetProcAddress(lib: THINSTANCE, name: cstring): TProcAddr {. + proc getProcAddress(lib: THINSTANCE, name: cstring): TProcAddr {. importc: "GetProcAddress", header: "<windows.h>", stdcall.} proc nimUnloadLibrary(lib: TLibHandle) = - FreeLibrary(cast[THINSTANCE](lib)) + freeLibrary(cast[THINSTANCE](lib)) proc nimLoadLibrary(path: string): TLibHandle = result = cast[TLibHandle](winLoadLibrary(path)) proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr = - result = GetProcAddress(cast[THINSTANCE](lib), name) - if result == nil: ProcAddrError(name) + result = getProcAddress(cast[THINSTANCE](lib), name) + if result == nil: procAddrError(name) elif defined(mac): # diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index 9b6a64fb0..1964e4d3d 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -17,7 +17,7 @@ var ## Unstable API. when not defined(windows) or not defined(guiapp): - proc writeToStdErr(msg: CString) = write(stdmsg, msg) + proc writeToStdErr(msg: cstring) = write(stdmsg, msg) else: proc MessageBoxA(hWnd: cint, lpText, lpCaption: cstring, uType: int): int32 {. @@ -240,7 +240,7 @@ proc raiseExceptionAux(e: ref E_Base) = showErrorMessage(buf) quitOrDebug() -proc raiseException(e: ref E_Base, ename: CString) {.compilerRtl.} = +proc raiseException(e: ref E_Base, ename: cstring) {.compilerRtl.} = e.name = ename when hasSomeStackTrace: e.trace = "" @@ -253,7 +253,7 @@ proc reraiseException() {.compilerRtl.} = else: raiseExceptionAux(currException) -proc WriteStackTrace() = +proc writeStackTrace() = when hasSomeStackTrace: var s = "" rawWriteStackTrace(s) @@ -280,7 +280,7 @@ when defined(endb): when not defined(noSignalHandler): proc signalHandler(sig: cint) {.exportc: "signalHandler", noconv.} = - template processSignal(s, action: expr) {.immediate.} = + template processSignal(s, action: expr) {.immediate, dirty.} = if s == SIGINT: action("SIGINT: Interrupted by Ctrl-C.\n") elif s == SIGSEGV: action("SIGSEGV: Illegal storage access. (Attempt to read from nil?)\n") diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 68e8b423d..0fb9bb482 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -84,7 +84,7 @@ var gch {.rtlThreadVar.}: TGcHeap when not defined(useNimRtl): - InstantiateForRegion(gch.region) + instantiateForRegion(gch.region) template acquire(gch: TGcHeap) = when hasThreadSupport and hasSharedHeap: @@ -132,9 +132,9 @@ when BitsPerPage mod (sizeof(int)*8) != 0: template color(c): expr = c.refCount and colorMask template setColor(c, col) = when col == rcBlack: - c.refcount = c.refCount and not colorMask + c.refcount = c.refcount and not colorMask else: - c.refcount = c.refCount and not colorMask or col + c.refcount = c.refcount and not colorMask or col proc writeCell(msg: cstring, c: PCell) = var kind = -1 @@ -151,10 +151,10 @@ template gcTrace(cell, state: expr): stmt {.immediate.} = # forward declarations: proc collectCT(gch: var TGcHeap) -proc IsOnStack*(p: pointer): bool {.noinline.} +proc isOnStack*(p: pointer): bool {.noinline.} proc forAllChildren(cell: PCell, op: TWalkOp) proc doOperation(p: pointer, op: TWalkOp) -proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp) +proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) # we need the prototype here for debugging purposes when hasThreadSupport and hasSharedHeap: @@ -162,9 +162,9 @@ when hasThreadSupport and hasSharedHeap: template `++`(x: expr): stmt = discard atomicInc(x, rcIncrement) else: template `--`(x: expr): expr = - Dec(x, rcIncrement) + dec(x, rcIncrement) x <% rcIncrement - template `++`(x: expr): stmt = Inc(x, rcIncrement) + template `++`(x: expr): stmt = inc(x, rcIncrement) proc prepareDealloc(cell: PCell) = when useMarkForDebug: @@ -203,7 +203,7 @@ proc decRef(c: PCell) {.inline.} = gcAssert(c.refcount >=% rcIncrement, "decRef") if --c.refcount: rtlAddZCT(c) - elif canBeCycleRoot(c): + elif canbeCycleRoot(c): # unfortunately this is necessary here too, because a cycle might just # have been broken up and we could recycle it. rtlAddCycleRoot(c) @@ -211,10 +211,10 @@ proc decRef(c: PCell) {.inline.} = proc incRef(c: PCell) {.inline.} = gcAssert(isAllocatedPtr(gch.region, c), "incRef: interiorPtr") - c.refcount = c.refCount +% rcIncrement + c.refcount = c.refcount +% rcIncrement # and not colorMask #writeCell("incRef", c) - if canBeCycleRoot(c): + if canbeCycleRoot(c): rtlAddCycleRoot(c) proc nimGCref(p: pointer) {.compilerProc, inline.} = incRef(usrToCell(p)) @@ -235,7 +235,7 @@ proc nimGCunrefNoCycle(p: pointer) {.compilerProc, inline.} = sysAssert(allocInv(gch.region), "end nimGCunrefNoCycle 2") sysAssert(allocInv(gch.region), "end nimGCunrefNoCycle 5") -proc asgnRef(dest: ppointer, src: pointer) {.compilerProc, inline.} = +proc asgnRef(dest: PPointer, src: pointer) {.compilerProc, inline.} = # the code generator calls this proc! gcAssert(not isOnStack(dest), "asgnRef") # BUGFIX: first incRef then decRef! @@ -243,7 +243,7 @@ proc asgnRef(dest: ppointer, src: pointer) {.compilerProc, inline.} = if dest[] != nil: decRef(usrToCell(dest[])) dest[] = src -proc asgnRefNoCycle(dest: ppointer, src: pointer) {.compilerProc, inline.} = +proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerProc, inline.} = # the code generator calls this proc if it is known at compile time that no # cycle is possible. if src != nil: @@ -255,7 +255,7 @@ proc asgnRefNoCycle(dest: ppointer, src: pointer) {.compilerProc, inline.} = rtlAddZCT(c) dest[] = src -proc unsureAsgnRef(dest: ppointer, src: pointer) {.compilerProc.} = +proc unsureAsgnRef(dest: PPointer, src: pointer) {.compilerProc.} = # unsureAsgnRef updates the reference counters only if dest is not on the # stack. It is used by the code generator if it cannot decide wether a # reference is in the stack or not (this can happen for var parameters). @@ -318,7 +318,7 @@ proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) = # inlined for speed if n.sons[i].kind == nkSlot: if n.sons[i].typ.kind in {tyRef, tyString, tySequence}: - doOperation(cast[ppointer](d +% n.sons[i].offset)[], op) + doOperation(cast[PPointer](d +% n.sons[i].offset)[], op) else: forAllChildrenAux(cast[pointer](d +% n.sons[i].offset), n.sons[i].typ, op) @@ -329,19 +329,19 @@ proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) = if m != nil: forAllSlotsAux(dest, m, op) of nkNone: sysAssert(false, "forAllSlotsAux") -proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp) = +proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) = var d = cast[TAddress](dest) if dest == nil: return # nothing to do if ntfNoRefs notin mt.flags: - case mt.Kind + case mt.kind of tyRef, tyString, tySequence: # leaf: - doOperation(cast[ppointer](d)[], op) + doOperation(cast[PPointer](d)[], op) of tyObject, tyTuple: forAllSlotsAux(dest, mt.node, op) of tyArray, tyArrayConstr, tyOpenArray: for i in 0..(mt.size div mt.base.size)-1: forAllChildrenAux(cast[pointer](d +% i *% mt.base.size), mt.base, op) - else: nil + else: discard proc forAllChildren(cell: PCell, op: TWalkOp) = gcAssert(cell != nil, "forAllChildren: 1") @@ -352,7 +352,7 @@ proc forAllChildren(cell: PCell, op: TWalkOp) = if marker != nil: marker(cellToUsr(cell), op.int) else: - case cell.typ.Kind + case cell.typ.kind of tyRef: # common case forAllChildrenAux(cellToUsr(cell), cell.typ.base, op) of tySequence: @@ -519,7 +519,7 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer = d[j] = res break dec(j) - if canBeCycleRoot(ol): excl(gch.cycleRoots, ol) + if canbeCycleRoot(ol): excl(gch.cycleRoots, ol) when logGC: writeCell("growObj old cell", ol) writeCell("growObj new cell", res) @@ -573,7 +573,7 @@ proc scan(s: PCell) = proc collectWhite(s: PCell) = if s.color == rcWhite and s notin gch.cycleRoots: - s.setcolor(rcBlack) + s.setColor(rcBlack) forAllChildren(s, waCollectWhite) freeCyclicCell(gch, s) @@ -582,7 +582,7 @@ proc markRoots(gch: var TGcHeap) = for s in elements(gch.cycleRoots): #writeCell("markRoot", s) inc tabSize - if s.color == rcPurple and s.refCount >=% rcIncrement: + if s.color == rcPurple and s.refcount >=% rcIncrement: markGray(s) else: excl(gch.cycleRoots, s) @@ -669,7 +669,7 @@ proc doOperation(p: pointer, op: TWalkOp) = proc nimGCvisit(d: pointer, op: int) {.compilerRtl.} = doOperation(d, TWalkOp(op)) -proc CollectZCT(gch: var TGcHeap): bool +proc collectZCT(gch: var TGcHeap): bool when useMarkForDebug or useBackupGc: proc markStackAndRegistersForSweep(gch: var TGcHeap) {.noinline, cdecl.} @@ -869,7 +869,7 @@ else: sp = sp +% sizeof(pointer)*8 # last few entries: while sp <=% max: - gcMark(gch, cast[ppointer](sp)[]) + gcMark(gch, cast[PPointer](sp)[]) sp = sp +% sizeof(pointer) proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} = @@ -891,7 +891,7 @@ proc collectZCT(gch: var TGcHeap): bool = const workPackage = 100 var L = addr(gch.zct.len) - when withRealtime: + when withRealTime: var steps = workPackage var t0: TTicks if gch.maxPause > 0: t0 = getticks() @@ -904,7 +904,7 @@ proc collectZCT(gch: var TGcHeap): bool = c.refcount = c.refcount and not ZctFlag gch.zct.d[0] = gch.zct.d[L[] - 1] dec(L[]) - when withRealtime: dec steps + when withRealTime: dec steps if c.refcount <% rcIncrement: # It may have a RC > 0, if it is in the hardware stack or # it has not been removed yet from the ZCT. This is because @@ -913,7 +913,7 @@ proc collectZCT(gch: var TGcHeap): bool = # In any case, it should be removed from the ZCT. But not # freed. **KEEP THIS IN MIND WHEN MAKING THIS INCREMENTAL!** when cycleGC: - if canBeCycleRoot(c): excl(gch.cycleRoots, c) + if canbeCycleRoot(c): excl(gch.cycleRoots, c) when logGC: writeCell("zct dealloc cell", c) gcTrace(c, csZctFreed) # We are about to free the object, call the finalizer BEFORE its @@ -927,7 +927,7 @@ proc collectZCT(gch: var TGcHeap): bool = else: sysAssert(c.typ != nil, "collectZCT 2") zeroMem(c, sizeof(TCell)) - when withRealtime: + when withRealTime: if steps == 0: steps = workPackage if gch.maxPause > 0: @@ -952,7 +952,7 @@ proc unmarkStackAndRegisters(gch: var TGcHeap) = gch.decStack.len = 0 proc collectCTBody(gch: var TGcHeap) = - when withRealtime: + when withRealTime: let t0 = getticks() sysAssert(allocInv(gch.region), "collectCT: begin") @@ -970,12 +970,12 @@ proc collectCTBody(gch: var TGcHeap) = #discard collectZCT(gch) inc(gch.stat.cycleCollections) gch.cycleThreshold = max(InitialCycleThreshold, getOccupiedMem() * - cycleIncrease) + CycleIncrease) gch.stat.maxThreshold = max(gch.stat.maxThreshold, gch.cycleThreshold) unmarkStackAndRegisters(gch) sysAssert(allocInv(gch.region), "collectCT: end") - when withRealtime: + when withRealTime: let duration = getticks() - t0 gch.stat.maxPause = max(gch.stat.maxPause, duration) when defined(reportMissedDeadlines): @@ -997,7 +997,7 @@ proc collectCT(gch: var TGcHeap) = markForDebug(gch) collectCTBody(gch) -when withRealtime: +when withRealTime: proc toNano(x: int): TNanos {.inline.} = result = x * 1000 diff --git a/lib/system/hti.nim b/lib/system/hti.nim index a2d132dbf..9d8ece7df 100644 --- a/lib/system/hti.nim +++ b/lib/system/hti.nim @@ -69,7 +69,7 @@ type kind: TNimNodeKind offset: int typ: ptr TNimType - name: Cstring + name: cstring len: int sons: ptr array [0..0x7fff, ptr TNimNode] diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim index 942b6778e..a80fdad8f 100644 --- a/lib/system/mmdisp.nim +++ b/lib/system/mmdisp.nim @@ -33,7 +33,7 @@ const type PPointer = ptr pointer - TByteArray = array[0..1000_0000, byte] + TByteArray = array[0..1000_0000, Byte] PByte = ptr TByteArray PString = ptr string diff --git a/lib/system/repr.nim b/lib/system/repr.nim index a51864ac2..cd3f7c3f4 100644 --- a/lib/system/repr.nim +++ b/lib/system/repr.nim @@ -72,7 +72,7 @@ proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} = result = $e & " (invalid data!)" type - pbyteArray = ptr array[0.. 0xffff, int8] + PByteArray = ptr array[0.. 0xffff, int8] proc addSetElem(result: var string, elem: int, typ: PNimType) = case typ.kind @@ -96,7 +96,7 @@ proc reprSetAux(result: var string, p: pointer, typ: PNimType) = of 4: u = ze64(cast[ptr int32](p)[]) of 8: u = cast[ptr int64](p)[] else: - var a = cast[pbyteArray](p) + var a = cast[PByteArray](p) for i in 0 .. typ.size*8-1: if (ze(a[i div 8]) and (1 shl (i mod 8))) != 0: if elemCounter > 0: add result, ", " @@ -129,12 +129,12 @@ when not defined(useNimRtl): when hasThreadSupport and hasSharedHeap and defined(heapLock): AcquireSys(HeapLock) when defined(TCellSet): - Init(cl.marked) + init(cl.marked) cl.recdepth = -1 # default is to display everything! cl.indent = 0 proc deinitReprClosure(cl: var TReprClosure) = - when defined(TCellSet): Deinit(cl.marked) + when defined(TCellSet): deinit(cl.marked) when hasThreadSupport and hasSharedHeap and defined(heapLock): ReleaseSys(HeapLock) @@ -164,7 +164,7 @@ when not defined(useNimRtl): for i in 0..cast[PGenericSeq](p).len-1: if i > 0: add result, ", " reprAux(result, cast[pointer](cast[TAddress](p) + GenericSeqSize + i*bs), - typ.Base, cl) + typ.base, cl) add result, "]" proc reprRecordAux(result: var string, p: pointer, n: ptr TNimNode, @@ -224,17 +224,17 @@ when not defined(useNimRtl): reprRecord(result, p, t, cl) of tyRef, tyPtr: sysAssert(p != nil, "reprAux") - if cast[ppointer](p)[] == nil: add result, "nil" - else: reprRef(result, cast[ppointer](p)[], typ, cl) + if cast[PPointer](p)[] == nil: add result, "nil" + else: reprRef(result, cast[PPointer](p)[], typ, cl) of tySequence: - reprSequence(result, cast[ppointer](p)[], typ, cl) + reprSequence(result, cast[PPointer](p)[], typ, cl) of tyInt: add result, $(cast[ptr int](p)[]) - of tyInt8: add result, $int(cast[ptr Int8](p)[]) - of tyInt16: add result, $int(cast[ptr Int16](p)[]) - of tyInt32: add result, $int(cast[ptr Int32](p)[]) - of tyInt64: add result, $(cast[ptr Int64](p)[]) - of tyUInt8: add result, $ze(cast[ptr Int8](p)[]) - of tyUInt16: add result, $ze(cast[ptr Int16](p)[]) + of tyInt8: add result, $int(cast[ptr int8](p)[]) + of tyInt16: add result, $int(cast[ptr int16](p)[]) + of tyInt32: add result, $int(cast[ptr int32](p)[]) + of tyInt64: add result, $(cast[ptr int64](p)[]) + of tyUInt8: add result, $ze(cast[ptr int8](p)[]) + of tyUInt16: add result, $ze(cast[ptr int16](p)[]) of tyFloat: add result, $(cast[ptr float](p)[]) of tyFloat32: add result, $(cast[ptr float32](p)[]) @@ -246,8 +246,8 @@ when not defined(useNimRtl): of tyCString: reprStrAux(result, $(cast[ptr cstring](p)[])) of tyRange: reprAux(result, p, typ.base, cl) of tyProc, tyPointer: - if cast[ppointer](p)[] == nil: add result, "nil" - else: add result, reprPointer(cast[ppointer](p)[]) + if cast[PPointer](p)[] == nil: add result, "nil" + else: add result, reprPointer(cast[PPointer](p)[]) else: add result, "(invalid data!)" inc(cl.recdepth) diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim index a877f8b28..56e6a9e5f 100644 --- a/lib/system/sysio.nim +++ b/lib/system/sysio.nim @@ -24,16 +24,16 @@ proc fgetc(stream: TFile): cint {.importc: "fgetc", header: "<stdio.h>", tags: [FReadIO].} proc ungetc(c: cint, f: TFile) {.importc: "ungetc", header: "<stdio.h>", tags: [].} -proc putc(c: Char, stream: TFile) {.importc: "putc", header: "<stdio.h>", +proc putc(c: char, stream: TFile) {.importc: "putc", header: "<stdio.h>", tags: [FWriteIO].} -proc fprintf(f: TFile, frmt: CString) {.importc: "fprintf", +proc fprintf(f: TFile, frmt: cstring) {.importc: "fprintf", header: "<stdio.h>", varargs, tags: [FWriteIO].} proc strlen(c: cstring): int {. importc: "strlen", header: "<string.h>", tags: [].} # C routine that is used here: -proc fread(buf: Pointer, size, n: int, f: TFile): int {. +proc fread(buf: pointer, size, n: int, f: TFile): int {. importc: "fread", header: "<stdio.h>", tags: [FReadIO].} proc fseek(f: TFile, offset: clong, whence: int): int {. importc: "fseek", header: "<stdio.h>", tags: [].} @@ -45,12 +45,24 @@ proc setvbuf(stream: TFile, buf: pointer, typ, size: cint): cint {. proc write(f: TFile, c: cstring) = fputs(c, f) {.pop.} -var - IOFBF {.importc: "_IOFBF", nodecl.}: cint - IONBF {.importc: "_IONBF", nodecl.}: cint +when NoFakeVars: + when defined(windows): + const + IOFBF = cint(0) + IONBF = cint(4) + elif defined(macosx) or defined(linux): + const + IOFBF = cint(0) + IONBF = cint(2) + else: + {.error: "IOFBF not ported to your platform".} +else: + var + IOFBF {.importc: "_IOFBF", nodecl.}: cint + IONBF {.importc: "_IONBF", nodecl.}: cint const - buf_size = 4000 + BufSize = 4000 proc raiseEIO(msg: string) {.noinline, noreturn.} = sysFatal(EIO, msg) @@ -59,7 +71,7 @@ proc readLine(f: TFile, line: var TaintedString): bool = # of course this could be optimized a bit; but IO is slow anyway... # and it was difficult to get this CORRECT with Ansi C's methods setLen(line.string, 0) # reuse the buffer! - while True: + while true: var c = fgetc(f) if c < 0'i32: if line.len > 0: break @@ -82,8 +94,8 @@ proc write(f: TFile, i: int) = else: fprintf(f, "%ld", i) -proc write(f: TFile, i: biggestInt) = - when sizeof(biggestint) == 8: +proc write(f: TFile, i: BiggestInt) = + when sizeof(BiggestInt) == 8: fprintf(f, "%lld", i) else: fprintf(f, "%ld", i) @@ -92,9 +104,9 @@ proc write(f: TFile, b: bool) = if b: write(f, "true") else: write(f, "false") proc write(f: TFile, r: float32) = fprintf(f, "%g", r) -proc write(f: TFile, r: biggestFloat) = fprintf(f, "%g", r) +proc write(f: TFile, r: BiggestFloat) = fprintf(f, "%g", r) -proc write(f: TFile, c: Char) = putc(c, f) +proc write(f: TFile, c: char) = putc(c, f) proc write(f: TFile, a: varargs[string, `$`]) = for x in items(a): write(f, x) @@ -102,10 +114,10 @@ proc readAllBuffer(file: TFile): string = # This proc is for TFile we want to read but don't know how many # bytes we need to read before the buffer is empty. result = "" - var buffer = newString(buf_size) - var bytesRead = buf_size - while bytesRead == buf_size: - bytesRead = readBuffer(file, addr(buffer[0]), buf_size) + var buffer = newString(BufSize) + var bytesRead = BufSize + while bytesRead == BufSize: + bytesRead = readBuffer(file, addr(buffer[0]), BufSize) result.add(buffer) proc rawFileSize(file: TFile): int = @@ -149,7 +161,7 @@ proc writeFile(filename, content: string) = finally: close(f) -proc EndOfFile(f: TFile): bool = +proc endOfFile(f: TFile): bool = # do not blame me; blame the ANSI C standard this is so brain-damaged var c = fgetc(f) ungetc(c, f) @@ -167,12 +179,12 @@ proc rawEchoNL() {.inline, compilerproc.} = write(stdout, "\n") when defined(windows) and not defined(useWinAnsi): include "system/widestrs" - proc wfopen(filename, mode: widecstring): pointer {. + proc wfopen(filename, mode: WideCString): pointer {. importc: "_wfopen", nodecl.} - proc wfreopen(filename, mode: widecstring, stream: TFile): TFile {. + proc wfreopen(filename, mode: WideCString, stream: TFile): TFile {. importc: "_wfreopen", nodecl.} - proc fopen(filename, mode: CString): pointer = + proc fopen(filename, mode: cstring): pointer = var f = newWideCString(filename) var m = newWideCString(mode) result = wfopen(f, m) @@ -183,7 +195,7 @@ when defined(windows) and not defined(useWinAnsi): result = wfreopen(f, m, stream) else: - proc fopen(filename, mode: CString): pointer {.importc: "fopen", noDecl.} + proc fopen(filename, mode: cstring): pointer {.importc: "fopen", noDecl.} proc freopen(filename, mode: cstring, stream: TFile): TFile {. importc: "freopen", nodecl.} @@ -194,9 +206,9 @@ const # should not be translated. -proc Open(f: var TFile, filename: string, +proc open(f: var TFile, filename: string, mode: TFileMode = fmRead, - bufSize: int = -1): Bool = + bufSize: int = -1): bool = var p: pointer = fopen(filename, FormatOpen[mode]) result = (p != nil) f = cast[TFile](p) @@ -217,23 +229,23 @@ proc open(f: var TFile, filehandle: TFileHandle, mode: TFileMode): bool = f = fdopen(filehandle, FormatOpen[mode]) result = f != nil -proc fwrite(buf: Pointer, size, n: int, f: TFile): int {. +proc fwrite(buf: pointer, size, n: int, f: TFile): int {. importc: "fwrite", noDecl.} proc readBuffer(f: TFile, buffer: pointer, len: int): int = result = fread(buffer, 1, len, f) -proc ReadBytes(f: TFile, a: var openarray[int8], start, len: int): int = +proc readBytes(f: TFile, a: var openArray[int8], start, len: int): int = result = readBuffer(f, addr(a[start]), len) -proc ReadChars(f: TFile, a: var openarray[char], start, len: int): int = +proc readChars(f: TFile, a: var openArray[char], start, len: int): int = result = readBuffer(f, addr(a[start]), len) {.push stackTrace:off, profiler:off.} -proc writeBytes(f: TFile, a: openarray[int8], start, len: int): int = +proc writeBytes(f: TFile, a: openArray[int8], start, len: int): int = var x = cast[ptr array[0..1000_000_000, int8]](a) result = writeBuffer(f, addr(x[start]), len) -proc writeChars(f: TFile, a: openarray[char], start, len: int): int = +proc writeChars(f: TFile, a: openArray[char], start, len: int): int = var x = cast[ptr array[0..1000_000_000, int8]](a) result = writeBuffer(f, addr(x[start]), len) proc writeBuffer(f: TFile, buffer: pointer, len: int): int = diff --git a/lib/system/syslocks.nim b/lib/system/syslocks.nim index 4d81dee01..5e3b04b7f 100644 --- a/lib/system/syslocks.nim +++ b/lib/system/syslocks.nim @@ -22,50 +22,53 @@ when defined(Windows): TSysCond = THandle - proc InitSysLock(L: var TSysLock) {.stdcall, noSideEffect, + proc initSysLock(L: var TSysLock) {.stdcall, noSideEffect, dynlib: "kernel32", importc: "InitializeCriticalSection".} ## Initializes the lock `L`. - proc TryAcquireSysAux(L: var TSysLock): int32 {.stdcall, noSideEffect, + proc tryAcquireSysAux(L: var TSysLock): int32 {.stdcall, noSideEffect, dynlib: "kernel32", importc: "TryEnterCriticalSection".} ## Tries to acquire the lock `L`. - proc TryAcquireSys(L: var TSysLock): bool {.inline.} = + proc tryAcquireSys(L: var TSysLock): bool {.inline.} = result = TryAcquireSysAux(L) != 0'i32 - proc AcquireSys(L: var TSysLock) {.stdcall, noSideEffect, + proc acquireSys(L: var TSysLock) {.stdcall, noSideEffect, dynlib: "kernel32", importc: "EnterCriticalSection".} ## Acquires the lock `L`. - proc ReleaseSys(L: var TSysLock) {.stdcall, noSideEffect, + proc releaseSys(L: var TSysLock) {.stdcall, noSideEffect, dynlib: "kernel32", importc: "LeaveCriticalSection".} ## Releases the lock `L`. - proc DeinitSys(L: var TSysLock) {.stdcall, noSideEffect, + proc deinitSys(L: var TSysLock) {.stdcall, noSideEffect, dynlib: "kernel32", importc: "DeleteCriticalSection".} - proc CreateEvent(lpEventAttributes: pointer, + proc createEvent(lpEventAttributes: pointer, bManualReset, bInitialState: int32, lpName: cstring): TSysCond {.stdcall, noSideEffect, dynlib: "kernel32", importc: "CreateEventA".} - proc CloseHandle(hObject: THandle) {.stdcall, noSideEffect, + proc closeHandle(hObject: THandle) {.stdcall, noSideEffect, dynlib: "kernel32", importc: "CloseHandle".} - proc WaitForSingleObject(hHandle: THandle, dwMilliseconds: int32): int32 {. + proc waitForSingleObject(hHandle: THandle, dwMilliseconds: int32): int32 {. stdcall, dynlib: "kernel32", importc: "WaitForSingleObject".} - proc SignalSysCond(hEvent: TSysCond) {.stdcall, noSideEffect, + proc signalSysCond(hEvent: TSysCond) {.stdcall, noSideEffect, dynlib: "kernel32", importc: "SetEvent".} - proc InitSysCond(cond: var TSysCond) {.inline.} = - cond = CreateEvent(nil, 0'i32, 0'i32, nil) - proc DeinitSysCond(cond: var TSysCond) {.inline.} = - CloseHandle(cond) - proc WaitSysCond(cond: var TSysCond, lock: var TSysLock) = + proc initSysCond(cond: var TSysCond) {.inline.} = + cond = createEvent(nil, 0'i32, 0'i32, nil) + proc deinitSysCond(cond: var TSysCond) {.inline.} = + closeHandle(cond) + proc waitSysCond(cond: var TSysCond, lock: var TSysLock) = releaseSys(lock) - discard WaitForSingleObject(cond, -1'i32) + discard waitForSingleObject(cond, -1'i32) acquireSys(lock) + proc waitSysCondWindows(cond: var TSysCond) = + discard waitForSingleObject(cond, -1'i32) + else: type TSysLock {.importc: "pthread_mutex_t", pure, final, @@ -73,29 +76,29 @@ else: TSysCond {.importc: "pthread_cond_t", pure, final, header: "<sys/types.h>".} = object - proc InitSysLock(L: var TSysLock, attr: pointer = nil) {. + proc initSysLock(L: var TSysLock, attr: pointer = nil) {. importc: "pthread_mutex_init", header: "<pthread.h>", noSideEffect.} - proc AcquireSys(L: var TSysLock) {.noSideEffect, + proc acquireSys(L: var TSysLock) {.noSideEffect, importc: "pthread_mutex_lock", header: "<pthread.h>".} - proc TryAcquireSysAux(L: var TSysLock): cint {.noSideEffect, + proc tryAcquireSysAux(L: var TSysLock): cint {.noSideEffect, importc: "pthread_mutex_trylock", header: "<pthread.h>".} - proc TryAcquireSys(L: var TSysLock): bool {.inline.} = - result = TryAcquireSysAux(L) == 0'i32 + proc tryAcquireSys(L: var TSysLock): bool {.inline.} = + result = tryAcquireSysAux(L) == 0'i32 - proc ReleaseSys(L: var TSysLock) {.noSideEffect, + proc releaseSys(L: var TSysLock) {.noSideEffect, importc: "pthread_mutex_unlock", header: "<pthread.h>".} - proc DeinitSys(L: var TSysLock) {. + proc deinitSys(L: var TSysLock) {. importc: "pthread_mutex_destroy", header: "<pthread.h>".} - proc InitSysCond(cond: var TSysCond, cond_attr: pointer = nil) {. + proc initSysCond(cond: var TSysCond, cond_attr: pointer = nil) {. importc: "pthread_cond_init", header: "<pthread.h>".} - proc WaitSysCond(cond: var TSysCond, lock: var TSysLock) {. + proc waitSysCond(cond: var TSysCond, lock: var TSysLock) {. importc: "pthread_cond_wait", header: "<pthread.h>".} - proc SignalSysCond(cond: var TSysCond) {. + proc signalSysCond(cond: var TSysCond) {. importc: "pthread_cond_signal", header: "<pthread.h>".} - proc DeinitSysCond(cond: var TSysCond) {. + proc deinitSysCond(cond: var TSysCond) {. importc: "pthread_cond_destroy", header: "<pthread.h>".} diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim index d62a987ff..4244bae4c 100644 --- a/lib/system/sysstr.nim +++ b/lib/system/sysstr.nim @@ -55,7 +55,7 @@ proc copyStrLast(s: NimString, start, last: int): NimString {.compilerProc.} = if len > 0: result = rawNewString(len) result.len = len - c_memcpy(result.data, addr(s.data[start]), len * sizeof(Char)) + c_memcpy(result.data, addr(s.data[start]), len * sizeof(char)) #result.data[len] = '\0' else: result = rawNewString(len) @@ -63,14 +63,14 @@ proc copyStrLast(s: NimString, start, last: int): NimString {.compilerProc.} = proc copyStr(s: NimString, start: int): NimString {.compilerProc.} = result = copyStrLast(s, start, s.len-1) -proc toNimStr(str: CString, len: int): NimString {.compilerProc.} = +proc toNimStr(str: cstring, len: int): NimString {.compilerProc.} = result = rawNewString(len) result.len = len - c_memcpy(result.data, str, (len+1) * sizeof(Char)) + c_memcpy(result.data, str, (len+1) * sizeof(char)) #result.data[len] = '\0' # readline relies on this! -proc cstrToNimstr(str: CString): NimString {.compilerRtl.} = - result = toNimstr(str, c_strlen(str)) +proc cstrToNimstr(str: cstring): NimString {.compilerRtl.} = + result = toNimStr(str, c_strlen(str)) proc copyString(src: NimString): NimString {.compilerRtl.} = if src != nil: @@ -79,7 +79,7 @@ proc copyString(src: NimString): NimString {.compilerRtl.} = else: result = rawNewString(src.space) result.len = src.len - c_memcpy(result.data, src.data, (src.len + 1) * sizeof(Char)) + c_memcpy(result.data, src.data, (src.len + 1) * sizeof(char)) proc copyStringRC1(src: NimString): NimString {.compilerRtl.} = if src != nil: @@ -98,8 +98,8 @@ proc hashString(s: string): int {.compilerproc.} = # the compiler needs exactly the same hash function! # this used to be used for efficient generation of string case statements var h = 0 - for i in 0..Len(s)-1: - h = h +% Ord(s[i]) + for i in 0..len(s)-1: + h = h +% ord(s[i]) h = h +% h shl 10 h = h xor (h shr 6) h = h +% h shl 3 @@ -150,10 +150,10 @@ proc addChar(s: NimString, c: char): NimString = # s = rawNewString(0); proc resizeString(dest: NimString, addlen: int): NimString {.compilerRtl.} = - if dest.len + addLen <= dest.space: + if dest.len + addlen <= dest.space: result = dest else: # slow path: - var sp = max(resize(dest.space), dest.len + addLen) + var sp = max(resize(dest.space), dest.len + addlen) result = cast[NimString](growObj(dest, sizeof(TGenericSeq) + sp + 1)) result.reserved = sp #result = rawNewString(sp) @@ -236,7 +236,7 @@ proc nimIntToStr(x: int): string {.compilerRtl.} = result = newString(sizeof(x)*4) var i = 0 var y = x - while True: + while true: var d = y div 10 result[i] = chr(abs(int(y - d*10)) + ord('0')) inc(i) @@ -259,7 +259,7 @@ proc nimInt64ToStr(x: int64): string {.compilerRtl.} = result = newString(sizeof(x)*4) var i = 0 var y = x - while True: + while true: var d = y div 10 result[i] = chr(abs(int(y - d*10)) + ord('0')) inc(i) @@ -280,7 +280,7 @@ proc nimCharToStr(x: char): string {.compilerRtl.} = result = newString(1) result[0] = x -proc binaryStrSearch(x: openarray[string], y: string): int {.compilerproc.} = +proc binaryStrSearch(x: openArray[string], y: string): int {.compilerproc.} = var a = 0 b = len(x) diff --git a/lib/system/threads.nim b/lib/system/threads.nim index 80420d791..ff9ab6cc0 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -29,11 +29,11 @@ ## ## proc threadFunc(interval: tuple[a,b: int]) {.thread.} = ## for i in interval.a..interval.b: -## Acquire(L) # lock stdout +## acquire(L) # lock stdout ## echo i -## Release(L) +## release(L) ## -## InitLock(L) +## initLock(L) ## ## for i in 0..high(thr): ## createThread(thr[i], threadFunc, (i*10, i*10+5)) @@ -54,9 +54,9 @@ when defined(windows): TSysThread = THandle TWinThreadProc = proc (x: pointer): int32 {.stdcall.} - proc CreateThread(lpThreadAttributes: Pointer, dwStackSize: int32, + proc createThread(lpThreadAttributes: pointer, dwStackSize: int32, lpStartAddress: TWinThreadProc, - lpParameter: Pointer, + lpParameter: pointer, dwCreationFlags: int32, lpThreadId: var int32): TSysThread {. stdcall, dynlib: "kernel32", importc: "CreateThread".} @@ -67,23 +67,23 @@ when defined(windows): proc winResumeThread(hThread: TSysThread): int32 {. stdcall, dynlib: "kernel32", importc: "ResumeThread".} - proc WaitForMultipleObjects(nCount: int32, + proc waitForMultipleObjects(nCount: int32, lpHandles: ptr TSysThread, bWaitAll: int32, dwMilliseconds: int32): int32 {. stdcall, dynlib: "kernel32", importc: "WaitForMultipleObjects".} - proc TerminateThread(hThread: TSysThread, dwExitCode: int32): int32 {. + proc terminateThread(hThread: TSysThread, dwExitCode: int32): int32 {. stdcall, dynlib: "kernel32", importc: "TerminateThread".} type TThreadVarSlot = distinct int32 - proc ThreadVarAlloc(): TThreadVarSlot {. + proc threadVarAlloc(): TThreadVarSlot {. importc: "TlsAlloc", stdcall, dynlib: "kernel32".} - proc ThreadVarSetValue(dwTlsIndex: TThreadVarSlot, lpTlsValue: pointer) {. + proc threadVarSetValue(dwTlsIndex: TThreadVarSlot, lpTlsValue: pointer) {. importc: "TlsSetValue", stdcall, dynlib: "kernel32".} - proc ThreadVarGetValue(dwTlsIndex: TThreadVarSlot): pointer {. + proc threadVarGetValue(dwTlsIndex: TThreadVarSlot): pointer {. importc: "TlsGetValue", stdcall, dynlib: "kernel32".} else: @@ -116,14 +116,14 @@ else: proc pthread_cancel(a1: TSysThread): cint {. importc: "pthread_cancel", header: "<pthread.h>".} - proc AcquireSysTimeoutAux(L: var TSysLock, timeout: var Ttimespec): cint {. + proc acquireSysTimeoutAux(L: var TSysLock, timeout: var Ttimespec): cint {. importc: "pthread_mutex_timedlock", header: "<time.h>".} - proc AcquireSysTimeout(L: var TSysLock, msTimeout: int) {.inline.} = + proc acquireSysTimeout(L: var TSysLock, msTimeout: int) {.inline.} = var a: Ttimespec a.tv_sec = msTimeout div 1000 a.tv_nsec = (msTimeout mod 1000) * 1000 - var res = AcquireSysTimeoutAux(L, a) + var res = acquireSysTimeoutAux(L, a) if res != 0'i32: raise newException(EResourceExhausted, $strerror(res)) type @@ -141,11 +141,11 @@ else: proc pthread_setspecific(a1: TThreadVarSlot, a2: pointer): int32 {. importc: "pthread_setspecific", header: "<pthread.h>".} - proc ThreadVarAlloc(): TThreadVarSlot {.inline.} = + proc threadVarAlloc(): TThreadVarSlot {.inline.} = discard pthread_key_create(addr(result), nil) - proc ThreadVarSetValue(s: TThreadVarSlot, value: pointer) {.inline.} = + proc threadVarSetValue(s: TThreadVarSlot, value: pointer) {.inline.} = discard pthread_setspecific(s, value) - proc ThreadVarGetValue(s: TThreadVarSlot): pointer {.inline.} = + proc threadVarGetValue(s: TThreadVarSlot): pointer {.inline.} = result = pthread_getspecific(s) when useStackMaskHack: @@ -159,7 +159,7 @@ const when emulatedThreadVars: # the compiler generates this proc for us, so that we can get the size of # the thread local var block; we use this only for sanity checking though - proc NimThreadVarsSize(): int {.noconv, importc: "NimThreadVarsSize".} + proc nimThreadVarsSize(): int {.noconv, importc: "NimThreadVarsSize".} # we preallocate a fixed size for thread local storage, so that no heap # allocations are needed. Currently less than 7K are used on a 64bit machine. @@ -184,7 +184,7 @@ type # XXX it'd be more efficient to not use a global variable for the # thread storage slot, but to rely on the implementation to assign slot X # for us... ;-) -var globalsSlot = ThreadVarAlloc() +var globalsSlot = threadVarAlloc() #const globalsSlot = TThreadVarSlot(0) #sysAssert checkSlot.int == globalsSlot.int @@ -193,7 +193,7 @@ when emulatedThreadVars: result = addr(cast[PGcThread](ThreadVarGetValue(globalsSlot)).tls) when useStackMaskHack: - proc MaskStackPointer(offset: int): pointer {.compilerRtl, inl.} = + proc maskStackPointer(offset: int): pointer {.compilerRtl, inl.} = var x {.volatile.}: pointer x = addr(x) result = cast[pointer]((cast[int](x) and not ThreadStackMask) +% @@ -205,7 +205,7 @@ when not defined(useNimRtl): when not useStackMaskHack: var mainThread: TGcThread - ThreadVarSetValue(globalsSlot, addr(mainThread)) + threadVarSetValue(globalsSlot, addr(mainThread)) when not defined(createNimRtl): initStackBottom() initGC() @@ -220,18 +220,18 @@ when not defined(useNimRtl): proc registerThread(t: PGcThread) = # we need to use the GC global lock here! - AcquireSys(HeapLock) + acquireSys(HeapLock) t.prev = nil t.next = threadList if threadList != nil: sysAssert(threadList.prev == nil, "threadList.prev == nil") threadList.prev = t threadList = t - ReleaseSys(HeapLock) + releaseSys(HeapLock) proc unregisterThread(t: PGcThread) = # we need to use the GC global lock here! - AcquireSys(HeapLock) + acquireSys(HeapLock) if t == threadList: threadList = t.next if t.next != nil: t.next.prev = t.prev if t.prev != nil: t.prev.next = t.next @@ -239,7 +239,7 @@ when not defined(useNimRtl): # code executes `destroyThread`: t.next = nil t.prev = nil - ReleaseSys(HeapLock) + releaseSys(HeapLock) # on UNIX, the GC uses ``SIGFREEZE`` to tell every thread to stop so that # the GC can examine the stacks? @@ -266,7 +266,7 @@ type when not defined(boehmgc) and not hasSharedHeap: proc deallocOsPages() -template ThreadProcWrapperBody(closure: expr) {.immediate.} = +template threadProcWrapperBody(closure: expr) {.immediate.} = when defined(globalsSlot): ThreadVarSetValue(globalsSlot, closure) var t = cast[ptr TThread[TArg]](closure) when useStackMaskHack: @@ -294,11 +294,11 @@ template ThreadProcWrapperBody(closure: expr) {.immediate.} = {.push stack_trace:off.} when defined(windows): proc threadProcWrapper[TArg](closure: pointer): int32 {.stdcall.} = - ThreadProcWrapperBody(closure) + threadProcWrapperBody(closure) # implicitly return 0 else: proc threadProcWrapper[TArg](closure: pointer) {.noconv.} = - ThreadProcWrapperBody(closure) + threadProcWrapperBody(closure) {.pop.} proc running*[TArg](t: TThread[TArg]): bool {.inline.} = @@ -308,7 +308,7 @@ proc running*[TArg](t: TThread[TArg]): bool {.inline.} = proc joinThread*[TArg](t: TThread[TArg]) {.inline.} = ## waits for the thread `t` to finish. when hostOS == "windows": - discard WaitForSingleObject(t.sys, -1'i32) + discard waitForSingleObject(t.sys, -1'i32) else: discard pthread_join(t.sys, nil) @@ -318,7 +318,7 @@ proc joinThreads*[TArg](t: varargs[TThread[TArg]]) = var a: array[0..255, TSysThread] sysAssert a.len >= t.len, "a.len >= t.len" for i in 0..t.high: a[i] = t[i].sys - discard WaitForMultipleObjects(t.len.int32, + discard waitForMultipleObjects(t.len.int32, cast[ptr TSysThread](addr(a)), 1, -1) else: for i in 0..t.high: joinThread(t[i]) @@ -346,7 +346,7 @@ proc createThread*[TArg](t: var TThread[TArg], when hasSharedHeap: t.stackSize = ThreadStackSize when hostOS == "windows": var dummyThreadId: int32 - t.sys = CreateThread(nil, ThreadStackSize, threadProcWrapper[TArg], + t.sys = createThread(nil, ThreadStackSize, threadProcWrapper[TArg], addr(t), 0'i32, dummyThreadId) if t.sys <= 0: raise newException(EResourceExhausted, "cannot create thread") diff --git a/lib/system/widestrs.nim b/lib/system/widestrs.nim index cf1f0910c..e2a5d87e9 100644 --- a/lib/system/widestrs.nim +++ b/lib/system/widestrs.nim @@ -1,149 +1,153 @@ -# -# -# Nimrod's Runtime Library -# (c) Copyright 2012 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## Nimrod support for C/C++'s `wide strings`:idx:. This is part of the system -## module! Do not import it directly! - -type - TUtf16Char* = distinct int16 - WideCString* = ref array[0.. 1_000_000, TUtf16Char] - -proc len*(w: WideCString): int = - ## returns the length of a widestring. This traverses the whole string to - ## find the binary zero end marker! - while int16(w[result]) != 0'i16: inc result - -const - UNI_REPLACEMENT_CHAR = TUtf16Char(0xFFFD'i16) - UNI_MAX_BMP = 0x0000FFFF - UNI_MAX_UTF16 = 0x0010FFFF - UNI_MAX_UTF32 = 0x7FFFFFFF - UNI_MAX_LEGAL_UTF32 = 0x0010FFFF - - halfShift = 10 - halfBase = 0x0010000 - halfMask = 0x3FF - - UNI_SUR_HIGH_START = 0xD800 - UNI_SUR_HIGH_END = 0xDBFF - UNI_SUR_LOW_START = 0xDC00 - UNI_SUR_LOW_END = 0xDFFF - -template ones(n: expr): expr = ((1 shl n)-1) - -template fastRuneAt(s: cstring, i: int, result: expr, doInc = true) = - ## Returns the unicode character ``s[i]`` in `result`. If ``doInc == true`` - ## `i` is incremented by the number of bytes that have been processed. - bind ones - - if ord(s[i]) <=% 127: - result = ord(s[i]) - when doInc: inc(i) - elif ord(s[i]) shr 5 == 0b110: - #assert(ord(s[i+1]) shr 6 == 0b10) - result = (ord(s[i]) and (ones(5))) shl 6 or (ord(s[i+1]) and ones(6)) - when doInc: inc(i, 2) - elif ord(s[i]) shr 4 == 0b1110: - #assert(ord(s[i+1]) shr 6 == 0b10) - #assert(ord(s[i+2]) shr 6 == 0b10) - result = (ord(s[i]) and ones(4)) shl 12 or - (ord(s[i+1]) and ones(6)) shl 6 or - (ord(s[i+2]) and ones(6)) - when doInc: inc(i, 3) - elif ord(s[i]) shr 3 == 0b11110: - #assert(ord(s[i+1]) shr 6 == 0b10) - #assert(ord(s[i+2]) shr 6 == 0b10) - #assert(ord(s[i+3]) shr 6 == 0b10) - result = (ord(s[i]) and ones(3)) shl 18 or - (ord(s[i+1]) and ones(6)) shl 12 or - (ord(s[i+2]) and ones(6)) shl 6 or - (ord(s[i+3]) and ones(6)) - when doInc: inc(i, 4) - else: - result = 0xFFFD - when doInc: inc(i) - -iterator runes(s: cstring): int = - var - i = 0 - result: int - while s[i] != '\0': - fastRuneAt(s, i, result, true) - yield result - -proc newWideCString*(source: cstring, L: int): WideCString = +# +# +# Nimrod's Runtime Library +# (c) Copyright 2012 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## Nimrod support for C/C++'s `wide strings`:idx:. This is part of the system +## module! Do not import it directly! + +when not defined(NimString): + {.error: "You must not import this module explicitly".} + +type + TUtf16Char* = distinct int16 + WideCString* = ref array[0.. 1_000_000, TUtf16Char] + +proc len*(w: WideCString): int = + ## returns the length of a widestring. This traverses the whole string to + ## find the binary zero end marker! + while int16(w[result]) != 0'i16: inc result + +const + UNI_REPLACEMENT_CHAR = TUtf16Char(0xFFFD'i16) + UNI_MAX_BMP = 0x0000FFFF + UNI_MAX_UTF16 = 0x0010FFFF + UNI_MAX_UTF32 = 0x7FFFFFFF + UNI_MAX_LEGAL_UTF32 = 0x0010FFFF + + halfShift = 10 + halfBase = 0x0010000 + halfMask = 0x3FF + + UNI_SUR_HIGH_START = 0xD800 + UNI_SUR_HIGH_END = 0xDBFF + UNI_SUR_LOW_START = 0xDC00 + UNI_SUR_LOW_END = 0xDFFF + +template ones(n: expr): expr = ((1 shl n)-1) + +template fastRuneAt(s: cstring, i: int, result: expr, doInc = true) = + ## Returns the unicode character ``s[i]`` in `result`. If ``doInc == true`` + ## `i` is incremented by the number of bytes that have been processed. + bind ones + + if ord(s[i]) <=% 127: + result = ord(s[i]) + when doInc: inc(i) + elif ord(s[i]) shr 5 == 0b110: + #assert(ord(s[i+1]) shr 6 == 0b10) + result = (ord(s[i]) and (ones(5))) shl 6 or (ord(s[i+1]) and ones(6)) + when doInc: inc(i, 2) + elif ord(s[i]) shr 4 == 0b1110: + #assert(ord(s[i+1]) shr 6 == 0b10) + #assert(ord(s[i+2]) shr 6 == 0b10) + result = (ord(s[i]) and ones(4)) shl 12 or + (ord(s[i+1]) and ones(6)) shl 6 or + (ord(s[i+2]) and ones(6)) + when doInc: inc(i, 3) + elif ord(s[i]) shr 3 == 0b11110: + #assert(ord(s[i+1]) shr 6 == 0b10) + #assert(ord(s[i+2]) shr 6 == 0b10) + #assert(ord(s[i+3]) shr 6 == 0b10) + result = (ord(s[i]) and ones(3)) shl 18 or + (ord(s[i+1]) and ones(6)) shl 12 or + (ord(s[i+2]) and ones(6)) shl 6 or + (ord(s[i+3]) and ones(6)) + when doInc: inc(i, 4) + else: + result = 0xFFFD + when doInc: inc(i) + +iterator runes(s: cstring): int = + var + i = 0 + result: int + while s[i] != '\0': + fastRuneAt(s, i, result, true) + yield result + +proc newWideCString*(source: cstring, L: int): WideCString = unsafeNew(result, L * 4 + 2) - #result = cast[wideCString](alloc(L * 4 + 2)) - var d = 0 - for ch in runes(source): - if ch <=% UNI_MAX_BMP: - if ch >=% UNI_SUR_HIGH_START and ch <=% UNI_SUR_LOW_END: - result[d] = UNI_REPLACEMENT_CHAR - else: - result[d] = TUtf16Char(toU16(ch)) - elif ch >% UNI_MAX_UTF16: - result[d] = UNI_REPLACEMENT_CHAR - else: - let ch = ch -% halfBase - result[d] = TUtf16Char(toU16((ch shr halfShift) +% UNI_SUR_HIGH_START)) - inc d - result[d] = TUtf16Char(toU16((ch and halfMask) +% UNI_SUR_LOW_START)) - inc d - result[d] = TUtf16Char(0'i16) - -proc newWideCString*(s: cstring): WideCString = - if s.isNil: return nil - - when not defined(c_strlen): - proc c_strlen(a: CString): int {.nodecl, noSideEffect, importc: "strlen".} - - let L = cstrlen(s) - result = newWideCString(s, L) - -proc newWideCString*(s: string): WideCString = - result = newWideCString(s, s.len) - -proc `$`*(w: wideCString, estimate: int): string = - result = newStringOfCap(estimate + estimate shr 2) - - var i = 0 - while w[i].int16 != 0'i16: - var ch = w[i].int - inc i - if ch >=% UNI_SUR_HIGH_START and ch <=% UNI_SUR_HIGH_END: - # If the 16 bits following the high surrogate are in the source buffer... - let ch2 = w[i].int - # If it's a low surrogate, convert to UTF32: - if ch2 >=% UNI_SUR_LOW_START and ch2 <=% UNI_SUR_LOW_END: - ch = ((ch -% UNI_SUR_HIGH_START) shr halfShift) +% - (ch2 -% UNI_SUR_LOW_START) +% halfBase - inc i - - if ch <=% 127: - result.add chr(ch) - elif ch <=% 0x07FF: - result.add chr((ch shr 6) or 0b110_00000) - result.add chr((ch and ones(6)) or 0b10_000000) - elif ch <=% 0xFFFF: - result.add chr(ch shr 12 or 0b1110_0000) - result.add chr(ch shr 6 and ones(6) or 0b10_0000_00) - result.add chr(ch and ones(6) or 0b10_0000_00) - elif ch <=% 0x0010FFFF: - result.add chr(ch shr 18 or 0b1111_0000) - result.add chr(ch shr 12 and ones(6) or 0b10_0000_00) - result.add chr(ch shr 6 and ones(6) or 0b10_0000_00) - result.add chr(ch and ones(6) or 0b10_0000_00) - else: - # replacement char: - result.add chr(0xFFFD shr 12 or 0b1110_0000) - result.add chr(0xFFFD shr 6 and ones(6) or 0b10_0000_00) - result.add chr(0xFFFD and ones(6) or 0b10_0000_00) - -proc `$`*(s: WideCString): string = - result = s $ 80 + #result = cast[wideCString](alloc(L * 4 + 2)) + var d = 0 + for ch in runes(source): + if ch <=% UNI_MAX_BMP: + if ch >=% UNI_SUR_HIGH_START and ch <=% UNI_SUR_LOW_END: + result[d] = UNI_REPLACEMENT_CHAR + else: + result[d] = TUtf16Char(toU16(ch)) + elif ch >% UNI_MAX_UTF16: + result[d] = UNI_REPLACEMENT_CHAR + else: + let ch = ch -% halfBase + result[d] = TUtf16Char(toU16((ch shr halfShift) +% UNI_SUR_HIGH_START)) + inc d + result[d] = TUtf16Char(toU16((ch and halfMask) +% UNI_SUR_LOW_START)) + inc d + result[d] = TUtf16Char(0'i16) + +proc newWideCString*(s: cstring): WideCString = + if s.isNil: return nil + + when not defined(c_strlen): + proc c_strlen(a: cstring): int {. + header: "<string.h>", noSideEffect, importc: "strlen".} + + let L = c_strlen(s) + result = newWideCString(s, L) + +proc newWideCString*(s: string): WideCString = + result = newWideCString(s, s.len) + +proc `$`*(w: WideCString, estimate: int): string = + result = newStringOfCap(estimate + estimate shr 2) + + var i = 0 + while w[i].int16 != 0'i16: + var ch = w[i].int + inc i + if ch >=% UNI_SUR_HIGH_START and ch <=% UNI_SUR_HIGH_END: + # If the 16 bits following the high surrogate are in the source buffer... + let ch2 = w[i].int + # If it's a low surrogate, convert to UTF32: + if ch2 >=% UNI_SUR_LOW_START and ch2 <=% UNI_SUR_LOW_END: + ch = ((ch -% UNI_SUR_HIGH_START) shr halfShift) +% + (ch2 -% UNI_SUR_LOW_START) +% halfBase + inc i + + if ch <=% 127: + result.add chr(ch) + elif ch <=% 0x07FF: + result.add chr((ch shr 6) or 0b110_00000) + result.add chr((ch and ones(6)) or 0b10_000000) + elif ch <=% 0xFFFF: + result.add chr(ch shr 12 or 0b1110_0000) + result.add chr(ch shr 6 and ones(6) or 0b10_0000_00) + result.add chr(ch and ones(6) or 0b10_0000_00) + elif ch <=% 0x0010FFFF: + result.add chr(ch shr 18 or 0b1111_0000) + result.add chr(ch shr 12 and ones(6) or 0b10_0000_00) + result.add chr(ch shr 6 and ones(6) or 0b10_0000_00) + result.add chr(ch and ones(6) or 0b10_0000_00) + else: + # replacement char: + result.add chr(0xFFFD shr 12 or 0b1110_0000) + result.add chr(0xFFFD shr 6 and ones(6) or 0b10_0000_00) + result.add chr(0xFFFD and ones(6) or 0b10_0000_00) + +proc `$`*(s: WideCString): string = + result = s $ 80 diff --git a/lib/windows/windows.nim b/lib/windows/windows.nim index 9b55b47b9..dd743ffa4 100644 --- a/lib/windows/windows.nim +++ b/lib/windows/windows.nim @@ -21856,15 +21856,9 @@ proc InflateRect*(lprc: var TRect, dx, dy: int): WINBOOL{.stdcall, dynlib: "user32", importc: "InflateRect".} proc InitializeAcl*(pAcl: var TACL, nAclLength, dwAclRevision: DWORD): WINBOOL{. stdcall, dynlib: "advapi32", importc: "InitializeAcl".} -proc InitializeCriticalSectionAndSpinCount*( - lpCriticalSection: var TRTLCriticalSection, dwSpinCount: DWORD): WINBOOL{. - stdcall, dynlib: "kernel32", - importc: "InitializeCriticalSectionAndSpinCount".} proc InitializeSid*(Sid: Pointer, pIdentifierAuthority: TSIDIdentifierAuthority, nSubAuthorityCount: int8): WINBOOL{.stdcall, dynlib: "advapi32", importc: "InitializeSid".} -proc InsertMenuItem*(p1: HMENU, p2: UINT, p3: WINBOOL, p4: TMenuItemInfo): WINBOOL{. - stdcall, dynlib: "user32", importc: "InsertMenuItemA".} proc InsertMenuItemA*(p1: HMENU, p2: UINT, p3: WINBOOL, p4: TMenuItemInfoA): WINBOOL{. stdcall, dynlib: "user32", importc: "InsertMenuItemA".} #function InsertMenuItemW(p1: HMENU; p2: UINT; p3: WINBOOL; const p4: TMenuItemInfoW): WINBOOL; stdcall; external 'user32' name 'InsertMenuItemW'; @@ -22362,11 +22356,6 @@ proc SetConsoleCursorInfo*(hConsoleOutput: THandle, lpConsoleCursorInfo: TConsoleCursorInfo): WINBOOL{. stdcall, dynlib: "kernel32", importc: "SetConsoleCursorInfo".} #function SetConsoleWindowInfo(hConsoleOutput: THandle; bAbsolute: WINBOOL; const lpConsoleWindow: TSmallRect): WINBOOL; stdcall; external 'kernel32' name 'SetConsoleWindowInfo'; -proc SetCriticalSectionSpinCount*(lpCriticalSection: var TRTLCriticalSection, - dwSpinCount: DWORD): DWORD{.stdcall, - dynlib: "kernel32", importc: "SetCriticalSectionSpinCount".} -proc SetDeviceGammaRamp*(DC: HDC, Ramp: pointer): WINBOOL{.stdcall, - dynlib: "gdi32", importc: "SetDeviceGammaRamp".} proc SetDIBColorTable*(DC: HDC, p2, p3: UINT, RGBQuadSTructs: pointer): UINT{. stdcall, dynlib: "gdi32", importc: "SetDIBColorTable".} proc SetDIBits*(DC: HDC, Bitmap: HBITMAP, StartScan, NumScans: UINT, @@ -22476,8 +22465,6 @@ proc TranslateMDISysAccel*(hWndClient: HWND, lpMsg: TMsg): WINBOOL{.stdcall, proc TranslateMessage*(lpMsg: TMsg): WINBOOL{.stdcall, dynlib: "user32", importc: "TranslateMessage".} #function TransparentDIBits(DC: HDC; p2, p3, p4, p5: Integer; const p6: Pointer; const p7: PBitmapInfo; p8: UINT; p9, p10, p11, p12: Integer; p13: UINT): WINBOOL;stdcall; external 'gdi32' name 'TransparentDIBits'; -proc TryEnterCriticalSection*(lpCriticalSection: var TRTLCriticalSection): WINBOOL{. - stdcall, dynlib: "kernel32", importc: "TryEnterCriticalSection".} proc UnhandledExceptionFilter*(ExceptionInfo: TExceptionPointers): int32{. stdcall, dynlib: "kernel32", importc: "UnhandledExceptionFilter".} proc UnionRect*(lprcDst: var TRect, lprcSrc1, lprcSrc2: TRect): WINBOOL{. @@ -22847,12 +22834,6 @@ proc SUBLANGID*(lgid: int32): int32 = # return type might be wrong result = toU16(lgid) shr 10'i16 -proc LANGIDFROMLCID*(lcid: int32): int16 = - result = toU16(lcid) - -proc SORTIDFROMLCID*(lcid: int32): int16 = - result = toU16((lcid and 0x000FFFFF'i32) shr 16'i32) - proc MAKELCID*(lgid, srtid: int32): DWORD = result = toU32(srtid shl 16'i32 or lgid and 0xffff'i32) diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 264285d09..91c6495ce 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -42,13 +42,13 @@ type wShowWindow*: int16 cbReserved2*: int16 lpReserved2*: pointer - hStdInput*: THANDLE - hStdOutput*: THANDLE - hStdError*: THANDLE + hStdInput*: THandle + hStdOutput*: THandle + hStdError*: THandle TPROCESS_INFORMATION* {.final, pure.} = object - hProcess*: THANDLE - hThread*: THANDLE + hProcess*: THandle + hThread*: THandle dwProcessId*: int32 dwThreadId*: int32 @@ -92,39 +92,39 @@ const DETACHED_PROCESS* = 8'i32 SW_SHOWNORMAL* = 1'i32 - INVALID_HANDLE_VALUE* = THANDLE(-1) + INVALID_HANDLE_VALUE* = THandle(-1) CREATE_UNICODE_ENVIRONMENT* = 1024'i32 -proc CloseHandle*(hObject: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32", +proc closeHandle*(hObject: THandle): WINBOOL {.stdcall, dynlib: "kernel32", importc: "CloseHandle".} -proc ReadFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToRead: int32, +proc readFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToRead: int32, lpNumberOfBytesRead: var int32, lpOverlapped: pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "ReadFile".} -proc WriteFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToWrite: int32, +proc writeFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToWrite: int32, lpNumberOfBytesWritten: var int32, lpOverlapped: pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteFile".} -proc CreatePipe*(hReadPipe, hWritePipe: var THandle, +proc createPipe*(hReadPipe, hWritePipe: var THandle, lpPipeAttributes: var TSECURITY_ATTRIBUTES, nSize: int32): WINBOOL{. stdcall, dynlib: "kernel32", importc: "CreatePipe".} when useWinUnicode: - proc CreateProcessW*(lpApplicationName, lpCommandLine: widecstring, + proc createProcessW*(lpApplicationName, lpCommandLine: WideCString, lpProcessAttributes: ptr TSECURITY_ATTRIBUTES, lpThreadAttributes: ptr TSECURITY_ATTRIBUTES, bInheritHandles: WINBOOL, dwCreationFlags: int32, - lpEnvironment, lpCurrentDirectory: widecstring, + lpEnvironment, lpCurrentDirectory: WideCString, lpStartupInfo: var TSTARTUPINFO, lpProcessInformation: var TPROCESS_INFORMATION): WINBOOL{. stdcall, dynlib: "kernel32", importc: "CreateProcessW".} else: - proc CreateProcessA*(lpApplicationName, lpCommandLine: cstring, + proc createProcessA*(lpApplicationName, lpCommandLine: cstring, lpProcessAttributes: ptr TSECURITY_ATTRIBUTES, lpThreadAttributes: ptr TSECURITY_ATTRIBUTES, bInheritHandles: WINBOOL, dwCreationFlags: int32, @@ -134,74 +134,76 @@ else: stdcall, dynlib: "kernel32", importc: "CreateProcessA".} -proc SuspendThread*(hThread: THANDLE): int32 {.stdcall, dynlib: "kernel32", +proc suspendThread*(hThread: THandle): int32 {.stdcall, dynlib: "kernel32", importc: "SuspendThread".} -proc ResumeThread*(hThread: THANDLE): int32 {.stdcall, dynlib: "kernel32", +proc resumeThread*(hThread: THandle): int32 {.stdcall, dynlib: "kernel32", importc: "ResumeThread".} -proc WaitForSingleObject*(hHandle: THANDLE, dwMilliseconds: int32): int32 {. +proc waitForSingleObject*(hHandle: THandle, dwMilliseconds: int32): int32 {. stdcall, dynlib: "kernel32", importc: "WaitForSingleObject".} -proc TerminateProcess*(hProcess: THANDLE, uExitCode: int): WINBOOL {.stdcall, +proc terminateProcess*(hProcess: THandle, uExitCode: int): WINBOOL {.stdcall, dynlib: "kernel32", importc: "TerminateProcess".} -proc GetExitCodeProcess*(hProcess: THANDLE, lpExitCode: var int32): WINBOOL {. +proc getExitCodeProcess*(hProcess: THandle, lpExitCode: var int32): WINBOOL {. stdcall, dynlib: "kernel32", importc: "GetExitCodeProcess".} -proc GetStdHandle*(nStdHandle: int32): THANDLE {.stdcall, dynlib: "kernel32", +proc getStdHandle*(nStdHandle: int32): THandle {.stdcall, dynlib: "kernel32", importc: "GetStdHandle".} -proc SetStdHandle*(nStdHandle: int32, hHandle: THANDLE): WINBOOL {.stdcall, +proc setStdHandle*(nStdHandle: int32, hHandle: THandle): WINBOOL {.stdcall, dynlib: "kernel32", importc: "SetStdHandle".} -proc FlushFileBuffers*(hFile: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32", +proc flushFileBuffers*(hFile: THandle): WINBOOL {.stdcall, dynlib: "kernel32", importc: "FlushFileBuffers".} -proc GetLastError*(): int32 {.importc, stdcall, dynlib: "kernel32".} +proc getLastError*(): int32 {.importc: "GetLastError", + stdcall, dynlib: "kernel32".} when useWinUnicode: - proc FormatMessageW*(dwFlags: int32, lpSource: pointer, + proc formatMessageW*(dwFlags: int32, lpSource: pointer, dwMessageId, dwLanguageId: int32, lpBuffer: pointer, nSize: int32, Arguments: pointer): int32 {. - importc, stdcall, dynlib: "kernel32".} + importc: "FormatMessageW", stdcall, dynlib: "kernel32".} else: - proc FormatMessageA*(dwFlags: int32, lpSource: pointer, + proc formatMessageA*(dwFlags: int32, lpSource: pointer, dwMessageId, dwLanguageId: int32, lpBuffer: pointer, nSize: int32, Arguments: pointer): int32 {. - importc, stdcall, dynlib: "kernel32".} + importc: "FormatMessageA", stdcall, dynlib: "kernel32".} -proc LocalFree*(p: pointer) {.importc, stdcall, dynlib: "kernel32".} +proc localFree*(p: pointer) {. + importc: "LocalFree", stdcall, dynlib: "kernel32".} when useWinUnicode: - proc GetCurrentDirectoryW*(nBufferLength: int32, - lpBuffer: widecstring): int32 {. - importc, dynlib: "kernel32", stdcall.} - proc SetCurrentDirectoryW*(lpPathName: widecstring): int32 {. - importc, dynlib: "kernel32", stdcall.} - proc CreateDirectoryW*(pathName: widecstring, security: Pointer=nil): int32 {. + proc getCurrentDirectoryW*(nBufferLength: int32, + lpBuffer: WideCString): int32 {. + importc: "GetCurrentDirectoryW", dynlib: "kernel32", stdcall.} + proc setCurrentDirectoryW*(lpPathName: WideCString): int32 {. + importc: "SetCurrentDirectoryW", dynlib: "kernel32", stdcall.} + proc createDirectoryW*(pathName: WideCString, security: pointer=nil): int32 {. importc: "CreateDirectoryW", dynlib: "kernel32", stdcall.} - proc RemoveDirectoryW*(lpPathName: widecstring): int32 {. - importc, dynlib: "kernel32", stdcall.} - proc SetEnvironmentVariableW*(lpName, lpValue: widecstring): int32 {. - stdcall, dynlib: "kernel32", importc.} + proc removeDirectoryW*(lpPathName: WideCString): int32 {. + importc: "RemoveDirectoryW", dynlib: "kernel32", stdcall.} + proc setEnvironmentVariableW*(lpName, lpValue: WideCString): int32 {. + stdcall, dynlib: "kernel32", importc: "SetEnvironmentVariableW".} - proc GetModuleFileNameW*(handle: THandle, buf: wideCString, - size: int32): int32 {.importc, + proc getModuleFileNameW*(handle: THandle, buf: WideCString, + size: int32): int32 {.importc: "GetModuleFileNameW", dynlib: "kernel32", stdcall.} else: - proc GetCurrentDirectoryA*(nBufferLength: int32, lpBuffer: cstring): int32 {. - importc, dynlib: "kernel32", stdcall.} - proc SetCurrentDirectoryA*(lpPathName: cstring): int32 {. - importc, dynlib: "kernel32", stdcall.} - proc CreateDirectoryA*(pathName: cstring, security: Pointer=nil): int32 {. + proc getCurrentDirectoryA*(nBufferLength: int32, lpBuffer: cstring): int32 {. + importc: "GetCurrentDirectoryA", dynlib: "kernel32", stdcall.} + proc setCurrentDirectoryA*(lpPathName: cstring): int32 {. + importc: "SetCurrentDirectoryA", dynlib: "kernel32", stdcall.} + proc createDirectoryA*(pathName: cstring, security: Pointer=nil): int32 {. importc: "CreateDirectoryA", dynlib: "kernel32", stdcall.} - proc RemoveDirectoryA*(lpPathName: cstring): int32 {. - importc, dynlib: "kernel32", stdcall.} - proc SetEnvironmentVariableA*(lpName, lpValue: cstring): int32 {. - stdcall, dynlib: "kernel32", importc.} + proc removeDirectoryA*(lpPathName: cstring): int32 {. + importc: "RemoveDirectoryA", dynlib: "kernel32", stdcall.} + proc setEnvironmentVariableA*(lpName, lpValue: cstring): int32 {. + stdcall, dynlib: "kernel32", importc: "SetEnvironmentVariableA".} - proc GetModuleFileNameA*(handle: THandle, buf: CString, size: int32): int32 {. - importc, dynlib: "kernel32", stdcall.} + proc getModuleFileNameA*(handle: THandle, buf: CString, size: int32): int32 {. + importc: "GetModuleFileNameA", dynlib: "kernel32", stdcall.} const FILE_ATTRIBUTE_ARCHIVE* = 32'i32 @@ -228,91 +230,97 @@ type cAlternateFileName*: array[0..13, TWinChar] when useWinUnicode: - proc FindFirstFileW*(lpFileName: widecstring, - lpFindFileData: var TWIN32_FIND_DATA): THANDLE {. + proc findFirstFileW*(lpFileName: WideCString, + lpFindFileData: var TWIN32_FIND_DATA): THandle {. stdcall, dynlib: "kernel32", importc: "FindFirstFileW".} - proc FindNextFileW*(hFindFile: THANDLE, + proc findNextFileW*(hFindFile: THandle, lpFindFileData: var TWIN32_FIND_DATA): int32 {. stdcall, dynlib: "kernel32", importc: "FindNextFileW".} else: - proc FindFirstFileA*(lpFileName: cstring, + proc findFirstFileA*(lpFileName: cstring, lpFindFileData: var TWIN32_FIND_DATA): THANDLE {. stdcall, dynlib: "kernel32", importc: "FindFirstFileA".} - proc FindNextFileA*(hFindFile: THANDLE, + proc findNextFileA*(hFindFile: THANDLE, lpFindFileData: var TWIN32_FIND_DATA): int32 {. stdcall, dynlib: "kernel32", importc: "FindNextFileA".} -proc FindClose*(hFindFile: THANDLE) {.stdcall, dynlib: "kernel32", +proc findClose*(hFindFile: THandle) {.stdcall, dynlib: "kernel32", importc: "FindClose".} when useWinUnicode: - proc GetFullPathNameW*(lpFileName: widecstring, nBufferLength: int32, - lpBuffer: widecstring, - lpFilePart: var widecstring): int32 {. - stdcall, dynlib: "kernel32", importc.} - proc GetFileAttributesW*(lpFileName: widecstring): int32 {. - stdcall, dynlib: "kernel32", importc.} - proc SetFileAttributesW*(lpFileName: widecstring, + proc getFullPathNameW*(lpFileName: WideCString, nBufferLength: int32, + lpBuffer: WideCString, + lpFilePart: var WideCString): int32 {. + stdcall, dynlib: "kernel32", + importc: "GetFullPathNameW".} + proc getFileAttributesW*(lpFileName: WideCString): int32 {. + stdcall, dynlib: "kernel32", + importc: "GetFileAttributesW".} + proc setFileAttributesW*(lpFileName: WideCString, dwFileAttributes: int32): WINBOOL {. stdcall, dynlib: "kernel32", importc: "SetFileAttributesW".} - proc CopyFileW*(lpExistingFileName, lpNewFileName: wideCString, + proc copyFileW*(lpExistingFileName, lpNewFileName: WideCString, bFailIfExists: cint): cint {. - importc, stdcall, dynlib: "kernel32".} + importc: "CopyFileW", stdcall, dynlib: "kernel32".} - proc GetEnvironmentStringsW*(): widecstring {. - stdcall, dynlib: "kernel32", importc.} - proc FreeEnvironmentStringsW*(para1: widecstring): int32 {. - stdcall, dynlib: "kernel32", importc.} + proc getEnvironmentStringsW*(): WideCString {. + stdcall, dynlib: "kernel32", importc: "GetEnvironmentStringsW".} + proc freeEnvironmentStringsW*(para1: WideCString): int32 {. + stdcall, dynlib: "kernel32", importc: "FreeEnvironmentStringsW".} - proc GetCommandLineW*(): wideCString {.importc, stdcall, dynlib: "kernel32".} + proc getCommandLineW*(): WideCString {.importc: "GetCommandLineW", + stdcall, dynlib: "kernel32".} else: - proc GetFullPathNameA*(lpFileName: cstring, nBufferLength: int32, + proc getFullPathNameA*(lpFileName: cstring, nBufferLength: int32, lpBuffer: cstring, lpFilePart: var cstring): int32 {. - stdcall, dynlib: "kernel32", importc.} - proc GetFileAttributesA*(lpFileName: cstring): int32 {. - stdcall, dynlib: "kernel32", importc.} - proc SetFileAttributesA*(lpFileName: cstring, + stdcall, dynlib: "kernel32", + importc: "GetFullPathNameA".} + proc getFileAttributesA*(lpFileName: cstring): int32 {. + stdcall, dynlib: "kernel32", + importc: "GetFileAttributesA".} + proc setFileAttributesA*(lpFileName: cstring, dwFileAttributes: int32): WINBOOL {. stdcall, dynlib: "kernel32", importc: "SetFileAttributesA".} - proc CopyFileA*(lpExistingFileName, lpNewFileName: CString, + proc copyFileA*(lpExistingFileName, lpNewFileName: CString, bFailIfExists: cint): cint {. - importc, stdcall, dynlib: "kernel32".} + importc: "CopyFileA", stdcall, dynlib: "kernel32".} - proc GetEnvironmentStringsA*(): cstring {. - stdcall, dynlib: "kernel32", importc.} - proc FreeEnvironmentStringsA*(para1: cstring): int32 {. - stdcall, dynlib: "kernel32", importc.} + proc getEnvironmentStringsA*(): cstring {. + stdcall, dynlib: "kernel32", importc: "GetEnvironmentStringsA".} + proc freeEnvironmentStringsA*(para1: cstring): int32 {. + stdcall, dynlib: "kernel32", importc: "FreeEnvironmentStringsA".} - proc GetCommandLineA*(): CString {.importc, stdcall, dynlib: "kernel32".} + proc getCommandLineA*(): cstring {. + importc: "GetCommandLineA", stdcall, dynlib: "kernel32".} proc rdFileTime*(f: TFILETIME): int64 = result = ze64(f.dwLowDateTime) or (ze64(f.dwHighDateTime) shl 32) -proc rdFileSize*(f: TWin32FindData): int64 = +proc rdFileSize*(f: TWIN32_FIND_DATA): int64 = result = ze64(f.nFileSizeLow) or (ze64(f.nFileSizeHigh) shl 32) -proc GetSystemTimeAsFileTime*(lpSystemTimeAsFileTime: var TFILETIME) {. +proc getSystemTimeAsFileTime*(lpSystemTimeAsFileTime: var TFILETIME) {. importc: "GetSystemTimeAsFileTime", dynlib: "kernel32", stdcall.} -proc Sleep*(dwMilliseconds: int32){.stdcall, dynlib: "kernel32", +proc sleep*(dwMilliseconds: int32){.stdcall, dynlib: "kernel32", importc: "Sleep".} when useWinUnicode: - proc ShellExecuteW*(HWND: THandle, lpOperation, lpFile, - lpParameters, lpDirectory: widecstring, + proc shellExecuteW*(HWND: THandle, lpOperation, lpFile, + lpParameters, lpDirectory: WideCString, nShowCmd: int32): THandle{. stdcall, dynlib: "shell32.dll", importc: "ShellExecuteW".} else: - proc ShellExecuteA*(HWND: THandle, lpOperation, lpFile, + proc shellExecuteA*(HWND: THandle, lpOperation, lpFile, lpParameters, lpDirectory: cstring, nShowCmd: int32): THandle{. stdcall, dynlib: "shell32.dll", importc: "ShellExecuteA".} -proc GetFileInformationByHandle*(hFile: THandle, +proc getFileInformationByHandle*(hFile: THandle, lpFileInformation: ptr TBY_HANDLE_FILE_INFORMATION): WINBOOL{. stdcall, dynlib: "kernel32", importc: "GetFileInformationByHandle".} @@ -332,7 +340,7 @@ const WSAEWOULDBLOCK* = 10035 WSAEINPROGRESS* = 10036 -proc WSAGetLastError*(): cint {.importc: "WSAGetLastError", dynlib: ws2dll.} +proc wsaGetLastError*(): cint {.importc: "WSAGetLastError", dynlib: ws2dll.} type TSocketHandle* = distinct int @@ -410,7 +418,7 @@ type ai_addr*: ptr TSockAddr ## Socket address of socket. ai_next*: ptr TAddrInfo ## Pointer to next in list. - Tsocklen* = cuint + TSockLen* = cuint var SOMAXCONN* {.importc, header: "Winsock2.h".}: cint @@ -437,10 +445,10 @@ proc getservbyname*(name, proto: cstring): ptr TServent {. proc getservbyport*(port: cint, proto: cstring): ptr TServent {. stdcall, importc: "getservbyport", dynlib: ws2dll.} -proc gethostbyaddr*(ip: ptr TInAddr, len: cuint, theType: cint): ptr THostEnt {. +proc gethostbyaddr*(ip: ptr TInAddr, len: cuint, theType: cint): ptr Thostent {. stdcall, importc: "gethostbyaddr", dynlib: ws2dll.} -proc gethostbyname*(name: cstring): ptr THostEnt {. +proc gethostbyname*(name: cstring): ptr Thostent {. stdcall, importc: "gethostbyname", dynlib: ws2dll.} proc socket*(af, typ, protocol: cint): TSocketHandle {. @@ -470,7 +478,7 @@ proc listen*(s: TSocketHandle, backlog: cint): cint {. proc recv*(s: TSocketHandle, buf: pointer, len, flags: cint): cint {. stdcall, importc: "recv", dynlib: ws2dll.} proc recvfrom*(s: TSocketHandle, buf: cstring, len, flags: cint, - fromm: ptr TSockAddr, fromlen: ptr Tsocklen): cint {. + fromm: ptr TSockAddr, fromlen: ptr TSockLen): cint {. stdcall, importc: "recvfrom", dynlib: ws2dll.} proc select*(nfds: cint, readfds, writefds, exceptfds: ptr TFdSet, timeout: ptr TTimeval): cint {. @@ -478,35 +486,35 @@ proc select*(nfds: cint, readfds, writefds, exceptfds: ptr TFdSet, proc send*(s: TSocketHandle, buf: pointer, len, flags: cint): cint {. stdcall, importc: "send", dynlib: ws2dll.} proc sendto*(s: TSocketHandle, buf: pointer, len, flags: cint, - to: ptr TSockAddr, tolen: Tsocklen): cint {. + to: ptr TSockAddr, tolen: TSockLen): cint {. stdcall, importc: "sendto", dynlib: ws2dll.} proc shutdown*(s: TSocketHandle, how: cint): cint {. stdcall, importc: "shutdown", dynlib: ws2dll.} -proc getnameinfo*(a1: ptr Tsockaddr, a2: Tsocklen, - a3: cstring, a4: Tsocklen, a5: cstring, - a6: Tsocklen, a7: cint): cint {. +proc getnameinfo*(a1: ptr TSockAddr, a2: TSockLen, + a3: cstring, a4: TSockLen, a5: cstring, + a6: TSockLen, a7: cint): cint {. stdcall, importc: "getnameinfo", dynlib: ws2dll.} proc inet_addr*(cp: cstring): int32 {. stdcall, importc: "inet_addr", dynlib: ws2dll.} -proc WSAFDIsSet(s: TSocketHandle, FDSet: var TFDSet): bool {. +proc WSAFDIsSet(s: TSocketHandle, FDSet: var TFdSet): bool {. stdcall, importc: "__WSAFDIsSet", dynlib: ws2dll.} -proc FD_ISSET*(Socket: TSocketHandle, FDSet: var TFDSet): cint = +proc FD_ISSET*(Socket: TSocketHandle, FDSet: var TFdSet): cint = result = if WSAFDIsSet(Socket, FDSet): 1'i32 else: 0'i32 -proc FD_SET*(Socket: TSocketHandle, FDSet: var TFDSet) = +proc FD_SET*(Socket: TSocketHandle, FDSet: var TFdSet) = if FDSet.fd_count < FD_SETSIZE: FDSet.fd_array[int(FDSet.fd_count)] = Socket inc(FDSet.fd_count) -proc FD_ZERO*(FDSet: var TFDSet) = +proc FD_ZERO*(FDSet: var TFdSet) = FDSet.fd_count = 0 -proc WSAStartup*(wVersionRequired: int16, WSData: ptr TWSAData): cint {. +proc wsaStartup*(wVersionRequired: int16, WSData: ptr TWSAData): cint {. stdcall, importc: "WSAStartup", dynlib: ws2dll.} proc getaddrinfo*(nodename, servname: cstring, hints: ptr TAddrInfo, @@ -523,10 +531,10 @@ const MAXIMUM_WAIT_OBJECTS* = 0x00000040 type - TWOHandleArray* = array[0..MAXIMUM_WAIT_OBJECTS - 1, THANDLE] + TWOHandleArray* = array[0..MAXIMUM_WAIT_OBJECTS - 1, THandle] PWOHandleArray* = ptr TWOHandleArray -proc WaitForMultipleObjects*(nCount: DWORD, lpHandles: PWOHandleArray, +proc waitForMultipleObjects*(nCount: DWORD, lpHandles: PWOHandleArray, bWaitAll: WINBOOL, dwMilliseconds: DWORD): DWORD{. stdcall, dynlib: "kernel32", importc: "WaitForMultipleObjects".} @@ -558,53 +566,53 @@ const ERROR_ACCESS_DENIED* = 5 when useWinUnicode: - proc CreateFileW*(lpFileName: widecstring, dwDesiredAccess, dwShareMode: DWORD, + proc createFileW*(lpFileName: WideCString, dwDesiredAccess, dwShareMode: DWORD, lpSecurityAttributes: pointer, dwCreationDisposition, dwFlagsAndAttributes: DWORD, - hTemplateFile: THANDLE): THANDLE {. + hTemplateFile: THandle): THandle {. stdcall, dynlib: "kernel32", importc: "CreateFileW".} - proc DeleteFileW*(pathName: widecstring): int32 {. + proc deleteFileW*(pathName: WideCString): int32 {. importc: "DeleteFileW", dynlib: "kernel32", stdcall.} else: - proc CreateFileA*(lpFileName: cstring, dwDesiredAccess, dwShareMode: DWORD, + proc createFileA*(lpFileName: cstring, dwDesiredAccess, dwShareMode: DWORD, lpSecurityAttributes: pointer, dwCreationDisposition, dwFlagsAndAttributes: DWORD, hTemplateFile: THANDLE): THANDLE {. stdcall, dynlib: "kernel32", importc: "CreateFileA".} - proc DeleteFileA*(pathName: cstring): int32 {. + proc deleteFileA*(pathName: cstring): int32 {. importc: "DeleteFileA", dynlib: "kernel32", stdcall.} -proc SetEndOfFile*(hFile: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32", +proc setEndOfFile*(hFile: THandle): WINBOOL {.stdcall, dynlib: "kernel32", importc: "SetEndOfFile".} -proc SetFilePointer*(hFile: THANDLE, lDistanceToMove: LONG, +proc setFilePointer*(hFile: THandle, lDistanceToMove: LONG, lpDistanceToMoveHigh: ptr LONG, dwMoveMethod: DWORD): DWORD {. stdcall, dynlib: "kernel32", importc: "SetFilePointer".} -proc GetFileSize*(hFile: THANDLE, lpFileSizeHigh: ptr DWORD): DWORD{.stdcall, +proc getFileSize*(hFile: THandle, lpFileSizeHigh: ptr DWORD): DWORD{.stdcall, dynlib: "kernel32", importc: "GetFileSize".} -proc MapViewOfFileEx*(hFileMappingObject: THANDLE, dwDesiredAccess: DWORD, +proc mapViewOfFileEx*(hFileMappingObject: THandle, dwDesiredAccess: DWORD, dwFileOffsetHigh, dwFileOffsetLow: DWORD, dwNumberOfBytesToMap: DWORD, lpBaseAddress: pointer): pointer{. stdcall, dynlib: "kernel32", importc: "MapViewOfFileEx".} -proc CreateFileMappingW*(hFile: THANDLE, +proc createFileMappingW*(hFile: THandle, lpFileMappingAttributes: pointer, flProtect, dwMaximumSizeHigh: DWORD, dwMaximumSizeLow: DWORD, - lpName: pointer): THANDLE {. + lpName: pointer): THandle {. stdcall, dynlib: "kernel32", importc: "CreateFileMappingW".} when not useWinUnicode: - proc CreateFileMappingA*(hFile: THANDLE, + proc createFileMappingA*(hFile: THANDLE, lpFileMappingAttributes: pointer, flProtect, dwMaximumSizeHigh: DWORD, dwMaximumSizeLow: DWORD, lpName: cstring): THANDLE {. stdcall, dynlib: "kernel32", importc: "CreateFileMappingA".} -proc UnmapViewOfFile*(lpBaseAddress: pointer): WINBOOL {.stdcall, +proc unmapViewOfFile*(lpBaseAddress: pointer): WINBOOL {.stdcall, dynlib: "kernel32", importc: "UnmapViewOfFile".} diff --git a/lib/wrappers/libffi/common/ffi.h b/lib/wrappers/libffi/common/ffi.h new file mode 100644 index 000000000..07d650eac --- /dev/null +++ b/lib/wrappers/libffi/common/ffi.h @@ -0,0 +1,331 @@ +/* -----------------------------------------------------------------*-C-*- + libffi 2.00-beta - Copyright (c) 1996-2003 Red Hat, Inc. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +/* ------------------------------------------------------------------- + The basic API is described in the README file. + + The raw API is designed to bypass some of the argument packing + and unpacking on architectures for which it can be avoided. + + The closure API allows interpreted functions to be packaged up + inside a C function pointer, so that they can be called as C functions, + with no understanding on the client side that they are interpreted. + It can also be used in other cases in which it is necessary to package + up a user specified parameter and a function pointer as a single + function pointer. + + The closure API must be implemented in order to get its functionality, + e.g. for use by gij. Routines are provided to emulate the raw API + if the underlying platform doesn't allow faster implementation. + + More details on the raw and cloure API can be found in: + + http://gcc.gnu.org/ml/java/1999-q3/msg00138.html + + and + + http://gcc.gnu.org/ml/java/1999-q3/msg00174.html + -------------------------------------------------------------------- */ + +#ifndef LIBFFI_H +#define LIBFFI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Specify which architecture libffi is configured for. */ +//XXX #define X86 + +/* ---- System configuration information --------------------------------- */ + +#include <ffitarget.h> + +#ifndef LIBFFI_ASM + +#include <stddef.h> +#include <limits.h> + +/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example). + But we can find it either under the correct ANSI name, or under GNU + C's internal name. */ +#ifdef LONG_LONG_MAX +# define FFI_LONG_LONG_MAX LONG_LONG_MAX +#else +# ifdef LLONG_MAX +# define FFI_LONG_LONG_MAX LLONG_MAX +# else +# ifdef __GNUC__ +# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__ +# endif +# ifdef _MSC_VER +# define FFI_LONG_LONG_MAX _I64_MAX +# endif +# endif +#endif + +#if SCHAR_MAX == 127 +# define ffi_type_uchar ffi_type_uint8 +# define ffi_type_schar ffi_type_sint8 +#else + #error "char size not supported" +#endif + +#if SHRT_MAX == 32767 +# define ffi_type_ushort ffi_type_uint16 +# define ffi_type_sshort ffi_type_sint16 +#elif SHRT_MAX == 2147483647 +# define ffi_type_ushort ffi_type_uint32 +# define ffi_type_sshort ffi_type_sint32 +#else + #error "short size not supported" +#endif + +#if INT_MAX == 32767 +# define ffi_type_uint ffi_type_uint16 +# define ffi_type_sint ffi_type_sint16 +#elif INT_MAX == 2147483647 +# define ffi_type_uint ffi_type_uint32 +# define ffi_type_sint ffi_type_sint32 +#elif INT_MAX == 9223372036854775807 +# define ffi_type_uint ffi_type_uint64 +# define ffi_type_sint ffi_type_sint64 +#else + #error "int size not supported" +#endif + +#define ffi_type_ulong ffi_type_uint64 +#define ffi_type_slong ffi_type_sint64 +#if LONG_MAX == 2147483647 +# if FFI_LONG_LONG_MAX != 9223372036854775807 + #error "no 64-bit data type supported" +# endif +#elif LONG_MAX != 9223372036854775807 + #error "long size not supported" +#endif + +/* The closure code assumes that this works on pointers, i.e. a size_t */ +/* can hold a pointer. */ + +typedef struct _ffi_type +{ + size_t size; + unsigned short alignment; + unsigned short type; + /*@null@*/ struct _ffi_type **elements; +} ffi_type; + +/* These are defined in types.c */ +extern const ffi_type ffi_type_void; +extern const ffi_type ffi_type_uint8; +extern const ffi_type ffi_type_sint8; +extern const ffi_type ffi_type_uint16; +extern const ffi_type ffi_type_sint16; +extern const ffi_type ffi_type_uint32; +extern const ffi_type ffi_type_sint32; +extern const ffi_type ffi_type_uint64; +extern const ffi_type ffi_type_sint64; +extern const ffi_type ffi_type_float; +extern const ffi_type ffi_type_double; +extern const ffi_type ffi_type_longdouble; +extern const ffi_type ffi_type_pointer; + + +typedef enum { + FFI_OK = 0, + FFI_BAD_TYPEDEF, + FFI_BAD_ABI +} ffi_status; + +typedef unsigned FFI_TYPE; + +typedef struct { + ffi_abi abi; + unsigned nargs; + /*@dependent@*/ ffi_type **arg_types; + /*@dependent@*/ ffi_type *rtype; + unsigned bytes; + unsigned flags; +#ifdef FFI_EXTRA_CIF_FIELDS + FFI_EXTRA_CIF_FIELDS; +#endif +} ffi_cif; + +/* ---- Definitions for the raw API -------------------------------------- */ + +#ifdef _WIN64 +#define FFI_SIZEOF_ARG 8 +#else +#define FFI_SIZEOF_ARG 4 +#endif + +typedef union { + ffi_sarg sint; + ffi_arg uint; + float flt; + char data[FFI_SIZEOF_ARG]; + void* ptr; +} ffi_raw; + +void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, + void (*fn)(), + /*@out@*/ void *rvalue, + /*@dependent@*/ ffi_raw *avalue); + +void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); +void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); +size_t ffi_raw_size (ffi_cif *cif); + +/* This is analogous to the raw API, except it uses Java parameter */ +/* packing, even on 64-bit machines. I.e. on 64-bit machines */ +/* longs and doubles are followed by an empty 64-bit word. */ + +void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, + void (*fn)(), + /*@out@*/ void *rvalue, + /*@dependent@*/ ffi_raw *avalue); + +void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); +void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); +size_t ffi_java_raw_size (ffi_cif *cif); + +/* ---- Definitions for closures ----------------------------------------- */ + +#if FFI_CLOSURES + +typedef struct { + char tramp[FFI_TRAMPOLINE_SIZE]; + ffi_cif *cif; + void (*fun)(ffi_cif*,void*,void**,void*); + void *user_data; +} ffi_closure; + +void ffi_closure_free(void *); +void *ffi_closure_alloc (size_t size, void **code); + +ffi_status +ffi_prep_closure_loc (ffi_closure*, + ffi_cif *, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc); + +typedef struct { + char tramp[FFI_TRAMPOLINE_SIZE]; + + ffi_cif *cif; + +#if !FFI_NATIVE_RAW_API + + /* if this is enabled, then a raw closure has the same layout + as a regular closure. We use this to install an intermediate + handler to do the transaltion, void** -> ffi_raw*. */ + + void (*translate_args)(ffi_cif*,void*,void**,void*); + void *this_closure; + +#endif + + void (*fun)(ffi_cif*,void*,ffi_raw*,void*); + void *user_data; + +} ffi_raw_closure; + +ffi_status +ffi_prep_raw_closure (ffi_raw_closure*, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void *user_data); + +ffi_status +ffi_prep_java_raw_closure (ffi_raw_closure*, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void *user_data); + +#endif /* FFI_CLOSURES */ + +/* ---- Public interface definition -------------------------------------- */ + +ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, + ffi_abi abi, + unsigned int nargs, + /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, + /*@dependent@*/ ffi_type **atypes); + +void +ffi_call(/*@dependent@*/ ffi_cif *cif, + void (*fn)(), + /*@out@*/ void *rvalue, + /*@dependent@*/ void **avalue); + +/* Useful for eliminating compiler warnings */ +#define FFI_FN(f) ((void (*)())f) + +/* ---- Definitions shared with assembly code ---------------------------- */ + +#endif + +/* If these change, update src/mips/ffitarget.h. */ +#define FFI_TYPE_VOID 0 +#define FFI_TYPE_INT 1 +#define FFI_TYPE_FLOAT 2 +#define FFI_TYPE_DOUBLE 3 +#if 1 +#define FFI_TYPE_LONGDOUBLE 4 +#else +#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE +#endif +#define FFI_TYPE_UINT8 5 +#define FFI_TYPE_SINT8 6 +#define FFI_TYPE_UINT16 7 +#define FFI_TYPE_SINT16 8 +#define FFI_TYPE_UINT32 9 +#define FFI_TYPE_SINT32 10 +#define FFI_TYPE_UINT64 11 +#define FFI_TYPE_SINT64 12 +#define FFI_TYPE_STRUCT 13 +#define FFI_TYPE_POINTER 14 + +/* This should always refer to the last type code (for sanity checks) */ +#define FFI_TYPE_LAST FFI_TYPE_POINTER + +#define FFI_HIDDEN /* no idea what the origial definition looks like ... */ + +#ifdef __GNUC__ +# define LIKELY(x) __builtin_expect(x, 1) +# define UNLIKELY(x) __builtin_expect(x, 0) +#else +# define LIKELY(x) (x) +# define UNLIKELY(x) (x) +#endif + +#define MAYBE_UNUSED + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/lib/wrappers/libffi/common/ffi_common.h b/lib/wrappers/libffi/common/ffi_common.h new file mode 100644 index 000000000..43fb83b48 --- /dev/null +++ b/lib/wrappers/libffi/common/ffi_common.h @@ -0,0 +1,77 @@ +/* ----------------------------------------------------------------------- + ffi_common.h - Copyright (c) 1996 Red Hat, Inc. + + Common internal definitions and macros. Only necessary for building + libffi. + ----------------------------------------------------------------------- */ + +#ifndef FFI_COMMON_H +#define FFI_COMMON_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <fficonfig.h> +#include <malloc.h> + +/* Check for the existence of memcpy. */ +#if STDC_HEADERS +# include <string.h> +#else +# ifndef HAVE_MEMCPY +# define memcpy(d, s, n) bcopy ((s), (d), (n)) +# endif +#endif + +#if defined(FFI_DEBUG) +#include <stdio.h> +#endif + +#ifdef FFI_DEBUG +/*@exits@*/ void ffi_assert(/*@temp@*/ char *expr, /*@temp@*/ char *file, int line); +void ffi_stop_here(void); +void ffi_type_test(/*@temp@*/ /*@out@*/ ffi_type *a, /*@temp@*/ char *file, int line); + +#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__)) +#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l))) +#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__) +#else +#define FFI_ASSERT(x) +#define FFI_ASSERT_AT(x, f, l) +#define FFI_ASSERT_VALID_TYPE(x) +#endif + +#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1) + +/* Perform machine dependent cif processing */ +ffi_status ffi_prep_cif_machdep(ffi_cif *cif); + +/* Extended cif, used in callback from assembly routine */ +typedef struct +{ + /*@dependent@*/ ffi_cif *cif; + /*@dependent@*/ void *rvalue; + /*@dependent@*/ void **avalue; +} extended_cif; + +/* Terse sized type definitions. */ +typedef unsigned int UINT8 __attribute__((__mode__(__QI__))); +typedef signed int SINT8 __attribute__((__mode__(__QI__))); +typedef unsigned int UINT16 __attribute__((__mode__(__HI__))); +typedef signed int SINT16 __attribute__((__mode__(__HI__))); +typedef unsigned int UINT32 __attribute__((__mode__(__SI__))); +typedef signed int SINT32 __attribute__((__mode__(__SI__))); +typedef unsigned int UINT64 __attribute__((__mode__(__DI__))); +typedef signed int SINT64 __attribute__((__mode__(__DI__))); + +typedef float FLOAT32; + + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/lib/wrappers/libffi/common/fficonfig.h b/lib/wrappers/libffi/common/fficonfig.h new file mode 100644 index 000000000..c14f653ec --- /dev/null +++ b/lib/wrappers/libffi/common/fficonfig.h @@ -0,0 +1,96 @@ +/* fficonfig.h. Originally created by configure, now hand_maintained for MSVC. */ + +/* fficonfig.h. Generated automatically by configure. */ +/* fficonfig.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define this for MSVC, but not for mingw32! */ +#ifdef _MSC_VER +#define __attribute__(x) /* */ +#endif +#define alloca _alloca + +/*----------------------------------------------------------------*/ + +/* Define if using alloca.c. */ +/* #undef C_ALLOCA */ + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +/* #undef CRAY_STACKSEG_END */ + +/* Define if you have alloca, as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define if you have <alloca.h> and it should be used (not on Ultrix). */ +/* #define HAVE_ALLOCA_H 1 */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +/* #undef STACK_DIRECTION */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY 1 + +/* Define if read-only mmap of a plain file works. */ +//#define HAVE_MMAP_FILE 1 + +/* Define if mmap of /dev/zero works. */ +//#define HAVE_MMAP_DEV_ZERO 1 + +/* Define if mmap with MAP_ANON(YMOUS) works. */ +//#define HAVE_MMAP_ANON 1 + +/* The number of bytes in type double */ +#define SIZEOF_DOUBLE 8 + +/* The number of bytes in type long double */ +#define SIZEOF_LONG_DOUBLE 12 + +/* Define if you have the long double type and it is bigger than a double */ +#define HAVE_LONG_DOUBLE 1 + +/* whether byteorder is bigendian */ +/* #undef WORDS_BIGENDIAN */ + +/* Define if the host machine stores words of multi-word integers in + big-endian order. */ +/* #undef HOST_WORDS_BIG_ENDIAN */ + +/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */ +#define BYTEORDER 1234 + +/* Define if your assembler and linker support unaligned PC relative relocs. */ +/* #undef HAVE_AS_SPARC_UA_PCREL */ + +/* Define if your assembler supports .register. */ +/* #undef HAVE_AS_REGISTER_PSEUDO_OP */ + +/* Define if .eh_frame sections should be read-only. */ +/* #undef HAVE_RO_EH_FRAME */ + +/* Define to the flags needed for the .section .eh_frame directive. */ +/* #define EH_FRAME_FLAGS "aw" */ + +/* Define to the flags needed for the .section .eh_frame directive. */ +/* #define EH_FRAME_FLAGS "aw" */ + +/* Define this if you want extra debugging. */ +/* #undef FFI_DEBUG */ + +/* Define this is you do not want support for aggregate types. */ +/* #undef FFI_NO_STRUCTS */ + +/* Define this is you do not want support for the raw API. */ +/* #undef FFI_NO_RAW_API */ + +/* Define this if you are using Purify and want to suppress spurious messages. */ +/* #undef USING_PURIFY */ + diff --git a/lib/wrappers/libffi/common/ffitarget.h b/lib/wrappers/libffi/common/ffitarget.h new file mode 100644 index 000000000..d8d60f2e7 --- /dev/null +++ b/lib/wrappers/libffi/common/ffitarget.h @@ -0,0 +1,150 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 1996-2003, 2010 Red Hat, Inc. + Copyright (C) 2008 Free Software Foundation, Inc. + + Target configuration macros for x86 and x86-64. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +/* ---- System specific configurations ----------------------------------- */ + +/* For code common to all platforms on x86 and x86_64. */ +#define X86_ANY + +#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) +# if defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) +# define X86_64 +# define X86_WIN64 +# else +# define X86_32 +# define X86_WIN32 +# endif +#endif + +#if defined (X86_64) && defined (__i386__) +#undef X86_64 +#define X86 +#endif + +#ifdef X86_WIN64 +#define FFI_SIZEOF_ARG 8 +#define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */ +#endif + +/* ---- Generic type definitions ----------------------------------------- */ + +#ifndef LIBFFI_ASM +#ifdef X86_WIN64 +#ifdef _MSC_VER +typedef unsigned __int64 ffi_arg; +typedef __int64 ffi_sarg; +#else +typedef unsigned long long ffi_arg; +typedef long long ffi_sarg; +#endif +#else +#if defined __x86_64__ && defined __ILP32__ +#define FFI_SIZEOF_ARG 8 +#define FFI_SIZEOF_JAVA_RAW 4 +typedef unsigned long long ffi_arg; +typedef long long ffi_sarg; +#else +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; +#endif +#endif + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + + /* ---- Intel x86 Win32 ---------- */ +#ifdef X86_WIN32 + FFI_SYSV, + FFI_STDCALL, + FFI_THISCALL, + FFI_FASTCALL, + FFI_MS_CDECL, + FFI_LAST_ABI, +#ifdef _MSC_VER + FFI_DEFAULT_ABI = FFI_MS_CDECL +#else + FFI_DEFAULT_ABI = FFI_SYSV +#endif + +#elif defined(X86_WIN64) + FFI_WIN64, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_WIN64 + +#else + /* ---- Intel x86 and AMD x86-64 - */ + FFI_SYSV, + FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */ + FFI_LAST_ABI, +#if defined(__i386__) || defined(__i386) + FFI_DEFAULT_ABI = FFI_SYSV +#else + FFI_DEFAULT_ABI = FFI_UNIX64 +#endif +#endif +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1) +#define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2) +#define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3) +#define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4) + +#if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN)) +#define FFI_TRAMPOLINE_SIZE 24 +#define FFI_NATIVE_RAW_API 0 +#else +#ifdef X86_WIN32 +#define FFI_TRAMPOLINE_SIZE 52 +#else +#ifdef X86_WIN64 +#define FFI_TRAMPOLINE_SIZE 29 +#define FFI_NATIVE_RAW_API 0 +#define FFI_NO_RAW_API 1 +#else +#define FFI_TRAMPOLINE_SIZE 10 +#endif +#endif +#ifndef X86_WIN64 +#define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */ +#endif +#endif + +#endif + diff --git a/lib/wrappers/libffi/common/malloc_closure.c b/lib/wrappers/libffi/common/malloc_closure.c new file mode 100644 index 000000000..5b33aa4ca --- /dev/null +++ b/lib/wrappers/libffi/common/malloc_closure.c @@ -0,0 +1,110 @@ +#include <ffi.h> +#ifdef MS_WIN32 +#include <windows.h> +#else +#include <sys/mman.h> +#include <unistd.h> +# if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) +# define MAP_ANONYMOUS MAP_ANON +# endif +#endif +#include "ctypes.h" + +/* BLOCKSIZE can be adjusted. Larger blocksize will take a larger memory + overhead, but allocate less blocks from the system. It may be that some + systems have a limit of how many mmap'd blocks can be open. +*/ + +#define BLOCKSIZE _pagesize + +/* #define MALLOC_CLOSURE_DEBUG */ /* enable for some debugging output */ + +/******************************************************************/ + +typedef union _tagITEM { + ffi_closure closure; + union _tagITEM *next; +} ITEM; + +static ITEM *free_list; +static int _pagesize; + +static void more_core(void) +{ + ITEM *item; + int count, i; + +/* determine the pagesize */ +#ifdef MS_WIN32 + if (!_pagesize) { + SYSTEM_INFO systeminfo; + GetSystemInfo(&systeminfo); + _pagesize = systeminfo.dwPageSize; + } +#else + if (!_pagesize) { +#ifdef _SC_PAGESIZE + _pagesize = sysconf(_SC_PAGESIZE); +#else + _pagesize = getpagesize(); +#endif + } +#endif + + /* calculate the number of nodes to allocate */ + count = BLOCKSIZE / sizeof(ITEM); + + /* allocate a memory block */ +#ifdef MS_WIN32 + item = (ITEM *)VirtualAlloc(NULL, + count * sizeof(ITEM), + MEM_COMMIT, + PAGE_EXECUTE_READWRITE); + if (item == NULL) + return; +#else + item = (ITEM *)mmap(NULL, + count * sizeof(ITEM), + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, + 0); + if (item == (void *)MAP_FAILED) + return; +#endif + +#ifdef MALLOC_CLOSURE_DEBUG + printf("block at %p allocated (%d bytes), %d ITEMs\n", + item, count * sizeof(ITEM), count); +#endif + /* put them into the free list */ + for (i = 0; i < count; ++i) { + item->next = free_list; + free_list = item; + ++item; + } +} + +/******************************************************************/ + +/* put the item back into the free list */ +void ffi_closure_free(void *p) +{ + ITEM *item = (ITEM *)p; + item->next = free_list; + free_list = item; +} + +/* return one item from the free list, allocating more if needed */ +void *ffi_closure_alloc(size_t ignored, void** codeloc) +{ + ITEM *item; + if (!free_list) + more_core(); + if (!free_list) + return NULL; + item = free_list; + free_list = item->next; + *codeloc = (void *)item; + return (void *)item; +} diff --git a/lib/wrappers/libffi/common/raw_api.c b/lib/wrappers/libffi/common/raw_api.c new file mode 100644 index 000000000..ce21372e2 --- /dev/null +++ b/lib/wrappers/libffi/common/raw_api.c @@ -0,0 +1,254 @@ +/* ----------------------------------------------------------------------- + raw_api.c - Copyright (c) 1999, 2008 Red Hat, Inc. + + Author: Kresten Krab Thorup <krab@gnu.org> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +/* This file defines generic functions for use with the raw api. */ + +#include <ffi.h> +#include <ffi_common.h> + +#if !FFI_NO_RAW_API + +size_t +ffi_raw_size (ffi_cif *cif) +{ + size_t result = 0; + int i; + + ffi_type **at = cif->arg_types; + + for (i = cif->nargs-1; i >= 0; i--, at++) + { +#if !FFI_NO_STRUCTS + if ((*at)->type == FFI_TYPE_STRUCT) + result += ALIGN (sizeof (void*), FFI_SIZEOF_ARG); + else +#endif + result += ALIGN ((*at)->size, FFI_SIZEOF_ARG); + } + + return result; +} + + +void +ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args) +{ + unsigned i; + ffi_type **tp = cif->arg_types; + +#if WORDS_BIGENDIAN + + for (i = 0; i < cif->nargs; i++, tp++, args++) + { + switch ((*tp)->type) + { + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 1); + break; + + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 2); + break; + +#if FFI_SIZEOF_ARG >= 4 + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 4); + break; +#endif + +#if !FFI_NO_STRUCTS + case FFI_TYPE_STRUCT: + *args = (raw++)->ptr; + break; +#endif + + case FFI_TYPE_POINTER: + *args = (void*) &(raw++)->ptr; + break; + + default: + *args = raw; + raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + } + } + +#else /* WORDS_BIGENDIAN */ + +#if !PDP + + /* then assume little endian */ + for (i = 0; i < cif->nargs; i++, tp++, args++) + { +#if !FFI_NO_STRUCTS + if ((*tp)->type == FFI_TYPE_STRUCT) + { + *args = (raw++)->ptr; + } + else +#endif + { + *args = (void*) raw; + raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*); + } + } + +#else +#error "pdp endian not supported" +#endif /* ! PDP */ + +#endif /* WORDS_BIGENDIAN */ +} + +void +ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw) +{ + unsigned i; + ffi_type **tp = cif->arg_types; + + for (i = 0; i < cif->nargs; i++, tp++, args++) + { + switch ((*tp)->type) + { + case FFI_TYPE_UINT8: + (raw++)->uint = *(UINT8*) (*args); + break; + + case FFI_TYPE_SINT8: + (raw++)->sint = *(SINT8*) (*args); + break; + + case FFI_TYPE_UINT16: + (raw++)->uint = *(UINT16*) (*args); + break; + + case FFI_TYPE_SINT16: + (raw++)->sint = *(SINT16*) (*args); + break; + +#if FFI_SIZEOF_ARG >= 4 + case FFI_TYPE_UINT32: + (raw++)->uint = *(UINT32*) (*args); + break; + + case FFI_TYPE_SINT32: + (raw++)->sint = *(SINT32*) (*args); + break; +#endif + +#if !FFI_NO_STRUCTS + case FFI_TYPE_STRUCT: + (raw++)->ptr = *args; + break; +#endif + + case FFI_TYPE_POINTER: + (raw++)->ptr = **(void***) args; + break; + + default: + memcpy ((void*) raw->data, (void*)*args, (*tp)->size); + raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + } + } +} + +#if !FFI_NATIVE_RAW_API + + +/* This is a generic definition of ffi_raw_call, to be used if the + * native system does not provide a machine-specific implementation. + * Having this, allows code to be written for the raw API, without + * the need for system-specific code to handle input in that format; + * these following couple of functions will handle the translation forth + * and back automatically. */ + +void ffi_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *raw) +{ + void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); + ffi_raw_to_ptrarray (cif, raw, avalue); + ffi_call (cif, fn, rvalue, avalue); +} + +#if FFI_CLOSURES /* base system provides closures */ + +static void +ffi_translate_args (ffi_cif *cif, void *rvalue, + void **avalue, void *user_data) +{ + ffi_raw *raw = (ffi_raw*)alloca (ffi_raw_size (cif)); + ffi_raw_closure *cl = (ffi_raw_closure*)user_data; + + ffi_ptrarray_to_raw (cif, avalue, raw); + (*cl->fun) (cif, rvalue, raw, cl->user_data); +} + +ffi_status +ffi_prep_raw_closure_loc (ffi_raw_closure* cl, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void *user_data, + void *codeloc) +{ + ffi_status status; + + status = ffi_prep_closure_loc ((ffi_closure*) cl, + cif, + &ffi_translate_args, + codeloc, + codeloc); + if (status == FFI_OK) + { + cl->fun = fun; + cl->user_data = user_data; + } + + return status; +} + +#endif /* FFI_CLOSURES */ +#endif /* !FFI_NATIVE_RAW_API */ + +#if FFI_CLOSURES + +/* Again, here is the generic version of ffi_prep_raw_closure, which + * will install an intermediate "hub" for translation of arguments from + * the pointer-array format, to the raw format */ + +ffi_status +ffi_prep_raw_closure (ffi_raw_closure* cl, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void *user_data) +{ + return ffi_prep_raw_closure_loc (cl, cif, fun, user_data, cl); +} + +#endif /* FFI_CLOSURES */ + +#endif /* !FFI_NO_RAW_API */ diff --git a/lib/wrappers/libffi/gcc/closures.c b/lib/wrappers/libffi/gcc/closures.c new file mode 100644 index 000000000..c0ee06891 --- /dev/null +++ b/lib/wrappers/libffi/gcc/closures.c @@ -0,0 +1,627 @@ +/* ----------------------------------------------------------------------- + closures.c - Copyright (c) 2007, 2009, 2010 Red Hat, Inc. + Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc + Copyright (c) 2011 Plausible Labs Cooperative, Inc. + + Code to allocate and deallocate memory for closures. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#if defined __linux__ && !defined _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#include <ffi.h> +#include <ffi_common.h> + +#if !FFI_MMAP_EXEC_WRIT && !FFI_EXEC_TRAMPOLINE_TABLE +# if __gnu_linux__ +/* This macro indicates it may be forbidden to map anonymous memory + with both write and execute permission. Code compiled when this + option is defined will attempt to map such pages once, but if it + fails, it falls back to creating a temporary file in a writable and + executable filesystem and mapping pages from it into separate + locations in the virtual memory space, one location writable and + another executable. */ +# define FFI_MMAP_EXEC_WRIT 1 +# define HAVE_MNTENT 1 +# endif +# if defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__) +/* Windows systems may have Data Execution Protection (DEP) enabled, + which requires the use of VirtualMalloc/VirtualFree to alloc/free + executable memory. */ +# define FFI_MMAP_EXEC_WRIT 1 +# endif +#endif + +#if FFI_MMAP_EXEC_WRIT && !defined FFI_MMAP_EXEC_SELINUX +# ifdef __linux__ +/* When defined to 1 check for SELinux and if SELinux is active, + don't attempt PROT_EXEC|PROT_WRITE mapping at all, as that + might cause audit messages. */ +# define FFI_MMAP_EXEC_SELINUX 1 +# endif +#endif + +#if FFI_CLOSURES + +# if FFI_EXEC_TRAMPOLINE_TABLE + +// Per-target implementation; It's unclear what can reasonable be shared +// between two OS/architecture implementations. + +# elif FFI_MMAP_EXEC_WRIT /* !FFI_EXEC_TRAMPOLINE_TABLE */ + +#define USE_LOCKS 1 +#define USE_DL_PREFIX 1 +#ifdef __GNUC__ +#ifndef USE_BUILTIN_FFS +#define USE_BUILTIN_FFS 1 +#endif +#endif + +/* We need to use mmap, not sbrk. */ +#define HAVE_MORECORE 0 + +/* We could, in theory, support mremap, but it wouldn't buy us anything. */ +#define HAVE_MREMAP 0 + +/* We have no use for this, so save some code and data. */ +#define NO_MALLINFO 1 + +/* We need all allocations to be in regular segments, otherwise we + lose track of the corresponding code address. */ +#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T + +/* Don't allocate more than a page unless needed. */ +#define DEFAULT_GRANULARITY ((size_t)malloc_getpagesize) + +#if FFI_CLOSURE_TEST +/* Don't release single pages, to avoid a worst-case scenario of + continuously allocating and releasing single pages, but release + pairs of pages, which should do just as well given that allocations + are likely to be small. */ +#define DEFAULT_TRIM_THRESHOLD ((size_t)malloc_getpagesize) +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#ifndef _MSC_VER +#include <unistd.h> +#endif +#include <string.h> +#include <stdio.h> +#if !defined(X86_WIN32) && !defined(X86_WIN64) +#ifdef HAVE_MNTENT +#include <mntent.h> +#endif /* HAVE_MNTENT */ +#include <sys/param.h> +#include <pthread.h> + +/* We don't want sys/mman.h to be included after we redefine mmap and + dlmunmap. */ +#include <sys/mman.h> +#define LACKS_SYS_MMAN_H 1 + +#if FFI_MMAP_EXEC_SELINUX +#include <sys/statfs.h> +#include <stdlib.h> + +static int selinux_enabled = -1; + +static int +selinux_enabled_check (void) +{ + struct statfs sfs; + FILE *f; + char *buf = NULL; + size_t len = 0; + + if (statfs ("/selinux", &sfs) >= 0 + && (unsigned int) sfs.f_type == 0xf97cff8cU) + return 1; + f = fopen ("/proc/mounts", "r"); + if (f == NULL) + return 0; + while (getline (&buf, &len, f) >= 0) + { + char *p = strchr (buf, ' '); + if (p == NULL) + break; + p = strchr (p + 1, ' '); + if (p == NULL) + break; + if (strncmp (p + 1, "selinuxfs ", 10) == 0) + { + free (buf); + fclose (f); + return 1; + } + } + free (buf); + fclose (f); + return 0; +} + +#define is_selinux_enabled() (selinux_enabled >= 0 ? selinux_enabled \ + : (selinux_enabled = selinux_enabled_check ())) + +#else + +#define is_selinux_enabled() 0 + +#endif /* !FFI_MMAP_EXEC_SELINUX */ + +/* On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC. */ +#ifdef FFI_MMAP_EXEC_EMUTRAMP_PAX +#include <stdlib.h> + +static int emutramp_enabled = -1; + +static int +emutramp_enabled_check (void) +{ + if (getenv ("FFI_DISABLE_EMUTRAMP") == NULL) + return 1; + else + return 0; +} + +#define is_emutramp_enabled() (emutramp_enabled >= 0 ? emutramp_enabled \ + : (emutramp_enabled = emutramp_enabled_check ())) +#endif /* FFI_MMAP_EXEC_EMUTRAMP_PAX */ + +#elif defined (__CYGWIN__) || defined(__INTERIX) + +#include <sys/mman.h> + +/* Cygwin is Linux-like, but not quite that Linux-like. */ +#define is_selinux_enabled() 0 + +#endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */ + +#ifndef FFI_MMAP_EXEC_EMUTRAMP_PAX +#define is_emutramp_enabled() 0 +#endif /* FFI_MMAP_EXEC_EMUTRAMP_PAX */ + +#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) +/* Use these for mmap and munmap within dlmalloc.c. */ +static void *dlmmap(void *, size_t, int, int, int, off_t); +static int dlmunmap(void *, size_t); +#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */ + +#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) + +/* A mutex used to synchronize access to *exec* variables in this file. */ +static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER; + +/* A file descriptor of a temporary file from which we'll map + executable pages. */ +static int execfd = -1; + +/* The amount of space already allocated from the temporary file. */ +static size_t execsize = 0; + +/* Open a temporary file name, and immediately unlink it. */ +static int +open_temp_exec_file_name (char *name) +{ + int fd = mkstemp (name); + + if (fd != -1) + unlink (name); + + return fd; +} + +/* Open a temporary file in the named directory. */ +static int +open_temp_exec_file_dir (const char *dir) +{ + static const char suffix[] = "/ffiXXXXXX"; + int lendir = strlen (dir); + char *tempname = __builtin_alloca (lendir + sizeof (suffix)); + + if (!tempname) + return -1; + + memcpy (tempname, dir, lendir); + memcpy (tempname + lendir, suffix, sizeof (suffix)); + + return open_temp_exec_file_name (tempname); +} + +/* Open a temporary file in the directory in the named environment + variable. */ +static int +open_temp_exec_file_env (const char *envvar) +{ + const char *value = getenv (envvar); + + if (!value) + return -1; + + return open_temp_exec_file_dir (value); +} + +#ifdef HAVE_MNTENT +/* Open a temporary file in an executable and writable mount point + listed in the mounts file. Subsequent calls with the same mounts + keep searching for mount points in the same file. Providing NULL + as the mounts file closes the file. */ +static int +open_temp_exec_file_mnt (const char *mounts) +{ + static const char *last_mounts; + static FILE *last_mntent; + + if (mounts != last_mounts) + { + if (last_mntent) + endmntent (last_mntent); + + last_mounts = mounts; + + if (mounts) + last_mntent = setmntent (mounts, "r"); + else + last_mntent = NULL; + } + + if (!last_mntent) + return -1; + + for (;;) + { + int fd; + struct mntent mnt; + char buf[MAXPATHLEN * 3]; + + if (getmntent_r (last_mntent, &mnt, buf, sizeof (buf)) == NULL) + return -1; + + if (hasmntopt (&mnt, "ro") + || hasmntopt (&mnt, "noexec") + || access (mnt.mnt_dir, W_OK)) + continue; + + fd = open_temp_exec_file_dir (mnt.mnt_dir); + + if (fd != -1) + return fd; + } +} +#endif /* HAVE_MNTENT */ + +/* Instructions to look for a location to hold a temporary file that + can be mapped in for execution. */ +static struct +{ + int (*func)(const char *); + const char *arg; + int repeat; +} open_temp_exec_file_opts[] = { + { open_temp_exec_file_env, "TMPDIR", 0 }, + { open_temp_exec_file_dir, "/tmp", 0 }, + { open_temp_exec_file_dir, "/var/tmp", 0 }, + { open_temp_exec_file_dir, "/dev/shm", 0 }, + { open_temp_exec_file_env, "HOME", 0 }, +#ifdef HAVE_MNTENT + { open_temp_exec_file_mnt, "/etc/mtab", 1 }, + { open_temp_exec_file_mnt, "/proc/mounts", 1 }, +#endif /* HAVE_MNTENT */ +}; + +/* Current index into open_temp_exec_file_opts. */ +static int open_temp_exec_file_opts_idx = 0; + +/* Reset a current multi-call func, then advances to the next entry. + If we're at the last, go back to the first and return nonzero, + otherwise return zero. */ +static int +open_temp_exec_file_opts_next (void) +{ + if (open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat) + open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func (NULL); + + open_temp_exec_file_opts_idx++; + if (open_temp_exec_file_opts_idx + == (sizeof (open_temp_exec_file_opts) + / sizeof (*open_temp_exec_file_opts))) + { + open_temp_exec_file_opts_idx = 0; + return 1; + } + + return 0; +} + +/* Return a file descriptor of a temporary zero-sized file in a + writable and exexutable filesystem. */ +static int +open_temp_exec_file (void) +{ + int fd; + + do + { + fd = open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func + (open_temp_exec_file_opts[open_temp_exec_file_opts_idx].arg); + + if (!open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat + || fd == -1) + { + if (open_temp_exec_file_opts_next ()) + break; + } + } + while (fd == -1); + + return fd; +} + +/* Map in a chunk of memory from the temporary exec file into separate + locations in the virtual memory address space, one writable and one + executable. Returns the address of the writable portion, after + storing an offset to the corresponding executable portion at the + last word of the requested chunk. */ +static void * +dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset) +{ + void *ptr; + + if (execfd == -1) + { + open_temp_exec_file_opts_idx = 0; + retry_open: + execfd = open_temp_exec_file (); + if (execfd == -1) + return MFAIL; + } + + offset = execsize; + + if (ftruncate (execfd, offset + length)) + return MFAIL; + + flags &= ~(MAP_PRIVATE | MAP_ANONYMOUS); + flags |= MAP_SHARED; + + ptr = mmap (NULL, length, (prot & ~PROT_WRITE) | PROT_EXEC, + flags, execfd, offset); + if (ptr == MFAIL) + { + if (!offset) + { + close (execfd); + goto retry_open; + } + ftruncate (execfd, offset); + return MFAIL; + } + else if (!offset + && open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat) + open_temp_exec_file_opts_next (); + + start = mmap (start, length, prot, flags, execfd, offset); + + if (start == MFAIL) + { + munmap (ptr, length); + ftruncate (execfd, offset); + return start; + } + + mmap_exec_offset ((char *)start, length) = (char*)ptr - (char*)start; + + execsize += length; + + return start; +} + +/* Map in a writable and executable chunk of memory if possible. + Failing that, fall back to dlmmap_locked. */ +static void * +dlmmap (void *start, size_t length, int prot, + int flags, int fd, off_t offset) +{ + void *ptr; + + assert (start == NULL && length % malloc_getpagesize == 0 + && prot == (PROT_READ | PROT_WRITE) + && flags == (MAP_PRIVATE | MAP_ANONYMOUS) + && fd == -1 && offset == 0); + +#if FFI_CLOSURE_TEST + printf ("mapping in %zi\n", length); +#endif + + if (execfd == -1 && is_emutramp_enabled ()) + { + ptr = mmap (start, length, prot & ~PROT_EXEC, flags, fd, offset); + return ptr; + } + + if (execfd == -1 && !is_selinux_enabled ()) + { + ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset); + + if (ptr != MFAIL || (errno != EPERM && errno != EACCES)) + /* Cool, no need to mess with separate segments. */ + return ptr; + + /* If MREMAP_DUP is ever introduced and implemented, try mmap + with ((prot & ~PROT_WRITE) | PROT_EXEC) and mremap with + MREMAP_DUP and prot at this point. */ + } + + if (execsize == 0 || execfd == -1) + { + pthread_mutex_lock (&open_temp_exec_file_mutex); + ptr = dlmmap_locked (start, length, prot, flags, offset); + pthread_mutex_unlock (&open_temp_exec_file_mutex); + + return ptr; + } + + return dlmmap_locked (start, length, prot, flags, offset); +} + +/* Release memory at the given address, as well as the corresponding + executable page if it's separate. */ +static int +dlmunmap (void *start, size_t length) +{ + /* We don't bother decreasing execsize or truncating the file, since + we can't quite tell whether we're unmapping the end of the file. + We don't expect frequent deallocation anyway. If we did, we + could locate pages in the file by writing to the pages being + deallocated and checking that the file contents change. + Yuck. */ + msegmentptr seg = segment_holding (gm, start); + void *code; + +#if FFI_CLOSURE_TEST + printf ("unmapping %zi\n", length); +#endif + + if (seg && (code = add_segment_exec_offset (start, seg)) != start) + { + int ret = munmap (code, length); + if (ret) + return ret; + } + + return munmap (start, length); +} + +#if FFI_CLOSURE_FREE_CODE +/* Return segment holding given code address. */ +static msegmentptr +segment_holding_code (mstate m, char* addr) +{ + msegmentptr sp = &m->seg; + for (;;) { + if (addr >= add_segment_exec_offset (sp->base, sp) + && addr < add_segment_exec_offset (sp->base, sp) + sp->size) + return sp; + if ((sp = sp->next) == 0) + return 0; + } +} +#endif + +#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */ + +/* Allocate a chunk of memory with the given size. Returns a pointer + to the writable address, and sets *CODE to the executable + corresponding virtual address. */ +void * +ffi_closure_alloc (size_t size, void **code) +{ + *code = malloc(size); + return *code; +#if 0 + void *ptr; + + if (!code) + return NULL; + + ptr = dlmalloc (size); + + if (ptr) + { + msegmentptr seg = segment_holding (gm, ptr); + + *code = add_segment_exec_offset (ptr, seg); + } + + return ptr; +#endif +} + +/* Release a chunk of memory allocated with ffi_closure_alloc. If + FFI_CLOSURE_FREE_CODE is nonzero, the given address can be the + writable or the executable address given. Otherwise, only the + writable address can be provided here. */ +void +ffi_closure_free (void *ptr) +{ +#if 0 +#if FFI_CLOSURE_FREE_CODE + msegmentptr seg = segment_holding_code(gm, ptr); + + if (seg) + ptr = sub_segment_exec_offset(ptr, seg); +#endif + + dlfree(ptr); +#endif + free(ptr); +} + + +#if FFI_CLOSURE_TEST +/* Do some internal sanity testing to make sure allocation and + deallocation of pages are working as intended. */ +int main () +{ + void *p[3]; +#define GET(idx, len) do { p[idx] = dlmalloc (len); printf ("allocated %zi for p[%i]\n", (len), (idx)); } while (0) +#define PUT(idx) do { printf ("freeing p[%i]\n", (idx)); dlfree (p[idx]); } while (0) + GET (0, malloc_getpagesize / 2); + GET (1, 2 * malloc_getpagesize - 64 * sizeof (void*)); + PUT (1); + GET (1, 2 * malloc_getpagesize); + GET (2, malloc_getpagesize / 2); + PUT (1); + PUT (0); + PUT (2); + return 0; +} +#endif /* FFI_CLOSURE_TEST */ +# else /* ! FFI_MMAP_EXEC_WRIT */ + +/* On many systems, memory returned by malloc is writable and + executable, so just use it. */ + +#include <stdlib.h> + +void * +ffi_closure_alloc (size_t size, void **code) +{ + if (!code) + return NULL; + + return *code = malloc (size); +} + +void +ffi_closure_free (void *ptr) +{ + free (ptr); +} + +# endif /* ! FFI_MMAP_EXEC_WRIT */ +#endif /* FFI_CLOSURES */ diff --git a/lib/wrappers/libffi/gcc/ffi.c b/lib/wrappers/libffi/gcc/ffi.c new file mode 100644 index 000000000..0600414d4 --- /dev/null +++ b/lib/wrappers/libffi/gcc/ffi.c @@ -0,0 +1,841 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008 Red Hat, Inc. + Copyright (c) 2002 Ranjit Mathew + Copyright (c) 2002 Bo Thorsen + Copyright (c) 2002 Roger Sayle + Copyright (C) 2008, 2010 Free Software Foundation, Inc. + + x86 Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#if !defined(__x86_64__) || defined(_WIN64) + +#ifdef _WIN64 +#include <windows.h> +#endif + +#include <ffi.h> +#include <ffi_common.h> + +#include <stdlib.h> + +/* ffi_prep_args is called by the assembly routine once stack space + has been allocated for the function's arguments */ + +void ffi_prep_args(char *stack, extended_cif *ecif) +{ + register unsigned int i; + register void **p_argv; + register char *argp; + register ffi_type **p_arg; +#ifdef X86_WIN32 + size_t p_stack_args[2]; + void *p_stack_data[2]; + char *argp2 = stack; + int stack_args_count = 0; + int cabi = ecif->cif->abi; +#endif + + argp = stack; + + if ((ecif->cif->flags == FFI_TYPE_STRUCT + || ecif->cif->flags == FFI_TYPE_MS_STRUCT) +#ifdef X86_WIN64 + && (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2 + && ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8) +#endif + ) + { + *(void **) argp = ecif->rvalue; +#ifdef X86_WIN32 + /* For fastcall/thiscall this is first register-passed + argument. */ + if (cabi == FFI_THISCALL || cabi == FFI_FASTCALL) + { + p_stack_args[stack_args_count] = sizeof (void*); + p_stack_data[stack_args_count] = argp; + ++stack_args_count; + } +#endif + argp += sizeof(void*); + } + + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + i != 0; + i--, p_arg++) + { + size_t z; + + /* Align if necessary */ + if ((sizeof(void*) - 1) & (size_t) argp) + argp = (char *) ALIGN(argp, sizeof(void*)); + + z = (*p_arg)->size; +#ifdef X86_WIN64 + if (z > sizeof(ffi_arg) + || ((*p_arg)->type == FFI_TYPE_STRUCT + && (z != 1 && z != 2 && z != 4 && z != 8)) +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE + || ((*p_arg)->type == FFI_TYPE_LONGDOUBLE) +#endif + ) + { + z = sizeof(ffi_arg); + *(void **)argp = *p_argv; + } + else if ((*p_arg)->type == FFI_TYPE_FLOAT) + { + memcpy(argp, *p_argv, z); + } + else +#endif + if (z < sizeof(ffi_arg)) + { + z = sizeof(ffi_arg); + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(ffi_sarg *) argp = (ffi_sarg)*(SINT8 *)(* p_argv); + break; + + case FFI_TYPE_UINT8: + *(ffi_arg *) argp = (ffi_arg)*(UINT8 *)(* p_argv); + break; + + case FFI_TYPE_SINT16: + *(ffi_sarg *) argp = (ffi_sarg)*(SINT16 *)(* p_argv); + break; + + case FFI_TYPE_UINT16: + *(ffi_arg *) argp = (ffi_arg)*(UINT16 *)(* p_argv); + break; + + case FFI_TYPE_SINT32: + *(ffi_sarg *) argp = (ffi_sarg)*(SINT32 *)(* p_argv); + break; + + case FFI_TYPE_UINT32: + *(ffi_arg *) argp = (ffi_arg)*(UINT32 *)(* p_argv); + break; + + case FFI_TYPE_STRUCT: + *(ffi_arg *) argp = *(ffi_arg *)(* p_argv); + break; + + default: + FFI_ASSERT(0); + } + } + else + { + memcpy(argp, *p_argv, z); + } + +#ifdef X86_WIN32 + /* For thiscall/fastcall convention register-passed arguments + are the first two none-floating-point arguments with a size + smaller or equal to sizeof (void*). */ + if ((cabi == FFI_THISCALL && stack_args_count < 1) + || (cabi == FFI_FASTCALL && stack_args_count < 2)) + { + if (z <= 4 + && ((*p_arg)->type != FFI_TYPE_FLOAT + && (*p_arg)->type != FFI_TYPE_STRUCT)) + { + p_stack_args[stack_args_count] = z; + p_stack_data[stack_args_count] = argp; + ++stack_args_count; + } + } +#endif + p_argv++; +#ifdef X86_WIN64 + argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1); +#else + argp += z; +#endif + } + +#ifdef X86_WIN32 + /* We need to move the register-passed arguments for thiscall/fastcall + on top of stack, so that those can be moved to registers ecx/edx by + call-handler. */ + if (stack_args_count > 0) + { + size_t zz = (p_stack_args[0] + 3) & ~3; + char *h; + + /* Move first argument to top-stack position. */ + if (p_stack_data[0] != argp2) + { + h = alloca (zz + 1); + memcpy (h, p_stack_data[0], zz); + memmove (argp2 + zz, argp2, + (size_t) ((char *) p_stack_data[0] - (char*)argp2)); + memcpy (argp2, h, zz); + } + + argp2 += zz; + --stack_args_count; + if (zz > 4) + stack_args_count = 0; + + /* If we have a second argument, then move it on top + after the first one. */ + if (stack_args_count > 0 && p_stack_data[1] != argp2) + { + zz = p_stack_args[1]; + zz = (zz + 3) & ~3; + h = alloca (zz + 1); + h = alloca (zz + 1); + memcpy (h, p_stack_data[1], zz); + memmove (argp2 + zz, argp2, (size_t) ((char*) p_stack_data[1] - (char*)argp2)); + memcpy (argp2, h, zz); + } + } +#endif + return; +} + +/* Perform machine dependent cif processing */ +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +{ + unsigned int i; + ffi_type **ptr; + + /* Set the return type flag */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + case FFI_TYPE_UINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT8: + case FFI_TYPE_SINT16: +#ifdef X86_WIN64 + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: +#endif + case FFI_TYPE_SINT64: + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: +#ifndef X86_WIN64 +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE + case FFI_TYPE_LONGDOUBLE: +#endif +#endif + cif->flags = (unsigned) cif->rtype->type; + break; + + case FFI_TYPE_UINT64: +#ifdef X86_WIN64 + case FFI_TYPE_POINTER: +#endif + cif->flags = FFI_TYPE_SINT64; + break; + + case FFI_TYPE_STRUCT: +#ifndef X86 + if (cif->rtype->size == 1) + { + cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */ + } + else if (cif->rtype->size == 2) + { + cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */ + } + else if (cif->rtype->size == 4) + { +#ifdef X86_WIN64 + cif->flags = FFI_TYPE_SMALL_STRUCT_4B; +#else + cif->flags = FFI_TYPE_INT; /* same as int type */ +#endif + } + else if (cif->rtype->size == 8) + { + cif->flags = FFI_TYPE_SINT64; /* same as int64 type */ + } + else +#endif + { +#ifdef X86_WIN32 + if (cif->abi == FFI_MS_CDECL) + cif->flags = FFI_TYPE_MS_STRUCT; + else +#endif + cif->flags = FFI_TYPE_STRUCT; + /* allocate space for return value pointer */ + cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG); + } + break; + + default: +#ifdef X86_WIN64 + cif->flags = FFI_TYPE_SINT64; + break; + case FFI_TYPE_INT: + cif->flags = FFI_TYPE_SINT32; +#else + cif->flags = FFI_TYPE_INT; +#endif + break; + } + + for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) + { + if (((*ptr)->alignment - 1) & cif->bytes) + cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment); + cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG); + } + +#ifdef X86_WIN64 + /* ensure space for storing four registers */ + cif->bytes += 4 * sizeof(ffi_arg); +#endif + + cif->bytes = (cif->bytes + 15) & ~0xF; + + return FFI_OK; +} + +#ifdef X86_WIN64 +extern int +ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *, + unsigned, unsigned, unsigned *, void (*fn)(void)); +#elif defined(X86_WIN32) +extern void +ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *, + unsigned, unsigned, unsigned, unsigned *, void (*fn)(void)); +#else +extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, + unsigned, unsigned, unsigned *, void (*fn)(void)); +#endif + +void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return */ + /* value address then we need to make one */ + +#ifdef X86_WIN64 + if (rvalue == NULL + && cif->flags == FFI_TYPE_STRUCT + && cif->rtype->size != 1 && cif->rtype->size != 2 + && cif->rtype->size != 4 && cif->rtype->size != 8) + { + ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF); + } +#else + if (rvalue == NULL + && (cif->flags == FFI_TYPE_STRUCT + || cif->flags == FFI_TYPE_MS_STRUCT)) + { + ecif.rvalue = alloca(cif->rtype->size); + } +#endif + else + ecif.rvalue = rvalue; + + + switch (cif->abi) + { +#ifdef X86_WIN64 + case FFI_WIN64: + ffi_call_win64(ffi_prep_args, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); + break; +#elif defined(X86_WIN32) + case FFI_SYSV: + case FFI_STDCALL: + case FFI_MS_CDECL: + ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags, + ecif.rvalue, fn); + break; + case FFI_THISCALL: + case FFI_FASTCALL: + { + unsigned int abi = cif->abi; + unsigned int i, passed_regs = 0; + + if (cif->flags == FFI_TYPE_STRUCT) + ++passed_regs; + + for (i=0; i < cif->nargs && passed_regs < 2;i++) + { + size_t sz; + + if (cif->arg_types[i]->type == FFI_TYPE_FLOAT + || cif->arg_types[i]->type == FFI_TYPE_STRUCT) + continue; + sz = (cif->arg_types[i]->size + 3) & ~3; + if (sz == 0 || sz > 4) + continue; + ++passed_regs; + } + if (passed_regs < 2 && abi == FFI_FASTCALL) + abi = FFI_THISCALL; + if (passed_regs < 1 && abi == FFI_THISCALL) + abi = FFI_STDCALL; + ffi_call_win32(ffi_prep_args, &ecif, abi, cif->bytes, cif->flags, + ecif.rvalue, fn); + } + break; +#else + case FFI_SYSV: + ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, + fn); + break; +#endif + default: + FFI_ASSERT(0); + break; + } +} + + +/** private members **/ + +/* The following __attribute__((regparm(1))) decorations will have no effect + on MSVC or SUNPRO_C -- standard conventions apply. */ +static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, + void** args, ffi_cif* cif); +void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *) + __attribute__ ((regparm(1))); +unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *) + __attribute__ ((regparm(1))); +void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *) + __attribute__ ((regparm(1))); +#ifdef X86_WIN32 +void FFI_HIDDEN ffi_closure_raw_THISCALL (ffi_raw_closure *) + __attribute__ ((regparm(1))); +void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *) + __attribute__ ((regparm(1))); +void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *) + __attribute__ ((regparm(1))); +#endif +#ifdef X86_WIN64 +void FFI_HIDDEN ffi_closure_win64 (ffi_closure *); +#endif + +/* This function is jumped to by the trampoline */ + +#ifdef X86_WIN64 +void * FFI_HIDDEN +ffi_closure_win64_inner (ffi_closure *closure, void *args) { + ffi_cif *cif; + void **arg_area; + void *result; + void *resp = &result; + + cif = closure->cif; + arg_area = (void**) alloca (cif->nargs * sizeof (void*)); + + /* this call will initialize ARG_AREA, such that each + * element in that array points to the corresponding + * value on the stack; and if the function returns + * a structure, it will change RESP to point to the + * structure return address. */ + + ffi_prep_incoming_args_SYSV(args, &resp, arg_area, cif); + + (closure->fun) (cif, resp, arg_area, closure->user_data); + + /* The result is returned in rax. This does the right thing for + result types except for floats; we have to 'mov xmm0, rax' in the + caller to correct this. + TODO: structure sizes of 3 5 6 7 are returned by reference, too!!! + */ + return cif->rtype->size > sizeof(void *) ? resp : *(void **)resp; +} + +#else +unsigned int FFI_HIDDEN __attribute__ ((regparm(1))) +ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args) +{ + /* our various things... */ + ffi_cif *cif; + void **arg_area; + + cif = closure->cif; + arg_area = (void**) alloca (cif->nargs * sizeof (void*)); + + /* this call will initialize ARG_AREA, such that each + * element in that array points to the corresponding + * value on the stack; and if the function returns + * a structure, it will change RESP to point to the + * structure return address. */ + + ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif); + + (closure->fun) (cif, *respp, arg_area, closure->user_data); + + return cif->flags; +} +#endif /* !X86_WIN64 */ + +static void +ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, + ffi_cif *cif) +{ + register unsigned int i; + register void **p_argv; + register char *argp; + register ffi_type **p_arg; + + argp = stack; + +#ifdef X86_WIN64 + if (cif->rtype->size > sizeof(ffi_arg) + || (cif->flags == FFI_TYPE_STRUCT + && (cif->rtype->size != 1 && cif->rtype->size != 2 + && cif->rtype->size != 4 && cif->rtype->size != 8))) { + *rvalue = *(void **) argp; + argp += sizeof(void *); + } +#else + if ( cif->flags == FFI_TYPE_STRUCT + || cif->flags == FFI_TYPE_MS_STRUCT ) { + *rvalue = *(void **) argp; + argp += sizeof(void *); + } +#endif + + p_argv = avalue; + + for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) + { + size_t z; + + /* Align if necessary */ + if ((sizeof(void*) - 1) & (size_t) argp) { + argp = (char *) ALIGN(argp, sizeof(void*)); + } + +#ifdef X86_WIN64 + if ((*p_arg)->size > sizeof(ffi_arg) + || ((*p_arg)->type == FFI_TYPE_STRUCT + && ((*p_arg)->size != 1 && (*p_arg)->size != 2 + && (*p_arg)->size != 4 && (*p_arg)->size != 8))) + { + z = sizeof(void *); + *p_argv = *(void **)argp; + } + else +#endif + { + z = (*p_arg)->size; + + /* because we're little endian, this is what it turns into. */ + + *p_argv = (void*) argp; + } + + p_argv++; +#ifdef X86_WIN64 + argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1); +#else + argp += z; +#endif + } + + return; +} + +#define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \ +{ unsigned char *__tramp = (unsigned char*)(TRAMP); \ + void* __fun = (void*)(FUN); \ + void* __ctx = (void*)(CTX); \ + *(unsigned char*) &__tramp[0] = 0x41; \ + *(unsigned char*) &__tramp[1] = 0xbb; \ + *(unsigned int*) &__tramp[2] = MASK; /* mov $mask, %r11 */ \ + *(unsigned char*) &__tramp[6] = 0x48; \ + *(unsigned char*) &__tramp[7] = 0xb8; \ + *(void**) &__tramp[8] = __ctx; /* mov __ctx, %rax */ \ + *(unsigned char *) &__tramp[16] = 0x49; \ + *(unsigned char *) &__tramp[17] = 0xba; \ + *(void**) &__tramp[18] = __fun; /* mov __fun, %r10 */ \ + *(unsigned char *) &__tramp[26] = 0x41; \ + *(unsigned char *) &__tramp[27] = 0xff; \ + *(unsigned char *) &__tramp[28] = 0xe2; /* jmp %r10 */ \ + } + +/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */ + +#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \ +{ unsigned char *__tramp = (unsigned char*)(TRAMP); \ + unsigned int __fun = (unsigned int)(FUN); \ + unsigned int __ctx = (unsigned int)(CTX); \ + unsigned int __dis = __fun - (__ctx + 10); \ + *(unsigned char*) &__tramp[0] = 0xb8; \ + *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ + *(unsigned char *) &__tramp[5] = 0xe9; \ + *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \ + } + +#define FFI_INIT_TRAMPOLINE_THISCALL(TRAMP,FUN,CTX,SIZE) \ +{ unsigned char *__tramp = (unsigned char*)(TRAMP); \ + unsigned int __fun = (unsigned int)(FUN); \ + unsigned int __ctx = (unsigned int)(CTX); \ + unsigned int __dis = __fun - (__ctx + 49); \ + unsigned short __size = (unsigned short)(SIZE); \ + *(unsigned int *) &__tramp[0] = 0x8324048b; /* mov (%esp), %eax */ \ + *(unsigned int *) &__tramp[4] = 0x4c890cec; /* sub $12, %esp */ \ + *(unsigned int *) &__tramp[8] = 0x04890424; /* mov %ecx, 4(%esp) */ \ + *(unsigned char*) &__tramp[12] = 0x24; /* mov %eax, (%esp) */ \ + *(unsigned char*) &__tramp[13] = 0xb8; \ + *(unsigned int *) &__tramp[14] = __size; /* mov __size, %eax */ \ + *(unsigned int *) &__tramp[18] = 0x08244c8d; /* lea 8(%esp), %ecx */ \ + *(unsigned int *) &__tramp[22] = 0x4802e8c1; /* shr $2, %eax ; dec %eax */ \ + *(unsigned short*) &__tramp[26] = 0x0b74; /* jz 1f */ \ + *(unsigned int *) &__tramp[28] = 0x8908518b; /* 2b: mov 8(%ecx), %edx */ \ + *(unsigned int *) &__tramp[32] = 0x04c18311; /* mov %edx, (%ecx) ; add $4, %ecx */ \ + *(unsigned char*) &__tramp[36] = 0x48; /* dec %eax */ \ + *(unsigned short*) &__tramp[37] = 0xf575; /* jnz 2b ; 1f: */ \ + *(unsigned char*) &__tramp[39] = 0xb8; \ + *(unsigned int*) &__tramp[40] = __ctx; /* movl __ctx, %eax */ \ + *(unsigned char *) &__tramp[44] = 0xe8; \ + *(unsigned int*) &__tramp[45] = __dis; /* call __fun */ \ + *(unsigned char*) &__tramp[49] = 0xc2; /* ret */ \ + *(unsigned short*) &__tramp[50] = (__size + 8); /* ret (__size + 8) */ \ + } + +#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \ +{ unsigned char *__tramp = (unsigned char*)(TRAMP); \ + unsigned int __fun = (unsigned int)(FUN); \ + unsigned int __ctx = (unsigned int)(CTX); \ + unsigned int __dis = __fun - (__ctx + 10); \ + unsigned short __size = (unsigned short)(SIZE); \ + *(unsigned char*) &__tramp[0] = 0xb8; \ + *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ + *(unsigned char *) &__tramp[5] = 0xe8; \ + *(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \ + *(unsigned char *) &__tramp[10] = 0xc2; \ + *(unsigned short*) &__tramp[11] = __size; /* ret __size */ \ + } + +/* the cif must already be prep'ed */ + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) +{ +#ifdef X86_WIN64 +#define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE) +#define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0) + if (cif->abi == FFI_WIN64) + { + int mask = FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3); + FFI_INIT_TRAMPOLINE_WIN64 (&closure->tramp[0], + &ffi_closure_win64, + codeloc, mask); + /* make sure we can execute here */ + } +#else + if (cif->abi == FFI_SYSV) + { + FFI_INIT_TRAMPOLINE (&closure->tramp[0], + &ffi_closure_SYSV, + (void*)codeloc); + } +#ifdef X86_WIN32 + else if (cif->abi == FFI_THISCALL) + { + FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0], + &ffi_closure_THISCALL, + (void*)codeloc, + cif->bytes); + } + else if (cif->abi == FFI_STDCALL) + { + FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0], + &ffi_closure_STDCALL, + (void*)codeloc, cif->bytes); + } + else if (cif->abi == FFI_MS_CDECL) + { + FFI_INIT_TRAMPOLINE (&closure->tramp[0], + &ffi_closure_SYSV, + (void*)codeloc); + } +#endif /* X86_WIN32 */ +#endif /* !X86_WIN64 */ + else + { + return FFI_BAD_ABI; + } + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} + +/* ------- Native raw API support -------------------------------- */ + +#if !FFI_NO_RAW_API + +ffi_status +ffi_prep_raw_closure_loc (ffi_raw_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void *user_data, + void *codeloc) +{ + int i; + + if (cif->abi != FFI_SYSV) { +#ifdef X86_WIN32 + if (cif->abi != FFI_THISCALL) +#endif + return FFI_BAD_ABI; + } + + /* we currently don't support certain kinds of arguments for raw + closures. This should be implemented by a separate assembly + language routine, since it would require argument processing, + something we don't do now for performance. */ + + for (i = cif->nargs-1; i >= 0; i--) + { + FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT); + FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE); + } + +#ifdef X86_WIN32 + if (cif->abi == FFI_SYSV) + { +#endif + FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV, + codeloc); +#ifdef X86_WIN32 + } + else if (cif->abi == FFI_THISCALL) + { + FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0], &ffi_closure_raw_THISCALL, + codeloc, cif->bytes); + } +#endif + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} + +static void +ffi_prep_args_raw(char *stack, extended_cif *ecif) +{ + memcpy (stack, ecif->avalue, ecif->cif->bytes); +} + +/* we borrow this routine from libffi (it must be changed, though, to + * actually call the function passed in the first argument. as of + * libffi-1.20, this is not the case.) + */ + +void +ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue) +{ + extended_cif ecif; + void **avalue = (void **)fake_avalue; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return */ + /* value address then we need to make one */ + + if (rvalue == NULL + && (cif->flags == FFI_TYPE_STRUCT + || cif->flags == FFI_TYPE_MS_STRUCT)) + { + ecif.rvalue = alloca(cif->rtype->size); + } + else + ecif.rvalue = rvalue; + + + switch (cif->abi) + { +#ifdef X86_WIN32 + case FFI_SYSV: + case FFI_STDCALL: + case FFI_MS_CDECL: + ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags, + ecif.rvalue, fn); + break; + case FFI_THISCALL: + case FFI_FASTCALL: + { + unsigned int abi = cif->abi; + unsigned int i, passed_regs = 0; + + if (cif->flags == FFI_TYPE_STRUCT) + ++passed_regs; + + for (i=0; i < cif->nargs && passed_regs < 2;i++) + { + size_t sz; + + if (cif->arg_types[i]->type == FFI_TYPE_FLOAT + || cif->arg_types[i]->type == FFI_TYPE_STRUCT) + continue; + sz = (cif->arg_types[i]->size + 3) & ~3; + if (sz == 0 || sz > 4) + continue; + ++passed_regs; + } + if (passed_regs < 2 && abi == FFI_FASTCALL) + cif->abi = abi = FFI_THISCALL; + if (passed_regs < 1 && abi == FFI_THISCALL) + cif->abi = abi = FFI_STDCALL; + ffi_call_win32(ffi_prep_args_raw, &ecif, abi, cif->bytes, cif->flags, + ecif.rvalue, fn); + } + break; +#else + case FFI_SYSV: + ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, + ecif.rvalue, fn); + break; +#endif + default: + FFI_ASSERT(0); + break; + } +} + +#endif + +#endif /* !__x86_64__ || X86_WIN64 */ + diff --git a/lib/wrappers/libffi/gcc/ffi64.c b/lib/wrappers/libffi/gcc/ffi64.c new file mode 100644 index 000000000..2014af24c --- /dev/null +++ b/lib/wrappers/libffi/gcc/ffi64.c @@ -0,0 +1,673 @@ +/* ----------------------------------------------------------------------- + ffi64.c - Copyright (c) 2013 The Written Word, Inc. + Copyright (c) 2011 Anthony Green + Copyright (c) 2008, 2010 Red Hat, Inc. + Copyright (c) 2002, 2007 Bo Thorsen <bo@suse.de> + + x86-64 Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#include <ffi.h> +#include <ffi_common.h> + +#include <stdlib.h> +#include <stdarg.h> + +#ifdef __x86_64__ + +#define MAX_GPR_REGS 6 +#define MAX_SSE_REGS 8 + +#if defined(__INTEL_COMPILER) +#define UINT128 __m128 +#else +#if defined(__SUNPRO_C) +#include <sunmedia_types.h> +#define UINT128 __m128i +#else +#define UINT128 __int128_t +#endif +#endif + +union big_int_union +{ + UINT32 i32; + UINT64 i64; + UINT128 i128; +}; + +struct register_args +{ + /* Registers for argument passing. */ + UINT64 gpr[MAX_GPR_REGS]; + union big_int_union sse[MAX_SSE_REGS]; +}; + +extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags, + void *raddr, void (*fnaddr)(void), unsigned ssecount); + +/* All reference to register classes here is identical to the code in + gcc/config/i386/i386.c. Do *not* change one without the other. */ + +/* Register class used for passing given 64bit part of the argument. + These represent classes as documented by the PS ABI, with the + exception of SSESF, SSEDF classes, that are basically SSE class, + just gcc will use SF or DFmode move instead of DImode to avoid + reformatting penalties. + + Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves + whenever possible (upper half does contain padding). */ +enum x86_64_reg_class + { + X86_64_NO_CLASS, + X86_64_INTEGER_CLASS, + X86_64_INTEGERSI_CLASS, + X86_64_SSE_CLASS, + X86_64_SSESF_CLASS, + X86_64_SSEDF_CLASS, + X86_64_SSEUP_CLASS, + X86_64_X87_CLASS, + X86_64_X87UP_CLASS, + X86_64_COMPLEX_X87_CLASS, + X86_64_MEMORY_CLASS + }; + +#define MAX_CLASSES 4 + +#define SSE_CLASS_P(X) ((X) >= X86_64_SSE_CLASS && X <= X86_64_SSEUP_CLASS) + +/* x86-64 register passing implementation. See x86-64 ABI for details. Goal + of this code is to classify each 8bytes of incoming argument by the register + class and assign registers accordingly. */ + +/* Return the union class of CLASS1 and CLASS2. + See the x86-64 PS ABI for details. */ + +static enum x86_64_reg_class +merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2) +{ + /* Rule #1: If both classes are equal, this is the resulting class. */ + if (class1 == class2) + return class1; + + /* Rule #2: If one of the classes is NO_CLASS, the resulting class is + the other class. */ + if (class1 == X86_64_NO_CLASS) + return class2; + if (class2 == X86_64_NO_CLASS) + return class1; + + /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */ + if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS) + return X86_64_MEMORY_CLASS; + + /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */ + if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS) + || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS)) + return X86_64_INTEGERSI_CLASS; + if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS + || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS) + return X86_64_INTEGER_CLASS; + + /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class, + MEMORY is used. */ + if (class1 == X86_64_X87_CLASS + || class1 == X86_64_X87UP_CLASS + || class1 == X86_64_COMPLEX_X87_CLASS + || class2 == X86_64_X87_CLASS + || class2 == X86_64_X87UP_CLASS + || class2 == X86_64_COMPLEX_X87_CLASS) + return X86_64_MEMORY_CLASS; + + /* Rule #6: Otherwise class SSE is used. */ + return X86_64_SSE_CLASS; +} + +/* Classify the argument of type TYPE and mode MODE. + CLASSES will be filled by the register class used to pass each word + of the operand. The number of words is returned. In case the parameter + should be passed in memory, 0 is returned. As a special case for zero + sized containers, classes[0] will be NO_CLASS and 1 is returned. + + See the x86-64 PS ABI for details. +*/ +static int +classify_argument (ffi_type *type, enum x86_64_reg_class classes[], + size_t byte_offset) +{ + switch (type->type) + { + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_POINTER: + { + int size = byte_offset + type->size; + + if (size <= 4) + { + classes[0] = X86_64_INTEGERSI_CLASS; + return 1; + } + else if (size <= 8) + { + classes[0] = X86_64_INTEGER_CLASS; + return 1; + } + else if (size <= 12) + { + classes[0] = X86_64_INTEGER_CLASS; + classes[1] = X86_64_INTEGERSI_CLASS; + return 2; + } + else if (size <= 16) + { + classes[0] = classes[1] = X86_64_INTEGERSI_CLASS; + return 2; + } + else + FFI_ASSERT (0); + } + case FFI_TYPE_FLOAT: + if (!(byte_offset % 8)) + classes[0] = X86_64_SSESF_CLASS; + else + classes[0] = X86_64_SSE_CLASS; + return 1; + case FFI_TYPE_DOUBLE: + classes[0] = X86_64_SSEDF_CLASS; + return 1; + case FFI_TYPE_LONGDOUBLE: + classes[0] = X86_64_X87_CLASS; + classes[1] = X86_64_X87UP_CLASS; + return 2; + case FFI_TYPE_STRUCT: + { + const int UNITS_PER_WORD = 8; + int words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; + ffi_type **ptr; + int i; + enum x86_64_reg_class subclasses[MAX_CLASSES]; + + /* If the struct is larger than 32 bytes, pass it on the stack. */ + if (type->size > 32) + return 0; + + for (i = 0; i < words; i++) + classes[i] = X86_64_NO_CLASS; + + /* Zero sized arrays or structures are NO_CLASS. We return 0 to + signalize memory class, so handle it as special case. */ + if (!words) + { + classes[0] = X86_64_NO_CLASS; + return 1; + } + + /* Merge the fields of structure. */ + for (ptr = type->elements; *ptr != NULL; ptr++) + { + int num; + + byte_offset = ALIGN (byte_offset, (*ptr)->alignment); + + num = classify_argument (*ptr, subclasses, byte_offset % 8); + if (num == 0) + return 0; + for (i = 0; i < num; i++) + { + int pos = byte_offset / 8; + classes[i + pos] = + merge_classes (subclasses[i], classes[i + pos]); + } + + byte_offset += (*ptr)->size; + } + + if (words > 2) + { + /* When size > 16 bytes, if the first one isn't + X86_64_SSE_CLASS or any other ones aren't + X86_64_SSEUP_CLASS, everything should be passed in + memory. */ + if (classes[0] != X86_64_SSE_CLASS) + return 0; + + for (i = 1; i < words; i++) + if (classes[i] != X86_64_SSEUP_CLASS) + return 0; + } + + /* Final merger cleanup. */ + for (i = 0; i < words; i++) + { + /* If one class is MEMORY, everything should be passed in + memory. */ + if (classes[i] == X86_64_MEMORY_CLASS) + return 0; + + /* The X86_64_SSEUP_CLASS should be always preceded by + X86_64_SSE_CLASS or X86_64_SSEUP_CLASS. */ + if (classes[i] == X86_64_SSEUP_CLASS + && classes[i - 1] != X86_64_SSE_CLASS + && classes[i - 1] != X86_64_SSEUP_CLASS) + { + /* The first one should never be X86_64_SSEUP_CLASS. */ + FFI_ASSERT (i != 0); + classes[i] = X86_64_SSE_CLASS; + } + + /* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS, + everything should be passed in memory. */ + if (classes[i] == X86_64_X87UP_CLASS + && (classes[i - 1] != X86_64_X87_CLASS)) + { + /* The first one should never be X86_64_X87UP_CLASS. */ + FFI_ASSERT (i != 0); + return 0; + } + } + return words; + } + + default: + FFI_ASSERT(0); + } + return 0; /* Never reached. */ +} + +/* Examine the argument and return set number of register required in each + class. Return zero iff parameter should be passed in memory, otherwise + the number of registers. */ + +static int +examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES], + _Bool in_return, int *pngpr, int *pnsse) +{ + int i, n, ngpr, nsse; + + n = classify_argument (type, classes, 0); + if (n == 0) + return 0; + + ngpr = nsse = 0; + for (i = 0; i < n; ++i) + switch (classes[i]) + { + case X86_64_INTEGER_CLASS: + case X86_64_INTEGERSI_CLASS: + ngpr++; + break; + case X86_64_SSE_CLASS: + case X86_64_SSESF_CLASS: + case X86_64_SSEDF_CLASS: + nsse++; + break; + case X86_64_NO_CLASS: + case X86_64_SSEUP_CLASS: + break; + case X86_64_X87_CLASS: + case X86_64_X87UP_CLASS: + case X86_64_COMPLEX_X87_CLASS: + return in_return != 0; + default: + abort (); + } + + *pngpr = ngpr; + *pnsse = nsse; + + return n; +} + +/* Perform machine dependent cif processing. */ + +ffi_status +ffi_prep_cif_machdep (ffi_cif *cif) +{ + int gprcount, ssecount, i, avn, n, ngpr, nsse, flags; + enum x86_64_reg_class classes[MAX_CLASSES]; + size_t bytes; + + gprcount = ssecount = 0; + + flags = cif->rtype->type; + if (flags != FFI_TYPE_VOID) + { + n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse); + if (n == 0) + { + /* The return value is passed in memory. A pointer to that + memory is the first argument. Allocate a register for it. */ + gprcount++; + /* We don't have to do anything in asm for the return. */ + flags = FFI_TYPE_VOID; + } + else if (flags == FFI_TYPE_STRUCT) + { + /* Mark which registers the result appears in. */ + _Bool sse0 = SSE_CLASS_P (classes[0]); + _Bool sse1 = n == 2 && SSE_CLASS_P (classes[1]); + if (sse0 && !sse1) + flags |= 1 << 8; + else if (!sse0 && sse1) + flags |= 1 << 9; + else if (sse0 && sse1) + flags |= 1 << 10; + /* Mark the true size of the structure. */ + flags |= cif->rtype->size << 12; + } + } + + /* Go over all arguments and determine the way they should be passed. + If it's in a register and there is space for it, let that be so. If + not, add it's size to the stack byte count. */ + for (bytes = 0, i = 0, avn = cif->nargs; i < avn; i++) + { + if (examine_argument (cif->arg_types[i], classes, 0, &ngpr, &nsse) == 0 + || gprcount + ngpr > MAX_GPR_REGS + || ssecount + nsse > MAX_SSE_REGS) + { + long align = cif->arg_types[i]->alignment; + + if (align < 8) + align = 8; + + bytes = ALIGN (bytes, align); + bytes += cif->arg_types[i]->size; + } + else + { + gprcount += ngpr; + ssecount += nsse; + } + } + if (ssecount) + flags |= 1 << 11; + cif->flags = flags; + cif->bytes = ALIGN (bytes, 8); + + return FFI_OK; +} + +void +ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + enum x86_64_reg_class classes[MAX_CLASSES]; + char *stack, *argp; + ffi_type **arg_types; + int gprcount, ssecount, ngpr, nsse, i, avn; + _Bool ret_in_memory; + struct register_args *reg_args; + + /* Can't call 32-bit mode from 64-bit mode. */ + FFI_ASSERT (cif->abi == FFI_UNIX64); + + /* If the return value is a struct and we don't have a return value + address then we need to make one. Note the setting of flags to + VOID above in ffi_prep_cif_machdep. */ + ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT + && (cif->flags & 0xff) == FFI_TYPE_VOID); + if (rvalue == NULL && ret_in_memory) + rvalue = alloca (cif->rtype->size); + + /* Allocate the space for the arguments, plus 4 words of temp space. */ + stack = alloca (sizeof (struct register_args) + cif->bytes + 4*8); + reg_args = (struct register_args *) stack; + argp = stack + sizeof (struct register_args); + + gprcount = ssecount = 0; + + /* If the return value is passed in memory, add the pointer as the + first integer argument. */ + if (ret_in_memory) + reg_args->gpr[gprcount++] = (unsigned long) rvalue; + + avn = cif->nargs; + arg_types = cif->arg_types; + + for (i = 0; i < avn; ++i) + { + size_t size = arg_types[i]->size; + int n; + + n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse); + if (n == 0 + || gprcount + ngpr > MAX_GPR_REGS + || ssecount + nsse > MAX_SSE_REGS) + { + long align = arg_types[i]->alignment; + + /* Stack arguments are *always* at least 8 byte aligned. */ + if (align < 8) + align = 8; + + /* Pass this argument in memory. */ + argp = (void *) ALIGN (argp, align); + memcpy (argp, avalue[i], size); + argp += size; + } + else + { + /* The argument is passed entirely in registers. */ + char *a = (char *) avalue[i]; + int j; + + for (j = 0; j < n; j++, a += 8, size -= 8) + { + switch (classes[j]) + { + case X86_64_INTEGER_CLASS: + case X86_64_INTEGERSI_CLASS: + /* Sign-extend integer arguments passed in general + purpose registers, to cope with the fact that + LLVM incorrectly assumes that this will be done + (the x86-64 PS ABI does not specify this). */ + switch (arg_types[i]->type) + { + case FFI_TYPE_SINT8: + *(SINT64 *)®_args->gpr[gprcount] = (SINT64) *((SINT8 *) a); + break; + case FFI_TYPE_SINT16: + *(SINT64 *)®_args->gpr[gprcount] = (SINT64) *((SINT16 *) a); + break; + case FFI_TYPE_SINT32: + *(SINT64 *)®_args->gpr[gprcount] = (SINT64) *((SINT32 *) a); + break; + default: + reg_args->gpr[gprcount] = 0; + memcpy (®_args->gpr[gprcount], a, size < 8 ? size : 8); + } + gprcount++; + break; + case X86_64_SSE_CLASS: + case X86_64_SSEDF_CLASS: + reg_args->sse[ssecount++].i64 = *(UINT64 *) a; + break; + case X86_64_SSESF_CLASS: + reg_args->sse[ssecount++].i32 = *(UINT32 *) a; + break; + default: + abort(); + } + } + } + } + + ffi_call_unix64 (stack, cif->bytes + sizeof (struct register_args), + cif->flags, rvalue, fn, ssecount); +} + + +extern void ffi_closure_unix64(void); + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ + volatile unsigned short *tramp; + + /* Sanity check on the cif ABI. */ + { + int abi = cif->abi; + if (UNLIKELY (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI))) + return FFI_BAD_ABI; + } + + tramp = (volatile unsigned short *) &closure->tramp[0]; + + tramp[0] = 0xbb49; /* mov <code>, %r11 */ + *((unsigned long long * volatile) &tramp[1]) + = (unsigned long) ffi_closure_unix64; + tramp[5] = 0xba49; /* mov <data>, %r10 */ + *((unsigned long long * volatile) &tramp[6]) + = (unsigned long) codeloc; + + /* Set the carry bit iff the function uses any sse registers. + This is clc or stc, together with the first byte of the jmp. */ + tramp[10] = cif->flags & (1 << 11) ? 0x49f9 : 0x49f8; + + tramp[11] = 0xe3ff; /* jmp *%r11 */ + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + +int +ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue, + struct register_args *reg_args, char *argp) +{ + ffi_cif *cif; + void **avalue; + ffi_type **arg_types; + long i, avn; + int gprcount, ssecount, ngpr, nsse; + int ret; + + cif = closure->cif; + avalue = alloca(cif->nargs * sizeof(void *)); + gprcount = ssecount = 0; + + ret = cif->rtype->type; + if (ret != FFI_TYPE_VOID) + { + enum x86_64_reg_class classes[MAX_CLASSES]; + int n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse); + if (n == 0) + { + /* The return value goes in memory. Arrange for the closure + return value to go directly back to the original caller. */ + rvalue = (void *) (unsigned long) reg_args->gpr[gprcount++]; + /* We don't have to do anything in asm for the return. */ + ret = FFI_TYPE_VOID; + } + else if (ret == FFI_TYPE_STRUCT && n == 2) + { + /* Mark which register the second word of the structure goes in. */ + _Bool sse0 = SSE_CLASS_P (classes[0]); + _Bool sse1 = SSE_CLASS_P (classes[1]); + if (!sse0 && sse1) + ret |= 1 << 8; + else if (sse0 && !sse1) + ret |= 1 << 9; + } + } + + avn = cif->nargs; + arg_types = cif->arg_types; + + for (i = 0; i < avn; ++i) + { + enum x86_64_reg_class classes[MAX_CLASSES]; + int n; + + n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse); + if (n == 0 + || gprcount + ngpr > MAX_GPR_REGS + || ssecount + nsse > MAX_SSE_REGS) + { + long align = arg_types[i]->alignment; + + /* Stack arguments are *always* at least 8 byte aligned. */ + if (align < 8) + align = 8; + + /* Pass this argument in memory. */ + argp = (void *) ALIGN (argp, align); + avalue[i] = argp; + argp += arg_types[i]->size; + } + /* If the argument is in a single register, or two consecutive + integer registers, then we can use that address directly. */ + else if (n == 1 + || (n == 2 && !(SSE_CLASS_P (classes[0]) + || SSE_CLASS_P (classes[1])))) + { + /* The argument is in a single register. */ + if (SSE_CLASS_P (classes[0])) + { + avalue[i] = ®_args->sse[ssecount]; + ssecount += n; + } + else + { + avalue[i] = ®_args->gpr[gprcount]; + gprcount += n; + } + } + /* Otherwise, allocate space to make them consecutive. */ + else + { + char *a = alloca (16); + int j; + + avalue[i] = a; + for (j = 0; j < n; j++, a += 8) + { + if (SSE_CLASS_P (classes[j])) + memcpy (a, ®_args->sse[ssecount++], 8); + else + memcpy (a, ®_args->gpr[gprcount++], 8); + } + } + } + + /* Invoke the closure. */ + closure->fun (cif, rvalue, avalue, closure->user_data); + + /* Tell assembly how to perform return type promotions. */ + return ret; +} + +#endif /* __x86_64__ */ diff --git a/lib/wrappers/libffi/gcc/prep_cif.c b/lib/wrappers/libffi/gcc/prep_cif.c new file mode 100644 index 000000000..e8ec5cf1e --- /dev/null +++ b/lib/wrappers/libffi/gcc/prep_cif.c @@ -0,0 +1,237 @@ +/* ----------------------------------------------------------------------- + prep_cif.c - Copyright (c) 2011, 2012 Anthony Green + Copyright (c) 1996, 1998, 2007 Red Hat, Inc. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#include <ffi.h> +#include <ffi_common.h> +#include <stdlib.h> + +/* Round up to FFI_SIZEOF_ARG. */ + +#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG) + +/* Perform machine independent initialization of aggregate type + specifications. */ + +static ffi_status initialize_aggregate(ffi_type *arg) +{ + ffi_type **ptr; + + if (UNLIKELY(arg == NULL || arg->elements == NULL)) + return FFI_BAD_TYPEDEF; + + arg->size = 0; + arg->alignment = 0; + + ptr = &(arg->elements[0]); + + if (UNLIKELY(ptr == 0)) + return FFI_BAD_TYPEDEF; + + while ((*ptr) != NULL) + { + if (UNLIKELY(((*ptr)->size == 0) + && (initialize_aggregate((*ptr)) != FFI_OK))) + return FFI_BAD_TYPEDEF; + + /* Perform a sanity check on the argument type */ + FFI_ASSERT_VALID_TYPE(*ptr); + + arg->size = ALIGN(arg->size, (*ptr)->alignment); + arg->size += (*ptr)->size; + + arg->alignment = (arg->alignment > (*ptr)->alignment) ? + arg->alignment : (*ptr)->alignment; + + ptr++; + } + + /* Structure size includes tail padding. This is important for + structures that fit in one register on ABIs like the PowerPC64 + Linux ABI that right justify small structs in a register. + It's also needed for nested structure layout, for example + struct A { long a; char b; }; struct B { struct A x; char y; }; + should find y at an offset of 2*sizeof(long) and result in a + total size of 3*sizeof(long). */ + arg->size = ALIGN (arg->size, arg->alignment); + + if (arg->size == 0) + return FFI_BAD_TYPEDEF; + else + return FFI_OK; +} + +#ifndef __CRIS__ +/* The CRIS ABI specifies structure elements to have byte + alignment only, so it completely overrides this functions, + which assumes "natural" alignment and padding. */ + +/* Perform machine independent ffi_cif preparation, then call + machine dependent routine. */ + +/* For non variadic functions isvariadic should be 0 and + nfixedargs==ntotalargs. + + For variadic calls, isvariadic should be 1 and nfixedargs + and ntotalargs set as appropriate. nfixedargs must always be >=1 */ + + +ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, + unsigned int isvariadic, + unsigned int nfixedargs, + unsigned int ntotalargs, + ffi_type *rtype, ffi_type **atypes) +{ + unsigned bytes = 0; + unsigned int i; + ffi_type **ptr; + + FFI_ASSERT(cif != NULL); + FFI_ASSERT((!isvariadic) || (nfixedargs >= 1)); + FFI_ASSERT(nfixedargs <= ntotalargs); + +#ifndef X86_WIN32 + if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI)) + return FFI_BAD_ABI; +#else + if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI || abi == FFI_THISCALL)) + return FFI_BAD_ABI; +#endif + + cif->abi = abi; + cif->arg_types = atypes; + cif->nargs = ntotalargs; + cif->rtype = rtype; + + cif->flags = 0; + + /* Initialize the return type if necessary */ + if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) + return FFI_BAD_TYPEDEF; + + /* Perform a sanity check on the return type */ + FFI_ASSERT_VALID_TYPE(cif->rtype); + + /* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */ +#if !defined M68K && !defined X86_ANY && !defined S390 && !defined PA + /* Make space for the return structure pointer */ + if (cif->rtype->type == FFI_TYPE_STRUCT +#ifdef SPARC + && (cif->abi != FFI_V9 || cif->rtype->size > 32) +#endif +#ifdef TILE + && (cif->rtype->size > 10 * FFI_SIZEOF_ARG) +#endif +#ifdef XTENSA + && (cif->rtype->size > 16) +#endif + + ) + bytes = STACK_ARG_SIZE(sizeof(void*)); +#endif + + for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) + { + + /* Initialize any uninitialized aggregate type definitions */ + if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) + return FFI_BAD_TYPEDEF; + + /* Perform a sanity check on the argument type, do this + check after the initialization. */ + FFI_ASSERT_VALID_TYPE(*ptr); + +#if !defined X86_ANY && !defined S390 && !defined PA +#ifdef SPARC + if (((*ptr)->type == FFI_TYPE_STRUCT + && ((*ptr)->size > 16 || cif->abi != FFI_V9)) + || ((*ptr)->type == FFI_TYPE_LONGDOUBLE + && cif->abi != FFI_V9)) + bytes += sizeof(void*); + else +#endif + { + /* Add any padding if necessary */ + if (((*ptr)->alignment - 1) & bytes) + bytes = ALIGN(bytes, (*ptr)->alignment); + +#ifdef TILE + if (bytes < 10 * FFI_SIZEOF_ARG && + bytes + STACK_ARG_SIZE((*ptr)->size) > 10 * FFI_SIZEOF_ARG) + { + /* An argument is never split between the 10 parameter + registers and the stack. */ + bytes = 10 * FFI_SIZEOF_ARG; + } +#endif +#ifdef XTENSA + if (bytes <= 6*4 && bytes + STACK_ARG_SIZE((*ptr)->size) > 6*4) + bytes = 6*4; +#endif + + bytes += STACK_ARG_SIZE((*ptr)->size); + } +#endif + } + + cif->bytes = bytes; + + /* Perform machine dependent cif processing */ +#ifdef FFI_TARGET_SPECIFIC_VARIADIC + if (isvariadic) + return ffi_prep_cif_machdep_var(cif, nfixedargs, ntotalargs); +#endif + + return ffi_prep_cif_machdep(cif); +} +#endif /* not __CRIS__ */ + +ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs, + ffi_type *rtype, ffi_type **atypes) +{ + return ffi_prep_cif_core(cif, abi, 0, nargs, nargs, rtype, atypes); +} + +ffi_status ffi_prep_cif_var(ffi_cif *cif, + ffi_abi abi, + unsigned int nfixedargs, + unsigned int ntotalargs, + ffi_type *rtype, + ffi_type **atypes) +{ + return ffi_prep_cif_core(cif, abi, 1, nfixedargs, ntotalargs, rtype, atypes); +} + +#if FFI_CLOSURES + +ffi_status +ffi_prep_closure (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data) +{ + return ffi_prep_closure_loc (closure, cif, fun, user_data, closure); +} + +#endif diff --git a/lib/wrappers/libffi/gcc/types.c b/lib/wrappers/libffi/gcc/types.c new file mode 100644 index 000000000..0a11eb0fb --- /dev/null +++ b/lib/wrappers/libffi/gcc/types.c @@ -0,0 +1,77 @@ +/* ----------------------------------------------------------------------- + types.c - Copyright (c) 1996, 1998 Red Hat, Inc. + + Predefined ffi_types needed by libffi. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +/* Hide the basic type definitions from the header file, so that we + can redefine them here as "const". */ +#define LIBFFI_HIDE_BASIC_TYPES + +#include <ffi.h> +#include <ffi_common.h> + +/* Type definitions */ + +#define FFI_TYPEDEF(name, type, id) \ +struct struct_align_##name { \ + char c; \ + type x; \ +}; \ +const ffi_type ffi_type_##name = { \ + sizeof(type), \ + offsetof(struct struct_align_##name, x), \ + id, NULL \ +} + +/* Size and alignment are fake here. They must not be 0. */ +const ffi_type ffi_type_void = { + 1, 1, FFI_TYPE_VOID, NULL +}; + +FFI_TYPEDEF(uint8, UINT8, FFI_TYPE_UINT8); +FFI_TYPEDEF(sint8, SINT8, FFI_TYPE_SINT8); +FFI_TYPEDEF(uint16, UINT16, FFI_TYPE_UINT16); +FFI_TYPEDEF(sint16, SINT16, FFI_TYPE_SINT16); +FFI_TYPEDEF(uint32, UINT32, FFI_TYPE_UINT32); +FFI_TYPEDEF(sint32, SINT32, FFI_TYPE_SINT32); +FFI_TYPEDEF(uint64, UINT64, FFI_TYPE_UINT64); +FFI_TYPEDEF(sint64, SINT64, FFI_TYPE_SINT64); + +FFI_TYPEDEF(pointer, void*, FFI_TYPE_POINTER); + +FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT); +FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE); + +#ifdef __alpha__ +/* Even if we're not configured to default to 128-bit long double, + maintain binary compatibility, as -mlong-double-128 can be used + at any time. */ +/* Validate the hard-coded number below. */ +# if defined(__LONG_DOUBLE_128__) && FFI_TYPE_LONGDOUBLE != 4 +# error FFI_TYPE_LONGDOUBLE out of date +# endif +const ffi_type ffi_type_longdouble = { 16, 16, 4, NULL }; +#elif FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE +FFI_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE); +#endif diff --git a/lib/wrappers/libffi/gcc/win32_asm.asm b/lib/wrappers/libffi/gcc/win32_asm.asm new file mode 100644 index 000000000..ce3c4f3f3 --- /dev/null +++ b/lib/wrappers/libffi/gcc/win32_asm.asm @@ -0,0 +1,759 @@ +/* ----------------------------------------------------------------------- + win32.S - Copyright (c) 1996, 1998, 2001, 2002, 2009 Red Hat, Inc. + Copyright (c) 2001 John Beniton + Copyright (c) 2002 Ranjit Mathew + Copyright (c) 2009 Daniel Witte + + + X86 Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- + */ + +#define LIBFFI_ASM +#include <fficonfig.h> +#include <ffi.h> +#include <ffitarget.h> + + .text + + // This assumes we are using gas. + .balign 16 + .globl _ffi_call_win32 +#ifndef __OS2__ + .def _ffi_call_win32; .scl 2; .type 32; .endef +#endif +_ffi_call_win32: +.LFB1: + pushl %ebp +.LCFI0: + movl %esp,%ebp +.LCFI1: + // Make room for all of the new args. + movl 20(%ebp),%ecx + subl %ecx,%esp + + movl %esp,%eax + + // Place all of the ffi_prep_args in position + pushl 12(%ebp) + pushl %eax + call *8(%ebp) + + // Return stack to previous state and call the function + addl $8,%esp + + // Handle fastcall and thiscall + cmpl $3, 16(%ebp) // FFI_THISCALL + jz .do_thiscall + cmpl $4, 16(%ebp) // FFI_FASTCALL + jnz .do_fncall + movl (%esp), %ecx + movl 4(%esp), %edx + addl $8, %esp + jmp .do_fncall +.do_thiscall: + movl (%esp), %ecx + addl $4, %esp + +.do_fncall: + + // FIXME: Align the stack to a 128-bit boundary to avoid + // potential performance hits. + + call *32(%ebp) + + // stdcall functions pop arguments off the stack themselves + + // Load %ecx with the return type code + movl 24(%ebp),%ecx + + // If the return value pointer is NULL, assume no return value. + cmpl $0,28(%ebp) + jne 0f + + // Even if there is no space for the return value, we are + // obliged to handle floating-point values. + cmpl $FFI_TYPE_FLOAT,%ecx + jne .Lnoretval + fstp %st(0) + + jmp .Lepilogue + +0: + call 1f + // Do not insert anything here between the call and the jump table. +.Lstore_table: + .long .Lnoretval /* FFI_TYPE_VOID */ + .long .Lretint /* FFI_TYPE_INT */ + .long .Lretfloat /* FFI_TYPE_FLOAT */ + .long .Lretdouble /* FFI_TYPE_DOUBLE */ + .long .Lretlongdouble /* FFI_TYPE_LONGDOUBLE */ + .long .Lretuint8 /* FFI_TYPE_UINT8 */ + .long .Lretsint8 /* FFI_TYPE_SINT8 */ + .long .Lretuint16 /* FFI_TYPE_UINT16 */ + .long .Lretsint16 /* FFI_TYPE_SINT16 */ + .long .Lretint /* FFI_TYPE_UINT32 */ + .long .Lretint /* FFI_TYPE_SINT32 */ + .long .Lretint64 /* FFI_TYPE_UINT64 */ + .long .Lretint64 /* FFI_TYPE_SINT64 */ + .long .Lretstruct /* FFI_TYPE_STRUCT */ + .long .Lretint /* FFI_TYPE_POINTER */ + .long .Lretstruct1b /* FFI_TYPE_SMALL_STRUCT_1B */ + .long .Lretstruct2b /* FFI_TYPE_SMALL_STRUCT_2B */ + .long .Lretstruct4b /* FFI_TYPE_SMALL_STRUCT_4B */ + .long .Lretstruct /* FFI_TYPE_MS_STRUCT */ +1: + add %ecx, %ecx + add %ecx, %ecx + add (%esp),%ecx + add $4, %esp + jmp *(%ecx) + + /* Sign/zero extend as appropriate. */ +.Lretsint8: + movsbl %al, %eax + jmp .Lretint + +.Lretsint16: + movswl %ax, %eax + jmp .Lretint + +.Lretuint8: + movzbl %al, %eax + jmp .Lretint + +.Lretuint16: + movzwl %ax, %eax + jmp .Lretint + +.Lretint: + // Load %ecx with the pointer to storage for the return value + movl 28(%ebp),%ecx + movl %eax,0(%ecx) + jmp .Lepilogue + +.Lretfloat: + // Load %ecx with the pointer to storage for the return value + movl 28(%ebp),%ecx + fstps (%ecx) + jmp .Lepilogue + +.Lretdouble: + // Load %ecx with the pointer to storage for the return value + movl 28(%ebp),%ecx + fstpl (%ecx) + jmp .Lepilogue + +.Lretlongdouble: + // Load %ecx with the pointer to storage for the return value + movl 28(%ebp),%ecx + fstpt (%ecx) + jmp .Lepilogue + +.Lretint64: + // Load %ecx with the pointer to storage for the return value + movl 28(%ebp),%ecx + movl %eax,0(%ecx) + movl %edx,4(%ecx) + jmp .Lepilogue + +.Lretstruct1b: + // Load %ecx with the pointer to storage for the return value + movl 28(%ebp),%ecx + movb %al,0(%ecx) + jmp .Lepilogue + +.Lretstruct2b: + // Load %ecx with the pointer to storage for the return value + movl 28(%ebp),%ecx + movw %ax,0(%ecx) + jmp .Lepilogue + +.Lretstruct4b: + // Load %ecx with the pointer to storage for the return value + movl 28(%ebp),%ecx + movl %eax,0(%ecx) + jmp .Lepilogue + +.Lretstruct: + // Nothing to do! + +.Lnoretval: +.Lepilogue: + movl %ebp,%esp + popl %ebp + ret +.ffi_call_win32_end: + .balign 16 + .globl _ffi_closure_THISCALL +#ifndef __OS2__ + .def _ffi_closure_THISCALL; .scl 2; .type 32; .endef +#endif +_ffi_closure_THISCALL: + pushl %ebp + movl %esp, %ebp + subl $40, %esp + leal -24(%ebp), %edx + movl %edx, -12(%ebp) /* resp */ + leal 12(%ebp), %edx /* account for stub return address on stack */ + jmp .stub +.LFE1: + + // This assumes we are using gas. + .balign 16 + .globl _ffi_closure_SYSV +#ifndef __OS2__ + .def _ffi_closure_SYSV; .scl 2; .type 32; .endef +#endif +_ffi_closure_SYSV: +.LFB3: + pushl %ebp +.LCFI4: + movl %esp, %ebp +.LCFI5: + subl $40, %esp + leal -24(%ebp), %edx + movl %edx, -12(%ebp) /* resp */ + leal 8(%ebp), %edx +.stub: + movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */ + leal -12(%ebp), %edx + movl %edx, (%esp) /* &resp */ + call _ffi_closure_SYSV_inner + movl -12(%ebp), %ecx + +0: + call 1f + // Do not insert anything here between the call and the jump table. +.Lcls_store_table: + .long .Lcls_noretval /* FFI_TYPE_VOID */ + .long .Lcls_retint /* FFI_TYPE_INT */ + .long .Lcls_retfloat /* FFI_TYPE_FLOAT */ + .long .Lcls_retdouble /* FFI_TYPE_DOUBLE */ + .long .Lcls_retldouble /* FFI_TYPE_LONGDOUBLE */ + .long .Lcls_retuint8 /* FFI_TYPE_UINT8 */ + .long .Lcls_retsint8 /* FFI_TYPE_SINT8 */ + .long .Lcls_retuint16 /* FFI_TYPE_UINT16 */ + .long .Lcls_retsint16 /* FFI_TYPE_SINT16 */ + .long .Lcls_retint /* FFI_TYPE_UINT32 */ + .long .Lcls_retint /* FFI_TYPE_SINT32 */ + .long .Lcls_retllong /* FFI_TYPE_UINT64 */ + .long .Lcls_retllong /* FFI_TYPE_SINT64 */ + .long .Lcls_retstruct /* FFI_TYPE_STRUCT */ + .long .Lcls_retint /* FFI_TYPE_POINTER */ + .long .Lcls_retstruct1 /* FFI_TYPE_SMALL_STRUCT_1B */ + .long .Lcls_retstruct2 /* FFI_TYPE_SMALL_STRUCT_2B */ + .long .Lcls_retstruct4 /* FFI_TYPE_SMALL_STRUCT_4B */ + .long .Lcls_retmsstruct /* FFI_TYPE_MS_STRUCT */ + +1: + add %eax, %eax + add %eax, %eax + add (%esp),%eax + add $4, %esp + jmp *(%eax) + + /* Sign/zero extend as appropriate. */ +.Lcls_retsint8: + movsbl (%ecx), %eax + jmp .Lcls_epilogue + +.Lcls_retsint16: + movswl (%ecx), %eax + jmp .Lcls_epilogue + +.Lcls_retuint8: + movzbl (%ecx), %eax + jmp .Lcls_epilogue + +.Lcls_retuint16: + movzwl (%ecx), %eax + jmp .Lcls_epilogue + +.Lcls_retint: + movl (%ecx), %eax + jmp .Lcls_epilogue + +.Lcls_retfloat: + flds (%ecx) + jmp .Lcls_epilogue + +.Lcls_retdouble: + fldl (%ecx) + jmp .Lcls_epilogue + +.Lcls_retldouble: + fldt (%ecx) + jmp .Lcls_epilogue + +.Lcls_retllong: + movl (%ecx), %eax + movl 4(%ecx), %edx + jmp .Lcls_epilogue + +.Lcls_retstruct1: + movsbl (%ecx), %eax + jmp .Lcls_epilogue + +.Lcls_retstruct2: + movswl (%ecx), %eax + jmp .Lcls_epilogue + +.Lcls_retstruct4: + movl (%ecx), %eax + jmp .Lcls_epilogue + +.Lcls_retstruct: + // Caller expects us to pop struct return value pointer hidden arg. + movl %ebp, %esp + popl %ebp + ret $0x4 + +.Lcls_retmsstruct: + // Caller expects us to return a pointer to the real return value. + mov %ecx, %eax + // Caller doesn't expects us to pop struct return value pointer hidden arg. + jmp .Lcls_epilogue + +.Lcls_noretval: +.Lcls_epilogue: + movl %ebp, %esp + popl %ebp + ret +.ffi_closure_SYSV_end: +.LFE3: + +#if !FFI_NO_RAW_API + +#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3) +#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4) +#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4) +#define CIF_FLAGS_OFFSET 20 + .balign 16 + .globl _ffi_closure_raw_THISCALL +#ifndef __OS2__ + .def _ffi_closure_raw_THISCALL; .scl 2; .type 32; .endef +#endif +_ffi_closure_raw_THISCALL: + pushl %ebp + movl %esp, %ebp + pushl %esi + subl $36, %esp + movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */ + movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */ + movl %edx, 12(%esp) /* user_data */ + leal 12(%ebp), %edx /* __builtin_dwarf_cfa () */ + jmp .stubraw + // This assumes we are using gas. + .balign 16 + .globl _ffi_closure_raw_SYSV +#ifndef __OS2__ + .def _ffi_closure_raw_SYSV; .scl 2; .type 32; .endef +#endif +_ffi_closure_raw_SYSV: +.LFB4: + pushl %ebp +.LCFI6: + movl %esp, %ebp +.LCFI7: + pushl %esi +.LCFI8: + subl $36, %esp + movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */ + movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */ + movl %edx, 12(%esp) /* user_data */ + leal 8(%ebp), %edx /* __builtin_dwarf_cfa () */ +.stubraw: + movl %edx, 8(%esp) /* raw_args */ + leal -24(%ebp), %edx + movl %edx, 4(%esp) /* &res */ + movl %esi, (%esp) /* cif */ + call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */ + movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */ +0: + call 1f + // Do not insert anything here between the call and the jump table. +.Lrcls_store_table: + .long .Lrcls_noretval /* FFI_TYPE_VOID */ + .long .Lrcls_retint /* FFI_TYPE_INT */ + .long .Lrcls_retfloat /* FFI_TYPE_FLOAT */ + .long .Lrcls_retdouble /* FFI_TYPE_DOUBLE */ + .long .Lrcls_retldouble /* FFI_TYPE_LONGDOUBLE */ + .long .Lrcls_retuint8 /* FFI_TYPE_UINT8 */ + .long .Lrcls_retsint8 /* FFI_TYPE_SINT8 */ + .long .Lrcls_retuint16 /* FFI_TYPE_UINT16 */ + .long .Lrcls_retsint16 /* FFI_TYPE_SINT16 */ + .long .Lrcls_retint /* FFI_TYPE_UINT32 */ + .long .Lrcls_retint /* FFI_TYPE_SINT32 */ + .long .Lrcls_retllong /* FFI_TYPE_UINT64 */ + .long .Lrcls_retllong /* FFI_TYPE_SINT64 */ + .long .Lrcls_retstruct /* FFI_TYPE_STRUCT */ + .long .Lrcls_retint /* FFI_TYPE_POINTER */ + .long .Lrcls_retstruct1 /* FFI_TYPE_SMALL_STRUCT_1B */ + .long .Lrcls_retstruct2 /* FFI_TYPE_SMALL_STRUCT_2B */ + .long .Lrcls_retstruct4 /* FFI_TYPE_SMALL_STRUCT_4B */ + .long .Lrcls_retstruct /* FFI_TYPE_MS_STRUCT */ +1: + add %eax, %eax + add %eax, %eax + add (%esp),%eax + add $4, %esp + jmp *(%eax) + + /* Sign/zero extend as appropriate. */ +.Lrcls_retsint8: + movsbl -24(%ebp), %eax + jmp .Lrcls_epilogue + +.Lrcls_retsint16: + movswl -24(%ebp), %eax + jmp .Lrcls_epilogue + +.Lrcls_retuint8: + movzbl -24(%ebp), %eax + jmp .Lrcls_epilogue + +.Lrcls_retuint16: + movzwl -24(%ebp), %eax + jmp .Lrcls_epilogue + +.Lrcls_retint: + movl -24(%ebp), %eax + jmp .Lrcls_epilogue + +.Lrcls_retfloat: + flds -24(%ebp) + jmp .Lrcls_epilogue + +.Lrcls_retdouble: + fldl -24(%ebp) + jmp .Lrcls_epilogue + +.Lrcls_retldouble: + fldt -24(%ebp) + jmp .Lrcls_epilogue + +.Lrcls_retllong: + movl -24(%ebp), %eax + movl -20(%ebp), %edx + jmp .Lrcls_epilogue + +.Lrcls_retstruct1: + movsbl -24(%ebp), %eax + jmp .Lrcls_epilogue + +.Lrcls_retstruct2: + movswl -24(%ebp), %eax + jmp .Lrcls_epilogue + +.Lrcls_retstruct4: + movl -24(%ebp), %eax + jmp .Lrcls_epilogue + +.Lrcls_retstruct: + // Nothing to do! + +.Lrcls_noretval: +.Lrcls_epilogue: + addl $36, %esp + popl %esi + popl %ebp + ret +.ffi_closure_raw_SYSV_end: +.LFE4: + +#endif /* !FFI_NO_RAW_API */ + + // This assumes we are using gas. + .balign 16 + .globl _ffi_closure_STDCALL +#ifndef __OS2__ + .def _ffi_closure_STDCALL; .scl 2; .type 32; .endef +#endif +_ffi_closure_STDCALL: +.LFB5: + pushl %ebp +.LCFI9: + movl %esp, %ebp +.LCFI10: + subl $40, %esp + leal -24(%ebp), %edx + movl %edx, -12(%ebp) /* resp */ + leal 12(%ebp), %edx /* account for stub return address on stack */ + movl %edx, 4(%esp) /* args */ + leal -12(%ebp), %edx + movl %edx, (%esp) /* &resp */ + call _ffi_closure_SYSV_inner + movl -12(%ebp), %ecx +0: + call 1f + // Do not insert anything here between the call and the jump table. +.Lscls_store_table: + .long .Lscls_noretval /* FFI_TYPE_VOID */ + .long .Lscls_retint /* FFI_TYPE_INT */ + .long .Lscls_retfloat /* FFI_TYPE_FLOAT */ + .long .Lscls_retdouble /* FFI_TYPE_DOUBLE */ + .long .Lscls_retldouble /* FFI_TYPE_LONGDOUBLE */ + .long .Lscls_retuint8 /* FFI_TYPE_UINT8 */ + .long .Lscls_retsint8 /* FFI_TYPE_SINT8 */ + .long .Lscls_retuint16 /* FFI_TYPE_UINT16 */ + .long .Lscls_retsint16 /* FFI_TYPE_SINT16 */ + .long .Lscls_retint /* FFI_TYPE_UINT32 */ + .long .Lscls_retint /* FFI_TYPE_SINT32 */ + .long .Lscls_retllong /* FFI_TYPE_UINT64 */ + .long .Lscls_retllong /* FFI_TYPE_SINT64 */ + .long .Lscls_retstruct /* FFI_TYPE_STRUCT */ + .long .Lscls_retint /* FFI_TYPE_POINTER */ + .long .Lscls_retstruct1 /* FFI_TYPE_SMALL_STRUCT_1B */ + .long .Lscls_retstruct2 /* FFI_TYPE_SMALL_STRUCT_2B */ + .long .Lscls_retstruct4 /* FFI_TYPE_SMALL_STRUCT_4B */ +1: + add %eax, %eax + add %eax, %eax + add (%esp),%eax + add $4, %esp + jmp *(%eax) + + /* Sign/zero extend as appropriate. */ +.Lscls_retsint8: + movsbl (%ecx), %eax + jmp .Lscls_epilogue + +.Lscls_retsint16: + movswl (%ecx), %eax + jmp .Lscls_epilogue + +.Lscls_retuint8: + movzbl (%ecx), %eax + jmp .Lscls_epilogue + +.Lscls_retuint16: + movzwl (%ecx), %eax + jmp .Lscls_epilogue + +.Lscls_retint: + movl (%ecx), %eax + jmp .Lscls_epilogue + +.Lscls_retfloat: + flds (%ecx) + jmp .Lscls_epilogue + +.Lscls_retdouble: + fldl (%ecx) + jmp .Lscls_epilogue + +.Lscls_retldouble: + fldt (%ecx) + jmp .Lscls_epilogue + +.Lscls_retllong: + movl (%ecx), %eax + movl 4(%ecx), %edx + jmp .Lscls_epilogue + +.Lscls_retstruct1: + movsbl (%ecx), %eax + jmp .Lscls_epilogue + +.Lscls_retstruct2: + movswl (%ecx), %eax + jmp .Lscls_epilogue + +.Lscls_retstruct4: + movl (%ecx), %eax + jmp .Lscls_epilogue + +.Lscls_retstruct: + // Nothing to do! + +.Lscls_noretval: +.Lscls_epilogue: + movl %ebp, %esp + popl %ebp + ret +.ffi_closure_STDCALL_end: +.LFE5: + +#ifndef __OS2__ + .section .eh_frame,"w" +#endif +.Lframe1: +.LSCIE1: + .long .LECIE1-.LASCIE1 /* Length of Common Information Entry */ +.LASCIE1: + .long 0x0 /* CIE Identifier Tag */ + .byte 0x1 /* CIE Version */ +#ifdef __PIC__ + .ascii "zR\0" /* CIE Augmentation */ +#else + .ascii "\0" /* CIE Augmentation */ +#endif + .byte 0x1 /* .uleb128 0x1; CIE Code Alignment Factor */ + .byte 0x7c /* .sleb128 -4; CIE Data Alignment Factor */ + .byte 0x8 /* CIE RA Column */ +#ifdef __PIC__ + .byte 0x1 /* .uleb128 0x1; Augmentation size */ + .byte 0x1b /* FDE Encoding (pcrel sdata4) */ +#endif + .byte 0xc /* DW_CFA_def_cfa CFA = r4 + 4 = 4(%esp) */ + .byte 0x4 /* .uleb128 0x4 */ + .byte 0x4 /* .uleb128 0x4 */ + .byte 0x88 /* DW_CFA_offset, column 0x8 %eip at CFA + 1 * -4 */ + .byte 0x1 /* .uleb128 0x1 */ + .align 4 +.LECIE1: + +.LSFDE1: + .long .LEFDE1-.LASFDE1 /* FDE Length */ +.LASFDE1: + .long .LASFDE1-.Lframe1 /* FDE CIE offset */ +#if defined __PIC__ && defined HAVE_AS_X86_PCREL + .long .LFB1-. /* FDE initial location */ +#else + .long .LFB1 +#endif + .long .LFE1-.LFB1 /* FDE address range */ +#ifdef __PIC__ + .byte 0x0 /* .uleb128 0x0; Augmentation size */ +#endif + /* DW_CFA_xxx CFI instructions go here. */ + + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI0-.LFB1 + .byte 0xe /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */ + .byte 0x8 /* .uleb128 0x8 */ + .byte 0x85 /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */ + .byte 0x2 /* .uleb128 0x2 */ + + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI1-.LCFI0 + .byte 0xd /* DW_CFA_def_cfa_register CFA = r5 = %ebp */ + .byte 0x5 /* .uleb128 0x5 */ + + /* End of DW_CFA_xxx CFI instructions. */ + .align 4 +.LEFDE1: + + +.LSFDE3: + .long .LEFDE3-.LASFDE3 /* FDE Length */ +.LASFDE3: + .long .LASFDE3-.Lframe1 /* FDE CIE offset */ +#if defined __PIC__ && defined HAVE_AS_X86_PCREL + .long .LFB3-. /* FDE initial location */ +#else + .long .LFB3 +#endif + .long .LFE3-.LFB3 /* FDE address range */ +#ifdef __PIC__ + .byte 0x0 /* .uleb128 0x0; Augmentation size */ +#endif + /* DW_CFA_xxx CFI instructions go here. */ + + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI4-.LFB3 + .byte 0xe /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */ + .byte 0x8 /* .uleb128 0x8 */ + .byte 0x85 /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */ + .byte 0x2 /* .uleb128 0x2 */ + + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI5-.LCFI4 + .byte 0xd /* DW_CFA_def_cfa_register CFA = r5 = %ebp */ + .byte 0x5 /* .uleb128 0x5 */ + + /* End of DW_CFA_xxx CFI instructions. */ + .align 4 +.LEFDE3: + +#if !FFI_NO_RAW_API + +.LSFDE4: + .long .LEFDE4-.LASFDE4 /* FDE Length */ +.LASFDE4: + .long .LASFDE4-.Lframe1 /* FDE CIE offset */ +#if defined __PIC__ && defined HAVE_AS_X86_PCREL + .long .LFB4-. /* FDE initial location */ +#else + .long .LFB4 +#endif + .long .LFE4-.LFB4 /* FDE address range */ +#ifdef __PIC__ + .byte 0x0 /* .uleb128 0x0; Augmentation size */ +#endif + /* DW_CFA_xxx CFI instructions go here. */ + + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI6-.LFB4 + .byte 0xe /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */ + .byte 0x8 /* .uleb128 0x8 */ + .byte 0x85 /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */ + .byte 0x2 /* .uleb128 0x2 */ + + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI7-.LCFI6 + .byte 0xd /* DW_CFA_def_cfa_register CFA = r5 = %ebp */ + .byte 0x5 /* .uleb128 0x5 */ + + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI8-.LCFI7 + .byte 0x86 /* DW_CFA_offset, column 0x6 %esi at CFA + 3 * -4 */ + .byte 0x3 /* .uleb128 0x3 */ + + /* End of DW_CFA_xxx CFI instructions. */ + .align 4 +.LEFDE4: + +#endif /* !FFI_NO_RAW_API */ + +.LSFDE5: + .long .LEFDE5-.LASFDE5 /* FDE Length */ +.LASFDE5: + .long .LASFDE5-.Lframe1 /* FDE CIE offset */ +#if defined __PIC__ && defined HAVE_AS_X86_PCREL + .long .LFB5-. /* FDE initial location */ +#else + .long .LFB5 +#endif + .long .LFE5-.LFB5 /* FDE address range */ +#ifdef __PIC__ + .byte 0x0 /* .uleb128 0x0; Augmentation size */ +#endif + /* DW_CFA_xxx CFI instructions go here. */ + + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI9-.LFB5 + .byte 0xe /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */ + .byte 0x8 /* .uleb128 0x8 */ + .byte 0x85 /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */ + .byte 0x2 /* .uleb128 0x2 */ + + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI10-.LCFI9 + .byte 0xd /* DW_CFA_def_cfa_register CFA = r5 = %ebp */ + .byte 0x5 /* .uleb128 0x5 */ + + /* End of DW_CFA_xxx CFI instructions. */ + .align 4 +.LEFDE5: diff --git a/lib/wrappers/libffi/gcc/win32_asm.s b/lib/wrappers/libffi/gcc/win32_asm.s new file mode 100644 index 000000000..7a3e7f16c --- /dev/null +++ b/lib/wrappers/libffi/gcc/win32_asm.s @@ -0,0 +1,736 @@ +# 1 "gcc\\win32_asm.asm" +# 1 "<command-line>" +# 1 "gcc\\win32_asm.asm" +# 33 "gcc\\win32_asm.asm" +# 1 "common/fficonfig.h" 1 +# 34 "gcc\\win32_asm.asm" 2 +# 1 "common/ffi.h" 1 +# 63 "common/ffi.h" +# 1 "common/ffitarget.h" 1 +# 64 "common/ffi.h" 2 +# 35 "gcc\\win32_asm.asm" 2 + + + .text + + + .balign 16 + .globl _ffi_call_win32 + + .def _ffi_call_win32; .scl 2; .type 32; .endef + +_ffi_call_win32: +.LFB1: + pushl %ebp +.LCFI0: + movl %esp,%ebp +.LCFI1: + + movl 20(%ebp),%ecx + subl %ecx,%esp + + movl %esp,%eax + + + pushl 12(%ebp) + pushl %eax + call *8(%ebp) + + + addl $8,%esp + + + cmpl $3, 16(%ebp) + jz .do_thiscall + cmpl $4, 16(%ebp) + jnz .do_fncall + movl (%esp), %ecx + movl 4(%esp), %edx + addl $8, %esp + jmp .do_fncall +.do_thiscall: + movl (%esp), %ecx + addl $4, %esp + +.do_fncall: + + + + + call *32(%ebp) + + + + + movl 24(%ebp),%ecx + + + cmpl $0,28(%ebp) + jne 0f + + + + cmpl $2,%ecx + jne .Lnoretval + fstp %st(0) + + jmp .Lepilogue + +0: + call 1f + +.Lstore_table: + .long .Lnoretval + .long .Lretint + .long .Lretfloat + .long .Lretdouble + .long .Lretlongdouble + .long .Lretuint8 + .long .Lretsint8 + .long .Lretuint16 + .long .Lretsint16 + .long .Lretint + .long .Lretint + .long .Lretint64 + .long .Lretint64 + .long .Lretstruct + .long .Lretint + .long .Lretstruct1b + .long .Lretstruct2b + .long .Lretstruct4b + .long .Lretstruct +1: + add %ecx, %ecx + add %ecx, %ecx + add (%esp),%ecx + add $4, %esp + jmp *(%ecx) + + +.Lretsint8: + movsbl %al, %eax + jmp .Lretint + +.Lretsint16: + movswl %ax, %eax + jmp .Lretint + +.Lretuint8: + movzbl %al, %eax + jmp .Lretint + +.Lretuint16: + movzwl %ax, %eax + jmp .Lretint + +.Lretint: + + movl 28(%ebp),%ecx + movl %eax,0(%ecx) + jmp .Lepilogue + +.Lretfloat: + + movl 28(%ebp),%ecx + fstps (%ecx) + jmp .Lepilogue + +.Lretdouble: + + movl 28(%ebp),%ecx + fstpl (%ecx) + jmp .Lepilogue + +.Lretlongdouble: + + movl 28(%ebp),%ecx + fstpt (%ecx) + jmp .Lepilogue + +.Lretint64: + + movl 28(%ebp),%ecx + movl %eax,0(%ecx) + movl %edx,4(%ecx) + jmp .Lepilogue + +.Lretstruct1b: + + movl 28(%ebp),%ecx + movb %al,0(%ecx) + jmp .Lepilogue + +.Lretstruct2b: + + movl 28(%ebp),%ecx + movw %ax,0(%ecx) + jmp .Lepilogue + +.Lretstruct4b: + + movl 28(%ebp),%ecx + movl %eax,0(%ecx) + jmp .Lepilogue + +.Lretstruct: + + +.Lnoretval: +.Lepilogue: + movl %ebp,%esp + popl %ebp + ret +.ffi_call_win32_end: + .balign 16 + .globl _ffi_closure_THISCALL + + .def _ffi_closure_THISCALL; .scl 2; .type 32; .endef + +_ffi_closure_THISCALL: + pushl %ebp + movl %esp, %ebp + subl $40, %esp + leal -24(%ebp), %edx + movl %edx, -12(%ebp) + leal 12(%ebp), %edx + jmp .stub +.LFE1: + + + .balign 16 + .globl _ffi_closure_SYSV + + .def _ffi_closure_SYSV; .scl 2; .type 32; .endef + +_ffi_closure_SYSV: +.LFB3: + pushl %ebp +.LCFI4: + movl %esp, %ebp +.LCFI5: + subl $40, %esp + leal -24(%ebp), %edx + movl %edx, -12(%ebp) + leal 8(%ebp), %edx +.stub: + movl %edx, 4(%esp) + leal -12(%ebp), %edx + movl %edx, (%esp) + call _ffi_closure_SYSV_inner + movl -12(%ebp), %ecx + +0: + call 1f + +.Lcls_store_table: + .long .Lcls_noretval + .long .Lcls_retint + .long .Lcls_retfloat + .long .Lcls_retdouble + .long .Lcls_retldouble + .long .Lcls_retuint8 + .long .Lcls_retsint8 + .long .Lcls_retuint16 + .long .Lcls_retsint16 + .long .Lcls_retint + .long .Lcls_retint + .long .Lcls_retllong + .long .Lcls_retllong + .long .Lcls_retstruct + .long .Lcls_retint + .long .Lcls_retstruct1 + .long .Lcls_retstruct2 + .long .Lcls_retstruct4 + .long .Lcls_retmsstruct + +1: + add %eax, %eax + add %eax, %eax + add (%esp),%eax + add $4, %esp + jmp *(%eax) + + +.Lcls_retsint8: + movsbl (%ecx), %eax + jmp .Lcls_epilogue + +.Lcls_retsint16: + movswl (%ecx), %eax + jmp .Lcls_epilogue + +.Lcls_retuint8: + movzbl (%ecx), %eax + jmp .Lcls_epilogue + +.Lcls_retuint16: + movzwl (%ecx), %eax + jmp .Lcls_epilogue + +.Lcls_retint: + movl (%ecx), %eax + jmp .Lcls_epilogue + +.Lcls_retfloat: + flds (%ecx) + jmp .Lcls_epilogue + +.Lcls_retdouble: + fldl (%ecx) + jmp .Lcls_epilogue + +.Lcls_retldouble: + fldt (%ecx) + jmp .Lcls_epilogue + +.Lcls_retllong: + movl (%ecx), %eax + movl 4(%ecx), %edx + jmp .Lcls_epilogue + +.Lcls_retstruct1: + movsbl (%ecx), %eax + jmp .Lcls_epilogue + +.Lcls_retstruct2: + movswl (%ecx), %eax + jmp .Lcls_epilogue + +.Lcls_retstruct4: + movl (%ecx), %eax + jmp .Lcls_epilogue + +.Lcls_retstruct: + + movl %ebp, %esp + popl %ebp + ret $0x4 + +.Lcls_retmsstruct: + + mov %ecx, %eax + + jmp .Lcls_epilogue + +.Lcls_noretval: +.Lcls_epilogue: + movl %ebp, %esp + popl %ebp + ret +.ffi_closure_SYSV_end: +.LFE3: + + + + + + + + .balign 16 + .globl _ffi_closure_raw_THISCALL + + .def _ffi_closure_raw_THISCALL; .scl 2; .type 32; .endef + +_ffi_closure_raw_THISCALL: + pushl %ebp + movl %esp, %ebp + pushl %esi + subl $36, %esp + movl ((52 + 3) & ~3)(%eax), %esi + movl ((((52 + 3) & ~3) + 4) + 4)(%eax), %edx + movl %edx, 12(%esp) + leal 12(%ebp), %edx + jmp .stubraw + + .balign 16 + .globl _ffi_closure_raw_SYSV + + .def _ffi_closure_raw_SYSV; .scl 2; .type 32; .endef + +_ffi_closure_raw_SYSV: +.LFB4: + pushl %ebp +.LCFI6: + movl %esp, %ebp +.LCFI7: + pushl %esi +.LCFI8: + subl $36, %esp + movl ((52 + 3) & ~3)(%eax), %esi + movl ((((52 + 3) & ~3) + 4) + 4)(%eax), %edx + movl %edx, 12(%esp) + leal 8(%ebp), %edx +.stubraw: + movl %edx, 8(%esp) + leal -24(%ebp), %edx + movl %edx, 4(%esp) + movl %esi, (%esp) + call *(((52 + 3) & ~3) + 4)(%eax) + movl 20(%esi), %eax +0: + call 1f + +.Lrcls_store_table: + .long .Lrcls_noretval + .long .Lrcls_retint + .long .Lrcls_retfloat + .long .Lrcls_retdouble + .long .Lrcls_retldouble + .long .Lrcls_retuint8 + .long .Lrcls_retsint8 + .long .Lrcls_retuint16 + .long .Lrcls_retsint16 + .long .Lrcls_retint + .long .Lrcls_retint + .long .Lrcls_retllong + .long .Lrcls_retllong + .long .Lrcls_retstruct + .long .Lrcls_retint + .long .Lrcls_retstruct1 + .long .Lrcls_retstruct2 + .long .Lrcls_retstruct4 + .long .Lrcls_retstruct +1: + add %eax, %eax + add %eax, %eax + add (%esp),%eax + add $4, %esp + jmp *(%eax) + + +.Lrcls_retsint8: + movsbl -24(%ebp), %eax + jmp .Lrcls_epilogue + +.Lrcls_retsint16: + movswl -24(%ebp), %eax + jmp .Lrcls_epilogue + +.Lrcls_retuint8: + movzbl -24(%ebp), %eax + jmp .Lrcls_epilogue + +.Lrcls_retuint16: + movzwl -24(%ebp), %eax + jmp .Lrcls_epilogue + +.Lrcls_retint: + movl -24(%ebp), %eax + jmp .Lrcls_epilogue + +.Lrcls_retfloat: + flds -24(%ebp) + jmp .Lrcls_epilogue + +.Lrcls_retdouble: + fldl -24(%ebp) + jmp .Lrcls_epilogue + +.Lrcls_retldouble: + fldt -24(%ebp) + jmp .Lrcls_epilogue + +.Lrcls_retllong: + movl -24(%ebp), %eax + movl -20(%ebp), %edx + jmp .Lrcls_epilogue + +.Lrcls_retstruct1: + movsbl -24(%ebp), %eax + jmp .Lrcls_epilogue + +.Lrcls_retstruct2: + movswl -24(%ebp), %eax + jmp .Lrcls_epilogue + +.Lrcls_retstruct4: + movl -24(%ebp), %eax + jmp .Lrcls_epilogue + +.Lrcls_retstruct: + + +.Lrcls_noretval: +.Lrcls_epilogue: + addl $36, %esp + popl %esi + popl %ebp + ret +.ffi_closure_raw_SYSV_end: +.LFE4: + + + + + .balign 16 + .globl _ffi_closure_STDCALL + + .def _ffi_closure_STDCALL; .scl 2; .type 32; .endef + +_ffi_closure_STDCALL: +.LFB5: + pushl %ebp +.LCFI9: + movl %esp, %ebp +.LCFI10: + subl $40, %esp + leal -24(%ebp), %edx + movl %edx, -12(%ebp) + leal 12(%ebp), %edx + movl %edx, 4(%esp) + leal -12(%ebp), %edx + movl %edx, (%esp) + call _ffi_closure_SYSV_inner + movl -12(%ebp), %ecx +0: + call 1f + +.Lscls_store_table: + .long .Lscls_noretval + .long .Lscls_retint + .long .Lscls_retfloat + .long .Lscls_retdouble + .long .Lscls_retldouble + .long .Lscls_retuint8 + .long .Lscls_retsint8 + .long .Lscls_retuint16 + .long .Lscls_retsint16 + .long .Lscls_retint + .long .Lscls_retint + .long .Lscls_retllong + .long .Lscls_retllong + .long .Lscls_retstruct + .long .Lscls_retint + .long .Lscls_retstruct1 + .long .Lscls_retstruct2 + .long .Lscls_retstruct4 +1: + add %eax, %eax + add %eax, %eax + add (%esp),%eax + add $4, %esp + jmp *(%eax) + + +.Lscls_retsint8: + movsbl (%ecx), %eax + jmp .Lscls_epilogue + +.Lscls_retsint16: + movswl (%ecx), %eax + jmp .Lscls_epilogue + +.Lscls_retuint8: + movzbl (%ecx), %eax + jmp .Lscls_epilogue + +.Lscls_retuint16: + movzwl (%ecx), %eax + jmp .Lscls_epilogue + +.Lscls_retint: + movl (%ecx), %eax + jmp .Lscls_epilogue + +.Lscls_retfloat: + flds (%ecx) + jmp .Lscls_epilogue + +.Lscls_retdouble: + fldl (%ecx) + jmp .Lscls_epilogue + +.Lscls_retldouble: + fldt (%ecx) + jmp .Lscls_epilogue + +.Lscls_retllong: + movl (%ecx), %eax + movl 4(%ecx), %edx + jmp .Lscls_epilogue + +.Lscls_retstruct1: + movsbl (%ecx), %eax + jmp .Lscls_epilogue + +.Lscls_retstruct2: + movswl (%ecx), %eax + jmp .Lscls_epilogue + +.Lscls_retstruct4: + movl (%ecx), %eax + jmp .Lscls_epilogue + +.Lscls_retstruct: + + +.Lscls_noretval: +.Lscls_epilogue: + movl %ebp, %esp + popl %ebp + ret +.ffi_closure_STDCALL_end: +.LFE5: + + + .section .eh_frame,"w" + +.Lframe1: +.LSCIE1: + .long .LECIE1-.LASCIE1 +.LASCIE1: + .long 0x0 + .byte 0x1 + + + + .ascii "\0" + + .byte 0x1 + .byte 0x7c + .byte 0x8 + + + + + .byte 0xc + .byte 0x4 + .byte 0x4 + .byte 0x88 + .byte 0x1 + .align 4 +.LECIE1: + +.LSFDE1: + .long .LEFDE1-.LASFDE1 +.LASFDE1: + .long .LASFDE1-.Lframe1 + + + + .long .LFB1 + + .long .LFE1-.LFB1 + + + + + + .byte 0x4 + .long .LCFI0-.LFB1 + .byte 0xe + .byte 0x8 + .byte 0x85 + .byte 0x2 + + .byte 0x4 + .long .LCFI1-.LCFI0 + .byte 0xd + .byte 0x5 + + + .align 4 +.LEFDE1: + + +.LSFDE3: + .long .LEFDE3-.LASFDE3 +.LASFDE3: + .long .LASFDE3-.Lframe1 + + + + .long .LFB3 + + .long .LFE3-.LFB3 + + + + + + .byte 0x4 + .long .LCFI4-.LFB3 + .byte 0xe + .byte 0x8 + .byte 0x85 + .byte 0x2 + + .byte 0x4 + .long .LCFI5-.LCFI4 + .byte 0xd + .byte 0x5 + + + .align 4 +.LEFDE3: + + + +.LSFDE4: + .long .LEFDE4-.LASFDE4 +.LASFDE4: + .long .LASFDE4-.Lframe1 + + + + .long .LFB4 + + .long .LFE4-.LFB4 + + + + + + .byte 0x4 + .long .LCFI6-.LFB4 + .byte 0xe + .byte 0x8 + .byte 0x85 + .byte 0x2 + + .byte 0x4 + .long .LCFI7-.LCFI6 + .byte 0xd + .byte 0x5 + + .byte 0x4 + .long .LCFI8-.LCFI7 + .byte 0x86 + .byte 0x3 + + + .align 4 +.LEFDE4: + + + +.LSFDE5: + .long .LEFDE5-.LASFDE5 +.LASFDE5: + .long .LASFDE5-.Lframe1 + + + + .long .LFB5 + + .long .LFE5-.LFB5 + + + + + + .byte 0x4 + .long .LCFI9-.LFB5 + .byte 0xe + .byte 0x8 + .byte 0x85 + .byte 0x2 + + .byte 0x4 + .long .LCFI10-.LCFI9 + .byte 0xd + .byte 0x5 + + + .align 4 +.LEFDE5: diff --git a/lib/wrappers/libffi/gcc/win64_asm.asm b/lib/wrappers/libffi/gcc/win64_asm.asm new file mode 100644 index 000000000..1dc98f99a --- /dev/null +++ b/lib/wrappers/libffi/gcc/win64_asm.asm @@ -0,0 +1,467 @@ +#define LIBFFI_ASM +#include <fficonfig.h> +#include <ffi.h> + +/* Constants for ffi_call_win64 */ +#define STACK 0 +#define PREP_ARGS_FN 32 +#define ECIF 40 +#define CIF_BYTES 48 +#define CIF_FLAGS 56 +#define RVALUE 64 +#define FN 72 + +/* ffi_call_win64 (void (*prep_args_fn)(char *, extended_cif *), + extended_cif *ecif, unsigned bytes, unsigned flags, + unsigned *rvalue, void (*fn)()); + */ + +#ifdef _MSC_VER +PUBLIC ffi_call_win64 + +EXTRN __chkstk:NEAR +EXTRN ffi_closure_win64_inner:NEAR + +_TEXT SEGMENT + +;;; ffi_closure_win64 will be called with these registers set: +;;; rax points to 'closure' +;;; r11 contains a bit mask that specifies which of the +;;; first four parameters are float or double +;;; +;;; It must move the parameters passed in registers to their stack location, +;;; call ffi_closure_win64_inner for the actual work, then return the result. +;;; +ffi_closure_win64 PROC FRAME + ;; copy register arguments onto stack + test r11, 1 + jne first_is_float + mov QWORD PTR [rsp+8], rcx + jmp second +first_is_float: + movlpd QWORD PTR [rsp+8], xmm0 + +second: + test r11, 2 + jne second_is_float + mov QWORD PTR [rsp+16], rdx + jmp third +second_is_float: + movlpd QWORD PTR [rsp+16], xmm1 + +third: + test r11, 4 + jne third_is_float + mov QWORD PTR [rsp+24], r8 + jmp fourth +third_is_float: + movlpd QWORD PTR [rsp+24], xmm2 + +fourth: + test r11, 8 + jne fourth_is_float + mov QWORD PTR [rsp+32], r9 + jmp done +fourth_is_float: + movlpd QWORD PTR [rsp+32], xmm3 + +done: + .ALLOCSTACK 40 + sub rsp, 40 + .ENDPROLOG + mov rcx, rax ; context is first parameter + mov rdx, rsp ; stack is second parameter + add rdx, 48 ; point to start of arguments + mov rax, ffi_closure_win64_inner + call rax ; call the real closure function + add rsp, 40 + movd xmm0, rax ; If the closure returned a float, + ; ffi_closure_win64_inner wrote it to rax + ret 0 +ffi_closure_win64 ENDP + +ffi_call_win64 PROC FRAME + ;; copy registers onto stack + mov QWORD PTR [rsp+32], r9 + mov QWORD PTR [rsp+24], r8 + mov QWORD PTR [rsp+16], rdx + mov QWORD PTR [rsp+8], rcx + .PUSHREG rbp + push rbp + .ALLOCSTACK 48 + sub rsp, 48 ; 00000030H + .SETFRAME rbp, 32 + lea rbp, QWORD PTR [rsp+32] + .ENDPROLOG + + mov eax, DWORD PTR CIF_BYTES[rbp] + add rax, 15 + and rax, -16 + call __chkstk + sub rsp, rax + lea rax, QWORD PTR [rsp+32] + mov QWORD PTR STACK[rbp], rax + + mov rdx, QWORD PTR ECIF[rbp] + mov rcx, QWORD PTR STACK[rbp] + call QWORD PTR PREP_ARGS_FN[rbp] + + mov rsp, QWORD PTR STACK[rbp] + + movlpd xmm3, QWORD PTR [rsp+24] + movd r9, xmm3 + + movlpd xmm2, QWORD PTR [rsp+16] + movd r8, xmm2 + + movlpd xmm1, QWORD PTR [rsp+8] + movd rdx, xmm1 + + movlpd xmm0, QWORD PTR [rsp] + movd rcx, xmm0 + + call QWORD PTR FN[rbp] +ret_struct4b$: + cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_4B + jne ret_struct2b$ + + mov rcx, QWORD PTR RVALUE[rbp] + mov DWORD PTR [rcx], eax + jmp ret_void$ + +ret_struct2b$: + cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_2B + jne ret_struct1b$ + + mov rcx, QWORD PTR RVALUE[rbp] + mov WORD PTR [rcx], ax + jmp ret_void$ + +ret_struct1b$: + cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_1B + jne ret_uint8$ + + mov rcx, QWORD PTR RVALUE[rbp] + mov BYTE PTR [rcx], al + jmp ret_void$ + +ret_uint8$: + cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT8 + jne ret_sint8$ + + mov rcx, QWORD PTR RVALUE[rbp] + movzx rax, al + mov QWORD PTR [rcx], rax + jmp ret_void$ + +ret_sint8$: + cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT8 + jne ret_uint16$ + + mov rcx, QWORD PTR RVALUE[rbp] + movsx rax, al + mov QWORD PTR [rcx], rax + jmp ret_void$ + +ret_uint16$: + cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT16 + jne ret_sint16$ + + mov rcx, QWORD PTR RVALUE[rbp] + movzx rax, ax + mov QWORD PTR [rcx], rax + jmp SHORT ret_void$ + +ret_sint16$: + cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT16 + jne ret_uint32$ + + mov rcx, QWORD PTR RVALUE[rbp] + movsx rax, ax + mov QWORD PTR [rcx], rax + jmp SHORT ret_void$ + +ret_uint32$: + cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT32 + jne ret_sint32$ + + mov rcx, QWORD PTR RVALUE[rbp] + mov eax, eax + mov QWORD PTR [rcx], rax + jmp SHORT ret_void$ + +ret_sint32$: + cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT32 + jne ret_float$ + + mov rcx, QWORD PTR RVALUE[rbp] + cdqe + mov QWORD PTR [rcx], rax + jmp SHORT ret_void$ + +ret_float$: + cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_FLOAT + jne SHORT ret_double$ + + mov rax, QWORD PTR RVALUE[rbp] + movss DWORD PTR [rax], xmm0 + jmp SHORT ret_void$ + +ret_double$: + cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_DOUBLE + jne SHORT ret_sint64$ + + mov rax, QWORD PTR RVALUE[rbp] + movlpd QWORD PTR [rax], xmm0 + jmp SHORT ret_void$ + +ret_sint64$: + cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT64 + jne ret_void$ + + mov rcx, QWORD PTR RVALUE[rbp] + mov QWORD PTR [rcx], rax + jmp SHORT ret_void$ + +ret_void$: + xor rax, rax + + lea rsp, QWORD PTR [rbp+16] + pop rbp + ret 0 +ffi_call_win64 ENDP +_TEXT ENDS +END + +#else + +#ifdef SYMBOL_UNDERSCORE +#define SYMBOL_NAME(name) _##name +#else +#define SYMBOL_NAME(name) name +#endif + +.text + +.extern SYMBOL_NAME(ffi_closure_win64_inner) + +// ffi_closure_win64 will be called with these registers set: +// rax points to 'closure' +// r11 contains a bit mask that specifies which of the +// first four parameters are float or double +// // It must move the parameters passed in registers to their stack location, +// call ffi_closure_win64_inner for the actual work, then return the result. +// + .balign 16 + .globl SYMBOL_NAME(ffi_closure_win64) +SYMBOL_NAME(ffi_closure_win64): + // copy register arguments onto stack + test $1,%r11 + jne .Lfirst_is_float + mov %rcx, 8(%rsp) + jmp .Lsecond +.Lfirst_is_float: + movlpd %xmm0, 8(%rsp) + +.Lsecond: + test $2, %r11 + jne .Lsecond_is_float + mov %rdx, 16(%rsp) + jmp .Lthird +.Lsecond_is_float: + movlpd %xmm1, 16(%rsp) + +.Lthird: + test $4, %r11 + jne .Lthird_is_float + mov %r8,24(%rsp) + jmp .Lfourth +.Lthird_is_float: + movlpd %xmm2, 24(%rsp) + +.Lfourth: + test $8, %r11 + jne .Lfourth_is_float + mov %r9, 32(%rsp) + jmp .Ldone +.Lfourth_is_float: + movlpd %xmm3, 32(%rsp) + +.Ldone: +// ALLOCSTACK 40 + sub $40, %rsp +// ENDPROLOG + mov %rax, %rcx // context is first parameter + mov %rsp, %rdx // stack is second parameter + add $48, %rdx // point to start of arguments + mov $SYMBOL_NAME(ffi_closure_win64_inner), %rax + callq *%rax // call the real closure function + add $40, %rsp + movq %rax, %xmm0 // If the closure returned a float, + // ffi_closure_win64_inner wrote it to rax + retq +.ffi_closure_win64_end: + + .balign 16 + .globl SYMBOL_NAME(ffi_call_win64) +SYMBOL_NAME(ffi_call_win64): + // copy registers onto stack + mov %r9,32(%rsp) + mov %r8,24(%rsp) + mov %rdx,16(%rsp) + mov %rcx,8(%rsp) + // PUSHREG rbp + push %rbp + // ALLOCSTACK 48 + sub $48,%rsp + // SETFRAME rbp, 32 + lea 32(%rsp),%rbp + // ENDPROLOG + + mov CIF_BYTES(%rbp),%eax + add $15, %rax + and $-16, %rax + cmpq $0x1000, %rax + jb Lch_done +Lch_probe: + subq $0x1000,%rsp + orl $0x0, (%rsp) + subq $0x1000,%rax + cmpq $0x1000,%rax + ja Lch_probe +Lch_done: + subq %rax, %rsp + orl $0x0, (%rsp) + lea 32(%rsp), %rax + mov %rax, STACK(%rbp) + + mov ECIF(%rbp), %rdx + mov STACK(%rbp), %rcx + callq *PREP_ARGS_FN(%rbp) + + mov STACK(%rbp), %rsp + + movlpd 24(%rsp), %xmm3 + movd %xmm3, %r9 + + movlpd 16(%rsp), %xmm2 + movd %xmm2, %r8 + + movlpd 8(%rsp), %xmm1 + movd %xmm1, %rdx + + movlpd (%rsp), %xmm0 + movd %xmm0, %rcx + + callq *FN(%rbp) +.Lret_struct4b: + cmpl $FFI_TYPE_SMALL_STRUCT_4B, CIF_FLAGS(%rbp) + jne .Lret_struct2b + + mov RVALUE(%rbp), %rcx + mov %eax, (%rcx) + jmp .Lret_void + +.Lret_struct2b: + cmpl $FFI_TYPE_SMALL_STRUCT_2B, CIF_FLAGS(%rbp) + jne .Lret_struct1b + + mov RVALUE(%rbp), %rcx + mov %ax, (%rcx) + jmp .Lret_void + +.Lret_struct1b: + cmpl $FFI_TYPE_SMALL_STRUCT_1B, CIF_FLAGS(%rbp) + jne .Lret_uint8 + + mov RVALUE(%rbp), %rcx + mov %al, (%rcx) + jmp .Lret_void + +.Lret_uint8: + cmpl $FFI_TYPE_UINT8, CIF_FLAGS(%rbp) + jne .Lret_sint8 + + mov RVALUE(%rbp), %rcx + movzbq %al, %rax + movq %rax, (%rcx) + jmp .Lret_void + +.Lret_sint8: + cmpl $FFI_TYPE_SINT8, CIF_FLAGS(%rbp) + jne .Lret_uint16 + + mov RVALUE(%rbp), %rcx + movsbq %al, %rax + movq %rax, (%rcx) + jmp .Lret_void + +.Lret_uint16: + cmpl $FFI_TYPE_UINT16, CIF_FLAGS(%rbp) + jne .Lret_sint16 + + mov RVALUE(%rbp), %rcx + movzwq %ax, %rax + movq %rax, (%rcx) + jmp .Lret_void + +.Lret_sint16: + cmpl $FFI_TYPE_SINT16, CIF_FLAGS(%rbp) + jne .Lret_uint32 + + mov RVALUE(%rbp), %rcx + movswq %ax, %rax + movq %rax, (%rcx) + jmp .Lret_void + +.Lret_uint32: + cmpl $FFI_TYPE_UINT32, CIF_FLAGS(%rbp) + jne .Lret_sint32 + + mov RVALUE(%rbp), %rcx + movl %eax, %eax + movq %rax, (%rcx) + jmp .Lret_void + +.Lret_sint32: + cmpl $FFI_TYPE_SINT32, CIF_FLAGS(%rbp) + jne .Lret_float + + mov RVALUE(%rbp), %rcx + cltq + movq %rax, (%rcx) + jmp .Lret_void + +.Lret_float: + cmpl $FFI_TYPE_FLOAT, CIF_FLAGS(%rbp) + jne .Lret_double + + mov RVALUE(%rbp), %rax + movss %xmm0, (%rax) + jmp .Lret_void + +.Lret_double: + cmpl $FFI_TYPE_DOUBLE, CIF_FLAGS(%rbp) + jne .Lret_sint64 + + mov RVALUE(%rbp), %rax + movlpd %xmm0, (%rax) + jmp .Lret_void + +.Lret_sint64: + cmpl $FFI_TYPE_SINT64, CIF_FLAGS(%rbp) + jne .Lret_void + + mov RVALUE(%rbp), %rcx + mov %rax, (%rcx) + jmp .Lret_void + +.Lret_void: + xor %rax, %rax + + lea 16(%rbp), %rsp + pop %rbp + retq +.ffi_call_win64_end: +#endif /* !_MSC_VER */ + diff --git a/lib/wrappers/libffi/gcc/win64_asm.s b/lib/wrappers/libffi/gcc/win64_asm.s new file mode 100644 index 000000000..f2c2df10d --- /dev/null +++ b/lib/wrappers/libffi/gcc/win64_asm.s @@ -0,0 +1,227 @@ +# 1 "gcc\\win64_asm.asm" +# 1 "<command-line>" +# 1 "gcc\\win64_asm.asm" + +# 1 "common/fficonfig.h" 1 +# 3 "gcc\\win64_asm.asm" 2 +# 1 "common/ffi.h" 1 +# 63 "common/ffi.h" +# 1 "common/ffitarget.h" 1 +# 64 "common/ffi.h" 2 +# 4 "gcc\\win64_asm.asm" 2 +# 244 "gcc\\win64_asm.asm" +.text + +.extern ffi_closure_win64_inner +# 255 "gcc\\win64_asm.asm" + .balign 16 + .globl ffi_closure_win64 +ffi_closure_win64: + + test $1,%r11 + jne .Lfirst_is_float + mov %rcx, 8(%rsp) + jmp .Lsecond +.Lfirst_is_float: + movlpd %xmm0, 8(%rsp) + +.Lsecond: + test $2, %r11 + jne .Lsecond_is_float + mov %rdx, 16(%rsp) + jmp .Lthird +.Lsecond_is_float: + movlpd %xmm1, 16(%rsp) + +.Lthird: + test $4, %r11 + jne .Lthird_is_float + mov %r8,24(%rsp) + jmp .Lfourth +.Lthird_is_float: + movlpd %xmm2, 24(%rsp) + +.Lfourth: + test $8, %r11 + jne .Lfourth_is_float + mov %r9, 32(%rsp) + jmp .Ldone +.Lfourth_is_float: + movlpd %xmm3, 32(%rsp) + +.Ldone: + + sub $40, %rsp + + mov %rax, %rcx + mov %rsp, %rdx + add $48, %rdx + mov $SYMBOL_NAME(ffi_closure_win64_inner), %rax + callq *%rax + add $40, %rsp + movq %rax, %xmm0 + + retq +.ffi_closure_win64_end: + + .balign 16 + .globl ffi_call_win64 +ffi_call_win64: + + mov %r9,32(%rsp) + mov %r8,24(%rsp) + mov %rdx,16(%rsp) + mov %rcx,8(%rsp) + + push %rbp + + sub $48,%rsp + + lea 32(%rsp),%rbp + + + mov 48(%rbp),%eax + add $15, %rax + and $-16, %rax + cmpq $0x1000, %rax + jb Lch_done +Lch_probe: + subq $0x1000,%rsp + orl $0x0, (%rsp) + subq $0x1000,%rax + cmpq $0x1000,%rax + ja Lch_probe +Lch_done: + subq %rax, %rsp + orl $0x0, (%rsp) + lea 32(%rsp), %rax + mov %rax, 0(%rbp) + + mov 40(%rbp), %rdx + mov 0(%rbp), %rcx + callq *32(%rbp) + + mov 0(%rbp), %rsp + + movlpd 24(%rsp), %xmm3 + movd %xmm3, %r9 + + movlpd 16(%rsp), %xmm2 + movd %xmm2, %r8 + + movlpd 8(%rsp), %xmm1 + movd %xmm1, %rdx + + movlpd (%rsp), %xmm0 + movd %xmm0, %rcx + + callq *72(%rbp) +.Lret_struct4b: + cmpl $FFI_TYPE_SMALL_STRUCT_4B, 56(%rbp) + jne .Lret_struct2b + + mov 64(%rbp), %rcx + mov %eax, (%rcx) + jmp .Lret_void + +.Lret_struct2b: + cmpl $FFI_TYPE_SMALL_STRUCT_2B, 56(%rbp) + jne .Lret_struct1b + + mov 64(%rbp), %rcx + mov %ax, (%rcx) + jmp .Lret_void + +.Lret_struct1b: + cmpl $FFI_TYPE_SMALL_STRUCT_1B, 56(%rbp) + jne .Lret_uint8 + + mov 64(%rbp), %rcx + mov %al, (%rcx) + jmp .Lret_void + +.Lret_uint8: + cmpl $FFI_TYPE_UINT8, 56(%rbp) + jne .Lret_sint8 + + mov 64(%rbp), %rcx + movzbq %al, %rax + movq %rax, (%rcx) + jmp .Lret_void + +.Lret_sint8: + cmpl $FFI_TYPE_SINT8, 56(%rbp) + jne .Lret_uint16 + + mov 64(%rbp), %rcx + movsbq %al, %rax + movq %rax, (%rcx) + jmp .Lret_void + +.Lret_uint16: + cmpl $FFI_TYPE_UINT16, 56(%rbp) + jne .Lret_sint16 + + mov 64(%rbp), %rcx + movzwq %ax, %rax + movq %rax, (%rcx) + jmp .Lret_void + +.Lret_sint16: + cmpl $FFI_TYPE_SINT16, 56(%rbp) + jne .Lret_uint32 + + mov 64(%rbp), %rcx + movswq %ax, %rax + movq %rax, (%rcx) + jmp .Lret_void + +.Lret_uint32: + cmpl $9, 56(%rbp) + jne .Lret_sint32 + + mov 64(%rbp), %rcx + movl %eax, %eax + movq %rax, (%rcx) + jmp .Lret_void + +.Lret_sint32: + cmpl $10, 56(%rbp) + jne .Lret_float + + mov 64(%rbp), %rcx + cltq + movq %rax, (%rcx) + jmp .Lret_void + +.Lret_float: + cmpl $2, 56(%rbp) + jne .Lret_double + + mov 64(%rbp), %rax + movss %xmm0, (%rax) + jmp .Lret_void + +.Lret_double: + cmpl $3, 56(%rbp) + jne .Lret_sint64 + + mov 64(%rbp), %rax + movlpd %xmm0, (%rax) + jmp .Lret_void + +.Lret_sint64: + cmpl $12, 56(%rbp) + jne .Lret_void + + mov 64(%rbp), %rcx + mov %rax, (%rcx) + jmp .Lret_void + +.Lret_void: + xor %rax, %rax + + lea 16(%rbp), %rsp + pop %rbp + retq +.ffi_call_win64_end: diff --git a/lib/wrappers/libffi.nim b/lib/wrappers/libffi/libffi.nim index 514ce024f..1b6130103 100644 --- a/lib/wrappers/libffi.nim +++ b/lib/wrappers/libffi/libffi.nim @@ -26,12 +26,36 @@ {.deadCodeElim: on.} -when defined(windows): - const libffidll* = "libffi.dll" -elif defined(macosx): - const libffidll* = "libffi.dylib" -else: - const libffidll* = "libffi.so" +when defined(windows): + # on Windows we don't use a DLL but instead embed libffi directly: + {.pragma: mylib, header: r"ffi.h".} + + #{.compile: r"common\malloc_closure.c".} + {.compile: r"common\raw_api.c".} + when defined(vcc): + {.compile: r"msvc\ffi.c".} + {.compile: r"msvc\prep_cif.c".} + {.compile: r"msvc\win32.c".} + {.compile: r"msvc\types.c".} + when defined(cpu64): + {.compile: r"msvc\win64_asm.asm".} + else: + {.compile: r"msvc\win32_asm.asm".} + else: + {.compile: r"gcc\ffi.c".} + {.compile: r"gcc\prep_cif.c".} + {.compile: r"gcc\types.c".} + {.compile: r"gcc\closures.c".} + when defined(cpu64): + {.compile: r"gcc\ffi64.c".} + {.compile: r"gcc\win64_asm.S".} + else: + {.compile: r"gcc\win32_asm.S".} + +elif defined(macosx): + {.pragma: mylib, dynlib: "libffi.dylib".} +else: + {.pragma: mylib, dynlib: "libffi.so".} type TArg* = int @@ -88,19 +112,19 @@ type elements*: ptr ptr TType var - type_void* {.importc: "ffi_type_void", dynlib: libffidll.}: TType - type_uint8* {.importc: "ffi_type_uint8", dynlib: libffidll.}: TType - type_sint8* {.importc: "ffi_type_sint8", dynlib: libffidll.}: TType - type_uint16* {.importc: "ffi_type_uint16", dynlib: libffidll.}: TType - type_sint16* {.importc: "ffi_type_sint16", dynlib: libffidll.}: TType - type_uint32* {.importc: "ffi_type_uint32", dynlib: libffidll.}: TType - type_sint32* {.importc: "ffi_type_sint32", dynlib: libffidll.}: TType - type_uint64* {.importc: "ffi_type_uint64", dynlib: libffidll.}: TType - type_sint64* {.importc: "ffi_type_sint64", dynlib: libffidll.}: TType - type_float* {.importc: "ffi_type_float", dynlib: libffidll.}: TType - type_double* {.importc: "ffi_type_double", dynlib: libffidll.}: TType - type_pointer* {.importc: "ffi_type_pointer", dynlib: libffidll.}: TType - type_longdouble* {.importc: "ffi_type_longdouble", dynlib: libffidll.}: TType + type_void* {.importc: "ffi_type_void", mylib.}: TType + type_uint8* {.importc: "ffi_type_uint8", mylib.}: TType + type_sint8* {.importc: "ffi_type_sint8", mylib.}: TType + type_uint16* {.importc: "ffi_type_uint16", mylib.}: TType + type_sint16* {.importc: "ffi_type_sint16", mylib.}: TType + type_uint32* {.importc: "ffi_type_uint32", mylib.}: TType + type_sint32* {.importc: "ffi_type_sint32", mylib.}: TType + type_uint64* {.importc: "ffi_type_uint64", mylib.}: TType + type_sint64* {.importc: "ffi_type_sint64", mylib.}: TType + type_float* {.importc: "ffi_type_float", mylib.}: TType + type_double* {.importc: "ffi_type_double", mylib.}: TType + type_pointer* {.importc: "ffi_type_pointer", mylib.}: TType + type_longdouble* {.importc: "ffi_type_longdouble", mylib.}: TType type Tstatus* {.size: sizeof(cint).} = enum @@ -119,20 +143,18 @@ type sint*: TSArg proc raw_call*(cif: var Tcif; fn: proc () {.cdecl.}; rvalue: pointer; - avalue: ptr TRaw) {.cdecl, importc: "ffi_raw_call", - dynlib: libffidll.} + avalue: ptr TRaw) {.cdecl, importc: "ffi_raw_call", mylib.} proc ptrarray_to_raw*(cif: var Tcif; args: ptr pointer; raw: ptr TRaw) {.cdecl, - importc: "ffi_ptrarray_to_raw", dynlib: libffidll.} + importc: "ffi_ptrarray_to_raw", mylib.} proc raw_to_ptrarray*(cif: var Tcif; raw: ptr TRaw; args: ptr pointer) {.cdecl, - importc: "ffi_raw_to_ptrarray", dynlib: libffidll.} -proc raw_size*(cif: var Tcif): int {.cdecl, importc: "ffi_raw_size", - dynlib: libffidll.} + importc: "ffi_raw_to_ptrarray", mylib.} +proc raw_size*(cif: var Tcif): int {.cdecl, importc: "ffi_raw_size", mylib.} proc prep_cif*(cif: var Tcif; abi: TABI; nargs: cuint; rtype: ptr TType; atypes: ptr ptr TType): TStatus {.cdecl, importc: "ffi_prep_cif", - dynlib: libffidll.} + mylib.} proc call*(cif: var Tcif; fn: proc () {.cdecl.}; rvalue: pointer; - avalue: ptr pointer) {.cdecl, importc: "ffi_call", dynlib: libffidll.} + avalue: ptr pointer) {.cdecl, importc: "ffi_call", mylib.} # the same with an easier interface: type @@ -141,9 +163,9 @@ type proc prep_cif*(cif: var Tcif; abi: TABI; nargs: cuint; rtype: ptr TType; atypes: TParamList): TStatus {.cdecl, importc: "ffi_prep_cif", - dynlib: libffidll.} + mylib.} proc call*(cif: var Tcif; fn, rvalue: pointer; - avalue: TArgList) {.cdecl, importc: "ffi_call", dynlib: libffidll.} + avalue: TArgList) {.cdecl, importc: "ffi_call", mylib.} # Useful for eliminating compiler warnings ##define FFI_FN(f) ((void (*)(void))f) diff --git a/lib/wrappers/libffi/msvc/ffi.c b/lib/wrappers/libffi/msvc/ffi.c new file mode 100644 index 000000000..6e595e9fe --- /dev/null +++ b/lib/wrappers/libffi/msvc/ffi.c @@ -0,0 +1,457 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 1996, 1998, 1999, 2001 Red Hat, Inc. + Copyright (c) 2002 Ranjit Mathew + Copyright (c) 2002 Bo Thorsen + Copyright (c) 2002 Roger Sayle + + x86 Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#include <ffi.h> +#include <ffi_common.h> + +#include <stdlib.h> + +/* ffi_prep_args is called by the assembly routine once stack space + has been allocated for the function's arguments */ + +extern void Py_FatalError(const char *msg); + +/*@-exportheader@*/ +void ffi_prep_args(char *stack, extended_cif *ecif) +/*@=exportheader@*/ +{ + register unsigned int i; + register void **p_argv; + register char *argp; + register ffi_type **p_arg; + + argp = stack; + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT) + { + *(void **) argp = ecif->rvalue; + argp += sizeof(void *); + } + + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + i != 0; + i--, p_arg++) + { + size_t z; + + /* Align if necessary */ + if ((sizeof(void *) - 1) & (size_t) argp) + argp = (char *) ALIGN(argp, sizeof(void *)); + + z = (*p_arg)->size; + if (z < sizeof(int)) + { + z = sizeof(int); + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); + break; + + case FFI_TYPE_SINT32: + *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv); + break; + + case FFI_TYPE_UINT32: + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + break; + + case FFI_TYPE_STRUCT: + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + break; + + default: + FFI_ASSERT(0); + } + } + else + { + memcpy(argp, *p_argv, z); + } + p_argv++; + argp += z; + } + + if (argp >= stack && (unsigned)(argp - stack) > ecif->cif->bytes) + { + Py_FatalError("FFI BUG: not enough stack space for arguments"); + } + return; +} + +/* Perform machine dependent cif processing */ +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +{ + /* Set the return type flag */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + case FFI_TYPE_STRUCT: + case FFI_TYPE_SINT64: + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + cif->flags = (unsigned) cif->rtype->type; + break; + + case FFI_TYPE_UINT64: +#ifdef _WIN64 + case FFI_TYPE_POINTER: +#endif + cif->flags = FFI_TYPE_SINT64; + break; + + default: + cif->flags = FFI_TYPE_INT; + break; + } + + return FFI_OK; +} + +#ifdef _WIN32 +extern int +ffi_call_x86(void (*)(char *, extended_cif *), + /*@out@*/ extended_cif *, + unsigned, unsigned, + /*@out@*/ unsigned *, + void (*fn)()); +#endif + +#ifdef _WIN64 +extern int +ffi_call_AMD64(void (*)(char *, extended_cif *), + /*@out@*/ extended_cif *, + unsigned, unsigned, + /*@out@*/ unsigned *, + void (*fn)()); +#endif + +int +ffi_call(/*@dependent@*/ ffi_cif *cif, + void (*fn)(), + /*@out@*/ void *rvalue, + /*@dependent@*/ void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return */ + /* value address then we need to make one */ + + if ((rvalue == NULL) && + (cif->rtype->type == FFI_TYPE_STRUCT)) + { + /*@-sysunrecog@*/ + ecif.rvalue = alloca(cif->rtype->size); + /*@=sysunrecog@*/ + } + else + ecif.rvalue = rvalue; + + + switch (cif->abi) + { +#if !defined(_WIN64) + case FFI_SYSV: + case FFI_STDCALL: + return ffi_call_x86(ffi_prep_args, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); + break; +#else + case FFI_SYSV: + /*@-usedef@*/ + /* Function call needs at least 40 bytes stack size, on win64 AMD64 */ + return ffi_call_AMD64(ffi_prep_args, &ecif, cif->bytes ? cif->bytes : 40, + cif->flags, ecif.rvalue, fn); + /*@=usedef@*/ + break; +#endif + + default: + FFI_ASSERT(0); + break; + } + return -1; /* theller: Hrm. */ +} + + +/** private members **/ + +static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, + void** args, ffi_cif* cif); +/* This function is jumped to by the trampoline */ + +#ifdef _WIN64 +void * +#else +static void __fastcall +#endif +ffi_closure_SYSV (ffi_closure *closure, int *argp) +{ + // this is our return value storage + long double res; + + // our various things... + ffi_cif *cif; + void **arg_area; + unsigned short rtype; + void *resp = (void*)&res; + void *args = &argp[1]; + + cif = closure->cif; + arg_area = (void**) alloca (cif->nargs * sizeof (void*)); + + /* this call will initialize ARG_AREA, such that each + * element in that array points to the corresponding + * value on the stack; and if the function returns + * a structure, it will re-set RESP to point to the + * structure return address. */ + + ffi_prep_incoming_args_SYSV(args, (void**)&resp, arg_area, cif); + + (closure->fun) (cif, resp, arg_area, closure->user_data); + + rtype = cif->flags; + +#if defined(_WIN32) && !defined(_WIN64) +#ifdef _MSC_VER + /* now, do a generic return based on the value of rtype */ + if (rtype == FFI_TYPE_INT) + { + _asm mov eax, resp ; + _asm mov eax, [eax] ; + } + else if (rtype == FFI_TYPE_FLOAT) + { + _asm mov eax, resp ; + _asm fld DWORD PTR [eax] ; +// asm ("flds (%0)" : : "r" (resp) : "st" ); + } + else if (rtype == FFI_TYPE_DOUBLE) + { + _asm mov eax, resp ; + _asm fld QWORD PTR [eax] ; +// asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); + } + else if (rtype == FFI_TYPE_LONGDOUBLE) + { +// asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); + } + else if (rtype == FFI_TYPE_SINT64) + { + _asm mov edx, resp ; + _asm mov eax, [edx] ; + _asm mov edx, [edx + 4] ; +// asm ("movl 0(%0),%%eax;" +// "movl 4(%0),%%edx" +// : : "r"(resp) +// : "eax", "edx"); + } +#else + /* now, do a generic return based on the value of rtype */ + if (rtype == FFI_TYPE_INT) + { + asm ("movl (%0),%%eax" : : "r" (resp) : "eax"); + } + else if (rtype == FFI_TYPE_FLOAT) + { + asm ("flds (%0)" : : "r" (resp) : "st" ); + } + else if (rtype == FFI_TYPE_DOUBLE) + { + asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); + } + else if (rtype == FFI_TYPE_LONGDOUBLE) + { + asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); + } + else if (rtype == FFI_TYPE_SINT64) + { + asm ("movl 0(%0),%%eax;" + "movl 4(%0),%%edx" + : : "r"(resp) + : "eax", "edx"); + } +#endif +#endif + +#ifdef _WIN64 + /* The result is returned in rax. This does the right thing for + result types except for floats; we have to 'mov xmm0, rax' in the + caller to correct this. + */ + return *(void **)resp; +#endif +} + +/*@-exportheader@*/ +static void +ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, + void **avalue, ffi_cif *cif) +/*@=exportheader@*/ +{ + register unsigned int i; + register void **p_argv; + register char *argp; + register ffi_type **p_arg; + + argp = stack; + + if ( cif->rtype->type == FFI_TYPE_STRUCT ) { + *rvalue = *(void **) argp; + argp += 4; + } + + p_argv = avalue; + + for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) + { + size_t z; + + /* Align if necessary */ + if ((sizeof(char *) - 1) & (size_t) argp) { + argp = (char *) ALIGN(argp, sizeof(char*)); + } + + z = (*p_arg)->size; + + /* because we're little endian, this is what it turns into. */ + + *p_argv = (void*) argp; + + p_argv++; + argp += z; + } + + return; +} + +/* the cif must already be prep'ed */ +extern void ffi_closure_OUTER(); + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) +{ + short bytes; + char *tramp; +#ifdef _WIN64 + int mask = 0; +#endif + FFI_ASSERT (cif->abi == FFI_SYSV); + + if (cif->abi == FFI_SYSV) + bytes = 0; +#if !defined(_WIN64) + else if (cif->abi == FFI_STDCALL) + bytes = cif->bytes; +#endif + else + return FFI_BAD_ABI; + + tramp = &closure->tramp[0]; + +#define BYTES(text) memcpy(tramp, text, sizeof(text)), tramp += sizeof(text)-1 +#define POINTER(x) *(void**)tramp = (void*)(x), tramp += sizeof(void*) +#define SHORT(x) *(short*)tramp = x, tramp += sizeof(short) +#define INT(x) *(int*)tramp = x, tramp += sizeof(int) + +#ifdef _WIN64 + if (cif->nargs >= 1 && + (cif->arg_types[0]->type == FFI_TYPE_FLOAT + || cif->arg_types[0]->type == FFI_TYPE_DOUBLE)) + mask |= 1; + if (cif->nargs >= 2 && + (cif->arg_types[1]->type == FFI_TYPE_FLOAT + || cif->arg_types[1]->type == FFI_TYPE_DOUBLE)) + mask |= 2; + if (cif->nargs >= 3 && + (cif->arg_types[2]->type == FFI_TYPE_FLOAT + || cif->arg_types[2]->type == FFI_TYPE_DOUBLE)) + mask |= 4; + if (cif->nargs >= 4 && + (cif->arg_types[3]->type == FFI_TYPE_FLOAT + || cif->arg_types[3]->type == FFI_TYPE_DOUBLE)) + mask |= 8; + + /* 41 BB ---- mov r11d,mask */ + BYTES("\x41\xBB"); INT(mask); + + /* 48 B8 -------- mov rax, closure */ + BYTES("\x48\xB8"); POINTER(closure); + + /* 49 BA -------- mov r10, ffi_closure_OUTER */ + BYTES("\x49\xBA"); POINTER(ffi_closure_OUTER); + + /* 41 FF E2 jmp r10 */ + BYTES("\x41\xFF\xE2"); + +#else + + /* mov ecx, closure */ + BYTES("\xb9"); POINTER(closure); + + /* mov edx, esp */ + BYTES("\x8b\xd4"); + + /* call ffi_closure_SYSV */ + BYTES("\xe8"); POINTER((char*)&ffi_closure_SYSV - (tramp + 4)); + + /* ret bytes */ + BYTES("\xc2"); + SHORT(bytes); + +#endif + + if (tramp - &closure->tramp[0] > FFI_TRAMPOLINE_SIZE) + Py_FatalError("FFI_TRAMPOLINE_SIZE too small in " __FILE__); + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + return FFI_OK; +} diff --git a/lib/wrappers/libffi/msvc/prep_cif.c b/lib/wrappers/libffi/msvc/prep_cif.c new file mode 100644 index 000000000..2650fa052 --- /dev/null +++ b/lib/wrappers/libffi/msvc/prep_cif.c @@ -0,0 +1,175 @@ +/* ----------------------------------------------------------------------- + prep_cif.c - Copyright (c) 1996, 1998 Red Hat, Inc. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#include <ffi.h> +#include <ffi_common.h> +#include <stdlib.h> + + +/* Round up to FFI_SIZEOF_ARG. */ + +#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG) + +/* Perform machine independent initialization of aggregate type + specifications. */ + +static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg) +{ + ffi_type **ptr; + + FFI_ASSERT(arg != NULL); + + /*@-usedef@*/ + + FFI_ASSERT(arg->elements != NULL); + FFI_ASSERT(arg->size == 0); + FFI_ASSERT(arg->alignment == 0); + + ptr = &(arg->elements[0]); + + while ((*ptr) != NULL) + { + if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) + return FFI_BAD_TYPEDEF; + + /* Perform a sanity check on the argument type */ + FFI_ASSERT_VALID_TYPE(*ptr); + + arg->size = ALIGN(arg->size, (*ptr)->alignment); + arg->size += (*ptr)->size; + + arg->alignment = (arg->alignment > (*ptr)->alignment) ? + arg->alignment : (*ptr)->alignment; + + ptr++; + } + + /* Structure size includes tail padding. This is important for + structures that fit in one register on ABIs like the PowerPC64 + Linux ABI that right justify small structs in a register. + It's also needed for nested structure layout, for example + struct A { long a; char b; }; struct B { struct A x; char y; }; + should find y at an offset of 2*sizeof(long) and result in a + total size of 3*sizeof(long). */ + arg->size = ALIGN (arg->size, arg->alignment); + + if (arg->size == 0) + return FFI_BAD_TYPEDEF; + else + return FFI_OK; + + /*@=usedef@*/ +} + +/* Perform machine independent ffi_cif preparation, then call + machine dependent routine. */ + +ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, + ffi_abi abi, unsigned int nargs, + /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, + /*@dependent@*/ ffi_type **atypes) +{ + unsigned bytes = 0; + unsigned int i; + ffi_type **ptr; + + FFI_ASSERT(cif != NULL); + FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI)); + + cif->abi = abi; + cif->arg_types = atypes; + cif->nargs = nargs; + cif->rtype = rtype; + + cif->flags = 0; + + /* Initialize the return type if necessary */ + /*@-usedef@*/ + if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) + return FFI_BAD_TYPEDEF; + /*@=usedef@*/ + + /* Perform a sanity check on the return type */ + FFI_ASSERT_VALID_TYPE(cif->rtype); + + /* x86-64 and s390 stack space allocation is handled in prep_machdep. */ +#if !defined M68K && !defined __x86_64__ && !defined S390 + /* Make space for the return structure pointer */ + if (cif->rtype->type == FFI_TYPE_STRUCT + /* MSVC returns small structures in registers. But we have a different + workaround: pretend int32 or int64 return type, and converting to + structure afterwards. */ +#ifdef SPARC + && (cif->abi != FFI_V9 || cif->rtype->size > 32) +#endif + ) + bytes = STACK_ARG_SIZE(sizeof(void*)); +#endif + + for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) + { + + /* Initialize any uninitialized aggregate type definitions */ + if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) + return FFI_BAD_TYPEDEF; + + /* Perform a sanity check on the argument type, do this + check after the initialization. */ + FFI_ASSERT_VALID_TYPE(*ptr); + +#if !defined __x86_64__ && !defined S390 +#ifdef SPARC + if (((*ptr)->type == FFI_TYPE_STRUCT + && ((*ptr)->size > 16 || cif->abi != FFI_V9)) + || ((*ptr)->type == FFI_TYPE_LONGDOUBLE + && cif->abi != FFI_V9)) + bytes += sizeof(void*); + else +#endif + { +#if !defined(_MSC_VER) && !defined(__MINGW32__) + /* Don't know if this is a libffi bug or not. At least on + Windows with MSVC, function call parameters are *not* + aligned in the same way as structure fields are, they are + only aligned in integer boundaries. + + This doesn't do any harm for cdecl functions and closures, + since the caller cleans up the stack, but it is wrong for + stdcall functions where the callee cleans. + */ + + /* Add any padding if necessary */ + if (((*ptr)->alignment - 1) & bytes) + bytes = ALIGN(bytes, (*ptr)->alignment); + +#endif + bytes += STACK_ARG_SIZE((*ptr)->size); + } +#endif + } + + cif->bytes = bytes; + + /* Perform machine dependent cif processing */ + return ffi_prep_cif_machdep(cif); +} diff --git a/lib/wrappers/libffi/msvc/types.c b/lib/wrappers/libffi/msvc/types.c new file mode 100644 index 000000000..df32190d1 --- /dev/null +++ b/lib/wrappers/libffi/msvc/types.c @@ -0,0 +1,104 @@ +/* ----------------------------------------------------------------------- + types.c - Copyright (c) 1996, 1998 Red Hat, Inc. + + Predefined ffi_types needed by libffi. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#include <ffi.h> +#include <ffi_common.h> + +/* Type definitions */ + +#define FFI_INTEGRAL_TYPEDEF(n, s, a, t) ffi_type ffi_type_##n = { s, a, t, NULL } +#define FFI_AGGREGATE_TYPEDEF(n, e) ffi_type ffi_type_##n = { 0, 0, FFI_TYPE_STRUCT, e } + +/* Size and alignment are fake here. They must not be 0. */ +FFI_INTEGRAL_TYPEDEF(void, 1, 1, FFI_TYPE_VOID); + +FFI_INTEGRAL_TYPEDEF(uint8, 1, 1, FFI_TYPE_UINT8); +FFI_INTEGRAL_TYPEDEF(sint8, 1, 1, FFI_TYPE_SINT8); +FFI_INTEGRAL_TYPEDEF(uint16, 2, 2, FFI_TYPE_UINT16); +FFI_INTEGRAL_TYPEDEF(sint16, 2, 2, FFI_TYPE_SINT16); +FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32); +FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32); +FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT); + +#if defined ALPHA || defined SPARC64 || defined X86_64 || defined S390X \ + || defined IA64 + +FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER); + +#else + +FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER); + +#endif + +#if defined X86 || defined X86_WIN32 || defined ARM || defined M68K + +FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); +FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); + +#elif defined SH + +FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); +FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); + +#else + +FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64); +FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64); + +#endif + + +#if defined X86 || defined X86_WIN32 || defined M68K + +FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); +FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE); + +#elif defined ARM || defined SH || defined POWERPC_AIX || defined POWERPC_DARWIN + +FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); +FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE); + +#elif defined SPARC + +FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); +#ifdef SPARC64 +FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); +#else +FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE); +#endif + +#elif defined X86_64 + +FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); +FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); + +#else + +FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); +FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE); + +#endif + diff --git a/lib/wrappers/libffi/msvc/win32.c b/lib/wrappers/libffi/msvc/win32.c new file mode 100644 index 000000000..d1149a85e --- /dev/null +++ b/lib/wrappers/libffi/msvc/win32.c @@ -0,0 +1,162 @@ +/* ----------------------------------------------------------------------- + win32.S - Copyright (c) 1996, 1998, 2001, 2002 Red Hat, Inc. + Copyright (c) 2001 John Beniton + Copyright (c) 2002 Ranjit Mathew + + + X86 Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +/* theller: almost verbatim translation from gas syntax to MSVC inline + assembler code. */ + +/* theller: ffi_call_x86 now returns an integer - the difference of the stack + pointer before and after the function call. If everything is ok, zero is + returned. If stdcall functions are passed the wrong number of arguments, + the difference will be nonzero. */ + +#include <ffi.h> +#include <ffi_common.h> + +__declspec(naked) int +ffi_call_x86(void (* prepfunc)(char *, extended_cif *), /* 8 */ + extended_cif *ecif, /* 12 */ + unsigned bytes, /* 16 */ + unsigned flags, /* 20 */ + unsigned *rvalue, /* 24 */ + void (*fn)()) /* 28 */ +{ + _asm { + push ebp + mov ebp, esp + + push esi // NEW: this register must be preserved across function calls +// XXX SAVE ESP NOW! + mov esi, esp // save stack pointer before the call + +// Make room for all of the new args. + mov ecx, [ebp+16] + sub esp, ecx // sub esp, bytes + + mov eax, esp + +// Place all of the ffi_prep_args in position + push [ebp + 12] // ecif + push eax + call [ebp + 8] // prepfunc + +// Return stack to previous state and call the function + add esp, 8 +// FIXME: Align the stack to a 128-bit boundary to avoid +// potential performance hits. + call [ebp + 28] + +// Load ecif->cif->abi + mov ecx, [ebp + 12] + mov ecx, [ecx]ecif.cif + mov ecx, [ecx]ecif.cif.abi + + cmp ecx, FFI_STDCALL + je noclean +// STDCALL: Remove the space we pushed for the args + mov ecx, [ebp + 16] + add esp, ecx +// CDECL: Caller has already cleaned the stack +noclean: +// Check that esp has the same value as before! + sub esi, esp + +// Load %ecx with the return type code + mov ecx, [ebp + 20] + +// If the return value pointer is NULL, assume no return value. +/* + Intel asm is weird. We have to explicitely specify 'DWORD PTR' in the nexr instruction, + otherwise only one BYTE will be compared (instead of a DWORD)! + */ + cmp DWORD PTR [ebp + 24], 0 + jne sc_retint + +// Even if there is no space for the return value, we are +// obliged to handle floating-point values. + cmp ecx, FFI_TYPE_FLOAT + jne sc_noretval +// fstp %st(0) + fstp st(0) + + jmp sc_epilogue + +sc_retint: + cmp ecx, FFI_TYPE_INT + jne sc_retfloat +// # Load %ecx with the pointer to storage for the return value + mov ecx, [ebp + 24] + mov [ecx + 0], eax + jmp sc_epilogue + +sc_retfloat: + cmp ecx, FFI_TYPE_FLOAT + jne sc_retdouble +// Load %ecx with the pointer to storage for the return value + mov ecx, [ebp+24] +// fstps (%ecx) + fstp DWORD PTR [ecx] + jmp sc_epilogue + +sc_retdouble: + cmp ecx, FFI_TYPE_DOUBLE + jne sc_retlongdouble +// movl 24(%ebp),%ecx + mov ecx, [ebp+24] + fstp QWORD PTR [ecx] + jmp sc_epilogue + + jmp sc_retlongdouble // avoid warning about unused label +sc_retlongdouble: + cmp ecx, FFI_TYPE_LONGDOUBLE + jne sc_retint64 +// Load %ecx with the pointer to storage for the return value + mov ecx, [ebp+24] +// fstpt (%ecx) + fstp QWORD PTR [ecx] /* XXX ??? */ + jmp sc_epilogue + +sc_retint64: + cmp ecx, FFI_TYPE_SINT64 + jne sc_retstruct +// Load %ecx with the pointer to storage for the return value + mov ecx, [ebp+24] + mov [ecx+0], eax + mov [ecx+4], edx + +sc_retstruct: +// Nothing to do! + +sc_noretval: +sc_epilogue: + mov eax, esi + pop esi // NEW restore: must be preserved across function calls + mov esp, ebp + pop ebp + ret + } +} diff --git a/lib/wrappers/libffi/msvc/win32_asm.asm b/lib/wrappers/libffi/msvc/win32_asm.asm new file mode 100644 index 000000000..407185e6a --- /dev/null +++ b/lib/wrappers/libffi/msvc/win32_asm.asm @@ -0,0 +1,470 @@ +/* ----------------------------------------------------------------------- + win32.S - Copyright (c) 1996, 1998, 2001, 2002, 2009 Red Hat, Inc. + Copyright (c) 2001 John Beniton + Copyright (c) 2002 Ranjit Mathew + Copyright (c) 2009 Daniel Witte + + + X86 Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- + */ + +#define LIBFFI_ASM +#include <fficonfig.h> +#include <ffi.h> + +.386 +.MODEL FLAT, C + +EXTRN ffi_closure_SYSV_inner:NEAR + +_TEXT SEGMENT + +ffi_call_win32 PROC NEAR, + ffi_prep_args : NEAR PTR DWORD, + ecif : NEAR PTR DWORD, + cif_abi : DWORD, + cif_bytes : DWORD, + cif_flags : DWORD, + rvalue : NEAR PTR DWORD, + fn : NEAR PTR DWORD + + ;; Make room for all of the new args. + mov ecx, cif_bytes + sub esp, ecx + + mov eax, esp + + ;; Place all of the ffi_prep_args in position + push ecif + push eax + call ffi_prep_args + + ;; Return stack to previous state and call the function + add esp, 8 + + ;; Handle thiscall and fastcall + cmp cif_abi, 3 ;; FFI_THISCALL + jz do_thiscall + cmp cif_abi, 4 ;; FFI_FASTCALL + jnz do_stdcall + mov ecx, DWORD PTR [esp] + mov edx, DWORD PTR [esp+4] + add esp, 8 + jmp do_stdcall +do_thiscall: + mov ecx, DWORD PTR [esp] + add esp, 4 +do_stdcall: + call fn + + ;; cdecl: we restore esp in the epilogue, so there's no need to + ;; remove the space we pushed for the args. + ;; stdcall: the callee has already cleaned the stack. + + ;; Load ecx with the return type code + mov ecx, cif_flags + + ;; If the return value pointer is NULL, assume no return value. + cmp rvalue, 0 + jne ca_jumptable + + ;; Even if there is no space for the return value, we are + ;; obliged to handle floating-point values. + cmp ecx, FFI_TYPE_FLOAT + jne ca_epilogue + fstp st(0) + + jmp ca_epilogue + +ca_jumptable: + jmp [ca_jumpdata + 4 * ecx] +ca_jumpdata: + ;; Do not insert anything here between label and jump table. + dd offset ca_epilogue ;; FFI_TYPE_VOID + dd offset ca_retint ;; FFI_TYPE_INT + dd offset ca_retfloat ;; FFI_TYPE_FLOAT + dd offset ca_retdouble ;; FFI_TYPE_DOUBLE + dd offset ca_retlongdouble ;; FFI_TYPE_LONGDOUBLE + dd offset ca_retuint8 ;; FFI_TYPE_UINT8 + dd offset ca_retsint8 ;; FFI_TYPE_SINT8 + dd offset ca_retuint16 ;; FFI_TYPE_UINT16 + dd offset ca_retsint16 ;; FFI_TYPE_SINT16 + dd offset ca_retint ;; FFI_TYPE_UINT32 + dd offset ca_retint ;; FFI_TYPE_SINT32 + dd offset ca_retint64 ;; FFI_TYPE_UINT64 + dd offset ca_retint64 ;; FFI_TYPE_SINT64 + dd offset ca_epilogue ;; FFI_TYPE_STRUCT + dd offset ca_retint ;; FFI_TYPE_POINTER + dd offset ca_retstruct1b ;; FFI_TYPE_SMALL_STRUCT_1B + dd offset ca_retstruct2b ;; FFI_TYPE_SMALL_STRUCT_2B + dd offset ca_retint ;; FFI_TYPE_SMALL_STRUCT_4B + dd offset ca_epilogue ;; FFI_TYPE_MS_STRUCT + + /* Sign/zero extend as appropriate. */ +ca_retuint8: + movzx eax, al + jmp ca_retint + +ca_retsint8: + movsx eax, al + jmp ca_retint + +ca_retuint16: + movzx eax, ax + jmp ca_retint + +ca_retsint16: + movsx eax, ax + jmp ca_retint + +ca_retint: + ;; Load %ecx with the pointer to storage for the return value + mov ecx, rvalue + mov [ecx + 0], eax + jmp ca_epilogue + +ca_retint64: + ;; Load %ecx with the pointer to storage for the return value + mov ecx, rvalue + mov [ecx + 0], eax + mov [ecx + 4], edx + jmp ca_epilogue + +ca_retfloat: + ;; Load %ecx with the pointer to storage for the return value + mov ecx, rvalue + fstp DWORD PTR [ecx] + jmp ca_epilogue + +ca_retdouble: + ;; Load %ecx with the pointer to storage for the return value + mov ecx, rvalue + fstp QWORD PTR [ecx] + jmp ca_epilogue + +ca_retlongdouble: + ;; Load %ecx with the pointer to storage for the return value + mov ecx, rvalue + fstp TBYTE PTR [ecx] + jmp ca_epilogue + +ca_retstruct1b: + ;; Load %ecx with the pointer to storage for the return value + mov ecx, rvalue + mov [ecx + 0], al + jmp ca_epilogue + +ca_retstruct2b: + ;; Load %ecx with the pointer to storage for the return value + mov ecx, rvalue + mov [ecx + 0], ax + jmp ca_epilogue + +ca_epilogue: + ;; Epilogue code is autogenerated. + ret +ffi_call_win32 ENDP + +ffi_closure_THISCALL PROC NEAR FORCEFRAME + sub esp, 40 + lea edx, [ebp -24] + mov [ebp - 12], edx /* resp */ + lea edx, [ebp + 12] /* account for stub return address on stack */ + jmp stub +ffi_closure_THISCALL ENDP + +ffi_closure_SYSV PROC NEAR FORCEFRAME + ;; the ffi_closure ctx is passed in eax by the trampoline. + + sub esp, 40 + lea edx, [ebp - 24] + mov [ebp - 12], edx ;; resp + lea edx, [ebp + 8] +stub:: + mov [esp + 8], edx ;; args + lea edx, [ebp - 12] + mov [esp + 4], edx ;; &resp + mov [esp], eax ;; closure + call ffi_closure_SYSV_inner + mov ecx, [ebp - 12] + +cs_jumptable: + jmp [cs_jumpdata + 4 * eax] +cs_jumpdata: + ;; Do not insert anything here between the label and jump table. + dd offset cs_epilogue ;; FFI_TYPE_VOID + dd offset cs_retint ;; FFI_TYPE_INT + dd offset cs_retfloat ;; FFI_TYPE_FLOAT + dd offset cs_retdouble ;; FFI_TYPE_DOUBLE + dd offset cs_retlongdouble ;; FFI_TYPE_LONGDOUBLE + dd offset cs_retuint8 ;; FFI_TYPE_UINT8 + dd offset cs_retsint8 ;; FFI_TYPE_SINT8 + dd offset cs_retuint16 ;; FFI_TYPE_UINT16 + dd offset cs_retsint16 ;; FFI_TYPE_SINT16 + dd offset cs_retint ;; FFI_TYPE_UINT32 + dd offset cs_retint ;; FFI_TYPE_SINT32 + dd offset cs_retint64 ;; FFI_TYPE_UINT64 + dd offset cs_retint64 ;; FFI_TYPE_SINT64 + dd offset cs_retstruct ;; FFI_TYPE_STRUCT + dd offset cs_retint ;; FFI_TYPE_POINTER + dd offset cs_retsint8 ;; FFI_TYPE_SMALL_STRUCT_1B + dd offset cs_retsint16 ;; FFI_TYPE_SMALL_STRUCT_2B + dd offset cs_retint ;; FFI_TYPE_SMALL_STRUCT_4B + dd offset cs_retmsstruct ;; FFI_TYPE_MS_STRUCT + +cs_retuint8: + movzx eax, BYTE PTR [ecx] + jmp cs_epilogue + +cs_retsint8: + movsx eax, BYTE PTR [ecx] + jmp cs_epilogue + +cs_retuint16: + movzx eax, WORD PTR [ecx] + jmp cs_epilogue + +cs_retsint16: + movsx eax, WORD PTR [ecx] + jmp cs_epilogue + +cs_retint: + mov eax, [ecx] + jmp cs_epilogue + +cs_retint64: + mov eax, [ecx + 0] + mov edx, [ecx + 4] + jmp cs_epilogue + +cs_retfloat: + fld DWORD PTR [ecx] + jmp cs_epilogue + +cs_retdouble: + fld QWORD PTR [ecx] + jmp cs_epilogue + +cs_retlongdouble: + fld TBYTE PTR [ecx] + jmp cs_epilogue + +cs_retstruct: + ;; Caller expects us to pop struct return value pointer hidden arg. + ;; Epilogue code is autogenerated. + ret 4 + +cs_retmsstruct: + ;; Caller expects us to return a pointer to the real return value. + mov eax, ecx + ;; Caller doesn't expects us to pop struct return value pointer hidden arg. + jmp cs_epilogue + +cs_epilogue: + ;; Epilogue code is autogenerated. + ret +ffi_closure_SYSV ENDP + +#if !FFI_NO_RAW_API + +#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) AND NOT 3) +#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4) +#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4) +#define CIF_FLAGS_OFFSET 20 + +ffi_closure_raw_THISCALL PROC NEAR USES esi FORCEFRAME + sub esp, 36 + mov esi, [eax + RAW_CLOSURE_CIF_OFFSET] ;; closure->cif + mov edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET] ;; closure->user_data + mov [esp + 12], edx + lea edx, [ebp + 12] + jmp stubraw +ffi_closure_raw_THISCALL ENDP + +ffi_closure_raw_SYSV PROC NEAR USES esi FORCEFRAME + ;; the ffi_closure ctx is passed in eax by the trampoline. + + sub esp, 40 + mov esi, [eax + RAW_CLOSURE_CIF_OFFSET] ;; closure->cif + mov edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET] ;; closure->user_data + mov [esp + 12], edx ;; user_data + lea edx, [ebp + 8] +stubraw:: + mov [esp + 8], edx ;; raw_args + lea edx, [ebp - 24] + mov [esp + 4], edx ;; &res + mov [esp], esi ;; cif + call DWORD PTR [eax + RAW_CLOSURE_FUN_OFFSET] ;; closure->fun + mov eax, [esi + CIF_FLAGS_OFFSET] ;; cif->flags + lea ecx, [ebp - 24] + +cr_jumptable: + jmp [cr_jumpdata + 4 * eax] +cr_jumpdata: + ;; Do not insert anything here between the label and jump table. + dd offset cr_epilogue ;; FFI_TYPE_VOID + dd offset cr_retint ;; FFI_TYPE_INT + dd offset cr_retfloat ;; FFI_TYPE_FLOAT + dd offset cr_retdouble ;; FFI_TYPE_DOUBLE + dd offset cr_retlongdouble ;; FFI_TYPE_LONGDOUBLE + dd offset cr_retuint8 ;; FFI_TYPE_UINT8 + dd offset cr_retsint8 ;; FFI_TYPE_SINT8 + dd offset cr_retuint16 ;; FFI_TYPE_UINT16 + dd offset cr_retsint16 ;; FFI_TYPE_SINT16 + dd offset cr_retint ;; FFI_TYPE_UINT32 + dd offset cr_retint ;; FFI_TYPE_SINT32 + dd offset cr_retint64 ;; FFI_TYPE_UINT64 + dd offset cr_retint64 ;; FFI_TYPE_SINT64 + dd offset cr_epilogue ;; FFI_TYPE_STRUCT + dd offset cr_retint ;; FFI_TYPE_POINTER + dd offset cr_retsint8 ;; FFI_TYPE_SMALL_STRUCT_1B + dd offset cr_retsint16 ;; FFI_TYPE_SMALL_STRUCT_2B + dd offset cr_retint ;; FFI_TYPE_SMALL_STRUCT_4B + dd offset cr_epilogue ;; FFI_TYPE_MS_STRUCT + +cr_retuint8: + movzx eax, BYTE PTR [ecx] + jmp cr_epilogue + +cr_retsint8: + movsx eax, BYTE PTR [ecx] + jmp cr_epilogue + +cr_retuint16: + movzx eax, WORD PTR [ecx] + jmp cr_epilogue + +cr_retsint16: + movsx eax, WORD PTR [ecx] + jmp cr_epilogue + +cr_retint: + mov eax, [ecx] + jmp cr_epilogue + +cr_retint64: + mov eax, [ecx + 0] + mov edx, [ecx + 4] + jmp cr_epilogue + +cr_retfloat: + fld DWORD PTR [ecx] + jmp cr_epilogue + +cr_retdouble: + fld QWORD PTR [ecx] + jmp cr_epilogue + +cr_retlongdouble: + fld TBYTE PTR [ecx] + jmp cr_epilogue + +cr_epilogue: + ;; Epilogue code is autogenerated. + ret +ffi_closure_raw_SYSV ENDP + +#endif /* !FFI_NO_RAW_API */ + +ffi_closure_STDCALL PROC NEAR FORCEFRAME + ;; the ffi_closure ctx is passed in eax by the trampoline. + + sub esp, 40 + lea edx, [ebp - 24] + mov [ebp - 12], edx ;; resp + lea edx, [ebp + 12] ;; account for stub return address on stack + mov [esp + 8], edx ;; args + lea edx, [ebp - 12] + mov [esp + 4], edx ;; &resp + mov [esp], eax ;; closure + call ffi_closure_SYSV_inner + mov ecx, [ebp - 12] + +cd_jumptable: + jmp [cd_jumpdata + 4 * eax] +cd_jumpdata: + ;; Do not insert anything here between the label and jump table. + dd offset cd_epilogue ;; FFI_TYPE_VOID + dd offset cd_retint ;; FFI_TYPE_INT + dd offset cd_retfloat ;; FFI_TYPE_FLOAT + dd offset cd_retdouble ;; FFI_TYPE_DOUBLE + dd offset cd_retlongdouble ;; FFI_TYPE_LONGDOUBLE + dd offset cd_retuint8 ;; FFI_TYPE_UINT8 + dd offset cd_retsint8 ;; FFI_TYPE_SINT8 + dd offset cd_retuint16 ;; FFI_TYPE_UINT16 + dd offset cd_retsint16 ;; FFI_TYPE_SINT16 + dd offset cd_retint ;; FFI_TYPE_UINT32 + dd offset cd_retint ;; FFI_TYPE_SINT32 + dd offset cd_retint64 ;; FFI_TYPE_UINT64 + dd offset cd_retint64 ;; FFI_TYPE_SINT64 + dd offset cd_epilogue ;; FFI_TYPE_STRUCT + dd offset cd_retint ;; FFI_TYPE_POINTER + dd offset cd_retsint8 ;; FFI_TYPE_SMALL_STRUCT_1B + dd offset cd_retsint16 ;; FFI_TYPE_SMALL_STRUCT_2B + dd offset cd_retint ;; FFI_TYPE_SMALL_STRUCT_4B + +cd_retuint8: + movzx eax, BYTE PTR [ecx] + jmp cd_epilogue + +cd_retsint8: + movsx eax, BYTE PTR [ecx] + jmp cd_epilogue + +cd_retuint16: + movzx eax, WORD PTR [ecx] + jmp cd_epilogue + +cd_retsint16: + movsx eax, WORD PTR [ecx] + jmp cd_epilogue + +cd_retint: + mov eax, [ecx] + jmp cd_epilogue + +cd_retint64: + mov eax, [ecx + 0] + mov edx, [ecx + 4] + jmp cd_epilogue + +cd_retfloat: + fld DWORD PTR [ecx] + jmp cd_epilogue + +cd_retdouble: + fld QWORD PTR [ecx] + jmp cd_epilogue + +cd_retlongdouble: + fld TBYTE PTR [ecx] + jmp cd_epilogue + +cd_epilogue: + ;; Epilogue code is autogenerated. + ret +ffi_closure_STDCALL ENDP + +_TEXT ENDS +END diff --git a/lib/wrappers/libffi/msvc/win64_asm.asm b/lib/wrappers/libffi/msvc/win64_asm.asm new file mode 100644 index 000000000..301188bc9 --- /dev/null +++ b/lib/wrappers/libffi/msvc/win64_asm.asm @@ -0,0 +1,156 @@ +PUBLIC ffi_call_AMD64 + +EXTRN __chkstk:NEAR +EXTRN ffi_closure_SYSV:NEAR + +_TEXT SEGMENT + +;;; ffi_closure_OUTER will be called with these registers set: +;;; rax points to 'closure' +;;; r11 contains a bit mask that specifies which of the +;;; first four parameters are float or double +;;; +;;; It must move the parameters passed in registers to their stack location, +;;; call ffi_closure_SYSV for the actual work, then return the result. +;;; +ffi_closure_OUTER PROC FRAME + ;; save actual arguments to their stack space. + test r11, 1 + jne first_is_float + mov QWORD PTR [rsp+8], rcx + jmp second +first_is_float: + movlpd QWORD PTR [rsp+8], xmm0 + +second: + test r11, 2 + jne second_is_float + mov QWORD PTR [rsp+16], rdx + jmp third +second_is_float: + movlpd QWORD PTR [rsp+16], xmm1 + +third: + test r11, 4 + jne third_is_float + mov QWORD PTR [rsp+24], r8 + jmp forth +third_is_float: + movlpd QWORD PTR [rsp+24], xmm2 + +forth: + test r11, 8 + jne forth_is_float + mov QWORD PTR [rsp+32], r9 + jmp done +forth_is_float: + movlpd QWORD PTR [rsp+32], xmm3 + +done: +.ALLOCSTACK 40 + sub rsp, 40 +.ENDPROLOG + mov rcx, rax ; context is first parameter + mov rdx, rsp ; stack is second parameter + add rdx, 40 ; correct our own area + mov rax, ffi_closure_SYSV + call rax ; call the real closure function + ;; Here, code is missing that handles float return values + add rsp, 40 + movd xmm0, rax ; In case the closure returned a float. + ret 0 +ffi_closure_OUTER ENDP + + +;;; ffi_call_AMD64 + +stack$ = 0 +prepfunc$ = 32 +ecif$ = 40 +bytes$ = 48 +flags$ = 56 +rvalue$ = 64 +fn$ = 72 + +ffi_call_AMD64 PROC FRAME + + mov QWORD PTR [rsp+32], r9 + mov QWORD PTR [rsp+24], r8 + mov QWORD PTR [rsp+16], rdx + mov QWORD PTR [rsp+8], rcx +.PUSHREG rbp + push rbp +.ALLOCSTACK 48 + sub rsp, 48 ; 00000030H +.SETFRAME rbp, 32 + lea rbp, QWORD PTR [rsp+32] +.ENDPROLOG + + mov eax, DWORD PTR bytes$[rbp] + add rax, 15 + and rax, -16 + call __chkstk + sub rsp, rax + lea rax, QWORD PTR [rsp+32] + mov QWORD PTR stack$[rbp], rax + + mov rdx, QWORD PTR ecif$[rbp] + mov rcx, QWORD PTR stack$[rbp] + call QWORD PTR prepfunc$[rbp] + + mov rsp, QWORD PTR stack$[rbp] + + movlpd xmm3, QWORD PTR [rsp+24] + movd r9, xmm3 + + movlpd xmm2, QWORD PTR [rsp+16] + movd r8, xmm2 + + movlpd xmm1, QWORD PTR [rsp+8] + movd rdx, xmm1 + + movlpd xmm0, QWORD PTR [rsp] + movd rcx, xmm0 + + call QWORD PTR fn$[rbp] +ret_int$: + cmp DWORD PTR flags$[rbp], 1 ; FFI_TYPE_INT + jne ret_float$ + + mov rcx, QWORD PTR rvalue$[rbp] + mov DWORD PTR [rcx], eax + jmp SHORT ret_nothing$ + +ret_float$: + cmp DWORD PTR flags$[rbp], 2 ; FFI_TYPE_FLOAT + jne SHORT ret_double$ + + mov rax, QWORD PTR rvalue$[rbp] + movlpd QWORD PTR [rax], xmm0 + jmp SHORT ret_nothing$ + +ret_double$: + cmp DWORD PTR flags$[rbp], 3 ; FFI_TYPE_DOUBLE + jne SHORT ret_int64$ + + mov rax, QWORD PTR rvalue$[rbp] + movlpd QWORD PTR [rax], xmm0 + jmp SHORT ret_nothing$ + +ret_int64$: + cmp DWORD PTR flags$[rbp], 12 ; FFI_TYPE_SINT64 + jne ret_nothing$ + + mov rcx, QWORD PTR rvalue$[rbp] + mov QWORD PTR [rcx], rax + jmp SHORT ret_nothing$ + +ret_nothing$: + xor eax, eax + + lea rsp, QWORD PTR [rbp+16] + pop rbp + ret 0 +ffi_call_AMD64 ENDP +_TEXT ENDS +END diff --git a/lib/wrappers/mysql.nim b/lib/wrappers/mysql.nim index 5a8d4c98b..84d70287f 100644 --- a/lib/wrappers/mysql.nim +++ b/lib/wrappers/mysql.nim @@ -19,7 +19,7 @@ when defined(Windows): type my_bool* = bool Pmy_bool* = ptr my_bool - PVIO* = Pointer + PVIO* = pointer Pgptr* = ptr gptr gptr* = cstring Pmy_socket* = ptr my_socket @@ -645,7 +645,7 @@ type next_slave*: Pst_mysql last_used_slave*: Pst_mysql # needed for round-robin slave pick last_used_con*: Pst_mysql # needed for send/read/store/use result to work correctly with replication - stmts*: Pointer # was PList, list of all statements + stmts*: pointer # was PList, list of all statements methods*: Pst_mysql_methods thd*: pointer # Points to boolean flag in MYSQL_RES or MYSQL_STMT. We set this flag # from mysql_stmt_close if close had to cancel result set of this object. diff --git a/lib/wrappers/pcre.nim b/lib/wrappers/pcre.nim index 46248dde5..afa8f447a 100644 --- a/lib/wrappers/pcre.nim +++ b/lib/wrappers/pcre.nim @@ -243,7 +243,7 @@ type # remain compatible. type - Textra*{.pure, final.} = object + TExtra*{.pure, final.} = object flags*: int ## Bits for which fields are set study_data*: pointer ## Opaque data from pcre_study() match_limit*: int ## Maximum number of calls to match() @@ -260,7 +260,7 @@ type # without modification. type - Tcallout_block*{.pure, final.} = object + TCalloutBlock*{.pure, final.} = object version*: cint ## Identifies version of block callout_number*: cint ## Number compiled into pattern offset_vector*: ptr cint ## The offset vector @@ -284,7 +284,7 @@ type # User defined callback which provides a stack just before the match starts. type - Tjit_callback* = proc(p: pointer): ptr Tjit_stack{.cdecl.} + TJitCallback* = proc(p: pointer): ptr Tjit_stack{.cdecl.} # Exported PCRE functions @@ -303,18 +303,18 @@ proc copy_substring*(a2: cstring, a3: ptr cint, a4: cint, a5: cint, a6: cstring, a7: cint): cint{.cdecl, importc: "pcre_copy_substring", pcreImport.} -proc dfa_exec*(a2: ptr TPcre, a3: ptr Textra, a4: cstring, a5: cint, +proc dfa_exec*(a2: ptr TPcre, a3: ptr TExtra, a4: cstring, a5: cint, a6: cint, a7: cint, a8: ptr cint, a9: cint, a10: ptr cint, a11: cint): cint{.cdecl, importc: "pcre_dfa_exec", pcreImport.} -proc exec*(a2: ptr TPcre, a3: ptr Textra, a4: cstring, a5: cint, a6: cint, +proc exec*(a2: ptr TPcre, a3: ptr TExtra, a4: cstring, a5: cint, a6: cint, a7: cint, a8: ptr cint, a9: cint): cint {. cdecl, importc: "pcre_exec", pcreImport.} proc free_substring*(a2: cstring){.cdecl, importc: "pcre_free_substring", pcreImport.} proc free_substring_list*(a2: cstringArray){.cdecl, importc: "pcre_free_substring_list", pcreImport.} -proc fullinfo*(a2: ptr TPcre, a3: ptr Textra, a4: cint, a5: pointer): cint{. +proc fullinfo*(a2: ptr TPcre, a3: ptr TExtra, a4: cint, a5: pointer): cint{. cdecl, importc: "pcre_fullinfo", pcreImport.} proc get_named_substring*(a2: ptr TPcre, a3: cstring, a4: ptr cint, a5: cint, a6: cstring, a7: cstringArray): cint{.cdecl, @@ -334,13 +334,13 @@ proc maketables*(): ptr char{.cdecl, importc: "pcre_maketables", pcreImport.} proc refcount*(a2: ptr TPcre, a3: cint): cint{.cdecl, importc: "pcre_refcount", pcreImport.} -proc study*(a2: ptr TPcre, a3: cint, a4: var cstring): ptr Textra{.cdecl, +proc study*(a2: ptr TPcre, a3: cint, a4: var cstring): ptr TExtra{.cdecl, importc: "pcre_study", pcreImport.} proc version*(): cstring{.cdecl, importc: "pcre_version", pcreImport.} # Utility functions for byte order swaps. -proc pattern_to_host_byte_order*(a2: ptr TPcre, a3: ptr Textra, +proc pattern_to_host_byte_order*(a2: ptr TPcre, a3: ptr TExtra, a4: ptr char): cint{.cdecl, importc: "pcre_pattern_to_host_byte_order", pcreImport.} @@ -350,7 +350,7 @@ proc jit_stack_alloc*(a2: cint, a3: cint): ptr Tjit_stack{.cdecl, importc: "pcre_jit_stack_alloc", pcreImport.} proc jit_stack_free*(a2: ptr Tjit_stack){.cdecl, importc: "pcre_jit_stack_free", pcreImport.} -proc assign_jit_stack*(a2: ptr Textra, a3: Tjit_callback, a4: pointer){.cdecl, +proc assign_jit_stack*(a2: ptr TExtra, a3: TJitCallback, a4: pointer){.cdecl, importc: "pcre_assign_jit_stack", pcreImport.} var diff --git a/lib/wrappers/zip/libzip.nim b/lib/wrappers/zip/libzip.nim index c3d1784a5..0b8d2b3ec 100644 --- a/lib/wrappers/zip/libzip.nim +++ b/lib/wrappers/zip/libzip.nim @@ -59,28 +59,28 @@ else: {.pragma: mydll.} type - Tzip_source_cmd* = int32 + TZipSourceCmd* = int32 - Tzip_source_callback* = proc (state: pointer, data: pointer, length: int, - cmd: Tzip_source_cmd): int {.cdecl.} - Pzip_stat* = ptr Tzip_stat - Tzip_stat* = object ## the 'zip_stat' struct + TZipSourceCallback* = proc (state: pointer, data: pointer, length: int, + cmd: TZipSourceCmd): int {.cdecl.} + PZipStat* = ptr TZipStat + TZipStat* = object ## the 'zip_stat' struct name*: cstring ## name of the file index*: int32 ## index within archive crc*: int32 ## crc of file data mtime*: TTime ## modification time size*: int ## size of file (uncompressed) - comp_size*: int ## size of file (compressed) - comp_method*: int16 ## compression method used - encryption_method*: int16 ## encryption method used + compSize*: int ## size of file (compressed) + compMethod*: int16 ## compression method used + encryptionMethod*: int16 ## encryption method used - Tzip = object - Tzip_source = object - Tzip_file = object + TZip = object + TZipSource = object + TZipFile = object - Pzip* = ptr Tzip ## represents a zip archive - Pzip_file* = ptr Tzip_file ## represents a file within an archive - Pzip_source* = ptr Tzip_source ## represents a source for an archive + PZip* = ptr TZip ## represents a zip archive + PZipFile* = ptr TZipFile ## represents a file within an archive + PZipSource* = ptr TZipSource ## represents a source for an archive # flags for zip_name_locate, zip_fopen, zip_stat, ... @@ -166,84 +166,84 @@ const ZIP_SOURCE_ERROR* = 4'i32 ## get error information constZIP_SOURCE_FREE* = 5'i32 ## cleanup and free resources -proc zip_add*(para1: Pzip, para2: cstring, para3: Pzip_source): int32 {.cdecl, +proc zip_add*(para1: PZip, para2: cstring, para3: PZipSource): int32 {.cdecl, importc: "zip_add", mydll.} -proc zip_add_dir*(para1: Pzip, para2: cstring): int32 {.cdecl, +proc zip_add_dir*(para1: PZip, para2: cstring): int32 {.cdecl, importc: "zip_add_dir", mydll.} -proc zip_close*(para1: Pzip) {.cdecl, importc: "zip_close", mydll.} -proc zip_delete*(para1: Pzip, para2: int32): int32 {.cdecl, mydll, +proc zip_close*(para1: PZip) {.cdecl, importc: "zip_close", mydll.} +proc zip_delete*(para1: PZip, para2: int32): int32 {.cdecl, mydll, importc: "zip_delete".} -proc zip_error_clear*(para1: Pzip) {.cdecl, importc: "zip_error_clear", mydll.} -proc zip_error_get*(para1: Pzip, para2: ptr int32, para3: ptr int32) {.cdecl, +proc zip_error_clear*(para1: PZip) {.cdecl, importc: "zip_error_clear", mydll.} +proc zip_error_get*(para1: PZip, para2: ptr int32, para3: ptr int32) {.cdecl, importc: "zip_error_get", mydll.} proc zip_error_get_sys_type*(para1: int32): int32 {.cdecl, mydll, importc: "zip_error_get_sys_type".} proc zip_error_to_str*(para1: cstring, para2: int, para3: int32, para4: int32): int32 {.cdecl, mydll, importc: "zip_error_to_str".} -proc zip_fclose*(para1: Pzip_file) {.cdecl, mydll, +proc zip_fclose*(para1: PZipFile) {.cdecl, mydll, importc: "zip_fclose".} -proc zip_file_error_clear*(para1: Pzip_file) {.cdecl, mydll, +proc zip_file_error_clear*(para1: PZipFile) {.cdecl, mydll, importc: "zip_file_error_clear".} -proc zip_file_error_get*(para1: Pzip_file, para2: ptr int32, para3: ptr int32) {. +proc zip_file_error_get*(para1: PZipFile, para2: ptr int32, para3: ptr int32) {. cdecl, mydll, importc: "zip_file_error_get".} -proc zip_file_strerror*(para1: Pzip_file): cstring {.cdecl, mydll, +proc zip_file_strerror*(para1: PZipFile): cstring {.cdecl, mydll, importc: "zip_file_strerror".} -proc zip_fopen*(para1: Pzip, para2: cstring, para3: int32): Pzip_file {.cdecl, +proc zip_fopen*(para1: PZip, para2: cstring, para3: int32): PZipFile {.cdecl, mydll, importc: "zip_fopen".} -proc zip_fopen_index*(para1: Pzip, para2: int32, para3: int32): Pzip_file {. +proc zip_fopen_index*(para1: PZip, para2: int32, para3: int32): PZipFile {. cdecl, mydll, importc: "zip_fopen_index".} -proc zip_fread*(para1: Pzip_file, para2: pointer, para3: int): int {. +proc zip_fread*(para1: PZipFile, para2: pointer, para3: int): int {. cdecl, mydll, importc: "zip_fread".} -proc zip_get_archive_comment*(para1: Pzip, para2: ptr int32, para3: int32): cstring {. +proc zip_get_archive_comment*(para1: PZip, para2: ptr int32, para3: int32): cstring {. cdecl, mydll, importc: "zip_get_archive_comment".} -proc zip_get_archive_flag*(para1: Pzip, para2: int32, para3: int32): int32 {. +proc zip_get_archive_flag*(para1: PZip, para2: int32, para3: int32): int32 {. cdecl, mydll, importc: "zip_get_archive_flag".} -proc zip_get_file_comment*(para1: Pzip, para2: int32, para3: ptr int32, +proc zip_get_file_comment*(para1: PZip, para2: int32, para3: ptr int32, para4: int32): cstring {.cdecl, mydll, importc: "zip_get_file_comment".} -proc zip_get_name*(para1: Pzip, para2: int32, para3: int32): cstring {.cdecl, +proc zip_get_name*(para1: PZip, para2: int32, para3: int32): cstring {.cdecl, mydll, importc: "zip_get_name".} -proc zip_get_num_files*(para1: Pzip): int32 {.cdecl, +proc zip_get_num_files*(para1: PZip): int32 {.cdecl, mydll, importc: "zip_get_num_files".} -proc zip_name_locate*(para1: Pzip, para2: cstring, para3: int32): int32 {.cdecl, +proc zip_name_locate*(para1: PZip, para2: cstring, para3: int32): int32 {.cdecl, mydll, importc: "zip_name_locate".} -proc zip_open*(para1: cstring, para2: int32, para3: ptr int32): Pzip {.cdecl, +proc zip_open*(para1: cstring, para2: int32, para3: ptr int32): PZip {.cdecl, mydll, importc: "zip_open".} -proc zip_rename*(para1: Pzip, para2: int32, para3: cstring): int32 {.cdecl, +proc zip_rename*(para1: PZip, para2: int32, para3: cstring): int32 {.cdecl, mydll, importc: "zip_rename".} -proc zip_replace*(para1: Pzip, para2: int32, para3: Pzip_source): int32 {.cdecl, +proc zip_replace*(para1: PZip, para2: int32, para3: PZipSource): int32 {.cdecl, mydll, importc: "zip_replace".} -proc zip_set_archive_comment*(para1: Pzip, para2: cstring, para3: int32): int32 {. +proc zip_set_archive_comment*(para1: PZip, para2: cstring, para3: int32): int32 {. cdecl, mydll, importc: "zip_set_archive_comment".} -proc zip_set_archive_flag*(para1: Pzip, para2: int32, para3: int32): int32 {. +proc zip_set_archive_flag*(para1: PZip, para2: int32, para3: int32): int32 {. cdecl, mydll, importc: "zip_set_archive_flag".} -proc zip_set_file_comment*(para1: Pzip, para2: int32, para3: cstring, +proc zip_set_file_comment*(para1: PZip, para2: int32, para3: cstring, para4: int32): int32 {.cdecl, mydll, importc: "zip_set_file_comment".} -proc zip_source_buffer*(para1: Pzip, para2: pointer, para3: int, para4: int32): Pzip_source {. +proc zip_source_buffer*(para1: PZip, para2: pointer, para3: int, para4: int32): PZipSource {. cdecl, mydll, importc: "zip_source_buffer".} -proc zip_source_file*(para1: Pzip, para2: cstring, para3: int, para4: int): Pzip_source {. +proc zip_source_file*(para1: PZip, para2: cstring, para3: int, para4: int): PZipSource {. cdecl, mydll, importc: "zip_source_file".} -proc zip_source_filep*(para1: Pzip, para2: TFile, para3: int, para4: int): Pzip_source {. +proc zip_source_filep*(para1: PZip, para2: TFile, para3: int, para4: int): PZipSource {. cdecl, mydll, importc: "zip_source_filep".} -proc zip_source_free*(para1: Pzip_source) {.cdecl, mydll, +proc zip_source_free*(para1: PZipSource) {.cdecl, mydll, importc: "zip_source_free".} -proc zip_source_function*(para1: Pzip, para2: Tzip_source_callback, - para3: pointer): Pzip_source {.cdecl, mydll, +proc zip_source_function*(para1: PZip, para2: TZipSourceCallback, + para3: pointer): PZipSource {.cdecl, mydll, importc: "zip_source_function".} -proc zip_source_zip*(para1: Pzip, para2: Pzip, para3: int32, para4: int32, - para5: int, para6: int): Pzip_source {.cdecl, mydll, +proc zip_source_zip*(para1: PZip, para2: PZip, para3: int32, para4: int32, + para5: int, para6: int): PZipSource {.cdecl, mydll, importc: "zip_source_zip".} -proc zip_stat*(para1: Pzip, para2: cstring, para3: int32, para4: Pzip_stat): int32 {. +proc zip_stat*(para1: PZip, para2: cstring, para3: int32, para4: PZipStat): int32 {. cdecl, mydll, importc: "zip_stat".} -proc zip_stat_index*(para1: Pzip, para2: int32, para3: int32, para4: Pzip_stat): int32 {. +proc zip_stat_index*(para1: PZip, para2: int32, para3: int32, para4: PZipStat): int32 {. cdecl, mydll, importc: "zip_stat_index".} -proc zip_stat_init*(para1: Pzip_stat) {.cdecl, mydll, importc: "zip_stat_init".} -proc zip_strerror*(para1: Pzip): cstring {.cdecl, mydll, importc: "zip_strerror".} -proc zip_unchange*(para1: Pzip, para2: int32): int32 {.cdecl, mydll, +proc zip_stat_init*(para1: PZipStat) {.cdecl, mydll, importc: "zip_stat_init".} +proc zip_strerror*(para1: PZip): cstring {.cdecl, mydll, importc: "zip_strerror".} +proc zip_unchange*(para1: PZip, para2: int32): int32 {.cdecl, mydll, importc: "zip_unchange".} -proc zip_unchange_all*(para1: Pzip): int32 {.cdecl, mydll, +proc zip_unchange_all*(para1: PZip): int32 {.cdecl, mydll, importc: "zip_unchange_all".} -proc zip_unchange_archive*(para1: Pzip): int32 {.cdecl, mydll, +proc zip_unchange_archive*(para1: PZip): int32 {.cdecl, mydll, importc: "zip_unchange_archive".} diff --git a/tests/run/tactiontable.nim b/tests/actiontable/tactiontable.nim index e2f19a099..e2f19a099 100644 --- a/tests/run/tactiontable.nim +++ b/tests/actiontable/tactiontable.nim diff --git a/tests/reject/tactiontable2.nim b/tests/actiontable/tactiontable2.nim index dbfa42f18..00b427603 100644 --- a/tests/reject/tactiontable2.nim +++ b/tests/actiontable/tactiontable2.nim @@ -5,23 +5,23 @@ discard """ import tables -proc action1(arg: string) = +proc action1(arg: string) = echo "action 1 ", arg -proc action2(arg: string) = +proc action2(arg: string) = echo "action 2 ", arg -proc action3(arg: string) = +proc action3(arg: string) = echo "action 3 ", arg -proc action4(arg: string) = +proc action4(arg: string) = echo "action 4 ", arg const actionTable = { - "A": action1, - "B": action2, - "C": action3, + "A": action1, + "B": action2, + "C": action3, "D": action4}.toTable actionTable["C"]("arg") diff --git a/tests/compile/talias.nim b/tests/alias/talias.nim index 819289c2e..819289c2e 100644 --- a/tests/compile/talias.nim +++ b/tests/alias/talias.nim diff --git a/tests/reject/mambsym1.nim b/tests/ambsym/mambsym1.nim index cf8ac5242..cf8ac5242 100644 --- a/tests/reject/mambsym1.nim +++ b/tests/ambsym/mambsym1.nim diff --git a/tests/reject/mambsym2.nim b/tests/ambsym/mambsym2.nim index eac8de6ba..eac8de6ba 100644 --- a/tests/reject/mambsym2.nim +++ b/tests/ambsym/mambsym2.nim diff --git a/tests/run/mambsys1.nim b/tests/ambsym/mambsys1.nim index 5472b5ae4..5472b5ae4 100644 --- a/tests/run/mambsys1.nim +++ b/tests/ambsym/mambsys1.nim diff --git a/tests/run/mambsys2.nim b/tests/ambsym/mambsys2.nim index 395425b86..395425b86 100644 --- a/tests/run/mambsys2.nim +++ b/tests/ambsym/mambsys2.nim diff --git a/tests/reject/tambsym.nim b/tests/ambsym/tambsym.nim index 902274648..902274648 100644 --- a/tests/reject/tambsym.nim +++ b/tests/ambsym/tambsym.nim diff --git a/tests/run/tambsym2.nim b/tests/ambsym/tambsym2.nim index 745427c54..745427c54 100644 --- a/tests/run/tambsym2.nim +++ b/tests/ambsym/tambsym2.nim diff --git a/tests/reject/tambsym3.nim b/tests/ambsym/tambsym3.nim index 0155f258c..0155f258c 100644 --- a/tests/reject/tambsym3.nim +++ b/tests/ambsym/tambsym3.nim diff --git a/tests/run/tambsys.nim b/tests/ambsym/tambsys.nim index 67522d7c9..67522d7c9 100644 --- a/tests/run/tambsys.nim +++ b/tests/ambsym/tambsys.nim diff --git a/tests/run/tarray.nim b/tests/array/tarray.nim index 16ef558d1..16ef558d1 100644 --- a/tests/run/tarray.nim +++ b/tests/array/tarray.nim diff --git a/tests/run/tarray2.nim b/tests/array/tarray2.nim index b6adabb45..b6adabb45 100644 --- a/tests/run/tarray2.nim +++ b/tests/array/tarray2.nim diff --git a/tests/run/tarray3.nim b/tests/array/tarray3.nim index d28778357..d28778357 100644 --- a/tests/run/tarray3.nim +++ b/tests/array/tarray3.nim diff --git a/tests/reject/tarraycons.nim b/tests/array/tarraycons.nim index 7de518b6e..7de518b6e 100644 --- a/tests/reject/tarraycons.nim +++ b/tests/array/tarraycons.nim diff --git a/tests/run/tarraycons.nim b/tests/array/tarraycons2.nim index 0b2a42c2f..0b2a42c2f 100644 --- a/tests/run/tarraycons.nim +++ b/tests/array/tarraycons2.nim diff --git a/tests/reject/tarrayplus.nim b/tests/array/tarrayplus.nim index 8c7452e85..8c7452e85 100644 --- a/tests/reject/tarrayplus.nim +++ b/tests/array/tarrayplus.nim diff --git a/tests/compile/tarrindx.nim b/tests/array/tarrindx.nim index 13919cc2c..13919cc2c 100644 --- a/tests/compile/tarrindx.nim +++ b/tests/array/tarrindx.nim diff --git a/tests/run/tassert.nim b/tests/assert/tassert.nim index 0ea8d2034..0ea8d2034 100644 --- a/tests/run/tassert.nim +++ b/tests/assert/tassert.nim diff --git a/tests/assert/tfailedassert.nim b/tests/assert/tfailedassert.nim new file mode 100644 index 000000000..d99e6dc60 --- /dev/null +++ b/tests/assert/tfailedassert.nim @@ -0,0 +1,51 @@ +discard """ + output: ''' +WARNING: false first asseertion from bar +ERROR: false second assertion from bar +-1 +tests/run/tfailedassert.nim:27 false assertion from foo +''' +""" + +type + TLineInfo = tuple[filename: string, line: int] + + TMyError = object of E_Base + lineinfo: TLineInfo + + EMyError = ref TMyError + +# module-wide policy to change the failed assert +# exception type in order to include a lineinfo +onFailedAssert(msg): + var e = new(TMyError) + e.msg = msg + e.lineinfo = instantiationInfo(-2) + raise e + +proc foo = + assert(false, "assertion from foo") + +proc bar: int = + # local overrides that are active only + # in this proc + onFailedAssert(msg): echo "WARNING: " & msg + + assert(false, "first asseertion from bar") + + onFailedAssert(msg): + echo "ERROR: " & msg + return -1 + + assert(false, "second assertion from bar") + return 10 + +echo("") +echo(bar()) + +try: + foo() +except: + let e = EMyError(getCurrentException()) + echo e.lineinfo.filename, ":", e.lineinfo.line, " ", e.msg + diff --git a/tests/assert/tunittests.nim b/tests/assert/tunittests.nim new file mode 100644 index 000000000..cbbfe63c6 --- /dev/null +++ b/tests/assert/tunittests.nim @@ -0,0 +1 @@ +import "../template/utemplates", "../closure/uclosures" diff --git a/tests/run/tuserassert.nim b/tests/assert/tuserassert.nim index 8710ee486..8710ee486 100644 --- a/tests/run/tuserassert.nim +++ b/tests/assert/tuserassert.nim diff --git a/tests/compile/tassign.nim b/tests/assign/tassign.nim index f51c20783..f51c20783 100644 --- a/tests/compile/tassign.nim +++ b/tests/assign/tassign.nim diff --git a/tests/run/tcopy.nim b/tests/assign/tcopy.nim index 5feb0d6b3..5feb0d6b3 100644 --- a/tests/run/tcopy.nim +++ b/tests/assign/tcopy.nim diff --git a/tests/run/tgenericassign.nim b/tests/assign/tgenericassign.nim index 654b0ab8f..654b0ab8f 100644 --- a/tests/run/tgenericassign.nim +++ b/tests/assign/tgenericassign.nim diff --git a/tests/run/tgenericassigntuples.nim b/tests/assign/tgenericassigntuples.nim index 6dd63a984..6dd63a984 100644 --- a/tests/run/tgenericassigntuples.nim +++ b/tests/assign/tgenericassigntuples.nim diff --git a/tests/run/tobjasgn.nim b/tests/assign/tobjasgn.nim index 5f411063f..5f411063f 100644 --- a/tests/run/tobjasgn.nim +++ b/tests/assign/tobjasgn.nim diff --git a/tests/run/tvariantasgn.nim b/tests/assign/tvariantasgn.nim index 46cc23dd1..46cc23dd1 100644 --- a/tests/run/tvariantasgn.nim +++ b/tests/assign/tvariantasgn.nim diff --git a/tests/run/tastoverload1.nim b/tests/astoverload/tastoverload1.nim index c8705547a..c8705547a 100644 --- a/tests/run/tastoverload1.nim +++ b/tests/astoverload/tastoverload1.nim diff --git a/tests/run/tasynciossl.nim b/tests/async/tasynciossl.nim index fbed46efb..fbed46efb 100644 --- a/tests/run/tasynciossl.nim +++ b/tests/async/tasynciossl.nim diff --git a/tests/run/tasyncudp.nim b/tests/async/tasyncudp.nim index fd7f3d568..fd7f3d568 100644 --- a/tests/run/tasyncudp.nim +++ b/tests/async/tasyncudp.nim diff --git a/tests/run/mbind3.nim b/tests/bind/mbind3.nim index d02bc79d0..d02bc79d0 100644 --- a/tests/run/mbind3.nim +++ b/tests/bind/mbind3.nim diff --git a/tests/run/tbind1.nim b/tests/bind/tbind1.nim index 6593b2307..6593b2307 100644 --- a/tests/run/tbind1.nim +++ b/tests/bind/tbind1.nim diff --git a/tests/reject/tbind2.nim b/tests/bind/tbind2.nim index 72a9844bb..e8e21ad02 100644 --- a/tests/reject/tbind2.nim +++ b/tests/bind/tbind2.nim @@ -1,6 +1,6 @@ discard """ file: "tbind2.nim" - line: 12 + line: 14 errormsg: "ambiguous call" """ # Test the new ``bind`` keyword for templates diff --git a/tests/run/tbind3.nim b/tests/bind/tbind3.nim index 551acc10f..551acc10f 100644 --- a/tests/run/tbind3.nim +++ b/tests/bind/tbind3.nim diff --git a/tests/compile/tbindoverload.nim b/tests/bind/tbindoverload.nim index 6f5bb339e..6f5bb339e 100644 --- a/tests/compile/tbindoverload.nim +++ b/tests/bind/tbindoverload.nim diff --git a/tests/reject/tbindtypedesc.nim b/tests/bind/tbindtypedesc.nim index d6fbae537..d6fbae537 100644 --- a/tests/reject/tbindtypedesc.nim +++ b/tests/bind/tbindtypedesc.nim diff --git a/tests/compile/tdatabind.nim b/tests/bind/tdatabind.nim index afa8aa47b..afa8aa47b 100644 --- a/tests/compile/tdatabind.nim +++ b/tests/bind/tdatabind.nim diff --git a/tests/run/tmixin.nim b/tests/bind/tmixin.nim index d841326a5..d841326a5 100644 --- a/tests/run/tmixin.nim +++ b/tests/bind/tmixin.nim diff --git a/tests/reject/tnicerrorforsymchoice.nim b/tests/bind/tnicerrorforsymchoice.nim index bc271dcab..bc271dcab 100644 --- a/tests/reject/tnicerrorforsymchoice.nim +++ b/tests/bind/tnicerrorforsymchoice.nim diff --git a/tests/reject/tblock1.nim b/tests/block/tblock1.nim index 5c41aaf82..5c41aaf82 100644 --- a/tests/reject/tblock1.nim +++ b/tests/block/tblock1.nim diff --git a/tests/run/tborrow.nim b/tests/borrow/tborrow.nim index 8e6aeba74..8e6aeba74 100644 --- a/tests/run/tborrow.nim +++ b/tests/borrow/tborrow.nim diff --git a/tests/reject/tinvalidborrow.nim b/tests/borrow/tinvalidborrow.nim index 9ab9e8d64..9ab9e8d64 100644 --- a/tests/reject/tinvalidborrow.nim +++ b/tests/borrow/tinvalidborrow.nim diff --git a/tests/run/tcase_setconstr.nim b/tests/casestmt/tcase_setconstr.nim index 21f657c2b..21f657c2b 100644 --- a/tests/run/tcase_setconstr.nim +++ b/tests/casestmt/tcase_setconstr.nim diff --git a/tests/reject/tcaseexpr1.nim b/tests/casestmt/tcaseexpr1.nim index e5e08e25e..e5e08e25e 100644 --- a/tests/reject/tcaseexpr1.nim +++ b/tests/casestmt/tcaseexpr1.nim diff --git a/tests/reject/tcaseoverlaprange.nim b/tests/casestmt/tcaseoverlaprange.nim index 5f24c3ca9..5f24c3ca9 100644 --- a/tests/reject/tcaseoverlaprange.nim +++ b/tests/casestmt/tcaseoverlaprange.nim diff --git a/tests/reject/tcaseoverlaprange2.nim b/tests/casestmt/tcaseoverlaprange2.nim index d6e301508..d6e301508 100644 --- a/tests/reject/tcaseoverlaprange2.nim +++ b/tests/casestmt/tcaseoverlaprange2.nim diff --git a/tests/run/tcasestm.nim b/tests/casestmt/tcasestm.nim index 003ec6e50..003ec6e50 100644 --- a/tests/run/tcasestm.nim +++ b/tests/casestmt/tcasestm.nim diff --git a/tests/compile/tcomputedgoto.nim b/tests/casestmt/tcomputedgoto.nim index 2c3b4bbd4..b21fc07a3 100644 --- a/tests/compile/tcomputedgoto.nim +++ b/tests/casestmt/tcomputedgoto.nim @@ -1,16 +1,16 @@ discard """ - output: '''yeah A -yeah A -yeah CD -yeah CD -yeah A -yeah CD -yeah CD -yeah A -yeah B -yeah A -yeah A -yeah A''' + output: '''yeah A enumB +yeah A enumB +yeah CD enumD +yeah CD enumE +yeah A enumB +yeah CD enumE +yeah CD enumD +yeah A enumB +yeah B enumC +yeah A enumB +yeah A enumB +yeah A enumB''' """ type @@ -32,13 +32,14 @@ proc vm() = while true: {.computedGoto.} let instr = instructions[pc] + let ra = instr.succ # instr.regA case instr of enumA: - echo "yeah A" + echo "yeah A ", ra of enumC, enumD: - echo "yeah CD" + echo "yeah CD ", ra of enumB: - echo "yeah B" + echo "yeah B ", ra of enumE: break inc(pc) diff --git a/tests/compile/tlinearscanend.nim b/tests/casestmt/tlinearscanend.nim index 15fd0c70a..15fd0c70a 100644 --- a/tests/compile/tlinearscanend.nim +++ b/tests/casestmt/tlinearscanend.nim diff --git a/tests/compile/tccgen1.nim b/tests/ccgbugs/tccgen1.nim index 137dd545d..137dd545d 100644 --- a/tests/compile/tccgen1.nim +++ b/tests/ccgbugs/tccgen1.nim diff --git a/tests/run/tcgbug.nim b/tests/ccgbugs/tcgbug.nim index 417b909ae..417b909ae 100644 --- a/tests/run/tcgbug.nim +++ b/tests/ccgbugs/tcgbug.nim diff --git a/tests/compile/tcodegenbug1.nim b/tests/ccgbugs/tcodegenbug1.nim index 7d0fc4ad5..7d0fc4ad5 100644 --- a/tests/compile/tcodegenbug1.nim +++ b/tests/ccgbugs/tcodegenbug1.nim diff --git a/tests/run/tclosure.nim b/tests/closure/tclosure.nim index d9e7b8ee4..d9e7b8ee4 100644 --- a/tests/run/tclosure.nim +++ b/tests/closure/tclosure.nim diff --git a/tests/run/tclosure2.nim b/tests/closure/tclosure2.nim index d2c16eac9..d2c16eac9 100644 --- a/tests/run/tclosure2.nim +++ b/tests/closure/tclosure2.nim diff --git a/tests/run/tclosure3.nim b/tests/closure/tclosure3.nim index bb217387f..bb217387f 100644 --- a/tests/run/tclosure3.nim +++ b/tests/closure/tclosure3.nim diff --git a/tests/compile/tclosure4.nim b/tests/closure/tclosure4.nim index 8e08376b6..8e08376b6 100644 --- a/tests/compile/tclosure4.nim +++ b/tests/closure/tclosure4.nim diff --git a/tests/compile/tclosurebug2.nim b/tests/closure/tclosurebug2.nim index ec4f0045b..ec4f0045b 100644 --- a/tests/compile/tclosurebug2.nim +++ b/tests/closure/tclosurebug2.nim diff --git a/tests/run/tinterf.nim b/tests/closure/tinterf.nim index 726fac9f6..726fac9f6 100644 --- a/tests/run/tinterf.nim +++ b/tests/closure/tinterf.nim diff --git a/tests/reject/tinvalidclosure.nim b/tests/closure/tinvalidclosure.nim index c06270bfa..c06270bfa 100644 --- a/tests/reject/tinvalidclosure.nim +++ b/tests/closure/tinvalidclosure.nim diff --git a/tests/reject/tinvalidclosure2.nim b/tests/closure/tinvalidclosure2.nim index 20e465c12..20e465c12 100644 --- a/tests/reject/tinvalidclosure2.nim +++ b/tests/closure/tinvalidclosure2.nim diff --git a/tests/compile/tnamedparamanonproc.nim b/tests/closure/tnamedparamanonproc.nim index 272b84e91..272b84e91 100644 --- a/tests/compile/tnamedparamanonproc.nim +++ b/tests/closure/tnamedparamanonproc.nim diff --git a/tests/compile/tnestedproc.nim b/tests/closure/tnestedproc.nim index 49ec6f9a7..49ec6f9a7 100644 --- a/tests/compile/tnestedproc.nim +++ b/tests/closure/tnestedproc.nim diff --git a/tests/run/uclosures.nim b/tests/closure/uclosures.nim index 6eea29ca1..6eea29ca1 100644 --- a/tests/run/uclosures.nim +++ b/tests/closure/uclosures.nim diff --git a/tests/run/tcnstseq.nim b/tests/cnstseq/tcnstseq.nim index e7d2333b4..e7d2333b4 100644 --- a/tests/run/tcnstseq.nim +++ b/tests/cnstseq/tcnstseq.nim diff --git a/tests/run/tcnstseq2.nim b/tests/cnstseq/tcnstseq2.nim index 1a27b2ba7..1a27b2ba7 100644 --- a/tests/run/tcnstseq2.nim +++ b/tests/cnstseq/tcnstseq2.nim diff --git a/tests/run/tcnstseq3.nim b/tests/cnstseq/tcnstseq3.nim index e59516e85..e59516e85 100644 --- a/tests/run/tcnstseq3.nim +++ b/tests/cnstseq/tcnstseq3.nim diff --git a/tests/compile/mvarious.nim b/tests/compile/mvarious.nim deleted file mode 100644 index 333b34d33..000000000 --- a/tests/compile/mvarious.nim +++ /dev/null @@ -1,6 +0,0 @@ -# Test a submodule - -#type -# TStringArr = array [0.. *] of string - -proc exportme* = nil diff --git a/tests/compile/sunset.tmpl b/tests/compile/sunset.tmpl deleted file mode 100644 index 6475bac4e..000000000 --- a/tests/compile/sunset.tmpl +++ /dev/null @@ -1,68 +0,0 @@ -#! stdtmpl -#proc sunsetTemplate*(current, ticker, content: string, -# tabs: openarray[array[0..1, string]]): string = -# result = "" -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> - -<head> - <title>Nimrod Programming System</title> - <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" /> - <link rel="stylesheet" type="text/css" href="style/style.css" /> -</head> - -<body> - <div id="main"> - <div id="links"> - <!-- **** INSERT LINKS HERE **** --> - </div> - <div id="logo"><h1>Nimrod Programming System</h1></div> - <div id="content"> - <div id="menu"> - <ul> - #for item in items(tabs): - #var name = item[0] - #var t = item[1] - #if t == current: - <li><a id="selected" href="${t}.html" title = "Nimrod - $name">$name</a></li> - #else: - <li><a href="${t}.html" title = "Nimrod - $name">$name</a></li> - #end if - #end for - </ul> - </div> - <div id="column1"> - <div class="sidebaritem"> - <div class="sbihead"> - <h1>latest news</h1> - </div> - <div class="sbicontent"> - $ticker - </div> - </div> - <div class="sidebaritem"> - <div class="sbihead"> - <h1>additional links</h1> - </div> - <div class="sbilinks"> - <!-- **** INSERT ADDITIONAL LINKS HERE **** --> - <ul> - <li><a class="reference" href="http://llvm.org">LLVM</a></li> - <li><a class="reference" href="http://gcc.gnu.org">GCC</a></li> - </ul> - </div> - </div> - </div> - <div id="column2"> - $content - </div> - </div> - <div id="footer"> - copyright © 2008 Andreas Rumpf | Last update: ${getDateStr()} - | <a class="reference" href="http://validator.w3.org/check?uri=referer">XHTML 1.1</a> - | <a class="reference" href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a> - | <a class="reference" href="http://www.dcarter.co.uk">design by dcarter</a> - </div> - </div> -</body> -</html> diff --git a/tests/compile/tambsym2.nim b/tests/compile/tambsym2.nim deleted file mode 100644 index 7758cc31a..000000000 --- a/tests/compile/tambsym2.nim +++ /dev/null @@ -1,6 +0,0 @@ - -from sdl import PSurface - -discard SDL.CreateRGBSurface(SDL.SWSURFACE, 23, 34, - 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xff000000'i32) - diff --git a/tests/compile/tbindtypedesc.nim b/tests/compile/tbindtypedesc.nim deleted file mode 100644 index dd4ef854c..000000000 --- a/tests/compile/tbindtypedesc.nim +++ /dev/null @@ -1,87 +0,0 @@ -discard """ - msg: ''' -int -float -TFoo -TFoo -''' -""" - -import typetraits - -type - TFoo = object - x, y: int - - TBar = tuple - x, y: int - -template good(e: expr) = - static: assert(compiles(e)) - -template bad(e: expr) = - static: assert(not compiles(e)) - -proc genericParamRepeated[T: typedesc](a: T, b: T) = - static: - echo a.name - echo b.name - -good(genericParamRepeated(int, int)) -good(genericParamRepeated(float, float)) - -bad(genericParamRepeated(string, int)) -bad(genericParamRepeated(int, float)) - -proc genericParamOnce[T: typedesc](a, b: T) = - static: - echo a.name - echo b.name - -good(genericParamOnce(int, int)) -good(genericParamOnce(TFoo, TFoo)) - -bad(genericParamOnce(string, int)) -bad(genericParamOnce(TFoo, float)) - -proc typePairs(A, B: type1; C, D: type2) = nil - -good(typePairs(int, int, TFoo, TFOO)) -good(typePairs(TBAR, TBar, TBAR, TBAR)) -good(typePairs(int, int, string, string)) - -bad(typePairs(TBAR, TBar, TBar, TFoo)) -bad(typePairs(string, int, TBAR, TBAR)) - -proc typePairs2[T: typedesc, U: typedesc](A, B: T; C, D: U) = nil - -good(typePairs2(int, int, TFoo, TFOO)) -good(typePairs2(TBAR, TBar, TBAR, TBAR)) -good(typePairs2(int, int, string, string)) - -bad(typePairs2(TBAR, TBar, TBar, TFoo)) -bad(typePairs2(string, int, TBAR, TBAR)) - -proc dontBind(a: typedesc, b: typedesc) = - static: - echo a.name - echo b.name - -good(dontBind(int, float)) -good(dontBind(TFoo, TFoo)) - -proc dontBind2(a, b: typedesc) = nil - -good(dontBind2(int, float)) -good(dontBind2(TBar, int)) - -proc bindArg(T: typedesc, U: typedesc, a, b: T, c, d: U) = nil - -good(bindArg(int, string, 10, 20, "test", "nest")) -good(bindArg(int, int, 10, 20, 30, 40)) - -bad(bindArg(int, string, 10, "test", "test", "nest")) -bad(bindArg(int, int, 10, 20, 30, "test")) -bad(bindArg(int, string, 10.0, 20, "test", "nest")) -bad(bindArg(int, string, "test", "nest", 10, 20)) - diff --git a/tests/compile/tcmdline.nim b/tests/compile/tcmdline.nim deleted file mode 100644 index f4ee20d31..000000000 --- a/tests/compile/tcmdline.nim +++ /dev/null @@ -1,14 +0,0 @@ -# Test the command line - -import - os, strutils - -var - i: int - params = paramCount() -i = 0 -writeln(stdout, "This exe: " & getAppFilename()) -writeln(stdout, "Number of parameters: " & $params) -while i <= params: - writeln(stdout, paramStr(i)) - i = i + 1 diff --git a/tests/compile/tcolonisproc.nim b/tests/compile/tcolonisproc.nim deleted file mode 100644 index e55587dfc..000000000 --- a/tests/compile/tcolonisproc.nim +++ /dev/null @@ -1,12 +0,0 @@ - -proc p(a, b: int, c: proc ()) = - c() - - -p(1, 3): - echo 1 - echo 3 - -p(1, 1, proc() = - echo 1 - echo 2) diff --git a/tests/compile/tdllvar.nim b/tests/compile/tdllvar.nim deleted file mode 100644 index ab767770c..000000000 --- a/tests/compile/tdllvar.nim +++ /dev/null @@ -1,16 +0,0 @@ -import os - -proc getDllName: string = - result = "mylib.dll" - if ExistsFile(result): return - result = "mylib2.dll" - if ExistsFile(result): return - quit("could not load dynamic library") - -proc myImport(s: cstring) {.cdecl, importc, dynlib: getDllName().} -proc myImport2(s: int) {.cdecl, importc, dynlib: getDllName().} - -myImport("test2") -myImport2(12) - - diff --git a/tests/compile/temptyecho.nim b/tests/compile/temptyecho.nim deleted file mode 100644 index 5f1aa6515..000000000 --- a/tests/compile/temptyecho.nim +++ /dev/null @@ -1,2 +0,0 @@ -echo() - diff --git a/tests/compile/tendian.nim b/tests/compile/tendian.nim deleted file mode 100644 index 256e2653c..000000000 --- a/tests/compile/tendian.nim +++ /dev/null @@ -1,3 +0,0 @@ -# test the new endian magic - -writeln(stdout, repr(system.cpuEndian)) diff --git a/tests/compile/tfib.nim b/tests/compile/tfib.nim deleted file mode 100644 index 09a4d5038..000000000 --- a/tests/compile/tfib.nim +++ /dev/null @@ -1,11 +0,0 @@ - -iterator fibonacci(): int = - var a = 0 - var b = 1 - while true: - yield a - var c = b - b = a - a = a + c - - diff --git a/tests/compile/tgenericshardcases.nim b/tests/compile/tgenericshardcases.nim deleted file mode 100644 index 90981c701..000000000 --- a/tests/compile/tgenericshardcases.nim +++ /dev/null @@ -1,30 +0,0 @@ -discard """ - file: "tgenericshardcases.nim" - output: "int\nfloat\nint\nstring" -""" - -import typetraits - -proc typeNameLen(x: typedesc): int {.compileTime.} = - result = x.name.len - -macro selectType(a, b: typedesc): typedesc = - result = a - -type - Foo[T] = object - data1: array[high(T), int] - data2: array[1..typeNameLen(T), selectType(float, string)] - - MyEnum = enum A, B, C,D - -var f1: Foo[MyEnum] -var f2: Foo[int8] - -static: - assert high(f1.data1) == D - assert high(f1.data2) == 6 # length of MyEnum - - assert high(f2.data1) == 127 - assert high(f2.data2) == 4 # length of int8 - diff --git a/tests/compile/tgetstartmilsecs.nim b/tests/compile/tgetstartmilsecs.nim deleted file mode 100644 index 5a3368e0f..000000000 --- a/tests/compile/tgetstartmilsecs.nim +++ /dev/null @@ -1,7 +0,0 @@ -# -import times, os - -var start = epochTime() -os.sleep(1000) - -echo epochTime() - start #OUT 1000 diff --git a/tests/compile/tgtk.nim b/tests/compile/tgtk.nim deleted file mode 100644 index 7febb0ab8..000000000 --- a/tests/compile/tgtk.nim +++ /dev/null @@ -1,51 +0,0 @@ - -import - gtk2, glib2, atk, gdk2, gdk2pixbuf, libglade2, pango, - pangoutils - -proc hello(widget: PWidget, data: pointer) {.cdecl.} = - write(stdout, "Hello World\n") - -proc delete_event(widget: PWidget, event: PEvent, - data: pointer): bool {.cdecl.} = - # If you return FALSE in the "delete_event" signal handler, - # GTK will emit the "destroy" signal. Returning TRUE means - # you don't want the window to be destroyed. - # This is useful for popping up 'are you sure you want to quit?' - # type dialogs. - write(stdout, "delete event occurred\n") - # Change TRUE to FALSE and the main window will be destroyed with - # a "delete_event". - return false - -# Another callback -proc mydestroy(widget: PWidget, data: pointer) {.cdecl.} = - gtk2.main_quit() - -proc mymain() = - # GtkWidget is the storage type for widgets - gtk2.nimrod_init() - var window = window_new(gtk2.WINDOW_TOPLEVEL) - discard g_signal_connect(window, "delete_event", - Gcallback(delete_event), nil) - discard g_signal_connect(window, "destroy", Gcallback(mydestroy), nil) - # Sets the border width of the window. - set_border_width(window, 10) - - # Creates a new button with the label "Hello World". - var button = button_new("Hello World") - - discard g_signal_connect(button, "clicked", Gcallback(hello), nil) - - # This packs the button into the window (a gtk container). - add(window, button) - - # The final step is to display this newly created widget. - show(button) - - # and the window - show(window) - - gtk2.main() - -mymain() diff --git a/tests/compile/thallo.nim b/tests/compile/thallo.nim deleted file mode 100644 index 7244c27a1..000000000 --- a/tests/compile/thallo.nim +++ /dev/null @@ -1,85 +0,0 @@ -# Hallo - -import - os, strutils, macros - -type - TMyEnum = enum - meA, meB, meC, meD - -when isMainModule: - {.hint: "this is the main file".} - -proc fac[T](x: T): T = - # test recursive generic procs - if x <= 1: return 1 - else: return x.`*`(fac(x-1)) - -macro macrotest(n: expr): stmt {.immediate.} = - let n = callsite() - expectKind(n, nnkCall) - expectMinLen(n, 2) - result = newNimNode(nnkStmtList, n) - for i in 2..n.len-1: - result.add(newCall("write", n[1], n[i])) - result.add(newCall("writeln", n[1], newStrLitNode(""))) - -macro debug(n: expr): stmt {.immediate.} = - let n = callsite() - result = newNimNode(nnkStmtList, n) - for i in 1..n.len-1: - result.add(newCall("write", newIdentNode("stdout"), toStrLit(n[i]))) - result.add(newCall("write", newIdentNode("stdout"), newStrLitNode(": "))) - result.add(newCall("writeln", newIdentNode("stdout"), n[i])) - -macrotest(stdout, "finally", 4, 5, "variable", "argument lists") -macrotest(stdout) - -#GC_disable() - -echo("This was compiled by Nimrod version " & system.nimrodVersion) -writeln(stdout, "Hello", " World", "!") - -echo(["a", "b", "c", "d"].len) -for x in items(["What's", "your", "name", "?", ]): - echo(x) -var `name` = readLine(stdin) -{.breakpoint.} -echo("Hi " & thallo.name & "!\n") -debug(name) - -var testseq: seq[string] = @[ - "a", "b", "c", "d", "e" -] -echo(repr(testseq)) - -var dummy = "hello" -echo(substr(dummy, 2, 3)) - -echo($meC) - -# test tuples: -for x, y in items([(1, 2), (3, 4), (6, 1), (5, 2)]): - echo x - echo y - -proc simpleConst(): int = return 34 - -# test constant evaluation: -const - constEval3 = simpleConst() - constEval = "abc".contains('b') - constEval2 = fac(7) - -echo(constEval3) -echo(constEval) -echo(constEval2) -echo(1.`+`(2)) - -for i in 2..6: - for j in countdown(i+4, 2): - echo(fac(i * j)) - -when isMainModule: - {.hint: "this is the main file".} - diff --git a/tests/compile/theaproots.nim b/tests/compile/theaproots.nim deleted file mode 100644 index aec140f42..000000000 --- a/tests/compile/theaproots.nim +++ /dev/null @@ -1,71 +0,0 @@ -type - Bar = object - x: int - - Foo = object - rheap: ref Bar - rmaybe: ref Bar - rstack: ref Bar - list: seq[ref Bar] - listarr: array[0..5, ref Bar] - nestedtup: Tup - inner: TInner - inref: ref TInner - - TInner = object - inref: ref Bar - - Tup = tuple - tupbar: ref Bar - inner: TInner - -proc acc(x: var Foo): var ref Bar = - result = x.rheap - -proc test(maybeFoo: var Foo, - maybeSeq: var seq[ref Bar], - bars: var openarray[ref Bar], - maybeTup: var Tup) = - var bb: ref Bar - maybeFoo.rmaybe = bb - maybeFoo.list[3] = bb - maybeFoo.listarr[3] = bb - acc(maybeFoo) = bb - - var localFoo: Foo - localFoo.rstack = bb - localFoo.list[3] = bb - localFoo.listarr[3] = bb - acc(localFoo) = bb - - var heapFoo: ref Foo - heapFoo.rheap = bb - heapFoo.list[3] = bb - heapFoo.listarr[3] = bb - acc(heapFoo[]) = bb - - heapFoo.nestedtup.tupbar = bb - heapFoo.nestedtup.inner.inref = bb - heapFoo.inner.inref = bb - heapFoo.inref.inref = bb - - var locseq: seq[ref Bar] - locseq[3] = bb - - var locarr: array[0..4, ref Bar] - locarr[3] = bb - - maybeSeq[3] = bb - - bars[3] = bb - - maybeTup[0] = bb - -var - ff: ref Foo - tt: Tup - gseq: seq[ref Bar] - -new(ff) - -test(ff[], gseq, gseq, tt) diff --git a/tests/compile/tlastmod.nim b/tests/compile/tlastmod.nim deleted file mode 100644 index 75b047fc8..000000000 --- a/tests/compile/tlastmod.nim +++ /dev/null @@ -1,18 +0,0 @@ -# test the new LastModificationTime() proc - -import - os, times, strutils - -proc main() = - var - a, b: TTime - a = getLastModificationTime(ParamStr(1)) - b = getLastModificationTime(ParamStr(2)) - writeln(stdout, $a) - writeln(stdout, $b) - if a < b: - Write(stdout, "$2 is newer than $1\n" % [ParamStr(1), ParamStr(2)]) - else: - Write(stdout, "$1 is newer than $2\n" % [ParamStr(1), ParamStr(2)]) - -main() diff --git a/tests/compile/tlibs.nim b/tests/compile/tlibs.nim deleted file mode 100644 index 971b2b836..000000000 --- a/tests/compile/tlibs.nim +++ /dev/null @@ -1,24 +0,0 @@ -# Test wether the bindings at least compile... - -import - unicode, cgi, terminal, libcurl, - parsexml, parseopt, parsecfg, - osproc, complex, - sdl, smpeg, sdl_gfx, sdl_net, sdl_mixer, sdl_ttf, - sdl_image, sdl_mixer_nosmpeg, - cursorfont, xatom, xf86vmode, xkb, xrandr, xshm, xvlib, keysym, xcms, xi, - xkblib, xrender, xutil, x, xf86dga, xinerama, xlib, xresource, xv, - gtk2, glib2, pango, gdk2, - cairowin32, cairoxlib, - odbcsql, - gl, glut, glu, glx, glext, wingl, - lua, lualib, lauxlib, mysql, sqlite3, python, tcl, - db_postgres, db_mysql, db_sqlite, ropes, sockets, browsers, httpserver, - httpclient, parseutils, unidecode, xmldom, xmldomparser, xmltree, xmlparser, - htmlparser, re, graphics, colors, pegs, subexes, dialogs - -when defined(linux): - import - zlib, zipfiles - -writeln(stdout, "test compilation of binding modules") diff --git a/tests/compile/tloops.nim b/tests/compile/tloops.nim deleted file mode 100644 index 2b1765b00..000000000 --- a/tests/compile/tloops.nim +++ /dev/null @@ -1,87 +0,0 @@ -# Test nested loops and some other things - -proc andTest() = - var a = 0 == 5 and 6 == 6 - -proc incx(x: var int) = # is built-in proc - x = x + 1 - -proc decx(x: var int) = - x = x - 1 - -proc First(y: var int) = - var x: int - i_ncx(x) - if x == 10: - y = 0 - else: - if x == 0: - incx(x) - else: - x=11 - -proc TestLoops() = - var i, j: int - while i >= 0: - if i mod 3 == 0: - break - i = i + 1 - while j == 13: - j = 13 - break - break - - while True: - break - - -proc Foo(n: int): int = - var - a, old: int - b, c: bool - F_irst(a) - if a == 10: - a = 30 - elif a == 11: - a = 22 - elif a == 12: - a = 23 - elif b: - old = 12 - else: - a = 40 - - # - b = false or 2 == 0 and 3 == 9 - a = 0 + 3 * 5 + 6 + 7 + +8 # 36 - while b: - a = a + 3 - a = a + 5 - write(stdout, "Hello!") - - -# We should come till here :-) -discard Foo(345) - -# test the new type symbol lookup feature: - -type - MyType[T] = tuple[ - x, y, z: T] - MyType2 = tuple[x, y: float] - -proc main[T]() = - var myType: MyType[T] - var b: MyType[T] - b = (1, 2, 3) - myType = b - echo myType - - var myType2: MyType2 - var c: MyType2 - c = (1.0, 2.0) - myType2 = c - echo myType2 - -main[int]() - diff --git a/tests/compile/tmandelbrot.nim b/tests/compile/tmandelbrot.nim deleted file mode 100644 index 1e39c8756..000000000 --- a/tests/compile/tmandelbrot.nim +++ /dev/null @@ -1,57 +0,0 @@ -discard """ - cmd: "nimrod cc --hints:on -d:release $# $#" -""" - -# -*- nimrod -*- - -import math -import os -import strutils - -type TComplex = tuple[re, im: float] - -proc `+` (a, b: TComplex): TComplex = - return (a.re + b.re, a.im + b.im) - -proc `*` (a, b: TComplex): TComplex = - result.re = a.re * b.re - a.im * b.im - result.im = a.re * b.im + a.im * b.re - -proc abs2 (a: TComplex): float = - return a.re * a.re + a.im * a.im - -var size = parseInt (paramStr (1)) -var bit = 128 -var byteAcc = 0 - -stdout.writeln ("P4") -stdout.write ($size) -stdout.write (" ") -stdout.writeln ($size) - -var fsize = float (size) -for y in 0 .. size-1: - var fy = 2.0 * float (y) / fsize - 1.0 - for x in 0 .. size-1: - var z = (0.0, 0.0) - var c = (float (2*x) / fsize - 1.5, fy) - - block iter: - for i in 0 .. 49: - z = z*z + c - if abs2 (z) >= 4.0: - break iter - byteAcc = byteAcc + bit - - if bit > 1: - bit = bit div 2 - else: - stdout.write (chr (byteAcc)) - bit = 128 - byteAcc = 0 - - if bit != 128: - stdout.write (chr (byteAcc)) - bit = 128 - byteAcc = 0 - diff --git a/tests/compile/tnew.nim b/tests/compile/tnew.nim deleted file mode 100644 index 6527541a2..000000000 --- a/tests/compile/tnew.nim +++ /dev/null @@ -1,49 +0,0 @@ -# Test the implementation of the new operator -# and the code generation for gc walkers -# (and the garbage collector): - -type - PNode = ref TNode - TNode = object - data: int - str: string - le, ri: PNode - - TStressTest = ref array [0..45, array [1..45, TNode]] - -proc finalizer(n: PNode) = - write(stdout, n.data) - write(stdout, " is now freed\n") - -proc newNode(data: int, le, ri: PNode): PNode = - new(result, finalizer) - result.le = le - result.ri = ri - result.data = data - -# now loop and build a tree -proc main() = - var - i = 0 - p: TStressTest - while i < 1000: - var n: PNode - - n = newNode(i, nil, newNode(i + 10000, nil, nil)) - inc(i) - new(p) - - write(stdout, "Simple tree node allocation worked!\n") - i = 0 - while i < 1000: - var m = newNode(i + 20000, nil, nil) - var k = newNode(i + 30000, nil, nil) - m.le = m - m.ri = k - k.le = m - k.ri = k - inc(i) - - write(stdout, "Simple cycle allocation worked!\n") - -main() diff --git a/tests/compile/tnewlibs.nim b/tests/compile/tnewlibs.nim deleted file mode 100644 index bdb53ae0b..000000000 --- a/tests/compile/tnewlibs.nim +++ /dev/null @@ -1,17 +0,0 @@ -# Test wether the bindings at least compile... - -import - tcl, - sdl, smpeg, sdl_gfx, sdl_net, sdl_mixer, sdl_ttf, - sdl_image, sdl_mixer_nosmpeg, - gtk2, glib2, pango, gdk2, - unicode, cgi, terminal, libcurl, - parsexml, parseopt, parsecfg, - osproc, - cairowin32, cairoxlib, - gl, glut, glu, glx, glext, wingl, - lua, lualib, lauxlib, mysql, sqlite3, db_mongo, md5, asyncio, mimetypes, - cookies, events, ftpclient, scgi, irc - - -writeln(stdout, "test compilation of binding modules") diff --git a/tests/compile/tnewsets.nim b/tests/compile/tnewsets.nim deleted file mode 100644 index 415fe8f7e..000000000 --- a/tests/compile/tnewsets.nim +++ /dev/null @@ -1,6 +0,0 @@ -# new test for sets: - -const elem = ' ' - -var s: set[char] = {elem} -assert(elem in s and 'a' not_in s and 'c' not_in s ) diff --git a/tests/compile/tnewuns.nim b/tests/compile/tnewuns.nim deleted file mode 100644 index 5181e467c..000000000 --- a/tests/compile/tnewuns.nim +++ /dev/null @@ -1,12 +0,0 @@ -# test the new unsigned operations: - -import - strutils - -var - x, y: int - -x = 1 -y = high(int) - -writeln(stdout, $ ( x +% y ) ) diff --git a/tests/compile/tnoforward.nim b/tests/compile/tnoforward.nim deleted file mode 100644 index 0359ff348..000000000 --- a/tests/compile/tnoforward.nim +++ /dev/null @@ -1,10 +0,0 @@ -{. noforward: on .} - -proc foo(x: int) = - bar x - -proc bar(x: int) = - echo x - -foo(10) - diff --git a/tests/compile/tparedef.nim b/tests/compile/tparedef.nim deleted file mode 100644 index dedebf6b7..000000000 --- a/tests/compile/tparedef.nim +++ /dev/null @@ -1,4 +0,0 @@ -# This test is now superfluous: - -proc a(a: int) = - return diff --git a/tests/compile/tprep.nim b/tests/compile/tprep.nim deleted file mode 100644 index 4ef9e2543..000000000 --- a/tests/compile/tprep.nim +++ /dev/null @@ -1,30 +0,0 @@ -# Test the features that used to belong to the preprocessor - -import - times - -#{.warning: "This is only a test warning!".} - -const - case2 = true - case3 = true - -when defined(case1): - {.hint: "Case 1".} - when case3: - {.hint: "Case 1.3".} -elif case2: - {.hint: "Case 2".} - when case3: - {.hint: "Case 2.3".} -elif case3: - {.hint: "Case 3".} -else: - {.hint: "unknown case".} - -var - s: string -write(stdout, "compiled at " & system.compileDate & - " " & compileTime & "\n") -echo getDateStr() -echo getClockStr() diff --git a/tests/compile/tquicksort.nim b/tests/compile/tquicksort.nim deleted file mode 100644 index 6706a185e..000000000 --- a/tests/compile/tquicksort.nim +++ /dev/null @@ -1,26 +0,0 @@ -proc QuickSort(list: seq[int]): seq[int] = - if len(list) == 0: - return @[] - var pivot = list[0] - var left: seq[int] = @[] - var right: seq[int] = @[] - for i in low(list)..high(list): - if list[i] < pivot: - left.add(list[i]) - elif list[i] > pivot: - right.add(list[i]) - result = QuickSort(left) & - pivot & - QuickSort(right) - -proc echoSeq(a: seq[int]) = - for i in low(a)..high(a): - echo(a[i]) - -var - list: seq[int] - -list = QuickSort(@[89,23,15,23,56,123,356,12,7,1,6,2,9,4,3]) -echoSeq(list) - - diff --git a/tests/compile/tradix.nim b/tests/compile/tradix.nim deleted file mode 100644 index e5998ee12..000000000 --- a/tests/compile/tradix.nim +++ /dev/null @@ -1,319 +0,0 @@ -# implements and tests an efficient radix tree - -## another method to store an efficient array of pointers: -## We use a radix tree with node compression. -## There are two node kinds: - -const bitsPerUnit = 8*sizeof(int) - -type - TRadixNodeKind = enum rnLinear, rnFull, rnLeafBits, rnLeafLinear - PRadixNode = ptr TRadixNode - TRadixNode {.pure, inheritable.} = object - kind: TRadixNodeKind - TRadixNodeLinear = object of TRadixNode - len: int8 - keys: array [0..31, int8] - vals: array [0..31, PRadixNode] - - TRadixNodeFull = object of TRadixNode - b: array [0..255, PRadixNode] - TRadixNodeLeafBits = object of TRadixNode - b: array [0..7, int] - TRadixNodeLeafLinear = object of TRadixNode - len: int8 - keys: array [0..31, int8] - -var - root: PRadixNode - -proc searchInner(r: PRadixNode, a: int): PRadixNode = - case r.kind - of rnLinear: - var x = cast[ptr TRadixNodeLinear](r) - for i in 0..ze(x.len)-1: - if ze(x.keys[i]) == a: return x.vals[i] - of rnFull: - var x = cast[ptr TRadixNodeFull](r) - return x.b[a] - else: assert(false) - -proc testBit(w, i: int): bool {.inline.} = - result = (w and (1 shl (i %% BitsPerUnit))) != 0 - -proc setBit(w: var int, i: int) {.inline.} = - w = w or (1 shl (i %% bitsPerUnit)) - -proc resetBit(w: var int, i: int) {.inline.} = - w = w and not (1 shl (i %% bitsPerUnit)) - -proc testOrSetBit(w: var int, i: int): bool {.inline.} = - var x = (1 shl (i %% bitsPerUnit)) - if (w and x) != 0: return true - w = w or x - -proc searchLeaf(r: PRadixNode, a: int): bool = - case r.kind - of rnLeafBits: - var x = cast[ptr TRadixNodeLeafBits](r) - return testBit(x.b[a /% BitsPerUnit], a) - of rnLeafLinear: - var x = cast[ptr TRadixNodeLeafLinear](r) - for i in 0..ze(x.len)-1: - if ze(x.keys[i]) == a: return true - else: assert(false) - -proc exclLeaf(r: PRadixNode, a: int) = - case r.kind - of rnLeafBits: - var x = cast[ptr TRadixNodeLeafBits](r) - resetBit(x.b[a /% BitsPerUnit], a) - of rnLeafLinear: - var x = cast[ptr TRadixNodeLeafLinear](r) - var L = ze(x.len) - for i in 0..L-1: - if ze(x.keys[i]) == a: - x.keys[i] = x.keys[L-1] - dec(x.len) - return - else: assert(false) - -proc contains*(r: PRadixNode, a: TAddress): bool = - if r == nil: return false - var x = searchInner(r, a shr 24 and 0xff) - if x == nil: return false - x = searchInner(x, a shr 16 and 0xff) - if x == nil: return false - x = searchInner(x, a shr 8 and 0xff) - if x == nil: return false - return searchLeaf(x, a and 0xff) - -proc excl*(r: PRadixNode, a: TAddress): bool = - if r == nil: return false - var x = searchInner(r, a shr 24 and 0xff) - if x == nil: return false - x = searchInner(x, a shr 16 and 0xff) - if x == nil: return false - x = searchInner(x, a shr 8 and 0xff) - if x == nil: return false - exclLeaf(x, a and 0xff) - -proc addLeaf(r: var PRadixNode, a: int): bool = - if r == nil: - # a linear node: - var x = cast[ptr TRadixNodeLinear](alloc(sizeof(TRadixNodeLinear))) - x.kind = rnLeafLinear - x.len = 1'i8 - x.keys[0] = toU8(a) - r = x - return false # not already in set - case r.kind - of rnLeafBits: - var x = cast[ptr TRadixNodeLeafBits](r) - return testOrSetBit(x.b[a /% BitsPerUnit], a) - of rnLeafLinear: - var x = cast[ptr TRadixNodeLeafLinear](r) - var L = ze(x.len) - for i in 0..L-1: - if ze(x.keys[i]) == a: return true - if L <= high(x.keys): - x.keys[L] = toU8(a) - inc(x.len) - else: - # transform into a full node: - var y = cast[ptr TRadixNodeLeafBits](alloc0(sizeof(TRadixNodeLeafBits))) - y.kind = rnLeafBits - for i in 0..ze(x.len)-1: - var u = ze(x.keys[i]) - setBit(y.b[u /% BitsPerUnit], u) - setBit(y.b[a /% BitsPerUnit], a) - dealloc(r) - r = y - else: assert(false) - -proc addInner(r: var PRadixNode, a: int, d: int): bool = - if d == 0: - return addLeaf(r, a and 0xff) - var k = a shr d and 0xff - if r == nil: - # a linear node: - var x = cast[ptr TRadixNodeLinear](alloc(sizeof(TRadixNodeLinear))) - x.kind = rnLinear - x.len = 1'i8 - x.keys[0] = toU8(k) - r = x - return addInner(x.vals[0], a, d-8) - case r.kind - of rnLinear: - var x = cast[ptr TRadixNodeLinear](r) - var L = ze(x.len) - for i in 0..L-1: - if ze(x.keys[i]) == k: # already exists - return addInner(x.vals[i], a, d-8) - if L <= high(x.keys): - x.keys[L] = toU8(k) - inc(x.len) - return addInner(x.vals[L], a, d-8) - else: - # transform into a full node: - var y = cast[ptr TRadixNodeFull](alloc0(sizeof(TRadixNodeFull))) - y.kind = rnFull - for i in 0..L-1: y.b[ze(x.keys[i])] = x.vals[i] - dealloc(r) - r = y - return addInner(y.b[k], a, d-8) - of rnFull: - var x = cast[ptr TRadixNodeFull](r) - return addInner(x.b[k], a, d-8) - else: assert(false) - -proc incl*(r: var PRadixNode, a: TAddress) {.inline.} = - discard addInner(r, a, 24) - -proc testOrIncl*(r: var PRadixNode, a: TAddress): bool {.inline.} = - return addInner(r, a, 24) - -iterator innerElements(r: PRadixNode): tuple[prefix: int, n: PRadixNode] = - if r != nil: - case r.kind - of rnFull: - var r = cast[ptr TRadixNodeFull](r) - for i in 0..high(r.b): - if r.b[i] != nil: - yield (i, r.b[i]) - of rnLinear: - var r = cast[ptr TRadixNodeLinear](r) - for i in 0..ze(r.len)-1: - yield (ze(r.keys[i]), r.vals[i]) - else: assert(false) - -iterator leafElements(r: PRadixNode): int = - if r != nil: - case r.kind - of rnLeafBits: - var r = cast[ptr TRadixNodeLeafBits](r) - # iterate over any bit: - for i in 0..high(r.b): - if r.b[i] != 0: # test all bits for zero - for j in 0..BitsPerUnit-1: - if testBit(r.b[i], j): - yield i*BitsPerUnit+j - of rnLeafLinear: - var r = cast[ptr TRadixNodeLeafLinear](r) - for i in 0..ze(r.len)-1: - yield ze(r.keys[i]) - else: assert(false) - -iterator elements*(r: PRadixNode): TAddress {.inline.} = - for p1, n1 in innerElements(r): - for p2, n2 in innerElements(n1): - for p3, n3 in innerElements(n2): - for p4 in leafElements(n3): - yield p1 shl 24 or p2 shl 16 or p3 shl 8 or p4 - -proc main() = - const - numbers = [128, 1, 2, 3, 4, 255, 17, -8, 45, 19_000] - var - r: PRadixNode = nil - for x in items(numbers): - echo testOrIncl(r, x) - for x in elements(r): echo(x) - -main() - - -when false: - proc traverse(r: PRadixNode, prefix: int, d: int) = - if r == nil: return - case r.kind - of rnLeafBits: - assert(d == 0) - var x = cast[ptr TRadixNodeLeafBits](r) - # iterate over any bit: - for i in 0..high(x.b): - if x.b[i] != 0: # test all bits for zero - for j in 0..BitsPerUnit-1: - if testBit(x.b[i], j): - visit(prefix or i*BitsPerUnit+j) - of rnLeafLinear: - assert(d == 0) - var x = cast[ptr TRadixNodeLeafLinear](r) - for i in 0..ze(x.len)-1: - visit(prefix or ze(x.keys[i])) - of rnFull: - var x = cast[ptr TRadixNodeFull](r) - for i in 0..high(r.b): - if r.b[i] != nil: - traverse(r.b[i], prefix or (i shl d), d-8) - of rnLinear: - var x = cast[ptr TRadixNodeLinear](r) - for i in 0..ze(x.len)-1: - traverse(x.vals[i], prefix or (ze(x.keys[i]) shl d), d-8) - - type - TRadixIter {.final.} = object - r: PRadixNode - p: int - x: int - - proc init(i: var TRadixIter, r: PRadixNode) = - i.r = r - i.x = 0 - i.p = 0 - - proc nextr(i: var TRadixIter): PRadixNode = - if i.r == nil: return nil - case i.r.kind - of rnFull: - var r = cast[ptr TRadixNodeFull](i.r) - while i.x <= high(r.b): - if r.b[i.x] != nil: - i.p = i.x - return r.b[i.x] - inc(i.x) - of rnLinear: - var r = cast[ptr TRadixNodeLinear](i.r) - if i.x < ze(r.len): - i.p = ze(r.keys[i.x]) - result = r.vals[i.x] - inc(i.x) - else: assert(false) - - proc nexti(i: var TRadixIter): int = - result = -1 - case i.r.kind - of rnLeafBits: - var r = cast[ptr TRadixNodeLeafBits](i.r) - # iterate over any bit: - for i in 0..high(r.b): - if x.b[i] != 0: # test all bits for zero - for j in 0..BitsPerUnit-1: - if testBit(x.b[i], j): - visit(prefix or i*BitsPerUnit+j) - of rnLeafLinear: - var r = cast[ptr TRadixNodeLeafLinear](i.r) - if i.x < ze(r.len): - result = ze(r.keys[i.x]) - inc(i.x) - - iterator elements(r: PRadixNode): TAddress {.inline.} = - var - a, b, c, d: TRadixIter - init(a, r) - while true: - var x = nextr(a) - if x != nil: - init(b, x) - while true: - var y = nextr(b) - if y != nil: - init(c, y) - while true: - var z = nextr(c) - if z != nil: - init(d, z) - while true: - var q = nexti(d) - if q != -1: - yield a.p shl 24 or b.p shl 16 or c.p shl 8 or q diff --git a/tests/compile/treadln.nim b/tests/compile/treadln.nim deleted file mode 100644 index 1117ab5f9..000000000 --- a/tests/compile/treadln.nim +++ /dev/null @@ -1,12 +0,0 @@ -# test the improved readline handling that does not care whether its -# Macintosh, Unix or Windows text format. - -var - inp: TFile - line: string - -if open(inp, "readme.txt"): - while not EndOfFile(inp): - line = readLine(inp) - echo("#" & line & "#") - close(inp) diff --git a/tests/compile/treadx.nim b/tests/compile/treadx.nim deleted file mode 100644 index 49b6ad691..000000000 --- a/tests/compile/treadx.nim +++ /dev/null @@ -1,14 +0,0 @@ - -when not defined(windows): - import posix - - var inp = "" - var buf: array[0..10, char] - while true: - var r = read(0, addr(buf), sizeof(buf)-1) - add inp, $buf - if r != sizeof(buf)-1: break - - echo inp - #dafkladskölklödsaf ölksdakölfölksfklwe4iojr389wr 89uweokf sdlkf jweklr jweflksdj fioewjfsdlfsd - diff --git a/tests/compile/tshadow_magic_type.nim b/tests/compile/tshadow_magic_type.nim deleted file mode 100644 index 5cd27435e..000000000 --- a/tests/compile/tshadow_magic_type.nim +++ /dev/null @@ -1,24 +0,0 @@ -type - TListItemType* = enum - RedisNil, RedisString - - TListItem* = object - case kind*: TListItemType - of RedisString: - str*: string - else: nil - TRedisList* = seq[TListItem] - -# Caused by this. -proc seq*() = - nil - -proc lrange*(key: string): TRedisList = - var foo: TListItem - foo.kind = RedisNil - result = @[foo] - -when isMainModule: - var p = lrange("mylist") - for i in items(p): - echo(i.str) diff --git a/tests/compile/tsizeof.nim b/tests/compile/tsizeof.nim deleted file mode 100644 index f7b70dd4d..000000000 --- a/tests/compile/tsizeof.nim +++ /dev/null @@ -1,10 +0,0 @@ -# Test the sizeof proc - -type - TMyRecord {.final.} = object - x, y: int - b: bool - r: float - s: string - -write(stdout, sizeof(TMyRecord)) diff --git a/tests/compile/tstrace.nim b/tests/compile/tstrace.nim deleted file mode 100644 index 3032a34a3..000000000 --- a/tests/compile/tstrace.nim +++ /dev/null @@ -1,16 +0,0 @@ -# Test the new stacktraces (great for debugging!) - -{.push stack_trace: on.} - -proc recTest(i: int) = - # enter - if i < 10: - recTest(i+1) - else: # should printStackTrace() - var p: ptr int = nil - p[] = 12 - # leave - -{.pop.} - -recTest(0) diff --git a/tests/compile/tstrdesc.nim b/tests/compile/tstrdesc.nim deleted file mode 100644 index 1c2e85b4b..000000000 --- a/tests/compile/tstrdesc.nim +++ /dev/null @@ -1,14 +0,0 @@ -var - x: array [0..2, int] - -x = [0, 1, 2] - -type - TStringDesc {.final.} = object - len, space: int # len and space without counting the terminating zero - data: array [0..0, char] # for the '\0' character - -var - emptyString {.exportc: "emptyString".}: TStringDesc - - diff --git a/tests/compile/tstrdist.nim b/tests/compile/tstrdist.nim deleted file mode 100644 index 3e1939e73..000000000 --- a/tests/compile/tstrdist.nim +++ /dev/null @@ -1,26 +0,0 @@ -# compute the edit distance between two strings - -proc editDistance(a, b: string): int = - var - c: seq[int] - n = a.len - m = b.len - newSeq(c, (n+1)*(m+1)) - for i in 0..n: - c[i*n] = i # [i,0] - for j in 0..m: - c[j] = j # [0,j] - - for i in 1..n: - for j in 1..m: - var x = c[(i-1)*n + j]+1 - var y = c[i*n + j-1]+1 - var z: int - if a[i-1] == b[j-1]: - z = c[(i-1)*n + j-1] - else: - z = c[(i-1)*n + j-1]+1 - c[(i-1)*n + (j-1)] = min(x,min(y,z)) - return c[n*m] - -write(stdout, editDistance("abc", "abd")) diff --git a/tests/compile/tvarious.nim b/tests/compile/tvarious.nim deleted file mode 100644 index 5883ba62f..000000000 --- a/tests/compile/tvarious.nim +++ /dev/null @@ -1,63 +0,0 @@ -# Test various aspects - -# bug #572 -var a=12345678901'u64 - -var x = (x: 42, y: (a: 8, z: 10)) -echo x.y - -import - mvarious - -type - PA = ref TA - PB = ref TB - - TB = object - a: PA - - TA = object - b: TB - x: int - -proc getPA(): PA = - var - b: bool - b = not false - return nil - -# bug #501 -proc f(): int = 54 - -var - global: int - -var - s: string - i: int - r: TA - -r.b.a.x = 0 -global = global + 1 -exportme() -write(stdout, "Hallo wie heißt du? ") -write(stdout, getPA().x) -s = readLine(stdin) -i = 0 -while i < s.len: - if s[i] == 'c': write(stdout, "'c' in deinem Namen gefunden\n") - i = i + 1 - -write(stdout, "Du heißt " & s) - -# bug #544 - -type Bar [T; I:range] = array[I, T] -proc foo*[T; I:range](a, b: Bar[T, I]): Bar[T, I] = - when len(a) != 3: - # Error: constant expression expected - {.fatal:"Dimensions have to be 3".} - #... -block: - var a, b: Bar[int, 0..2] - discard foo(a, b) diff --git a/tests/compile/tcompiles.nim b/tests/compiles/tcompiles.nim index d0fccdaff..d0fccdaff 100644 --- a/tests/compile/tcompiles.nim +++ b/tests/compiles/tcompiles.nim diff --git a/tests/run/tconcat.nim b/tests/concat/tconcat.nim index fdce3ea00..fdce3ea00 100644 --- a/tests/run/tconcat.nim +++ b/tests/concat/tconcat.nim diff --git a/tests/run/tnodeadlocks.nim b/tests/concurrency/tnodeadlocks.nim index 18fdca3e9..18fdca3e9 100644 --- a/tests/run/tnodeadlocks.nim +++ b/tests/concurrency/tnodeadlocks.nim diff --git a/tests/reject/tconstr1.nim b/tests/constr/tconstr1.nim index cb6594213..cb6594213 100644 --- a/tests/reject/tconstr1.nim +++ b/tests/constr/tconstr1.nim diff --git a/tests/run/tconstr2.nim b/tests/constr/tconstr2.nim index 30cec5cb8..30cec5cb8 100644 --- a/tests/run/tconstr2.nim +++ b/tests/constr/tconstr2.nim diff --git a/tests/reject/tconstraints.nim b/tests/constraints/tconstraints.nim index e61095fff..e61095fff 100644 --- a/tests/reject/tconstraints.nim +++ b/tests/constraints/tconstraints.nim diff --git a/tests/run/tcontinue.nim b/tests/controlflow/tcontinue.nim index 092026e8c..092026e8c 100644 --- a/tests/run/tcontinue.nim +++ b/tests/controlflow/tcontinue.nim diff --git a/tests/reject/tstatret.nim b/tests/controlflow/tstatret.nim index bf90255a0..bf90255a0 100644 --- a/tests/reject/tstatret.nim +++ b/tests/controlflow/tstatret.nim diff --git a/tests/compile/tconvcolors.nim b/tests/converter/tconvcolors.nim index 07e829550..07e829550 100644 --- a/tests/compile/tconvcolors.nim +++ b/tests/converter/tconvcolors.nim diff --git a/tests/compile/tconvert.nim b/tests/converter/tconvert.nim index a8ddcf119..a8ddcf119 100644 --- a/tests/compile/tconvert.nim +++ b/tests/converter/tconvert.nim diff --git a/tests/run/tgenericconverter.nim b/tests/converter/tgenericconverter.nim index e1c9f7c4c..e1c9f7c4c 100644 --- a/tests/run/tgenericconverter.nim +++ b/tests/converter/tgenericconverter.nim diff --git a/tests/compile/ttypeconverter1.nim b/tests/converter/ttypeconverter1.nim index b9a5e88ae..b9a5e88ae 100644 --- a/tests/compile/ttypeconverter1.nim +++ b/tests/converter/ttypeconverter1.nim diff --git a/tests/compile/mdefaultprocparam.nim b/tests/defaultprocparam/mdefaultprocparam.nim index 4a17277c0..4a17277c0 100644 --- a/tests/compile/mdefaultprocparam.nim +++ b/tests/defaultprocparam/mdefaultprocparam.nim diff --git a/tests/compile/tdefaultprocparam.nim b/tests/defaultprocparam/tdefaultprocparam.nim index 23ecf72e9..23ecf72e9 100644 --- a/tests/compile/tdefaultprocparam.nim +++ b/tests/defaultprocparam/tdefaultprocparam.nim diff --git a/tests/reject/tdeprecated.nim b/tests/deprecated/tdeprecated.nim index f41f0a72f..f41f0a72f 100644 --- a/tests/reject/tdeprecated.nim +++ b/tests/deprecated/tdeprecated.nim diff --git a/tests/destructor/tdestructor.nim b/tests/destructor/tdestructor.nim new file mode 100644 index 000000000..bb1410d92 --- /dev/null +++ b/tests/destructor/tdestructor.nim @@ -0,0 +1,84 @@ +discard """ + output: '''---- +myobj constructed +myobj destroyed +---- +mygeneric1 constructed +mygeneric1 destroyed +---- +mygeneric2 constructed +mygeneric2 destroyed +myobj destroyed +---- +mygeneric3 constructed +mygeneric1 destroyed +''' +""" + +type + TMyObj = object + x, y: int + p: pointer + + TMyGeneric1[T] = object + x: T + + TMyGeneric2[A, B] = object + x: A + y: B + + TMyGeneric3[A, B, C] = object + x: A + y: B + z: C + +proc destruct(o: var TMyObj) {.destructor.} = + if o.p != nil: dealloc o.p + echo "myobj destroyed" + +proc destroy(o: var TMyGeneric1) {.destructor.} = + echo "mygeneric1 destroyed" + +proc destroy[A, B](o: var TMyGeneric2[A, B]) {.destructor.} = + echo "mygeneric2 destroyed" + +proc open: TMyObj = + # allow for superfluous () + result = (TMyObj(x: 1, y: 2, p: alloc(3))) + +proc `$`(x: TMyObj): string = $x.y + +proc myobj() = + var x = open() + echo "myobj constructed" + +proc mygeneric1() = + var x = TMyGeneric1[int](x: 10) + echo "mygeneric1 constructed" + +proc mygeneric2[T](val: T) = + var + a = open() + b = TMyGeneric2[int, T](x: 10, y: val) + c = TMyGeneric3[int, int, string](x: 10, y: 20, z: "test") + + echo "mygeneric2 constructed" + +proc mygeneric3 = + var x = TMyGeneric3[int, string, TMyGeneric1[int]]( + x: 10, y: "test", z: TMyGeneric1[int](x: 10)) + + echo "mygeneric3 constructed" + +echo "----" +myobj() + +echo "----" +mygeneric1() + +echo "----" +mygeneric2[int](10) + +echo "----" +mygeneric3() + diff --git a/tests/reject/tdestructor.nim b/tests/destructor/tdestructor2.nim index da9192a3f..da9192a3f 100644 --- a/tests/reject/tdestructor.nim +++ b/tests/destructor/tdestructor2.nim diff --git a/tests/compile/tdictdestruct.nim b/tests/destructor/tdictdestruct.nim index ec1084105..ec1084105 100644 --- a/tests/compile/tdictdestruct.nim +++ b/tests/destructor/tdictdestruct.nim diff --git a/tests/compile/tdiscardable.nim b/tests/discard/tdiscardable.nim index c0551ba2f..c0551ba2f 100644 --- a/tests/compile/tdiscardable.nim +++ b/tests/discard/tdiscardable.nim diff --git a/tests/reject/tneedsdiscard.nim b/tests/discard/tneedsdiscard.nim index 24f5b2eee..24f5b2eee 100644 --- a/tests/reject/tneedsdiscard.nim +++ b/tests/discard/tneedsdiscard.nim diff --git a/tests/run/tcurrncy.nim b/tests/distinct/tcurrncy.nim index 78dbc2a89..78dbc2a89 100644 --- a/tests/run/tcurrncy.nim +++ b/tests/distinct/tcurrncy.nim diff --git a/tests/reject/teffects1.nim b/tests/effects/teffects1.nim index 1c6c4bed8..b72e8b00c 100644 --- a/tests/reject/teffects1.nim +++ b/tests/effects/teffects1.nim @@ -1,5 +1,5 @@ discard """ - line: 1804 + line: 1855 file: "system.nim" errormsg: "can raise an unlisted exception: ref EIO" """ diff --git a/tests/reject/teffects2.nim b/tests/effects/teffects2.nim index 7e6b17c36..7e6b17c36 100644 --- a/tests/reject/teffects2.nim +++ b/tests/effects/teffects2.nim diff --git a/tests/reject/teffects3.nim b/tests/effects/teffects3.nim index 78543a929..78543a929 100644 --- a/tests/reject/teffects3.nim +++ b/tests/effects/teffects3.nim diff --git a/tests/reject/teffects4.nim b/tests/effects/teffects4.nim index 4584e6dc8..4584e6dc8 100644 --- a/tests/reject/teffects4.nim +++ b/tests/effects/teffects4.nim diff --git a/tests/reject/teffects5.nim b/tests/effects/teffects5.nim index d630a6fc4..d630a6fc4 100644 --- a/tests/reject/teffects5.nim +++ b/tests/effects/teffects5.nim diff --git a/tests/compile/teffects1.nim b/tests/effects/teffects6.nim index 54200f2c3..54200f2c3 100644 --- a/tests/compile/teffects1.nim +++ b/tests/effects/teffects6.nim diff --git a/tests/reject/tsidee1.nim b/tests/effects/tsidee1.nim index bd5b32dd7..bd5b32dd7 100644 --- a/tests/reject/tsidee1.nim +++ b/tests/effects/tsidee1.nim diff --git a/tests/run/tsidee2.nim b/tests/effects/tsidee2.nim index e73c89608..e73c89608 100644 --- a/tests/run/tsidee2.nim +++ b/tests/effects/tsidee2.nim diff --git a/tests/run/tsidee3.nim b/tests/effects/tsidee3.nim index e0c427ab6..e0c427ab6 100644 --- a/tests/run/tsidee3.nim +++ b/tests/effects/tsidee3.nim diff --git a/tests/reject/tsidee4.nim b/tests/effects/tsidee4.nim index cbebfbd36..cbebfbd36 100644 --- a/tests/reject/tsidee4.nim +++ b/tests/effects/tsidee4.nim diff --git a/tests/compile/tenum.nim b/tests/enum/tenum.nim index 6e53b9c08..6e53b9c08 100644 --- a/tests/compile/tenum.nim +++ b/tests/enum/tenum.nim diff --git a/tests/compile/tenum2.nim b/tests/enum/tenum2.nim index feba36dd6..feba36dd6 100644 --- a/tests/compile/tenum2.nim +++ b/tests/enum/tenum2.nim diff --git a/tests/compile/tenum3.nim b/tests/enum/tenum3.nim index 09a516932..09a516932 100644 --- a/tests/compile/tenum3.nim +++ b/tests/enum/tenum3.nim diff --git a/tests/run/tenumhole.nim b/tests/enum/tenumhole.nim index a35526378..a35526378 100644 --- a/tests/run/tenumhole.nim +++ b/tests/enum/tenumhole.nim diff --git a/tests/reject/tenumitems.nim b/tests/enum/tenumitems.nim index b6eee5ba8..b6eee5ba8 100644 --- a/tests/reject/tenumitems.nim +++ b/tests/enum/tenumitems.nim diff --git a/tests/run/tenumitems.nim b/tests/enum/tenumitems2.nim index db4c6b554..db4c6b554 100644 --- a/tests/run/tenumitems.nim +++ b/tests/enum/tenumitems2.nim diff --git a/tests/reject/tenummix.nim b/tests/enum/tenummix.nim index f58e7989d..aaf0be2cb 100644 --- a/tests/reject/tenummix.nim +++ b/tests/enum/tenummix.nim @@ -1,6 +1,6 @@ discard """ - file: "system.nim" - line: 696 + file: "tenummix.nim" + line: 11 errormsg: "type mismatch" """ diff --git a/tests/run/tnamedenumfields.nim b/tests/enum/tnamedenumfields.nim index e9ac88a42..e9ac88a42 100644 --- a/tests/run/tnamedenumfields.nim +++ b/tests/enum/tnamedenumfields.nim diff --git a/tests/compile/toptions.nim b/tests/enum/toptions.nim index 95bb5cfbc..3c841de2c 100644 --- a/tests/compile/toptions.nim +++ b/tests/enum/toptions.nim @@ -1,7 +1,3 @@ -# Converted by Pas2mor v1.54 -# Used command line arguments: -# -m -q -o bootstrap\options.mor options.pas -# type # please make sure we have under 32 options (improves code efficiency!) diff --git a/tests/run/tcontinuexc.nim b/tests/exception/tcontinuexc.nim index f618abc14..f618abc14 100644 --- a/tests/run/tcontinuexc.nim +++ b/tests/exception/tcontinuexc.nim diff --git a/tests/run/texceptions.nim b/tests/exception/texceptions.nim index 69b2d0f6a..69b2d0f6a 100644 --- a/tests/run/texceptions.nim +++ b/tests/exception/texceptions.nim diff --git a/tests/run/texcpt1.nim b/tests/exception/texcpt1.nim index ec74c9470..ec74c9470 100644 --- a/tests/run/texcpt1.nim +++ b/tests/exception/texcpt1.nim diff --git a/tests/run/texcsub.nim b/tests/exception/texcsub.nim index 3dba357f9..3dba357f9 100644 --- a/tests/run/texcsub.nim +++ b/tests/exception/texcsub.nim diff --git a/tests/run/tfinally.nim b/tests/exception/tfinally.nim index 16fb3e7da..16fb3e7da 100644 --- a/tests/run/tfinally.nim +++ b/tests/exception/tfinally.nim diff --git a/tests/run/tfinally2.nim b/tests/exception/tfinally2.nim index e1e8d4c7e..e1e8d4c7e 100644 --- a/tests/run/tfinally2.nim +++ b/tests/exception/tfinally2.nim diff --git a/tests/run/tfinally3.nim b/tests/exception/tfinally3.nim index e65661cd0..e65661cd0 100644 --- a/tests/run/tfinally3.nim +++ b/tests/exception/tfinally3.nim diff --git a/tests/run/tonraise.nim b/tests/exception/tonraise.nim index 1a555dd94..1a555dd94 100644 --- a/tests/run/tonraise.nim +++ b/tests/exception/tonraise.nim diff --git a/tests/run/treraise.nim b/tests/exception/treraise.nim index cbd0b5f8a..cbd0b5f8a 100644 --- a/tests/run/treraise.nim +++ b/tests/exception/treraise.nim diff --git a/tests/run/tunhandledexc.nim b/tests/exception/tunhandledexc.nim index f24881aef..f24881aef 100644 --- a/tests/run/tunhandledexc.nim +++ b/tests/exception/tunhandledexc.nim diff --git a/tests/run/twrongexc.nim b/tests/exception/twrongexc.nim index 755f7d979..755f7d979 100644 --- a/tests/run/twrongexc.nim +++ b/tests/exception/twrongexc.nim diff --git a/tests/reject/texprstmt.nim b/tests/exprs/texprstmt.nim index b32394d8d..b32394d8d 100644 --- a/tests/reject/texprstmt.nim +++ b/tests/exprs/texprstmt.nim diff --git a/tests/reject/tstmtexp.nim b/tests/exprs/tstmtexp.nim index 7cbf2eb3d..7cbf2eb3d 100644 --- a/tests/reject/tstmtexp.nim +++ b/tests/exprs/tstmtexp.nim diff --git a/tests/run/tstmtexprs.nim b/tests/exprs/tstmtexprs.nim index 497a2f6d0..497a2f6d0 100644 --- a/tests/run/tstmtexprs.nim +++ b/tests/exprs/tstmtexprs.nim diff --git a/tests/run/tfieldindex.nim b/tests/fields/tfieldindex.nim index f0674af54..f0674af54 100644 --- a/tests/run/tfieldindex.nim +++ b/tests/fields/tfieldindex.nim diff --git a/tests/run/tfielditerator.nim b/tests/fields/tfielditerator.nim index 2919aab41..2919aab41 100644 --- a/tests/run/tfielditerator.nim +++ b/tests/fields/tfielditerator.nim diff --git a/tests/run/tfielditerator2.nim b/tests/fields/tfielditerator2.nim index 76fa568f2..76fa568f2 100644 --- a/tests/run/tfielditerator2.nim +++ b/tests/fields/tfielditerator2.nim diff --git a/tests/run/tfloat1.nim b/tests/float/tfloat1.nim index f290fdb57..f290fdb57 100644 --- a/tests/run/tfloat1.nim +++ b/tests/float/tfloat1.nim diff --git a/tests/run/tfloat2.nim b/tests/float/tfloat2.nim index 51883674f..51883674f 100644 --- a/tests/run/tfloat2.nim +++ b/tests/float/tfloat2.nim diff --git a/tests/run/tfloat3.nim b/tests/float/tfloat3.nim index 4382dd3ed..4382dd3ed 100644 --- a/tests/run/tfloat3.nim +++ b/tests/float/tfloat3.nim diff --git a/tests/run/mfriends.nim b/tests/friends/mfriends.nim index f1c663655..f1c663655 100644 --- a/tests/run/mfriends.nim +++ b/tests/friends/mfriends.nim diff --git a/tests/run/tfriends.nim b/tests/friends/tfriends.nim index 1e70d50a5..1e70d50a5 100644 --- a/tests/run/tfriends.nim +++ b/tests/friends/tfriends.nim diff --git a/tests/run/tbintre2.nim b/tests/generics/tbintre2.nim index 2a7225411..2a7225411 100644 --- a/tests/run/tbintre2.nim +++ b/tests/generics/tbintre2.nim diff --git a/tests/run/tbintree.nim b/tests/generics/tbintree.nim index 8cc8acb82..8cc8acb82 100644 --- a/tests/run/tbintree.nim +++ b/tests/generics/tbintree.nim diff --git a/tests/compile/tcan_alias_generic.nim b/tests/generics/tcan_alias_generic.nim index e90bdc6d2..e90bdc6d2 100644 --- a/tests/compile/tcan_alias_generic.nim +++ b/tests/generics/tcan_alias_generic.nim diff --git a/tests/compile/tcan_alias_specialised_generic.nim b/tests/generics/tcan_alias_specialised_generic.nim index 8d4a29abd..8d4a29abd 100644 --- a/tests/compile/tcan_alias_specialised_generic.nim +++ b/tests/generics/tcan_alias_specialised_generic.nim diff --git a/tests/compile/tcan_inherit_generic.nim b/tests/generics/tcan_inherit_generic.nim index a6f4d946b..a6f4d946b 100644 --- a/tests/compile/tcan_inherit_generic.nim +++ b/tests/generics/tcan_inherit_generic.nim diff --git a/tests/compile/tcan_specialise_generic.nim b/tests/generics/tcan_specialise_generic.nim index 64d5f56e3..64d5f56e3 100644 --- a/tests/compile/tcan_specialise_generic.nim +++ b/tests/generics/tcan_specialise_generic.nim diff --git a/tests/run/texplicitgeneric1.nim b/tests/generics/texplicitgeneric1.nim index 6cca71ac0..6cca71ac0 100644 --- a/tests/run/texplicitgeneric1.nim +++ b/tests/generics/texplicitgeneric1.nim diff --git a/tests/run/texplicitgeneric2.nim b/tests/generics/texplicitgeneric2.nim index 95461d023..95461d023 100644 --- a/tests/run/texplicitgeneric2.nim +++ b/tests/generics/texplicitgeneric2.nim diff --git a/tests/compile/tforwardgeneric.nim b/tests/generics/tforwardgeneric.nim index c5943b966..c5943b966 100644 --- a/tests/compile/tforwardgeneric.nim +++ b/tests/generics/tforwardgeneric.nim diff --git a/tests/compile/tgeneric.nim b/tests/generics/tgeneric0.nim index 9292b729f..9292b729f 100644 --- a/tests/compile/tgeneric.nim +++ b/tests/generics/tgeneric0.nim diff --git a/tests/run/tgenerics1.nim b/tests/generics/tgeneric1.nim index 5d20a864b..5d20a864b 100644 --- a/tests/run/tgenerics1.nim +++ b/tests/generics/tgeneric1.nim diff --git a/tests/compile/tgeneric2.nim b/tests/generics/tgeneric2.nim index 56803017a..56803017a 100644 --- a/tests/compile/tgeneric2.nim +++ b/tests/generics/tgeneric2.nim diff --git a/tests/compile/tgeneric3.nim b/tests/generics/tgeneric3.nim index 3c543ecfa..3c543ecfa 100644 --- a/tests/compile/tgeneric3.nim +++ b/tests/generics/tgeneric3.nim diff --git a/tests/compile/tgeneric4.nim b/tests/generics/tgeneric4.nim index f79096636..f79096636 100644 --- a/tests/compile/tgeneric4.nim +++ b/tests/generics/tgeneric4.nim diff --git a/tests/compile/tgenericdefaults.nim b/tests/generics/tgenericdefaults.nim index ad96f1851..ad96f1851 100644 --- a/tests/compile/tgenericdefaults.nim +++ b/tests/generics/tgenericdefaults.nim diff --git a/tests/compile/tgenericmatcher.nim b/tests/generics/tgenericmatcher.nim index edd0c4cf1..edd0c4cf1 100644 --- a/tests/compile/tgenericmatcher.nim +++ b/tests/generics/tgenericmatcher.nim diff --git a/tests/compile/tgenericmatcher2.nim b/tests/generics/tgenericmatcher2.nim index aa2f9dbb3..aa2f9dbb3 100644 --- a/tests/compile/tgenericmatcher2.nim +++ b/tests/generics/tgenericmatcher2.nim diff --git a/tests/run/tgenericprocvar.nim b/tests/generics/tgenericprocvar.nim index 1eba81fec..1eba81fec 100644 --- a/tests/run/tgenericprocvar.nim +++ b/tests/generics/tgenericprocvar.nim diff --git a/tests/compile/tgenericprop.nim b/tests/generics/tgenericprop.nim index 7cddf5617..7cddf5617 100644 --- a/tests/compile/tgenericprop.nim +++ b/tests/generics/tgenericprop.nim diff --git a/tests/compile/tgenericrefs.nim b/tests/generics/tgenericrefs.nim index ef931dfa7..ef931dfa7 100644 --- a/tests/compile/tgenericrefs.nim +++ b/tests/generics/tgenericrefs.nim diff --git a/tests/generics/tgenericshardcases.nim b/tests/generics/tgenericshardcases.nim new file mode 100644 index 000000000..2ef63bc20 --- /dev/null +++ b/tests/generics/tgenericshardcases.nim @@ -0,0 +1,36 @@ +discard """ + file: "tgenericshardcases.nim" + output: "2\n5\n126\n3" +""" + +import typetraits + +proc typeNameLen(x: typedesc): int {.compileTime.} = + result = x.name.len + +macro selectType(a, b: typedesc): typedesc = + result = a + +type + Foo[T] = object + data1: array[T.high, int] + data2: array[typeNameLen(T), float] # data3: array[0..T.typeNameLen, selectType(float, int)] + + MyEnum = enum A, B, C, D + +var f1: Foo[MyEnum] +var f2: Foo[int8] + +echo high(f1.data1) # (D = 3) - 1 == 2 +echo high(f1.data2) # (MyEnum.len = 6) - 1 == 5 + +echo high(f2.data1) # 127 - 1 == 126 +echo high(f2.data2) # int8.len - 1 == 3 + +#static: +# assert high(f1.data1) == ord(D) +# assert high(f1.data2) == 6 # length of MyEnum + +# assert high(f2.data1) == 127 +# assert high(f2.data2) == 4 # length of int8 + diff --git a/tests/compile/tgenerictmpl.nim b/tests/generics/tgenerictmpl.nim index a749e6570..a749e6570 100644 --- a/tests/compile/tgenerictmpl.nim +++ b/tests/generics/tgenerictmpl.nim diff --git a/tests/compile/tgenericvariant.nim b/tests/generics/tgenericvariant.nim index 51d01355a..51d01355a 100644 --- a/tests/compile/tgenericvariant.nim +++ b/tests/generics/tgenericvariant.nim diff --git a/tests/compile/tspecialised_is_equivalent.nim b/tests/generics/tspecialised_is_equivalent.nim index 60b976e90..60b976e90 100644 --- a/tests/compile/tspecialised_is_equivalent.nim +++ b/tests/generics/tspecialised_is_equivalent.nim diff --git a/tests/compile/tthread_generic.nim b/tests/generics/tthread_generic.nim index beae4b652..beae4b652 100644 --- a/tests/compile/tthread_generic.nim +++ b/tests/generics/tthread_generic.nim diff --git a/tests/run/tvarargs_vs_generic.nim b/tests/generics/tvarargs_vs_generic.nim index 122f3e453..122f3e453 100644 --- a/tests/run/tvarargs_vs_generic.nim +++ b/tests/generics/tvarargs_vs_generic.nim diff --git a/tests/run/tgensym.nim b/tests/gensym/tgensym.nim index 3c85b0b83..3c85b0b83 100644 --- a/tests/run/tgensym.nim +++ b/tests/gensym/tgensym.nim diff --git a/tests/compile/tgensymgeneric.nim b/tests/gensym/tgensymgeneric.nim index 54390a4ef..54390a4ef 100644 --- a/tests/compile/tgensymgeneric.nim +++ b/tests/gensym/tgensymgeneric.nim diff --git a/tests/run/tglobal.nim b/tests/global/tglobal.nim index 84c4510c1..84c4510c1 100644 --- a/tests/run/tglobal.nim +++ b/tests/global/tglobal.nim diff --git a/tests/compile/tglobalforvar.nim b/tests/global/tglobalforvar.nim index af75df5c8..af75df5c8 100644 --- a/tests/compile/tglobalforvar.nim +++ b/tests/global/tglobalforvar.nim diff --git a/tests/run/tnestif.nim b/tests/ifstmt/tnestif.nim index bfcd8751c..bfcd8751c 100644 --- a/tests/run/tnestif.nim +++ b/tests/ifstmt/tnestif.nim diff --git a/tests/compile/timplicititems.nim b/tests/implicit/timplicititems.nim index dbe321cb6..dbe321cb6 100644 --- a/tests/compile/timplicititems.nim +++ b/tests/implicit/timplicititems.nim diff --git a/tests/compile/timplictderef.nim b/tests/implicit/timplictderef.nim index 99b0b645b..99b0b645b 100644 --- a/tests/compile/timplictderef.nim +++ b/tests/implicit/timplictderef.nim diff --git a/tests/run/tdrdobbs_examples.nim b/tests/important/tdrdobbs_examples.nim index d1e0585d2..d1e0585d2 100644 --- a/tests/run/tdrdobbs_examples.nim +++ b/tests/important/tdrdobbs_examples.nim diff --git a/tests/reject/tuninit1.nim b/tests/init/tuninit1.nim index 2a994b187..2a994b187 100644 --- a/tests/reject/tuninit1.nim +++ b/tests/init/tuninit1.nim diff --git a/tests/run/tzeroarray.nim b/tests/init/tzeroarray.nim index b784b601e..b784b601e 100644 --- a/tests/run/tzeroarray.nim +++ b/tests/init/tzeroarray.nim diff --git a/tests/run/tcountup.nim b/tests/iter/tcountup.nim index e68a614b0..e68a614b0 100644 --- a/tests/run/tcountup.nim +++ b/tests/iter/tcountup.nim diff --git a/tests/compile/titer.nim b/tests/iter/titer.nim index 19a11dc4e..19a11dc4e 100644 --- a/tests/compile/titer.nim +++ b/tests/iter/titer.nim diff --git a/tests/compile/titer2.nim b/tests/iter/titer2.nim index dab2713e8..dab2713e8 100644 --- a/tests/compile/titer2.nim +++ b/tests/iter/titer2.nim diff --git a/tests/run/titer3.nim b/tests/iter/titer3.nim index ab95dd7bd..ab95dd7bd 100644 --- a/tests/run/titer3.nim +++ b/tests/iter/titer3.nim diff --git a/tests/reject/titer4.nim b/tests/iter/titer4.nim index 9b52f8055..9b52f8055 100644 --- a/tests/reject/titer4.nim +++ b/tests/iter/titer4.nim diff --git a/tests/run/titer5.nim b/tests/iter/titer5.nim index bbd50fcb1..bbd50fcb1 100644 --- a/tests/run/titer5.nim +++ b/tests/iter/titer5.nim diff --git a/tests/run/titer6.nim b/tests/iter/titer6.nim index dceace0e0..dceace0e0 100644 --- a/tests/run/titer6.nim +++ b/tests/iter/titer6.nim diff --git a/tests/run/titer7.nim b/tests/iter/titer7.nim index d0337b7bd..d0337b7bd 100644 --- a/tests/run/titer7.nim +++ b/tests/iter/titer7.nim diff --git a/tests/run/titer8.nim b/tests/iter/titer8.nim index af0e643f1..af0e643f1 100644 --- a/tests/run/titer8.nim +++ b/tests/iter/titer8.nim diff --git a/tests/run/titer9.nim b/tests/iter/titer9.nim index 99874e70a..99874e70a 100644 --- a/tests/run/titer9.nim +++ b/tests/iter/titer9.nim diff --git a/tests/compile/titer_no_tuple_unpack.nim b/tests/iter/titer_no_tuple_unpack.nim index da5e1bc46..da5e1bc46 100644 --- a/tests/compile/titer_no_tuple_unpack.nim +++ b/tests/iter/titer_no_tuple_unpack.nim diff --git a/tests/compile/titerovl.nim b/tests/iter/titerovl.nim index be665b2b7..be665b2b7 100644 --- a/tests/compile/titerovl.nim +++ b/tests/iter/titerovl.nim diff --git a/tests/run/titerslice.nim b/tests/iter/titerslice.nim index e5d2e14a3..e5d2e14a3 100644 --- a/tests/run/titerslice.nim +++ b/tests/iter/titerslice.nim diff --git a/tests/run/titervaropenarray.nim b/tests/iter/titervaropenarray.nim index 1e70ce247..1e70ce247 100644 --- a/tests/run/titervaropenarray.nim +++ b/tests/iter/titervaropenarray.nim diff --git a/tests/run/tmoditer.nim b/tests/iter/tmoditer.nim index 1e6be37e4..1e6be37e4 100644 --- a/tests/run/tmoditer.nim +++ b/tests/iter/tmoditer.nim diff --git a/tests/reject/treciter.nim b/tests/iter/treciter.nim index dacdbdfd7..dacdbdfd7 100644 --- a/tests/reject/treciter.nim +++ b/tests/iter/treciter.nim diff --git a/tests/reject/twrongiter.nim b/tests/iter/twrongiter.nim index 2d2502a6a..33394219b 100644 --- a/tests/reject/twrongiter.nim +++ b/tests/iter/twrongiter.nim @@ -1,5 +1,5 @@ discard """ -line: 14 +line: 12 errormsg: "type mismatch" """ diff --git a/tests/reject/tlet.nim b/tests/let/tlet.nim index 3d36432fb..3d36432fb 100644 --- a/tests/reject/tlet.nim +++ b/tests/let/tlet.nim diff --git a/tests/reject/tlet2.nim b/tests/let/tlet2.nim index 8b1ddf940..8b1ddf940 100644 --- a/tests/reject/tlet2.nim +++ b/tests/let/tlet2.nim diff --git a/tests/run/thexlit.nim b/tests/lexer/thexlit.nim index 04a530c9c..04a530c9c 100644 --- a/tests/run/thexlit.nim +++ b/tests/lexer/thexlit.nim diff --git a/tests/compile/thexrange.nim b/tests/lexer/thexrange.nim index e5e4c10c6..e5e4c10c6 100644 --- a/tests/compile/thexrange.nim +++ b/tests/lexer/thexrange.nim diff --git a/tests/compile/tident.nim b/tests/lexer/tident.nim index 1ed9894c6..1ed9894c6 100644 --- a/tests/compile/tident.nim +++ b/tests/lexer/tident.nim diff --git a/tests/reject/tind1.nim b/tests/lexer/tind1.nim index f3fd952cc..f3fd952cc 100644 --- a/tests/reject/tind1.nim +++ b/tests/lexer/tind1.nim diff --git a/tests/run/tindent1.nim b/tests/lexer/tindent1.nim index 78a303783..78a303783 100644 --- a/tests/run/tindent1.nim +++ b/tests/lexer/tindent1.nim diff --git a/tests/compile/tlexer.nim b/tests/lexer/tlexer.nim index 10a8ab51d..10a8ab51d 100644 --- a/tests/compile/tlexer.nim +++ b/tests/lexer/tlexer.nim diff --git a/tests/reject/tmissingnl.nim b/tests/lexer/tmissingnl.nim index 33b7debf1..33b7debf1 100644 --- a/tests/reject/tmissingnl.nim +++ b/tests/lexer/tmissingnl.nim diff --git a/tests/run/tstrlits.nim b/tests/lexer/tstrlits.nim index 1cd43975a..1cd43975a 100644 --- a/tests/run/tstrlits.nim +++ b/tests/lexer/tstrlits.nim diff --git a/tests/reject/tunderscores.nim b/tests/lexer/tunderscores.nim index 8075fdae4..8075fdae4 100644 --- a/tests/reject/tunderscores.nim +++ b/tests/lexer/tunderscores.nim diff --git a/tests/run/tkoeniglookup.nim b/tests/lookups/tkoeniglookup.nim index e6f5c0112..e6f5c0112 100644 --- a/tests/run/tkoeniglookup.nim +++ b/tests/lookups/tkoeniglookup.nim diff --git a/tests/compile/tredef.nim b/tests/lookups/tredef.nim index 02d1f7776..02d1f7776 100644 --- a/tests/compile/tredef.nim +++ b/tests/lookups/tredef.nim diff --git a/tests/compile/tdumpast.nim b/tests/macros/tdumpast.nim index 55a964327..55a964327 100644 --- a/tests/compile/tdumpast.nim +++ b/tests/macros/tdumpast.nim diff --git a/tests/compile/tdumpast2.nim b/tests/macros/tdumpast2.nim index c6eab39a9..c6eab39a9 100644 --- a/tests/compile/tdumpast2.nim +++ b/tests/macros/tdumpast2.nim diff --git a/tests/run/tdumptree.nim b/tests/macros/tdumptree.nim index 5299a94e3..5299a94e3 100644 --- a/tests/run/tdumptree.nim +++ b/tests/macros/tdumptree.nim diff --git a/tests/run/tidgen.nim b/tests/macros/tidgen.nim index 2fe9e0f82..2fe9e0f82 100644 --- a/tests/run/tidgen.nim +++ b/tests/macros/tidgen.nim diff --git a/tests/compile/tmacro1.nim b/tests/macros/tmacro1.nim index 3a67c2611..3a67c2611 100644 --- a/tests/compile/tmacro1.nim +++ b/tests/macros/tmacro1.nim diff --git a/tests/run/tmacro2.nim b/tests/macros/tmacro2.nim index 8515322d5..8515322d5 100644 --- a/tests/run/tmacro2.nim +++ b/tests/macros/tmacro2.nim diff --git a/tests/run/tmacro3.nim b/tests/macros/tmacro3.nim index 162212326..162212326 100644 --- a/tests/run/tmacro3.nim +++ b/tests/macros/tmacro3.nim diff --git a/tests/run/tmacro4.nim b/tests/macros/tmacro4.nim index 10a23b159..10a23b159 100644 --- a/tests/run/tmacro4.nim +++ b/tests/macros/tmacro4.nim diff --git a/tests/compile/tmacro2.nim b/tests/macros/tmacro5.nim index e7bc648db..39324e497 100644 --- a/tests/compile/tmacro2.nim +++ b/tests/macros/tmacro5.nim @@ -26,7 +26,7 @@ macro importImpl_forward(name, returns): stmt {.immediate.} = p2.add newIdentNode("errors") p2.add newNimNode(nnkVarTy) p2.add newNimNode(nnkEmpty) - p2[1].add newNimNOde(nnkBracketExpr) + p2[1].add newNimNode(nnkBracketExpr) p2[1][0].add newIdentNode("seq") p2[1][0].add newIdentNode("string") res[3].add p2 diff --git a/tests/compile/tmacroaspragma.nim b/tests/macros/tmacroaspragma.nim index 0e5c352b3..0e5c352b3 100644 --- a/tests/compile/tmacroaspragma.nim +++ b/tests/macros/tmacroaspragma.nim diff --git a/tests/run/tmacrogenerics.nim b/tests/macros/tmacrogenerics.nim index 5ae59e0da..5ae59e0da 100644 --- a/tests/run/tmacrogenerics.nim +++ b/tests/macros/tmacrogenerics.nim diff --git a/tests/run/tmacros1.nim b/tests/macros/tmacros1.nim index 3c814ad6d..3c814ad6d 100644 --- a/tests/run/tmacros1.nim +++ b/tests/macros/tmacros1.nim diff --git a/tests/compile/tmacrostmt.nim b/tests/macros/tmacrostmt.nim index d9c70197d..d9c70197d 100644 --- a/tests/compile/tmacrostmt.nim +++ b/tests/macros/tmacrostmt.nim diff --git a/tests/compile/tmacrotypes.nim b/tests/macros/tmacrotypes.nim index 7697dba27..7697dba27 100644 --- a/tests/compile/tmacrotypes.nim +++ b/tests/macros/tmacrotypes.nim diff --git a/tests/compile/tnimrodnode_for_runtime.nim b/tests/macros/tnimrodnode_for_runtime.nim index e73c8430f..e73c8430f 100644 --- a/tests/compile/tnimrodnode_for_runtime.nim +++ b/tests/macros/tnimrodnode_for_runtime.nim diff --git a/tests/run/tprintf.nim b/tests/macros/tprintf.nim index c8fb51cdc..c8fb51cdc 100644 --- a/tests/run/tprintf.nim +++ b/tests/macros/tprintf.nim diff --git a/tests/run/tquotewords.nim b/tests/macros/tquotewords.nim index 76b8d8af7..76b8d8af7 100644 --- a/tests/run/tquotewords.nim +++ b/tests/macros/tquotewords.nim diff --git a/tests/reject/trecmacro.nim b/tests/macros/trecmacro.nim index 28b6db530..28b6db530 100644 --- a/tests/reject/trecmacro.nim +++ b/tests/macros/trecmacro.nim diff --git a/tests/run/tstringinterp.nim b/tests/macros/tstringinterp.nim index f030213e0..f030213e0 100644 --- a/tests/run/tstringinterp.nim +++ b/tests/macros/tstringinterp.nim diff --git a/tests/run/tvtable.nim b/tests/macros/tvtable.nim index 51894618c..51894618c 100644 --- a/tests/run/tvtable.nim +++ b/tests/macros/tvtable.nim diff --git a/tests/run/tlowhigh.nim b/tests/magics/tlowhigh.nim index d1cbd3272..d1cbd3272 100644 --- a/tests/run/tlowhigh.nim +++ b/tests/magics/tlowhigh.nim diff --git a/tests/run/tmatrix.nim b/tests/matrix/tmatrix.nim index 90dfde959..90dfde959 100644 --- a/tests/run/tmatrix.nim +++ b/tests/matrix/tmatrix.nim diff --git a/tests/compile/tmatrix1.nim b/tests/matrix/tmatrix1.nim index 0adf30b57..0adf30b57 100644 --- a/tests/compile/tmatrix1.nim +++ b/tests/matrix/tmatrix1.nim diff --git a/tests/compile/tmatrix2.nim b/tests/matrix/tmatrix2.nim index 442096e93..442096e93 100644 --- a/tests/compile/tmatrix2.nim +++ b/tests/matrix/tmatrix2.nim diff --git a/tests/metatype/tbindtypedesc.nim b/tests/metatype/tbindtypedesc.nim new file mode 100644 index 000000000..5ea8cf063 --- /dev/null +++ b/tests/metatype/tbindtypedesc.nim @@ -0,0 +1,91 @@ +discard """ + msg: ''' +int +float +TFoo +TFoo +''' +""" + +import typetraits + +type + TFoo = object + x, y: int + + TBar = tuple + x, y: int + +template accept(e: expr) = + static: assert(compiles(e)) + +template reject(e: expr) = + static: assert(not compiles(e)) + +proc genericParamRepeated[T: typedesc](a: T, b: T) = + static: + echo a.name + echo b.name + +accept genericParamRepeated(int, int) +accept genericParamRepeated(float, float) + +reject genericParamRepeated(string, int) +reject genericParamRepeated(int, float) + +proc genericParamOnce[T: typedesc](a, b: T) = + static: + echo a.name + echo b.name + +accept genericParamOnce(int, int) +accept genericParamOnce(TFoo, TFoo) + +reject genericParamOnce(string, int) +reject genericParamOnce(TFoo, float) + +type + type1 = typedesc + type2 = typedesc + +proc typePairs(A, B: type1; C, D: type2) = nil + +accept typePairs(int, int, TFoo, TFOO) +accept typePairs(TBAR, TBar, TBAR, TBAR) +accept typePairs(int, int, string, string) + +reject typePairs(TBAR, TBar, TBar, TFoo) +reject typePairs(string, int, TBAR, TBAR) + +proc typePairs2[T: typedesc, U: typedesc](A, B: T; C, D: U) = nil + +accept typePairs2(int, int, TFoo, TFOO) +accept typePairs2(TBAR, TBar, TBAR, TBAR) +accept typePairs2(int, int, string, string) + +reject typePairs2(TBAR, TBar, TBar, TFoo) +reject typePairs2(string, int, TBAR, TBAR) + +proc dontBind(a: typedesc, b: typedesc) = + static: + echo a.name + echo b.name + +accept dontBind(int, float) +accept dontBind(TFoo, TFoo) + +proc dontBind2(a, b: typedesc) = nil + +accept dontBind2(int, float) +accept dontBind2(TBar, int) + +proc bindArg(T: typedesc, U: typedesc, a, b: T, c, d: U) = nil + +accept bindArg(int, string, 10, 20, "test", "nest") +accept bindArg(int, int, 10, 20, 30, 40) + +reject bindArg(int, string, 10, "test", "test", "nest") +reject bindArg(int, int, 10, 20, 30, "test") +reject bindArg(int, string, 10.0, 20, "test", "nest") +reject bindArg(int, string, "test", "nest", 10, 20) + diff --git a/tests/metatype/tcompositetypeclasses.nim b/tests/metatype/tcompositetypeclasses.nim new file mode 100644 index 000000000..a2db73769 --- /dev/null +++ b/tests/metatype/tcompositetypeclasses.nim @@ -0,0 +1,59 @@ +template accept(e) = + static: assert(compiles(e)) + +template reject(e) = + static: assert(not compiles(e)) + +type + TFoo[T, U] = tuple + x: T + y: U + + TBar[K] = TFoo[K, K] + + TUserClass = int|string + + TBaz = TBar[TUserClass] + +var + vfoo: TFoo[int, string] + vbar: TFoo[string, string] + vbaz: TFoo[int, int] + vnotbaz: TFoo[TObject, TObject] + +proc foo(x: TFoo) = echo "foo" +proc bar(x: TBar) = echo "bar" +proc baz(x: TBaz) = echo "baz" + +accept foo(vfoo) +accept bar(vbar) +accept baz(vbar) +accept baz(vbaz) + +reject baz(vnotbaz) +reject bar(vfoo) + +# https://github.com/Araq/Nimrod/issues/517 +type + TVecT*[T] = array[0..1, T]|array[0..2, T]|array[0..3, T] + TVec2* = array[0..1, float32] + +proc f[T](a: TVecT[T], b: TVecT[T]): T = discard + +var x: float = f([0.0'f32, 0.0'f32], [0.0'f32, 0.0'f32]) +var y = f(TVec2([0.0'f32, 0.0'f32]), TVec2([0.0'f32, 0.0'f32])) + +# https://github.com/Araq/Nimrod/issues/602 +type + TTest = object + TTest2* = object + TUnion = TTest | TTest2 + +proc f(src: ptr TUnion, dst: ptr TUnion) = + echo("asd") + +var tx: TTest +var ty: TTest2 + +accept f(addr tx, addr tx) +reject f(addr tx, addr ty) diff --git a/tests/compile/tconstraints.nim b/tests/metatype/tconstraints.nim index 7aef0d645..7aef0d645 100644 --- a/tests/compile/tconstraints.nim +++ b/tests/metatype/tconstraints.nim diff --git a/tests/metatype/tsemistatic.nim b/tests/metatype/tsemistatic.nim new file mode 100644 index 000000000..d187f153c --- /dev/null +++ b/tests/metatype/tsemistatic.nim @@ -0,0 +1,24 @@ +discard """ + msg: "static 10\ndynamic\nstatic 20\n" + output: "s\nd\nd\ns" +""" + +proc foo(x: semistatic[int]) = + when isStatic(x): + static: echo "static ", x + echo "s" + else: + static: echo "dynamic" + echo "d" + +foo 10 + +var + x = 10 + y: int + +foo x +foo y + +foo 20 + diff --git a/tests/metatype/ttypebar.nim b/tests/metatype/ttypebar.nim new file mode 100644 index 000000000..304dfffcb --- /dev/null +++ b/tests/metatype/ttypebar.nim @@ -0,0 +1,14 @@ + +# bug #602 + +type + TTest = object + TTest2* = object + TFoo = TTest | TTest2 + +proc f(src: ptr TFoo, dst: ptr TFoo) = + echo("asd") + +var x: TTest +f(addr x, addr x) + diff --git a/tests/compile/ttypeclasses.nim b/tests/metatype/ttypeclasses.nim index 677229868..677229868 100644 --- a/tests/compile/ttypeclasses.nim +++ b/tests/metatype/ttypeclasses.nim diff --git a/tests/run/ttypedesc1.nim b/tests/metatype/ttypedesc1.nim index 0c6f5dce4..0c6f5dce4 100644 --- a/tests/run/ttypedesc1.nim +++ b/tests/metatype/ttypedesc1.nim diff --git a/tests/compile/ttypeselectors.nim b/tests/metatype/ttypeselectors.nim index cca643e1f..cca643e1f 100644 --- a/tests/compile/ttypeselectors.nim +++ b/tests/metatype/ttypeselectors.nim diff --git a/tests/run/ttypetraits.nim b/tests/metatype/ttypetraits.nim index 9a4a7d0d3..4344855eb 100644 --- a/tests/run/ttypetraits.nim +++ b/tests/metatype/ttypetraits.nim @@ -1,6 +1,6 @@ discard """ msg: "int\nstring\nTBar[int]" - output: "int\nstring\nTBar[int]\nint\nrange 0..2\nstring" + output: "int\nstring\nTBar[int]\nint\nrange 0..2(int)\nstring" """ import typetraits diff --git a/tests/run/tusertypeclasses.nim b/tests/metatype/tusertypeclasses.nim index 4c2f07b85..4c2f07b85 100644 --- a/tests/run/tusertypeclasses.nim +++ b/tests/metatype/tusertypeclasses.nim diff --git a/tests/run/utypeclasses.nim b/tests/metatype/utypeclasses.nim index 06bab375e..06bab375e 100644 --- a/tests/run/utypeclasses.nim +++ b/tests/metatype/utypeclasses.nim diff --git a/tests/run/mmultim3.nim b/tests/method/mmultim3.nim index 3139a8089..3139a8089 100644 --- a/tests/run/mmultim3.nim +++ b/tests/method/mmultim3.nim diff --git a/tests/reject/tmethod.nim b/tests/method/tmethod.nim index 0cfe24c70..0cfe24c70 100644 --- a/tests/reject/tmethod.nim +++ b/tests/method/tmethod.nim diff --git a/tests/run/tmethods1.nim b/tests/method/tmethods1.nim index f4add6af4..f4add6af4 100644 --- a/tests/run/tmethods1.nim +++ b/tests/method/tmethods1.nim diff --git a/tests/run/tmultim1.nim b/tests/method/tmultim1.nim index 7f551aa64..7f551aa64 100644 --- a/tests/run/tmultim1.nim +++ b/tests/method/tmultim1.nim diff --git a/tests/run/tmultim2.nim b/tests/method/tmultim2.nim index 75f652137..75f652137 100644 --- a/tests/run/tmultim2.nim +++ b/tests/method/tmultim2.nim diff --git a/tests/run/tmultim3.nim b/tests/method/tmultim3.nim index 373c84c0e..373c84c0e 100644 --- a/tests/run/tmultim3.nim +++ b/tests/method/tmultim3.nim diff --git a/tests/run/tmultim4.nim b/tests/method/tmultim4.nim index d824086b2..d824086b2 100644 --- a/tests/run/tmultim4.nim +++ b/tests/method/tmultim4.nim diff --git a/tests/run/tmultim6.nim b/tests/method/tmultim6.nim index 5f45f572a..5f45f572a 100644 --- a/tests/run/tmultim6.nim +++ b/tests/method/tmultim6.nim diff --git a/tests/run/tsimmeth.nim b/tests/method/tsimmeth.nim index 11ff2674f..11ff2674f 100644 --- a/tests/run/tsimmeth.nim +++ b/tests/method/tsimmeth.nim diff --git a/tests/reject/mopaque.nim b/tests/module/mopaque.nim index 7eee4bd96..7eee4bd96 100644 --- a/tests/reject/mopaque.nim +++ b/tests/module/mopaque.nim diff --git a/tests/compile/mrecmod.nim b/tests/module/mrecmod.nim index fab9654d5..fab9654d5 100644 --- a/tests/compile/mrecmod.nim +++ b/tests/module/mrecmod.nim diff --git a/tests/compile/mrecmod2.nim b/tests/module/mrecmod2.nim index 9557ce729..9557ce729 100644 --- a/tests/compile/mrecmod2.nim +++ b/tests/module/mrecmod2.nim diff --git a/tests/reject/topaque.nim b/tests/module/topaque.nim index f0587c959..f0587c959 100644 --- a/tests/reject/topaque.nim +++ b/tests/module/topaque.nim diff --git a/tests/reject/trecinca.nim b/tests/module/trecinca.nim index 73a0ec937..73a0ec937 100644 --- a/tests/reject/trecinca.nim +++ b/tests/module/trecinca.nim diff --git a/tests/reject/trecincb.nim b/tests/module/trecincb.nim index 9dd7d51de..9dd7d51de 100644 --- a/tests/reject/trecincb.nim +++ b/tests/module/trecincb.nim diff --git a/tests/compile/trecmod.nim b/tests/module/trecmod.nim index 9d39d3ff7..9d39d3ff7 100644 --- a/tests/compile/trecmod.nim +++ b/tests/module/trecmod.nim diff --git a/tests/compile/trecmod2.nim b/tests/module/trecmod2.nim index 85fe2215f..85fe2215f 100644 --- a/tests/compile/trecmod2.nim +++ b/tests/module/trecmod2.nim diff --git a/tests/compile/mexporta.nim b/tests/modules/mexporta.nim index b7d4ddec9..b7d4ddec9 100644 --- a/tests/compile/mexporta.nim +++ b/tests/modules/mexporta.nim diff --git a/tests/compile/mexportb.nim b/tests/modules/mexportb.nim index 10d89f388..10d89f388 100644 --- a/tests/compile/mexportb.nim +++ b/tests/modules/mexportb.nim diff --git a/tests/compile/texport.nim b/tests/modules/texport.nim index 99228dfce..99228dfce 100644 --- a/tests/compile/texport.nim +++ b/tests/modules/texport.nim diff --git a/tests/reject/timportexcept.nim b/tests/modules/timportexcept.nim index 93a7fd642..93a7fd642 100644 --- a/tests/reject/timportexcept.nim +++ b/tests/modules/timportexcept.nim diff --git a/tests/reject/tnamedparams.nim b/tests/namedparams/tnamedparams.nim index 9397fea4a..9397fea4a 100644 --- a/tests/reject/tnamedparams.nim +++ b/tests/namedparams/tnamedparams.nim diff --git a/tests/compile/tnamedparams.nim b/tests/namedparams/tnamedparams2.nim index 4b0cd5361..4b0cd5361 100644 --- a/tests/compile/tnamedparams.nim +++ b/tests/namedparams/tnamedparams2.nim diff --git a/tests/reject/mnamspc1.nim b/tests/namspc/mnamspc1.nim index da13c5f24..da13c5f24 100644 --- a/tests/reject/mnamspc1.nim +++ b/tests/namspc/mnamspc1.nim diff --git a/tests/reject/mnamspc2.nim b/tests/namspc/mnamspc2.nim index 84ef8533e..84ef8533e 100644 --- a/tests/reject/mnamspc2.nim +++ b/tests/namspc/mnamspc2.nim diff --git a/tests/reject/tnamspc.nim b/tests/namspc/tnamspc.nim index 1e2049cec..1e2049cec 100644 --- a/tests/reject/tnamspc.nim +++ b/tests/namspc/tnamspc.nim diff --git a/tests/reject/tnotnil.nim b/tests/notnil/tnotnil.nim index fba7fa917..fba7fa917 100644 --- a/tests/reject/tnotnil.nim +++ b/tests/notnil/tnotnil.nim diff --git a/tests/reject/tnotnil1.nim b/tests/notnil/tnotnil1.nim index 863fe45f8..863fe45f8 100644 --- a/tests/reject/tnotnil1.nim +++ b/tests/notnil/tnotnil1.nim diff --git a/tests/reject/tnotnil2.nim b/tests/notnil/tnotnil2.nim index bd6b8b675..bd6b8b675 100644 --- a/tests/reject/tnotnil2.nim +++ b/tests/notnil/tnotnil2.nim diff --git a/tests/run/tobjconstr.nim b/tests/object/tobjconstr.nim index 3bd785728..3bd785728 100644 --- a/tests/run/tobjconstr.nim +++ b/tests/object/tobjconstr.nim diff --git a/tests/compile/tobjconstr2.nim b/tests/object/tobjconstr2.nim index cb47e146d..cb47e146d 100644 --- a/tests/compile/tobjconstr2.nim +++ b/tests/object/tobjconstr2.nim diff --git a/tests/compile/tobjcov.nim b/tests/object/tobjcov.nim index fc44edf8e..fc44edf8e 100644 --- a/tests/compile/tobjcov.nim +++ b/tests/object/tobjcov.nim diff --git a/tests/run/tobject.nim b/tests/object/tobject.nim index 5fec84441..5fec84441 100644 --- a/tests/run/tobject.nim +++ b/tests/object/tobject.nim diff --git a/tests/compile/tobject2.nim b/tests/object/tobject2.nim index 0f1869695..0f1869695 100644 --- a/tests/compile/tobject2.nim +++ b/tests/object/tobject2.nim diff --git a/tests/compile/tobject3.nim b/tests/object/tobject3.nim index 935e6ca8c..935e6ca8c 100644 --- a/tests/compile/tobject3.nim +++ b/tests/object/tobject3.nim diff --git a/tests/compile/toop.nim b/tests/object/toop.nim index 0b42c2c22..0b42c2c22 100644 --- a/tests/compile/toop.nim +++ b/tests/object/toop.nim diff --git a/tests/run/toop1.nim b/tests/object/toop1.nim index 350799f51..350799f51 100644 --- a/tests/run/toop1.nim +++ b/tests/object/toop1.nim diff --git a/tests/compile/tobjects.nim b/tests/objects/tobjects.nim index 06fa15583..06fa15583 100644 --- a/tests/compile/tobjects.nim +++ b/tests/objects/tobjects.nim diff --git a/tests/reject/tadrdisc.nim b/tests/objvariant/tadrdisc.nim index 0e0324562..0e0324562 100644 --- a/tests/reject/tadrdisc.nim +++ b/tests/objvariant/tadrdisc.nim diff --git a/tests/reject/tcheckedfield1.nim b/tests/objvariant/tcheckedfield1.nim index 5ade3a13a..5ade3a13a 100644 --- a/tests/reject/tcheckedfield1.nim +++ b/tests/objvariant/tcheckedfield1.nim diff --git a/tests/reject/temptycaseobj.nim b/tests/objvariant/temptycaseobj.nim index 5c012746e..5c012746e 100644 --- a/tests/reject/temptycaseobj.nim +++ b/tests/objvariant/temptycaseobj.nim diff --git a/tests/run/tvariantstack.nim b/tests/objvariant/tvariantstack.nim index d81f6e001..d81f6e001 100644 --- a/tests/run/tvariantstack.nim +++ b/tests/objvariant/tvariantstack.nim diff --git a/tests/reject/topena1.nim b/tests/openarray/topena1.nim index 0dbc5506a..0dbc5506a 100644 --- a/tests/reject/topena1.nim +++ b/tests/openarray/topena1.nim diff --git a/tests/run/topenarrayrepr.nim b/tests/openarray/topenarrayrepr.nim index d276756bc..d276756bc 100644 --- a/tests/run/topenarrayrepr.nim +++ b/tests/openarray/topenarrayrepr.nim diff --git a/tests/run/topenlen.nim b/tests/openarray/topenlen.nim index fec8e87b7..fec8e87b7 100644 --- a/tests/run/topenlen.nim +++ b/tests/openarray/topenlen.nim diff --git a/tests/run/tofopr.nim b/tests/operator/tofopr.nim index 961d81bd3..961d81bd3 100644 --- a/tests/run/tofopr.nim +++ b/tests/operator/tofopr.nim diff --git a/tests/run/toprprec.nim b/tests/operator/toprprec.nim index ce33934b5..ce33934b5 100644 --- a/tests/run/toprprec.nim +++ b/tests/operator/toprprec.nim diff --git a/tests/run/tprecedence.nim b/tests/operator/tprecedence.nim index 6b1b250a2..6b1b250a2 100644 --- a/tests/run/tprecedence.nim +++ b/tests/operator/tprecedence.nim diff --git a/tests/run/toverflw.nim b/tests/overflw/toverflw.nim index cd7b65acf..cd7b65acf 100644 --- a/tests/run/toverflw.nim +++ b/tests/overflw/toverflw.nim diff --git a/tests/run/toverflw2.nim b/tests/overflw/toverflw2.nim index f7fe3d574..f7fe3d574 100644 --- a/tests/run/toverflw2.nim +++ b/tests/overflw/toverflw2.nim diff --git a/tests/run/tovfint.nim b/tests/overflw/tovfint.nim index f0b1ccaa6..f0b1ccaa6 100644 --- a/tests/run/tovfint.nim +++ b/tests/overflw/tovfint.nim diff --git a/tests/reject/toverl.nim b/tests/overload/toverl.nim index 807b643a4..807b643a4 100644 --- a/tests/reject/toverl.nim +++ b/tests/overload/toverl.nim diff --git a/tests/run/toverl2.nim b/tests/overload/toverl2.nim index ea0249e9f..ea0249e9f 100644 --- a/tests/run/toverl2.nim +++ b/tests/overload/toverl2.nim diff --git a/tests/run/toverl3.nim b/tests/overload/toverl3.nim index b3e0f2fa7..b3e0f2fa7 100644 --- a/tests/run/toverl3.nim +++ b/tests/overload/toverl3.nim diff --git a/tests/compile/toverprc.nim b/tests/overload/toverprc.nim index 22b64ed48..22b64ed48 100644 --- a/tests/compile/toverprc.nim +++ b/tests/overload/toverprc.nim diff --git a/tests/run/toverwr.nim b/tests/overload/toverwr.nim index ef25e8913..ef25e8913 100644 --- a/tests/run/toverwr.nim +++ b/tests/overload/toverwr.nim diff --git a/tests/run/tpatterns.nim b/tests/pattern/tpatterns.nim index 6bc8772e3..6bc8772e3 100644 --- a/tests/run/tpatterns.nim +++ b/tests/pattern/tpatterns.nim diff --git a/tests/patterns/tor.nim b/tests/patterns/tor.nim index 7de1a7fa1..833418919 100644 --- a/tests/patterns/tor.nim +++ b/tests/patterns/tor.nim @@ -1,5 +1,5 @@ discard """ - output: '''110 + output: '''3060 true''' """ diff --git a/tests/compile/tuserpragma.nim b/tests/pragma/tuserpragma.nim index 784baa176..784baa176 100644 --- a/tests/compile/tuserpragma.nim +++ b/tests/pragma/tuserpragma.nim diff --git a/tests/compile/tpush.nim b/tests/pragmas/tpush.nim index 5fb411a79..5fb411a79 100644 --- a/tests/compile/tpush.nim +++ b/tests/pragmas/tpush.nim diff --git a/tests/run/tnestprc.nim b/tests/proc/tnestprc.nim index c10ad6abf..c10ad6abf 100644 --- a/tests/run/tnestprc.nim +++ b/tests/proc/tnestprc.nim diff --git a/tests/reject/tprocredef.nim b/tests/proc/tprocredef.nim index 86ed92b62..86ed92b62 100644 --- a/tests/reject/tprocredef.nim +++ b/tests/proc/tprocredef.nim diff --git a/tests/compile/tgenericprocvar.nim b/tests/procvar/tgenericprocvar.nim index e642e3577..e642e3577 100644 --- a/tests/compile/tgenericprocvar.nim +++ b/tests/procvar/tgenericprocvar.nim diff --git a/tests/reject/tprocvar.nim b/tests/procvar/tprocvar.nim index 56f76c613..56f76c613 100644 --- a/tests/reject/tprocvar.nim +++ b/tests/procvar/tprocvar.nim diff --git a/tests/run/tprocvar.nim b/tests/procvar/tprocvar2.nim index 237e2ef7a..237e2ef7a 100644 --- a/tests/run/tprocvar.nim +++ b/tests/procvar/tprocvar2.nim diff --git a/tests/compile/tprocvars.nim b/tests/procvar/tprocvars.nim index dc7592526..dc7592526 100644 --- a/tests/compile/tprocvars.nim +++ b/tests/procvar/tprocvars.nim diff --git a/tests/range/compilehelpers.nim b/tests/range/compilehelpers.nim new file mode 100644 index 000000000..cb26ca5b5 --- /dev/null +++ b/tests/range/compilehelpers.nim @@ -0,0 +1,6 @@ +template accept(e: expr) = + static: assert(compiles(e)) + +template reject(e: expr) = + static: assert(not compiles(e)) + diff --git a/tests/run/tbug499771.nim b/tests/range/tbug499771.nim index 682148422..682148422 100644 --- a/tests/run/tbug499771.nim +++ b/tests/range/tbug499771.nim diff --git a/tests/compile/tcolors.nim b/tests/range/tcolors.nim index 9d1034405..9d1034405 100644 --- a/tests/compile/tcolors.nim +++ b/tests/range/tcolors.nim diff --git a/tests/range/tmatrix3.nim b/tests/range/tmatrix3.nim new file mode 100644 index 000000000..900404524 --- /dev/null +++ b/tests/range/tmatrix3.nim @@ -0,0 +1,41 @@ +discard """ + output: '''0.0000000000000000e+00 +0.0000000000000000e+00 +0 +0 +0 +''' +""" + +include compilehelpers + +type + Matrix*[M, N, T] = object + aij*: array[M, array[N, T]] + + Matrix2*[T] = Matrix[range[0..1], range[0..1], T] + + Matrix3*[T] = Matrix[range[0..2], range[0..2], T] + +proc mn(x: Matrix): Matrix.T = x.aij[0][0] + +proc m2(x: Matrix2): Matrix2.T = x.aij[0][0] + +proc m3(x: Matrix3): auto = x.aij[0][0] + +var + matn: Matrix[range[0..3], range[0..2], int] + mat2: Matrix2[int] + mat3: Matrix3[float] + +echo m3(mat3) +echo mn(mat3) +echo m2(mat2) +echo mn(mat2) +echo mn(matn) + +reject m3(mat2) +reject m3(matn) +reject m2(mat3) +reject m2(matn) + diff --git a/tests/reject/tsubrange.nim b/tests/range/tsubrange.nim index b4a333bf3..b4a333bf3 100644 --- a/tests/reject/tsubrange.nim +++ b/tests/range/tsubrange.nim diff --git a/tests/run/tsubrange2.nim b/tests/range/tsubrange2.nim index 51598713b..51598713b 100644 --- a/tests/run/tsubrange2.nim +++ b/tests/range/tsubrange2.nim diff --git a/tests/run/tsubrange.nim b/tests/range/tsubrange3.nim index b3e02fd29..b3e02fd29 100644 --- a/tests/run/tsubrange.nim +++ b/tests/range/tsubrange3.nim diff --git a/tests/reject/99bottles.nim b/tests/reject/99bottles.nim deleted file mode 100644 index 14904ac0f..000000000 --- a/tests/reject/99bottles.nim +++ /dev/null @@ -1 +0,0 @@ -# Test if the compiler detects invalid module names diff --git a/tests/reject/mbind4.nim b/tests/reject/mbind4.nim deleted file mode 100644 index 53b8331cd..000000000 --- a/tests/reject/mbind4.nim +++ /dev/null @@ -1,9 +0,0 @@ -# Module A -var - lastId = 0 - -template genId*: expr = - inc(lastId) - lastId - - diff --git a/tests/reject/t99bott.nim b/tests/reject/t99bott.nim deleted file mode 100644 index 7ebfd61e9..000000000 --- a/tests/reject/t99bott.nim +++ /dev/null @@ -1,36 +0,0 @@ -discard """ - file: "t99bott.nim" - line: 26 - errormsg: "constant expression expected" - disabled: false -""" -## 99 Bottles of Beer -## http://www.99-bottles-of-beer.net/ -## Nimrod version - -## Author: Philippe Lhoste <PhiLho(a)GMX.net> http://Phi.Lho.free.fr -# 2012-11-25 -# Loosely based on my old Lua version... Updated to current official lyrics. - -proc GetBottleNumber(n: int): string = - var bs: string - if n == 0: - bs = "No more bottles" - elif n == 1: - bs = "1 bottle" - else: - bs = $n & " bottles" - return bs & " of beer" - -for bn in countdown(99, 1): - const cur = GetBottleNumber(bn) - echo(cur, " on the wall, ", cur, ".") - echo("Take one down and pass it around, ", GetBottleNumber(bn-1), - " on the wall.\n") - -echo "No more bottles of beer on the wall, no more bottles of beer." -echo "Go to the store and buy some more, 99 bottles of beer on the wall." - - - - diff --git a/tests/reject/tatomic.nim b/tests/reject/tatomic.nim deleted file mode 100644 index 1fa0cff8d..000000000 --- a/tests/reject/tatomic.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - file: "tatomic.nim" - line: 7 - errormsg: "identifier expected, but found 'keyword atomic'" -""" -var - atomic: int - -echo atomic - - - diff --git a/tests/reject/tbind4.nim b/tests/reject/tbind4.nim deleted file mode 100644 index a0ba88e7c..000000000 --- a/tests/reject/tbind4.nim +++ /dev/null @@ -1,13 +0,0 @@ -discard """ - file: "mbind4.nim" - line: 6 - errormsg: "undeclared identifier: \'lastId\'" -""" -# Module B -import mbind4 - -echo genId() - - - - diff --git a/tests/reject/tgenconstraints.nim b/tests/reject/tgenconstraints.nim deleted file mode 100644 index e32aa877b..000000000 --- a/tests/reject/tgenconstraints.nim +++ /dev/null @@ -1,30 +0,0 @@ -discard """ - file: "tgenconstraints.nim" - line: 25 - errormsg: "cannot instantiate T2" -""" - -type - T1[T: int|string] = object - x: T - - T2[T: Ordinal] = object - x: T - -var x1: T1[int] -var x2: T1[string] -var x3: T2[int] - -proc foo[T](x: T): T2[T] {.discardable.} = - var o: T1[T] - -foo(10) - -proc bar(x: string|TNumber): T1[type(x)] {.discardable.} = - when type(x) is TNumber: - var o: T2[type(x)] - -bar "test" -bar 100 -bar 1.1 - diff --git a/tests/reject/tinc.nim b/tests/reject/tinc.nim deleted file mode 100644 index 8038a2a01..000000000 --- a/tests/reject/tinc.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - file: "tinc.nim" - line: 8 - errormsg: "for a \'var\' type a variable needs to be passed" -""" -var x = 0 - -inc(x+1) - - - - diff --git a/tests/reject/tinout.nim b/tests/reject/tinout.nim deleted file mode 100644 index 034c496f5..000000000 --- a/tests/reject/tinout.nim +++ /dev/null @@ -1,16 +0,0 @@ -discard """ - file: "tinout.nim" - line: 12 - errormsg: "for a \'var\' type a variable needs to be passed" -""" -# Test in out checking for parameters - -proc abc(x: var int) = - x = 0 - -proc b() = - abc(3) #ERROR - -b() - - diff --git a/tests/reject/tinvalidarrayaccess.nim b/tests/reject/tinvalidarrayaccess.nim deleted file mode 100644 index 03105b41b..000000000 --- a/tests/reject/tinvalidarrayaccess.nim +++ /dev/null @@ -1,14 +0,0 @@ -discard """ - errormsg: "index out of bounds" - line: 11 -""" - - -type TTestArr = array[0..1, int16] -var f: TTestArr -f[0] = 30 -f[1] = 40 -f[2] = 50 -f[3] = 60 - -echo(repr(f)) diff --git a/tests/reject/tinvalidnewseq.nim b/tests/reject/tinvalidnewseq.nim deleted file mode 100644 index 957a25560..000000000 --- a/tests/reject/tinvalidnewseq.nim +++ /dev/null @@ -1,27 +0,0 @@ -discard """ - file: "tinvalidnewseq.nim" - line: 15 - errormsg: "type mismatch: got (array[0..6, string], int literal(7))" -""" -import re, strutils - -type - TURL = tuple[protocol, subdomain, domain, port: string, path: seq[string]] - -proc parseURL(url: string): TURL = - #([a-zA-Z]+://)?(\w+?\.)?(\w+)(\.\w+)(:[0-9]+)?(/.+)? - var pattern: string = r"([a-zA-Z]+://)?(\w+?\.)?(\w+)(\.\w+)(:[0-9]+)?(/.+)?" - var m: array[0..6, string] #Array with the matches - newSeq(m, 7) #ERROR - discard regexprs.match(url, re(pattern), m) - - result = (protocol: m[1], subdomain: m[2], domain: m[3] & m[4], - port: m[5], path: m[6].split('/')) - -var r: TUrl - -r = parseUrl(r"http://google.com/search?var=bleahdhsad") -echo(r.domain) - - - diff --git a/tests/reject/tinvwhen.nim b/tests/reject/tinvwhen.nim deleted file mode 100644 index ea8a7ddf0..000000000 --- a/tests/reject/tinvwhen.nim +++ /dev/null @@ -1,15 +0,0 @@ -discard """ - file: "tinvwhen.nim" - line: 11 - errormsg: "invalid indentation" -""" -# This was parsed even though it should not! - -proc chdir(path: CString): cint {.importc: "chdir", header: "dirHeader".} - -proc getcwd(buf: CString, buflen: cint): CString - when defined(unix): {.importc: "getcwd", header: "<unistd.h>".} #ERROR_MSG invalid indentation - elif defined(windows): {.importc: "getcwd", header: "<direct.h>"} - else: {.error: "os library not ported to your OS. Please help!".} - - diff --git a/tests/reject/tnoinst.nim b/tests/reject/tnoinst.nim deleted file mode 100644 index 23a4145e0..000000000 --- a/tests/reject/tnoinst.nim +++ /dev/null @@ -1,16 +0,0 @@ -discard """ - line: 12 - errormsg: "instantiate 'notConcrete' explicitely" -""" - -proc wrap[T]() = - proc notConcrete[T](x, y: int): int = - var dummy: T - result = x - y - - var x: proc (x, y: T): int - x = notConcrete - - -wrap[int]() - diff --git a/tests/reject/tnolen.nim b/tests/reject/tnolen.nim deleted file mode 100644 index e33086536..000000000 --- a/tests/reject/tnolen.nim +++ /dev/null @@ -1,9 +0,0 @@ -discard """ - line: 8 - msg: "type mismatch: got (int literal(3))" -""" - -# please finally disallow Len(3) - -echo len(3) - diff --git a/tests/reject/tnoop.nim b/tests/reject/tnoop.nim deleted file mode 100644 index c79403e11..000000000 --- a/tests/reject/tnoop.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - file: "tnoop.nim" - line: 11 - errormsg: "expression \'a()\' cannot be called" -""" -# Tests the new check in the semantic pass - -var - a: int - -a() #ERROR_MSG expression 'a()' cannot be called - diff --git a/tests/reject/tnot.nim b/tests/reject/tnot.nim deleted file mode 100644 index 1985ef666..000000000 --- a/tests/reject/tnot.nim +++ /dev/null @@ -1,21 +0,0 @@ -discard """ - file: "system.nim" - errormsg: "type mismatch" -""" -# BUG: following compiles, but should not: - -proc nodeOfDegree(x: Int): bool = - result = false - -proc main = - for j in 0..2: - for i in 0..10: - if not nodeOfDegree(1) >= 0: #ERROR_MSG type mismatch - Echo "Yes" - else: - Echo "No" - -main() - - - diff --git a/tests/reject/trawstr.nim b/tests/reject/trawstr.nim deleted file mode 100644 index ab2aae159..000000000 --- a/tests/reject/trawstr.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - file: "trawstr.nim" - line: 10 - errormsg: "closing \" expected" -""" -# Test the new raw strings: - -const - xxx = r"This is a raw string!" - yyy = "This not\" #ERROR - - diff --git a/tests/reject/tsimtych.nim b/tests/reject/tsimtych.nim deleted file mode 100644 index dd969958c..000000000 --- a/tests/reject/tsimtych.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - file: "tsimtych.nim" - line: 10 - errormsg: "type mismatch: got (bool) but expected \'string\'" -""" -# Test 2 -# Simple type checking - -var a: string -a = false #ERROR - - diff --git a/tests/run/globalaux.nim b/tests/run/globalaux.nim deleted file mode 100644 index 5f6f72721..000000000 --- a/tests/run/globalaux.nim +++ /dev/null @@ -1,15 +0,0 @@ -type - TObj*[T] = object - val*: T - -var - totalGlobals* = 0 - -proc makeObj[T](x: T): TObj[T] = - totalGlobals += 1 - result.val = x - -proc globalInstance*[T]: var TObj[T] = - var g {.global.} = when T is int: makeObj(10) else: makeObj("hello") - result = g - diff --git a/tests/run/globalaux2.nim b/tests/run/globalaux2.nim deleted file mode 100644 index 6c77f1f48..000000000 --- a/tests/run/globalaux2.nim +++ /dev/null @@ -1,4 +0,0 @@ -import globalaux - -echo "in globalaux2: ", globalInstance[int]().val - diff --git a/tests/run/minit.nim b/tests/run/minit.nim deleted file mode 100644 index 75fcebb77..000000000 --- a/tests/run/minit.nim +++ /dev/null @@ -1,2 +0,0 @@ -# Test the new initialization for modules -write(stdout, "Hello from module! ") diff --git a/tests/run/tack.nim b/tests/run/tack.nim deleted file mode 100644 index 680ff567e..000000000 --- a/tests/run/tack.nim +++ /dev/null @@ -1,21 +0,0 @@ -discard """ - file: "tack.nim" - output: "125" -""" -# the Ackermann function - -proc ack(x, y: int): int = - if x != 0: - if y != 0: - return ack(x-1, ack(x, y-1)) - return ack(x-1, 1) - else: - return y + 1 -# if x == 0: return y + 1 -# elif y == 0: return ack(x-1, 1) -# else: return ack(x-1, ack(x, y-1)) - -# echo(ack(0, 0)) -write(stdout, ack(3, 4)) #OUT 125 - - diff --git a/tests/run/tbug511622.nim b/tests/run/tbug511622.nim deleted file mode 100644 index a5360423d..000000000 --- a/tests/run/tbug511622.nim +++ /dev/null @@ -1,16 +0,0 @@ -discard """ - file: "tbug511622.nim" - output: "3" -""" -import StrUtils, Math - -proc FibonacciA(n: int): int64 = - var fn = float64(n) - var p: float64 = (1.0 + sqrt(5.0)) / 2.0 - var q: float64 = 1.0 / p - return int64((pow(p, fn) + pow(q, fn)) / sqrt(5.0)) - -echo FibonacciA(4) #OUT 3 - - - diff --git a/tests/run/tdestructor.nim b/tests/run/tdestructor.nim deleted file mode 100644 index 8aae2fce2..000000000 --- a/tests/run/tdestructor.nim +++ /dev/null @@ -1,26 +0,0 @@ -discard """ - output: '''some text -Destructor called!''' -""" - -type - TMyObj = object - x, y: int - p: pointer - -proc destruct(o: var TMyObj) {.destructor.} = - if o.p != nil: dealloc o.p - echo "Destructor called!" - -proc open: TMyObj = - # allow for superfluous () - result = (TMyObj(x: 1, y: 2, p: alloc(3))) - - -proc `$`(x: TMyObj): string = $x.y - -proc main() = - var x = open() - echo "some text" - -main() diff --git a/tests/run/tdomulttest.nim b/tests/run/tdomulttest.nim deleted file mode 100644 index 4ee6de128..000000000 --- a/tests/run/tdomulttest.nim +++ /dev/null @@ -1,17 +0,0 @@ -discard """ - file: "tdomulttest.nim" - output: "555\ntest\nmulti lines\n99999999\nend" - disabled: true -""" -proc foo(bar, baz: proc (x: int): int) = - echo bar(555) - echo baz(99999999) - -foo do (x: int) -> int: - return x -do (x: int) -> int: - echo("test") - echo("multi lines") - return x - -echo("end") \ No newline at end of file diff --git a/tests/run/temit.nim b/tests/run/temit.nim deleted file mode 100644 index ff8df0585..000000000 --- a/tests/run/temit.nim +++ /dev/null @@ -1,20 +0,0 @@ -discard """ - file: "temit.nim" - output: "509" -""" -# Test the new ``emit`` pragma: - -{.emit: """ -static int cvariable = 420; - -""".} - -proc embedsC() = - var nimrodVar = 89 - {.emit: """printf("%d\n", cvariable + (int)`nimrodVar`);""".} - -embedsC() - - - - diff --git a/tests/run/teventemitter.nim b/tests/run/teventemitter.nim deleted file mode 100644 index 9ecf72ea2..000000000 --- a/tests/run/teventemitter.nim +++ /dev/null @@ -1,33 +0,0 @@ -discard """ - output: "pie" -""" - -import tables, lists - -type - TEventArgs = object of TObject - TEventEmitter = object of TObject - events*: TTable[string, TDoublyLinkedList[proc(e: TEventArgs) {.nimcall.}]] - -proc emit*(emitter: TEventEmitter, event: string, args: TEventArgs) = - for func in nodes(emitter.events[event]): - func.value(args) #call function with args. - -proc on*(emitter: var TEventEmitter, event: string, - func: proc(e: TEventArgs) {.nimcall.}) = - if not hasKey(emitter.events, event): - var list: TDoublyLinkedList[proc(e: TEventArgs) {.nimcall.}] - add(emitter.events, event, list) #if not, add it. - append(emitter.events.mget(event), func) - -proc initEmitter(emitter: var TEventEmitter) = - emitter.events = initTable[string, - TDoublyLinkedList[proc(e: TEventArgs) {.nimcall.}]]() - -var - ee: TEventEmitter - args: TEventArgs -initEmitter(ee) -ee.on("print", proc(e: TEventArgs) = echo("pie")) -ee.emit("print", args) - diff --git a/tests/run/tevents.nim b/tests/run/tevents.nim deleted file mode 100644 index fb94b1f79..000000000 --- a/tests/run/tevents.nim +++ /dev/null @@ -1,48 +0,0 @@ -discard """ -file: "tevents.nim" -output: '''HandlePrintEvent: Output -> Handled print event -HandlePrintEvent2: Output -> printing for ME -HandlePrintEvent2: Output -> printing for ME''' -""" - -import events - -type - TPrintEventArgs = object of TEventArgs - user*: string - -proc handleprintevent*(e: TEventArgs) = - write(stdout, "HandlePrintEvent: Output -> Handled print event\n") - -proc handleprintevent2*(e: TEventArgs) = - var args: TPrintEventArgs = TPrintEventArgs(e) - write(stdout, "HandlePrintEvent2: Output -> printing for " & args.user) - -var ee = initEventEmitter() - -var eventargs: TPrintEventArgs -eventargs.user = "ME\n" - -##method one test - -ee.on("print", handleprintevent) -ee.on("print", handleprintevent2) - -ee.emit("print", eventargs) - -##method two test - -type - TSomeObject = object of TObject - PrintEvent: TEventHandler - -var obj: TSomeObject -obj.PrintEvent = initEventHandler("print") -obj.PrintEvent.addHandler(handleprintevent2) - -ee.emit(obj.PrintEvent, eventargs) - -obj.PrintEvent.removeHandler(handleprintevent2) - -ee.emit(obj.PrintEvent, eventargs) - diff --git a/tests/run/tfilter.nim b/tests/run/tfilter.nim deleted file mode 100644 index 5846d0efb..000000000 --- a/tests/run/tfilter.nim +++ /dev/null @@ -1,41 +0,0 @@ -discard """ - output: "02468101214161820\n15" -""" - -proc filter[T](list: seq[T], f: proc (item: T): bool {.closure.}): seq[T] = - result = @[] - for i in items(list): - if f(i): - result.add(i) - -let nums = @[0, 1, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] - -when true: - let nums2 = filter(nums, - (proc (item: int): bool = - result = (item mod 2) == 0) - ) - -proc outer = - # lets use a proper closure this time: - var modulo = 2 - let nums2 = filter(nums, - (proc (item: int): bool = result = (item mod modulo) == 0) - ) - - for n in nums2: stdout.write(n) - stdout.write("\n") - -outer() - -import math -proc compose[T](f1, f2: proc (x: T): T {.closure.}): proc (x: T): T {.closure.} = - result = (proc (x: T): T = - result = f1(f2(x))) - - -proc add5(x: int): int = result = x + 5 - -var test = compose(add5, add5) -echo test(5) - diff --git a/tests/run/thintoff.nim b/tests/run/thintoff.nim deleted file mode 100644 index 807ff44f3..000000000 --- a/tests/run/thintoff.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - file: "thintoff.nim" - output: "0" -""" - -{.hint[XDeclaredButNotUsed]: off.} -var - x: int - -echo x #OUT 0 - - diff --git a/tests/run/tinit.nim b/tests/run/tinit.nim deleted file mode 100644 index 5c75567ec..000000000 --- a/tests/run/tinit.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - file: "tinit.nim" - output: "Hello from module! Hello from main module!" -""" -# Test the new init section in modules - -import minit - -write(stdout, "Hello from main module!\n") -#OUT Hello from module! Hello from main module! - - diff --git a/tests/run/tints.nim b/tests/run/tints.nim deleted file mode 100644 index fb2852af9..000000000 --- a/tests/run/tints.nim +++ /dev/null @@ -1,45 +0,0 @@ -discard """ - file: "tints.nim" - output: "Success" -""" -# Test the different integer operations - -var testNumber = 0 - -template test(opr, a, b, c: expr): stmt {.immediate.} = - # test the expression at compile and runtime - block: - const constExpr = opr(a, b) - when constExpr != c: - {.error: "Test failed " & $constExpr & " " & $c.} - inc(testNumber) - #Echo("Test: " & $testNumber) - var aa = a - var bb = b - var varExpr = opr(aa, bb) - assert(varExpr == c) - -test(`+`, 12'i8, -13'i16, -1'i16) -test(`shl`, 0b11, 0b100, 0b110000) -test(`shl`, 0b11'i32, 0b100'i64, 0b110000'i64) -test(`shl`, 0b11'i32, 0b100'i32, 0b110000'i32) - -test(`or`, 0xf0f0'i16, 0x0d0d'i16, 0xfdfd'i16) -test(`and`, 0xf0f0'i16, 0xfdfd'i16, 0xf0f0'i16) - -test(`shr`, 0xffffffffffffffff'i64, 0x4'i64, 0x0fffffffffffffff'i64) -test(`shr`, 0xffff'i16, 0x4'i16, 0x0fff'i16) -test(`shr`, 0xff'i8, 0x4'i8, 0x0f'i8) - -test(`shr`, 0xffffffff'i64, 0x4'i64, 0x0fffffff'i64) -test(`shr`, 0xffffffff'i32, 0x4'i32, 0x0fffffff'i32) - -test(`shl`, 0xffffffffffffffff'i64, 0x4'i64, 0xfffffffffffffff0'i64) -test(`shl`, 0xffff'i16, 0x4'i16, 0xfff0'i16) -test(`shl`, 0xff'i8, 0x4'i8, 0xf0'i8) - -test(`shl`, 0xffffffff'i64, 0x4'i64, 0xffffffff0'i64) -test(`shl`, 0xffffffff'i32, 0x4'i32, 0xfffffff0'i32) - -Echo("Success") #OUT Success - diff --git a/tests/run/tlocals.nim b/tests/run/tlocals.nim deleted file mode 100644 index 94a34139b..000000000 --- a/tests/run/tlocals.nim +++ /dev/null @@ -1,11 +0,0 @@ -discard """ - output: "(x: string here, a: 1, b: 3)" -""" - -proc simple[T](a, b: T) = - var - x = "string here" - echo locals() - -simple(1, 3) - diff --git a/tests/run/tmemoization.nim b/tests/run/tmemoization.nim deleted file mode 100644 index 78f0515f3..000000000 --- a/tests/run/tmemoization.nim +++ /dev/null @@ -1,17 +0,0 @@ -discard """ - msg: "test 1\ntest 2" - output: "TEST 1\nTEST 2\nTEST 2" -""" - -import strutils - -proc foo(s: expr[string]): string = - static: echo s - - const R = s.toUpper - return R - -echo foo("test 1") -echo foo("test 2") -echo foo("test " & $2) - diff --git a/tests/run/tnewderef.nim b/tests/run/tnewderef.nim deleted file mode 100644 index 89dc4c8d1..000000000 --- a/tests/run/tnewderef.nim +++ /dev/null @@ -1,11 +0,0 @@ -discard """ - output: 3 - -""" - -var x: ref int -new(x) -x[] = 3 - -echo x[] - diff --git a/tests/run/tpos.nim b/tests/run/tpos.nim deleted file mode 100644 index 3d72536dd..000000000 --- a/tests/run/tpos.nim +++ /dev/null @@ -1,35 +0,0 @@ -discard """ - file: "tpos.nim" - output: "6" -""" -# test this particular function - -proc mypos(sub, s: string, start: int = 0): int = - var - i, j, M, N: int - M = sub.len - N = s.len - i = start - j = 0 - if i >= N: - result = -1 - else: - while True: - if s[i] == sub[j]: - Inc(i) - Inc(j) - else: - i = i - j + 1 - j = 0 - if (j >= M) or (i >= N): break - if j >= M: - result = i - M - else: - result = -1 - -var sub = "hello" -var s = "world hello" -write(stdout, mypos(sub, s)) -#OUT 6 - - diff --git a/tests/run/tromans.nim b/tests/run/tromans.nim deleted file mode 100644 index fa6a63595..000000000 --- a/tests/run/tromans.nim +++ /dev/null @@ -1,71 +0,0 @@ -discard """ - file: "tromans.nim" - output: "success" -""" -import - strutils - -## Convert an integer to a Roman numeral -# See http://en.wikipedia.org/wiki/Roman_numerals for reference - -proc raiseInvalidValue(msg: string) {.noreturn.} = - # Yes, we really need a shorthand for this code... - var e: ref EInvalidValue - new(e) - e.msg = msg - raise e - -# I should use a class, perhaps. -# --> No. Why introduce additional state into such a simple and nice -# interface? State is evil. :D - -proc RomanToDecimal(romanVal: string): int = - result = 0 - var prevVal = 0 - for i in countdown(romanVal.len - 1, 0): - var val = 0 - case romanVal[i] - of 'I', 'i': val = 1 - of 'V', 'v': val = 5 - of 'X', 'x': val = 10 - of 'L', 'l': val = 50 - of 'C', 'c': val = 100 - of 'D', 'd': val = 500 - of 'M', 'm': val = 1000 - else: raiseInvalidValue("Incorrect character in roman numeral! (" & - $romanVal[i] & ")") - if val >= prevVal: - inc(result, val) - else: - dec(result, val) - prevVal = val - -proc DecimalToRoman(decValParam: int): string = - # Apparently numbers cannot be above 4000 - # Well, they can be (using overbar or parenthesis notation) - # but I see little interest (beside coding challenge) in coding them as - # we rarely use huge Roman numeral. - const romanComposites = [ - ("M", 1000), ("CM", 900), - ("D", 500), ("CD", 400), ("C", 100), - ("XC", 90), ("L", 50), ("XL", 40), ("X", 10), ("IX", 9), - ("V", 5), ("IV", 4), ("I", 1)] - if decValParam < 1 or decValParam > 3999: - raiseInvalidValue("number not representable") - result = "" - var decVal = decValParam - for key, val in items(romanComposites): - while decVal >= val: - dec(decVal, val) - result.add(key) - -for i in 1..100: - if RomanToDecimal(DecimalToRoman(i)) != i: quit "BUG" - -for i in items([1238, 1777, 3830, 2401, 379, 33, 940, 3973]): - if RomanToDecimal(DecimalToRoman(i)) != i: quit "BUG" - -echo "success" #OUT success - - - diff --git a/tests/run/tsimplesort.nim b/tests/run/tsimplesort.nim deleted file mode 100644 index 0167ca78a..000000000 --- a/tests/run/tsimplesort.nim +++ /dev/null @@ -1,313 +0,0 @@ -discard """ - output: '''true''' -""" - -import hashes, math - - -when defined(shallowADT): - {.pragma: myShallow, shallow.} -else: - {.pragma: myShallow.} - -type - TSlotEnum = enum seEmpty, seFilled, seDeleted - TKeyValuePair[A, B] = tuple[slot: TSlotEnum, key: A, val: B] - TKeyValuePairSeq[A, B] = seq[TKeyValuePair[A, B]] - TTable* {.final, myShallow.}[A, B] = object - data: TKeyValuePairSeq[A, B] - counter: int - -proc len*[A, B](t: TTable[A, B]): int = - ## returns the number of keys in `t`. - result = t.counter - -iterator pairs*[A, B](t: TTable[A, B]): tuple[key: A, val: B] = - ## iterates over any (key, value) pair in the table `t`. - for h in 0..high(t.data): - if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) - -iterator keys*[A, B](t: TTable[A, B]): A = - ## iterates over any key in the table `t`. - for h in 0..high(t.data): - if t.data[h].slot == seFilled: yield t.data[h].key - -iterator values*[A, B](t: TTable[A, B]): B = - ## iterates over any value in the table `t`. - for h in 0..high(t.data): - if t.data[h].slot == seFilled: yield t.data[h].val - -const - growthFactor = 2 - -proc mustRehash(length, counter: int): bool {.inline.} = - assert(length > counter) - result = (length * 2 < counter * 3) or (length - counter < 4) - -proc nextTry(h, maxHash: THash): THash {.inline.} = - result = ((5 * h) + 1) and maxHash - -template rawGetImpl() = - var h: THash = hash(key) and high(t.data) # start with real hash value - while t.data[h].slot != seEmpty: - if t.data[h].key == key and t.data[h].slot == seFilled: - return h - h = nextTry(h, high(t.data)) - result = -1 - -template rawInsertImpl() = - var h: THash = hash(key) and high(data) - while data[h].slot == seFilled: - h = nextTry(h, high(data)) - data[h].key = key - data[h].val = val - data[h].slot = seFilled - -proc RawGet[A, B](t: TTable[A, B], key: A): int = - rawGetImpl() - -proc `[]`*[A, B](t: TTable[A, B], key: A): B = - ## retrieves the value at ``t[key]``. If `key` is not in `t`, - ## default empty value for the type `B` is returned - ## and no exception is raised. One can check with ``hasKey`` whether the key - ## exists. - var index = RawGet(t, key) - if index >= 0: result = t.data[index].val - -proc hasKey*[A, B](t: TTable[A, B], key: A): bool = - ## returns true iff `key` is in the table `t`. - result = rawGet(t, key) >= 0 - -proc RawInsert[A, B](t: var TTable[A, B], data: var TKeyValuePairSeq[A, B], - key: A, val: B) = - rawInsertImpl() - -proc Enlarge[A, B](t: var TTable[A, B]) = - var n: TKeyValuePairSeq[A, B] - newSeq(n, len(t.data) * growthFactor) - for i in countup(0, high(t.data)): - if t.data[i].slot == seFilled: RawInsert(t, n, t.data[i].key, t.data[i].val) - swap(t.data, n) - -template PutImpl() = - var index = RawGet(t, key) - if index >= 0: - t.data[index].val = val - else: - if mustRehash(len(t.data), t.counter): Enlarge(t) - RawInsert(t, t.data, key, val) - inc(t.counter) - -proc `[]=`*[A, B](t: var TTable[A, B], key: A, val: B) = - ## puts a (key, value)-pair into `t`. - putImpl() - -proc del*[A, B](t: var TTable[A, B], key: A) = - ## deletes `key` from hash table `t`. - var index = RawGet(t, key) - if index >= 0: - t.data[index].slot = seDeleted - dec(t.counter) - -proc initTable*[A, B](initialSize=64): TTable[A, B] = - ## creates a new hash table that is empty. `initialSize` needs to be - ## a power of two. - assert isPowerOfTwo(initialSize) - result.counter = 0 - newSeq(result.data, initialSize) - -proc toTable*[A, B](pairs: openarray[tuple[key: A, - val: B]]): TTable[A, B] = - ## creates a new hash table that contains the given `pairs`. - result = initTable[A, B](nextPowerOfTwo(pairs.len+10)) - for key, val in items(pairs): result[key] = val - -template dollarImpl(): stmt = - if t.len == 0: - result = "{:}" - else: - result = "{" - for key, val in pairs(t): - if result.len > 1: result.add(", ") - result.add($key) - result.add(": ") - result.add($val) - result.add("}") - -proc `$`*[A, B](t: TTable[A, B]): string = - ## The `$` operator for hash tables. - dollarImpl() - -# ------------------------------ count tables ------------------------------- - -type - TCountTable* {.final, myShallow.}[ - A] = object ## table that counts the number of each key - data: seq[tuple[key: A, val: int]] - counter: int - -proc len*[A](t: TCountTable[A]): int = - ## returns the number of keys in `t`. - result = t.counter - -iterator pairs*[A](t: TCountTable[A]): tuple[key: A, val: int] = - ## iterates over any (key, value) pair in the table `t`. - for h in 0..high(t.data): - if t.data[h].val != 0: yield (t.data[h].key, t.data[h].val) - -iterator keys*[A](t: TCountTable[A]): A = - ## iterates over any key in the table `t`. - for h in 0..high(t.data): - if t.data[h].val != 0: yield t.data[h].key - -iterator values*[A](t: TCountTable[A]): int = - ## iterates over any value in the table `t`. - for h in 0..high(t.data): - if t.data[h].val != 0: yield t.data[h].val - -proc RawGet[A](t: TCountTable[A], key: A): int = - var h: THash = hash(key) and high(t.data) # start with real hash value - while t.data[h].val != 0: - if t.data[h].key == key: return h - h = nextTry(h, high(t.data)) - result = -1 - -proc `[]`*[A](t: TCountTable[A], key: A): int = - ## retrieves the value at ``t[key]``. If `key` is not in `t`, - ## 0 is returned. One can check with ``hasKey`` whether the key - ## exists. - var index = RawGet(t, key) - if index >= 0: result = t.data[index].val - -proc hasKey*[A](t: TCountTable[A], key: A): bool = - ## returns true iff `key` is in the table `t`. - result = rawGet(t, key) >= 0 - -proc RawInsert[A](t: TCountTable[A], data: var seq[tuple[key: A, val: int]], - key: A, val: int) = - var h: THash = hash(key) and high(data) - while data[h].val != 0: h = nextTry(h, high(data)) - data[h].key = key - data[h].val = val - -proc Enlarge[A](t: var TCountTable[A]) = - var n: seq[tuple[key: A, val: int]] - newSeq(n, len(t.data) * growthFactor) - for i in countup(0, high(t.data)): - if t.data[i].val != 0: RawInsert(t, n, t.data[i].key, t.data[i].val) - swap(t.data, n) - -proc `[]=`*[A](t: var TCountTable[A], key: A, val: int) = - ## puts a (key, value)-pair into `t`. `val` has to be positive. - assert val > 0 - PutImpl() - -proc initCountTable*[A](initialSize=64): TCountTable[A] = - ## creates a new count table that is empty. `initialSize` needs to be - ## a power of two. - assert isPowerOfTwo(initialSize) - result.counter = 0 - newSeq(result.data, initialSize) - -proc toCountTable*[A](keys: openArray[A]): TCountTable[A] = - ## creates a new count table with every key in `keys` having a count of 1. - result = initCountTable[A](nextPowerOfTwo(keys.len+10)) - for key in items(keys): result[key] = 1 - -proc `$`*[A](t: TCountTable[A]): string = - ## The `$` operator for count tables. - dollarImpl() - -proc inc*[A](t: var TCountTable[A], key: A, val = 1) = - ## increments `t[key]` by `val`. - var index = RawGet(t, key) - if index >= 0: - inc(t.data[index].val, val) - else: - if mustRehash(len(t.data), t.counter): Enlarge(t) - RawInsert(t, t.data, key, val) - inc(t.counter) - -proc Smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] = - ## returns the largest (key,val)-pair. Efficiency: O(n) - assert t.len > 0 - var minIdx = 0 - for h in 1..high(t.data): - if t.data[h].val > 0 and t.data[minIdx].val > t.data[h].val: minIdx = h - result.key = t.data[minIdx].key - result.val = t.data[minIdx].val - -proc Largest*[A](t: TCountTable[A]): tuple[key: A, val: int] = - ## returns the (key,val)-pair with the largest `val`. Efficiency: O(n) - assert t.len > 0 - var maxIdx = 0 - for h in 1..high(t.data): - if t.data[maxIdx].val < t.data[h].val: maxIdx = h - result.key = t.data[maxIdx].key - result.val = t.data[maxIdx].val - -proc sort*[A](t: var TCountTable[A]) = - ## sorts the count table so that the entry with the highest counter comes - ## first. This is destructive! You must not modify `t` afterwards! - ## You can use the iterators `pairs`, `keys`, and `values` to iterate over - ## `t` in the sorted order. - - # we use shellsort here; fast enough and simple - var h = 1 - while true: - h = 3 * h + 1 - if h >= high(t.data): break - while true: - h = h div 3 - for i in countup(h, high(t.data)): - var j = i - while t.data[j-h].val <= t.data[j].val: - var xyz = t.data[j] - t.data[j] = t.data[j-h] - t.data[j-h] = xyz - j = j-h - if j < h: break - if h == 1: break - - -const - data = { - "34": 123456, "12": 789, - "90": 343, "0": 34404, - "1": 344004, "2": 344774, - "3": 342244, "4": 3412344, - "5": 341232144, "6": 34214544, - "7": 3434544, "8": 344544, - "9": 34435644, "---00": 346677844, - "10": 34484, "11": 34474, "19": 34464, - "20": 34454, "30": 34141244, "40": 344114, - "50": 344490, "60": 344491, "70": 344492, - "80": 344497} - -proc countTableTest1 = - var s = initTable[string, int](64) - for key, val in items(data): s[key] = val - var w: tuple[key: string, val: int] #type(otherCountTable.data[0]) - - var t = initCountTable[string]() - for k, v in items(data): t.inc(k) - for k in t.keys: assert t[k] == 1 - t.inc("90", 3) - t.inc("12", 2) - t.inc("34", 1) - assert t.largest()[0] == "90" - t.sort() - - var i = 0 - for k, v in t.pairs: - case i - of 0: assert k == "90" and v == 4 - of 1: assert k == "12" and v == 3 - of 2: assert k == "34" and v == 2 - else: break - inc i - -countTableTest1() -echo true - - diff --git a/tests/run/tslices.nim b/tests/run/tslices.nim deleted file mode 100644 index 0de1171e3..000000000 --- a/tests/run/tslices.nim +++ /dev/null @@ -1,59 +0,0 @@ -discard """ - file: "tslices.nim" - output: '''456456 -456456 -456456 -Zugr5nd -egerichtetd -verichtetd -''' -""" - -# Test the new slices. - -import strutils - -var mystr = "Abgrund" -mystr[..1] = "Zu" - -mystr[4..4] = "5" - -type - TEnum = enum e1, e2, e3, e4, e5, e6 - -var myarr: array[TEnum, int] = [1, 2, 3, 4, 5, 6] -myarr[e1..e3] = myarr[e4..e6] -myarr[..e3] = myarr[e4..e6] - -for x in items(myarr): stdout.write(x) -echo() - -var myarr2: array[0..5, int] = [1, 2, 3, 4, 5, 6] -myarr2[0..2] = myarr2[3..5] - -for x in items(myarr2): stdout.write(x) -echo() - - -var myseq = @[1, 2, 3, 4, 5, 6] -myseq[0..2] = myseq[-3.. -1] - -for x in items(myseq): stdout.write(x) -echo() - -echo mystr - -mystr[4..4] = "u" - -# test full replacement -mystr[.. -2] = "egerichtet" - -echo mystr - -mystr[0..2] = "ve" -echo mystr - -var s = "abcdef" -s[1 .. -2] = "xyz" -assert s == "axyzf" - diff --git a/tests/run/tsortdev.nim b/tests/run/tsortdev.nim deleted file mode 100644 index d7d42d22c..000000000 --- a/tests/run/tsortdev.nim +++ /dev/null @@ -1,59 +0,0 @@ -discard """ - output: "done" -""" - -import algorithm, strutils - -proc cmpPlatforms(a, b: string): int = - if a == b: return 0 - var dashes = a.split('-') - var dashes2 = b.split('-') - if dashes[0] == dashes2[0]: - if dashes[1] == dashes2[1]: return system.cmp(a,b) - case dashes[1] - of "x86": - return 1 - of "x86_64": - if dashes2[1] == "x86": return -1 - else: return 1 - of "ppc64": - if dashes2[1] == "x86" or dashes2[1] == "x86_64": return -1 - else: return 1 - else: - return system.cmp(dashes[1], dashes2[1]) - else: - case dashes[0] - of "linux": - return 1 - of "windows": - if dashes2[0] == "linux": return -1 - else: return 1 - of "macosx": - if dashes2[0] == "linux" or dashes2[0] == "windows": return -1 - else: return 1 - else: - if dashes2[0] == "linux" or dashes2[0] == "windows" or - dashes2[0] == "macosx": return -1 - else: - return system.cmp(a, b) - -proc sorted[T](a: openArray[T]): bool = - result = true - for i in 0 .. < a.high: - if cmpPlatforms(a[i], a[i+1]) > 0: - echo "Out of order: ", a[i], " ", a[i+1] - result = false - -proc main() = - var testData = @["netbsd-x86_64", "windows-x86", "linux-x86_64", "linux-x86", - "linux-ppc64", "macosx-x86-1058", "macosx-x86-1068"] - - sort(testData, cmpPlatforms) - - doAssert sorted(testData) - -for i in 0..1_000: - main() - -echo "done" - diff --git a/tests/run/tstrange.nim b/tests/run/tstrange.nim deleted file mode 100644 index 3947755fc..000000000 --- a/tests/run/tstrange.nim +++ /dev/null @@ -1,23 +0,0 @@ -discard """ - file: "tstrange.nim" - output: "hallo4" -""" -# test for extremely strange bug - -proc ack(x: int, y: int): int = - if x != 0: - if y != 5: - return y - return x - return x+y - -proc gen[T](a: T) = - write(stdout, a) - - -gen("hallo") -write(stdout, ack(5, 4)) -#OUT hallo4 - - - diff --git a/tests/run/tunittests.nim b/tests/run/tunittests.nim deleted file mode 100644 index c77f691d9..000000000 --- a/tests/run/tunittests.nim +++ /dev/null @@ -1 +0,0 @@ -import utemplates, uclosures diff --git a/tests/run/tvarious1.nim b/tests/run/tvarious1.nim deleted file mode 100644 index 6e4612ae3..000000000 --- a/tests/run/tvarious1.nim +++ /dev/null @@ -1,41 +0,0 @@ -discard """ - file: "tlenopenarray.nim" - output: '''1 -0 -Whopie -12''' -""" - -echo len([1_000_000]) #OUT 1 - -type - TArray = array[0..3, int] - TVector = distinct array[0..3, int] -proc `[]`(v: TVector; idx: int): int = TArray(v)[idx] -var v: TVector -echo v[2] - -# bug #569 - -import queues - -type - TWidget = object - names: TQueue[string] - -var w = TWidget(names: initQueue[string]()) - -add(w.names, "Whopie") - -for n in w.names: echo(n) - -# bug #681 - -type TSomeRange = object - hour: range[0..23] - -var value: string -var val12 = TSomeRange(hour: 12) - -value = $(if val12.hour > 12: val12.hour - 12 else: val12.hour) -echo value diff --git a/tests/run/tvarnums.nim b/tests/run/tvarnums.nim deleted file mode 100644 index 4f99df8b9..000000000 --- a/tests/run/tvarnums.nim +++ /dev/null @@ -1,142 +0,0 @@ -discard """ - file: "tvarnums.nim" - output: "Success!" -""" -# Test variable length binary integers - -import - strutils - -type - TBuffer = array [0..10, int8] - -proc toVarNum(x: int32, b: var TBuffer) = - # encoding: first bit indicates end of number (0 if at end) - # second bit of the first byte denotes the sign (1 --> negative) - var a = x - if x != low(x): - # low(int) is a special case, - # because abs() does not work here! - # we leave x as it is and use the check >% instead of > - # for low(int) this is needed and positive numbers are not affected - # anyway - a = abs(x) - # first 6 bits: - b[0] = toU8(ord(a >% 63'i32) shl 7 or (ord(x < 0'i32) shl 6) or (int(a) and 63)) - a = a shr 6'i32 # skip first 6 bits - var i = 1 - while a != 0'i32: - b[i] = toU8(ord(a >% 127'i32) shl 7 or (int(a) and 127)) - inc(i) - a = a shr 7'i32 - -proc toVarNum64(x: int64, b: var TBuffer) = - # encoding: first bit indicates end of number (0 if at end) - # second bit of the first byte denotes the sign (1 --> negative) - var a = x - if x != low(x): - # low(int) is a special case, - # because abs() does not work here! - # we leave x as it is and use the check >% instead of > - # for low(int) this is needed and positive numbers are not affected - # anyway - a = abs(x) - # first 6 bits: - b[0] = toU8(ord(a >% 63'i64) shl 7 or (ord(x < 0'i64) shl 6) or int(a and 63)) - a = a shr 6 # skip first 6 bits - var i = 1 - while a != 0'i64: - b[i] = toU8(ord(a >% 127'i64) shl 7 or int(a and 127)) - inc(i) - a = a shr 7 - -proc toNum64(b: TBuffer): int64 = - # treat first byte different: - result = ze64(b[0]) and 63 - var - i = 0 - Shift = 6'i64 - while (ze(b[i]) and 128) != 0: - inc(i) - result = result or ((ze64(b[i]) and 127) shl Shift) - inc(Shift, 7) - if (ze(b[0]) and 64) != 0: # sign bit set? - result = not result +% 1 - # this is the same as ``- result`` - # but gives no overflow error for low(int) - -proc toNum(b: TBuffer): int32 = - # treat first byte different: - result = ze(b[0]) and 63 - var - i = 0 - Shift = 6'i32 - while (ze(b[i]) and 128) != 0: - inc(i) - result = result or ((int32(ze(b[i])) and 127'i32) shl Shift) - Shift = shift + 7'i32 - if (ze(b[0]) and (1 shl 6)) != 0: # sign bit set? - result = (not result) +% 1'i32 - # this is the same as ``- result`` - # but gives no overflow error for low(int) - -proc toBinary(x: int64): string = - result = newString(64) - for i in 0..63: - result[63-i] = chr((int(x shr i) and 1) + ord('0')) - -proc t64(i: int64) = - var - b: TBuffer - toVarNum64(i, b) - var x = toNum64(b) - if x != i: - writeln(stdout, $i) - writeln(stdout, toBinary(i)) - writeln(stdout, toBinary(x)) - -proc t32(i: int32) = - var - b: TBuffer - toVarNum(i, b) - var x = toNum(b) - if x != i: - writeln(stdout, toBinary(i)) - writeln(stdout, toBinary(x)) - -proc tm(i: int32) = - var - b: TBuffer - toVarNum64(i, b) - var x = toNum(b) - if x != i: - writeln(stdout, toBinary(i)) - writeln(stdout, toBinary(x)) - -t32(0) -t32(1) -t32(-1) -t32(-100_000) -t32(100_000) -t32(low(int32)) -t32(high(int32)) - -t64(low(int64)) -t64(high(int64)) -t64(0) -t64(-1) -t64(1) -t64(1000_000) -t64(-1000_000) - -tm(0) -tm(1) -tm(-1) -tm(-100_000) -tm(100_000) -tm(low(int32)) -tm(high(int32)) - -writeln(stdout, "Success!") #OUT Success! - - diff --git a/tests/compile/tseq2.nim b/tests/seq/tseq2.nim index e1271964c..e1271964c 100644 --- a/tests/compile/tseq2.nim +++ b/tests/seq/tseq2.nim diff --git a/tests/run/tseqcon.nim b/tests/seq/tseqcon.nim index 6e0a5b56d..6e0a5b56d 100644 --- a/tests/run/tseqcon.nim +++ b/tests/seq/tseqcon.nim diff --git a/tests/compile/tseqcon2.nim b/tests/seq/tseqcon2.nim index 4f2763ffe..4f2763ffe 100644 --- a/tests/compile/tseqcon2.nim +++ b/tests/seq/tseqcon2.nim diff --git a/tests/run/tseqtuple.nim b/tests/seq/tseqtuple.nim index 7ef92f7f1..7ef92f7f1 100644 --- a/tests/run/tseqtuple.nim +++ b/tests/seq/tseqtuple.nim diff --git a/tests/run/tsequtils.nim b/tests/seq/tsequtils.nim index 7bc15ef9c..7bc15ef9c 100644 --- a/tests/run/tsequtils.nim +++ b/tests/seq/tsequtils.nim diff --git a/tests/run/ttoseq.nim b/tests/seq/ttoseq.nim index 34cc4824b..34cc4824b 100644 --- a/tests/run/ttoseq.nim +++ b/tests/seq/ttoseq.nim diff --git a/tests/run/tsets.nim b/tests/sets/tsets.nim index 7b806f15b..7b806f15b 100644 --- a/tests/run/tsets.nim +++ b/tests/sets/tsets.nim diff --git a/tests/run/tsets2.nim b/tests/sets/tsets2.nim index ac977096b..ac977096b 100644 --- a/tests/run/tsets2.nim +++ b/tests/sets/tsets2.nim diff --git a/tests/run/tstaticparams.nim b/tests/static/tstaticparams.nim index f2d6e1dd6..b1377443b 100644 --- a/tests/run/tstaticparams.nim +++ b/tests/static/tstaticparams.nim @@ -4,15 +4,15 @@ discard """ """ type - TFoo[T; Val: expr[string]] = object + TFoo[T; Val: static[string]] = object data: array[4, T] - TBar[T; I: expr[int]] = object + TBar[T; I: static[int]] = object data: array[I, T] - TA1[T; I: expr[int]] = array[I, T] - TA2[T; I: expr[int]] = array[0..I, T] - TA3[T; I: expr[int]] = array[I-1, T] + TA1[T; I: static[int]] = array[I, T] + # TA2[T; I: static[int]] = array[0..I, T] + # TA3[T; I: static[int]] = array[I-1, T] proc takeFoo(x: TFoo) = echo "abracadabra" @@ -25,7 +25,7 @@ var y: TBar[float, 4] echo high(y.data) var - t1: TA1 - t2: TA2 - t3: TA3 + t1: TA1[float, 1] + # t2: TA2[string, 4] + # t3: TA3[int, 10] diff --git a/tests/compile/tcputime.nim b/tests/stdlib/tcputime.nim index 2fc46ee64..2fc46ee64 100644 --- a/tests/compile/tcputime.nim +++ b/tests/stdlib/tcputime.nim diff --git a/tests/run/tcritbits.nim b/tests/stdlib/tcritbits.nim index fb447b80b..fb447b80b 100644 --- a/tests/run/tcritbits.nim +++ b/tests/stdlib/tcritbits.nim diff --git a/tests/compile/tdialogs.nim b/tests/stdlib/tdialogs.nim index d161a976d..d161a976d 100644 --- a/tests/compile/tdialogs.nim +++ b/tests/stdlib/tdialogs.nim diff --git a/tests/compile/techo.nim b/tests/stdlib/techo.nim index 0fa4b5fe0..0fa4b5fe0 100644 --- a/tests/compile/techo.nim +++ b/tests/stdlib/techo.nim diff --git a/tests/run/tformat.nim b/tests/stdlib/tformat.nim index 92c0c16f5..92c0c16f5 100644 --- a/tests/run/tformat.nim +++ b/tests/stdlib/tformat.nim diff --git a/tests/run/thashes.nim b/tests/stdlib/thashes.nim index c442b43fb..c442b43fb 100644 --- a/tests/run/thashes.nim +++ b/tests/stdlib/thashes.nim diff --git a/tests/compile/tio.nim b/tests/stdlib/tio.nim index 5ae119f77..5ae119f77 100644 --- a/tests/compile/tio.nim +++ b/tests/stdlib/tio.nim diff --git a/tests/compile/tircbot.nim b/tests/stdlib/tircbot.nim index d16c99b69..6008838ff 100644 --- a/tests/compile/tircbot.nim +++ b/tests/stdlib/tircbot.nim @@ -257,7 +257,7 @@ proc limitCommitMsg(m: string): string = proc handleWebMessage(state: PState, line: string) = echo("Got message from hub: " & line) var json = parseJson(line) - if json.existsKey("payload"): + if json.hasKey("payload"): for i in 0..min(4, json["payload"]["commits"].len-1): var commit = json["payload"]["commits"][i] # Create the message @@ -273,8 +273,8 @@ proc handleWebMessage(state: PState, line: string) = # Send message to #nimrod. state.ircClient.privmsg(joinChans[0], message) - elif json.existsKey("redisinfo"): - assert json["redisinfo"].existsKey("port") + elif json.hasKey("redisinfo"): + assert json["redisinfo"].hasKey("port") #let redisPort = json["redisinfo"]["port"].num state.dbConnected = true diff --git a/tests/run/tlists.nim b/tests/stdlib/tlists.nim index 7d5379945..7d5379945 100644 --- a/tests/run/tlists.nim +++ b/tests/stdlib/tlists.nim diff --git a/tests/compile/tmarshal.nim b/tests/stdlib/tmarshal.nim index 5471d347a..5471d347a 100644 --- a/tests/compile/tmarshal.nim +++ b/tests/stdlib/tmarshal.nim diff --git a/tests/run/tmath.nim b/tests/stdlib/tmath.nim index a86a3b84c..a86a3b84c 100644 --- a/tests/run/tmath.nim +++ b/tests/stdlib/tmath.nim diff --git a/tests/compile/tmath.nim b/tests/stdlib/tmath2.nim index 6a1dae54d..6a1dae54d 100644 --- a/tests/compile/tmath.nim +++ b/tests/stdlib/tmath2.nim diff --git a/tests/compile/tmongo.nim b/tests/stdlib/tmongo.nim index 1c4c0f4e6..1c4c0f4e6 100644 --- a/tests/compile/tmongo.nim +++ b/tests/stdlib/tmongo.nim diff --git a/tests/compile/tos.nim b/tests/stdlib/tos.nim index fa9993cc9..fa9993cc9 100644 --- a/tests/compile/tos.nim +++ b/tests/stdlib/tos.nim diff --git a/tests/compile/tparscfg.nim b/tests/stdlib/tparscfg.nim index 618ecadd6..618ecadd6 100644 --- a/tests/compile/tparscfg.nim +++ b/tests/stdlib/tparscfg.nim diff --git a/tests/compile/tparsefloat.nim b/tests/stdlib/tparsefloat.nim index 38ed2db6d..38ed2db6d 100644 --- a/tests/compile/tparsefloat.nim +++ b/tests/stdlib/tparsefloat.nim diff --git a/tests/compile/tparsopt.nim b/tests/stdlib/tparsopt.nim index 2b2da7e51..2b2da7e51 100644 --- a/tests/compile/tparsopt.nim +++ b/tests/stdlib/tparsopt.nim diff --git a/tests/run/tpegs.nim b/tests/stdlib/tpegs.nim index bdd8db0f8..bdd8db0f8 100644 --- a/tests/run/tpegs.nim +++ b/tests/stdlib/tpegs.nim diff --git a/tests/compile/tposix.nim b/tests/stdlib/tposix.nim index bf0b49586..bf0b49586 100644 --- a/tests/compile/tposix.nim +++ b/tests/stdlib/tposix.nim diff --git a/tests/compile/tquit.nim b/tests/stdlib/tquit.nim index d4dc1522d..d4dc1522d 100644 --- a/tests/compile/tquit.nim +++ b/tests/stdlib/tquit.nim diff --git a/tests/run/tregex.nim b/tests/stdlib/tregex.nim index bb4695f02..bb4695f02 100644 --- a/tests/run/tregex.nim +++ b/tests/stdlib/tregex.nim diff --git a/tests/run/treguse.nim b/tests/stdlib/treguse.nim index a610ad725..a610ad725 100644 --- a/tests/run/treguse.nim +++ b/tests/stdlib/treguse.nim diff --git a/tests/run/trepr.nim b/tests/stdlib/trepr.nim index 41c830621..41c830621 100644 --- a/tests/run/trepr.nim +++ b/tests/stdlib/trepr.nim diff --git a/tests/compile/trepr.nim b/tests/stdlib/trepr2.nim index b15081e48..b15081e48 100644 --- a/tests/compile/trepr.nim +++ b/tests/stdlib/trepr2.nim diff --git a/tests/compile/tsockets.nim b/tests/stdlib/tsockets.nim index 6078504f5..6078504f5 100644 --- a/tests/compile/tsockets.nim +++ b/tests/stdlib/tsockets.nim diff --git a/tests/compile/tsortcall.nim b/tests/stdlib/tsortcall.nim index efe1d0b8b..efe1d0b8b 100644 --- a/tests/compile/tsortcall.nim +++ b/tests/stdlib/tsortcall.nim diff --git a/tests/run/tsplit.nim b/tests/stdlib/tsplit.nim index 25bad33e2..25bad33e2 100644 --- a/tests/run/tsplit.nim +++ b/tests/stdlib/tsplit.nim diff --git a/tests/compile/tstreams.nim b/tests/stdlib/tstreams.nim index 640565a27..640565a27 100644 --- a/tests/compile/tstreams.nim +++ b/tests/stdlib/tstreams.nim diff --git a/tests/compile/tstrset.nim b/tests/stdlib/tstrset.nim index 9cdb5ed35..9cdb5ed35 100644 --- a/tests/compile/tstrset.nim +++ b/tests/stdlib/tstrset.nim diff --git a/tests/compile/tstrtabs.nim b/tests/stdlib/tstrtabs.nim index 251ec77ef..251ec77ef 100644 --- a/tests/compile/tstrtabs.nim +++ b/tests/stdlib/tstrtabs.nim diff --git a/tests/run/tstrutil.nim b/tests/stdlib/tstrutil.nim index 80c2f3870..80c2f3870 100644 --- a/tests/run/tstrutil.nim +++ b/tests/stdlib/tstrutil.nim diff --git a/tests/compile/ttime.nim b/tests/stdlib/ttime.nim index bad818816..bad818816 100644 --- a/tests/compile/ttime.nim +++ b/tests/stdlib/ttime.nim diff --git a/tests/run/tunidecode.nim b/tests/stdlib/tunidecode.nim index cb6589d60..cb6589d60 100644 --- a/tests/run/tunidecode.nim +++ b/tests/stdlib/tunidecode.nim diff --git a/tests/compile/twalker.nim b/tests/stdlib/twalker.nim index 89e6c2b9d..89e6c2b9d 100644 --- a/tests/compile/twalker.nim +++ b/tests/stdlib/twalker.nim diff --git a/tests/run/txmlgen.nim b/tests/stdlib/txmlgen.nim index 917427abc..917427abc 100644 --- a/tests/run/txmlgen.nim +++ b/tests/stdlib/txmlgen.nim diff --git a/tests/run/txmltree.nim b/tests/stdlib/txmltree.nim index 931871f15..931871f15 100644 --- a/tests/run/txmltree.nim +++ b/tests/stdlib/txmltree.nim diff --git a/tests/compile/ttableconstr.nim b/tests/table/ttableconstr.nim index c627e68e8..c627e68e8 100644 --- a/tests/compile/ttableconstr.nim +++ b/tests/table/ttableconstr.nim diff --git a/tests/run/ttables.nim b/tests/table/ttables.nim index 681ff5424..681ff5424 100644 --- a/tests/run/ttables.nim +++ b/tests/table/ttables.nim diff --git a/tests/run/ttables2.nim b/tests/table/ttables2.nim index b88c8dfbf..b88c8dfbf 100644 --- a/tests/run/ttables2.nim +++ b/tests/table/ttables2.nim diff --git a/tests/template/mcan_access_hidden_field.nim b/tests/template/mcan_access_hidden_field.nim new file mode 100644 index 000000000..bf3592701 --- /dev/null +++ b/tests/template/mcan_access_hidden_field.nim @@ -0,0 +1,9 @@ + +type + Foo* = object + fooa, foob: int + +proc createFoo*(a, b: int): Foo = Foo(fooa: a, foob: b) + +template geta*(f: Foo): expr = f.fooa + diff --git a/tests/compile/mtempl5.nim b/tests/template/mtempl5.nim index 51e8461b8..51e8461b8 100644 --- a/tests/compile/mtempl5.nim +++ b/tests/template/mtempl5.nim diff --git a/tests/template/tcan_access_hidden_field.nim b/tests/template/tcan_access_hidden_field.nim new file mode 100644 index 000000000..a6f6490cc --- /dev/null +++ b/tests/template/tcan_access_hidden_field.nim @@ -0,0 +1,9 @@ +discard """ + output: 33 +""" + +import mcan_access_hidden_field + +var myfoo = createFoo(33, 44) + +echo myfoo.geta diff --git a/tests/compile/thygienictempl.nim b/tests/template/thygienictempl.nim index 3cdbac40e..3cdbac40e 100644 --- a/tests/compile/thygienictempl.nim +++ b/tests/template/thygienictempl.nim diff --git a/tests/compile/tmodulealias.nim b/tests/template/tmodulealias.nim index a7d155e51..a7d155e51 100644 --- a/tests/compile/tmodulealias.nim +++ b/tests/template/tmodulealias.nim diff --git a/tests/run/tstempl.nim b/tests/template/tstempl.nim index 2b4a8baa0..2b4a8baa0 100644 --- a/tests/run/tstempl.nim +++ b/tests/template/tstempl.nim diff --git a/tests/compile/ttempl.nim b/tests/template/ttempl.nim index 2c4785325..2c4785325 100644 --- a/tests/compile/ttempl.nim +++ b/tests/template/ttempl.nim diff --git a/tests/reject/ttempl2.nim b/tests/template/ttempl2.nim index 142bbb8c7..142bbb8c7 100644 --- a/tests/reject/ttempl2.nim +++ b/tests/template/ttempl2.nim diff --git a/tests/compile/ttempl3.nim b/tests/template/ttempl3.nim index 59be24624..59be24624 100644 --- a/tests/compile/ttempl3.nim +++ b/tests/template/ttempl3.nim diff --git a/tests/compile/ttempl4.nim b/tests/template/ttempl4.nim index 26c82e471..26c82e471 100644 --- a/tests/compile/ttempl4.nim +++ b/tests/template/ttempl4.nim diff --git a/tests/compile/ttempl5.nim b/tests/template/ttempl5.nim index 85692e97b..85692e97b 100644 --- a/tests/compile/ttempl5.nim +++ b/tests/template/ttempl5.nim diff --git a/tests/compile/ttemplreturntype.nim b/tests/template/ttemplreturntype.nim index 642fa1b72..642fa1b72 100644 --- a/tests/compile/ttemplreturntype.nim +++ b/tests/template/ttemplreturntype.nim diff --git a/tests/run/utemplates.nim b/tests/template/utemplates.nim index 68fbb23a6..38ad4f515 100644 --- a/tests/run/utemplates.nim +++ b/tests/template/utemplates.nim @@ -18,7 +18,7 @@ test "previous definitions can be further overloaded or hidden in local scopes": check t("test") == "string" test "templates can be redefined multiple times": - template customAssert(cond: bool, msg: string): stmt = + template customAssert(cond: bool, msg: string): stmt {.immediate, dirty.} = if not cond: fail(msg) template assertion_failed(body: stmt) {.immediate.} = diff --git a/tests/testament/backend.nim b/tests/testament/backend.nim new file mode 100644 index 000000000..bc1f92eba --- /dev/null +++ b/tests/testament/backend.nim @@ -0,0 +1,121 @@ +# +# +# The Nimrod Tester +# (c) Copyright 2014 Andreas Rumpf +# +# Look at license.txt for more info. +# All rights reserved. + +import strutils, db_sqlite, os, osproc + +var db: TDbConn + +proc createDb() = + db.exec(sql""" + create table if not exists Machine( + id integer primary key, + name varchar(100) not null, + os varchar(20) not null, + cpu varchar(20) not null + );""") + + db.exec(sql""" + create table if not exists [Commit]( + id integer primary key, + hash varchar(256) not null, + branch varchar(50) not null + );""") + + db.exec(sql""" + create table if not exists TestResult( + id integer primary key, + name varchar(100) not null, + category varchar(100) not null, + target varchar(20) not null, + action varchar(10) not null, + result varchar(30) not null, + [commit] int not null, + machine int not null, + expected varchar(10000) not null, + given varchar(10000) not null, + created timestamp not null default (DATETIME('now')), + + foreign key ([commit]) references [commit](id), + foreign key (machine) references machine(id) + );""") + + #db.exec(sql""" + # --create unique index if not exists TsstNameIx on TestResult(name); + # """, []) + +type + MachineId = distinct int64 + CommitId = distinct int64 + +proc `$`(id: MachineId): string {.borrow.} +proc `$`(id: CommitId): string {.borrow.} + +var + thisMachine: MachineId + thisCommit: CommitId + +proc `()`(cmd: string{lit}): string = cmd.execProcess.string.strip + +proc getMachine: MachineId = + var name = "hostname"() + if name.len == 0: + name = when defined(posix): getenv"HOSTNAME".string + else: getenv"COMPUTERNAME".string + if name.len == 0: + quit "cannot determine the machine name" + + let id = db.getValue(sql"select id from Machine where name = ?", name) + if id.len > 0: + result = id.parseInt.MachineId + else: + result = db.insertId(sql"insert into Machine(name, os, cpu) values (?,?,?)", + name, system.hostOS, system.hostCPU).MachineId + +proc getCommit: CommitId = + const commLen = "commit ".len + let hash = "git log -n 1"()[commLen..commLen+10] + let branch = "git symbolic-ref --short HEAD"() + if hash.len == 0 or branch.len == 0: quit "cannot determine git HEAD" + + let id = db.getValue(sql"select id from [Commit] where hash = ? and branch = ?", + hash, branch) + if id.len > 0: + result = id.parseInt.CommitId + else: + result = db.insertId(sql"insert into [Commit](hash, branch) values (?, ?)", + hash, branch).CommitId + +proc writeTestResult*(name, category, target, + action, result, expected, given: string) = + let id = db.getValue(sql"""select id from TestResult + where name = ? and category = ? and target = ? and + machine = ? and [commit] = ?""", + name, category, target, + thisMachine, thisCommit) + if id.len > 0: + db.exec(sql"""update TestResult + set action = ?, result = ?, expected = ?, given = ? + where id = ?""", action, result, expected, given, id) + else: + db.exec(sql"""insert into TestResult(name, category, target, + action, + result, expected, given, + [commit], machine) + values (?,?,?,?,?,?,?,?,?) """, name, category, target, + action, + result, expected, given, + thisCommit, thisMachine) + +proc open*() = + db = open(connection="testament.db", user="testament", password="", + database="testament") + createDb() + thisMachine = getMachine() + thisCommit = getCommit() + +proc close*() = close(db) diff --git a/tests/caasdriver.nim b/tests/testament/caasdriver.nim index 28f0bae9b..28f0bae9b 100644 --- a/tests/caasdriver.nim +++ b/tests/testament/caasdriver.nim diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim new file mode 100644 index 000000000..5dd841447 --- /dev/null +++ b/tests/testament/categories.nim @@ -0,0 +1,264 @@ +# +# +# Nimrod Tester +# (c) Copyright 2014 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## Include for the tester that contains test suites that test special features +## of the compiler. + +# included from tester.nim +# ---------------- ROD file tests --------------------------------------------- + +const + rodfilesDir = "tests/rodfiles" + nimcacheDir = rodfilesDir / "nimcache" + +proc delNimCache() = + try: + removeDir(nimcacheDir) + except EOS: + echo "[Warning] could not delete: ", nimcacheDir + +proc runRodFiles(r: var TResults, cat: Category, options: string) = + template test(filename: expr): stmt = + testSpec r, makeTest(rodfilesDir / filename, options, cat, actionRun) + + delNimCache() + + # test basic recompilation scheme: + test "hallo" + test "hallo" + # test incremental type information: + test "hallo2" + delNimCache() + + # test type converters: + test "aconv" + test "bconv" + delNimCache() + + # test G, A, B example from the documentation; test init sections: + test "deada" + test "deada2" + delNimCache() + + # test method generation: + test "bmethods" + test "bmethods2" + delNimCache() + + # test generics: + test "tgeneric1" + test "tgeneric2" + delNimCache() + +proc compileRodFiles(r: var TResults, cat: Category, options: string) = + template test(filename: expr): stmt = + testSpec r, makeTest(rodfilesDir / filename, options, cat) + + delNimCache() + # test DLL interfacing: + test "gtkex1" + test "gtkex2" + delNimCache() + +# --------------------- DLL generation tests ---------------------------------- + +proc safeCopyFile(src, dest: string) = + try: + copyFile(src, dest) + except EOS: + echo "[Warning] could not copy: ", src, " to ", dest + +proc runBasicDLLTest(c, r: var TResults, cat: Category, options: string) = + testSpec c, makeTest("lib/nimrtl.nim", + options & " --app:lib -d:createNimRtl", cat) + testSpec c, makeTest("tests/dll/server.nim", + options & " --app:lib -d:useNimRtl", cat) + + when defined(Windows): + # windows looks in the dir of the exe (yay!): + var nimrtlDll = DynlibFormat % "nimrtl" + safeCopyFile("lib" / nimrtlDll, "tests/dll" / nimrtlDll) + else: + # posix relies on crappy LD_LIBRARY_PATH (ugh!): + var libpath = getenv"LD_LIBRARY_PATH".string + if peg"\i '/nimrod' (!'/')* '/lib'" notin libpath: + echo "[Warning] insufficient LD_LIBRARY_PATH" + var serverDll = DynlibFormat % "server" + safeCopyFile("tests/dll" / serverDll, "lib" / serverDll) + + testSpec r, makeTest("tests/dll/client.nim", options & " -d:useNimRtl", + cat, actionRun) + +proc dllTests(r: var TResults, cat: Category, options: string) = + # dummy compile result: + var c = initResults() + + runBasicDLLTest c, r, cat, options + runBasicDLLTest c, r, cat, options & " -d:release" + runBasicDLLTest c, r, cat, options & " --gc:boehm" + runBasicDLLTest c, r, cat, options & " -d:release --gc:boehm" + +# ------------------------------ GC tests ------------------------------------- + +proc gcTests(r: var TResults, cat: Category, options: string) = + template test(filename: expr): stmt = + testSpec r, makeTest("tests/gc" / filename, options, cat, actionRun) + testSpec r, makeTest("tests/gc" / filename, options & + " -d:release", cat, actionRun) + testSpec r, makeTest("tests/gc" / filename, options & + " -d:release -d:useRealtimeGC", cat, actionRun) + testSpec r, makeTest("tests/gc" / filename, options & + " --gc:markAndSweep", cat, actionRun) + testSpec r, makeTest("tests/gc" / filename, options & + " -d:release --gc:markAndSweep", cat, actionRun) + + test "gcbench" + test "gcleak" + test "gcleak2" + test "gctest" + test "gcleak3" + test "weakrefs" + test "cycleleak" + test "closureleak" + +# ------------------------- threading tests ----------------------------------- + +proc threadTests(r: var TResults, cat: Category, options: string) = + template test(filename: expr): stmt = + testSpec r, makeTest("tests/threads" / filename, options, cat, actionRun) + testSpec r, makeTest("tests/threads" / filename, options & + " -d:release", cat, actionRun) + testSpec r, makeTest("tests/threads" / filename, options & + " --tlsEmulation:on", cat, actionRun) + + test "tactors" + test "tactors2" + test "threadex" + # deactivated because output capturing still causes problems sometimes: + #test "trecursive_actor" + #test "threadring" + #test "tthreadanalysis" + #test "tthreadsort" + test "tthreadanalysis2" + test "tthreadanalysis3" + test "tthreadheapviolation1" + +# ------------------------- IO tests ------------------------------------------ + +proc ioTests(r: var TResults, cat: Category, options: string) = + # We need readall_echo to be compiled for this test to run. + # dummy compile result: + var c = initResults() + testSpec c, makeTest("tests/system/helpers/readall_echo", options, cat) + testSpec r, makeTest("tests/system/io", options, cat) + +# ------------------------- debugger tests ------------------------------------ + +proc debuggerTests(r: var TResults, cat: Category, options: string) = + testNoSpec r, makeTest("tools/nimgrep", options & " --debugger:on", cat) + +# ------------------------- JS tests ------------------------------------------ + +proc jsTests(r: var TResults, cat: Category, options: string) = + template test(filename: expr): stmt = + testSpec r, makeTest(filename, options & " -d:nodejs", cat, + actionRun, targetJS) + testSpec r, makeTest(filename, options & " -d:nodejs -d:release", cat, + actionRun, targetJS) + + for t in os.walkFiles("tests/js/t*.nim"): + test(t) + for testfile in ["texceptions", "texcpt1", "texcsub", "tfinally", + "tfinally2", "tfinally3", "tactiontable", "tmultim1", + "tmultim3", "tmultim4"]: + test "tests/run/" & testfile & ".nim" + +# ------------------------- manyloc ------------------------------------------- +#proc runSpecialTests(r: var TResults, options: string) = +# for t in ["lib/packages/docutils/highlite"]: +# testSpec(r, t, options) + +proc findMainFile(dir: string): string = + # finds the file belonging to ".nimrod.cfg"; if there is no such file + # it returns the some ".nim" file if there is only one: + const cfgExt = ".nimrod.cfg" + result = "" + var nimFiles = 0 + for kind, file in os.walkDir(dir): + if kind == pcFile: + if file.endsWith(cfgExt): return file[.. -(cfgExt.len+1)] & ".nim" + elif file.endsWith(".nim"): + if result.len == 0: result = file + inc nimFiles + if nimFiles != 1: result.setlen(0) + +proc manyLoc(r: var TResults, cat: Category, options: string) = + for kind, dir in os.walkDir("tests/manyloc"): + if kind == pcDir: + let mainfile = findMainFile(dir) + if mainfile != ".nim": + testNoSpec r, makeTest(mainfile, options, cat) + +proc compileExample(r: var TResults, pattern, options: string, cat: Category) = + for test in os.walkFiles(pattern): + testNoSpec r, makeTest(test, options, cat) + +proc testStdlib(r: var TResults, pattern, options: string, cat: Category) = + for test in os.walkFiles(pattern): + let contents = readFile(test).string + if contents.contains("when isMainModule"): + testSpec r, makeTest(test, options, cat, actionRun) + else: + testNoSpec r, makeTest(test, options, cat, actionCompile) + +# ---------------------------------------------------------------------------- + +const AdditionalCategories = ["debugger", "tools", "examples", "stdlib"] + +proc `&.?`(a, b: string): string = + # candidate for the stdlib? + result = if b.startswith(a): b else: a & b + +proc `&?.`(a, b: string): string = + # candidate for the stdlib? + result = if a.endswith(b): a else: a & b + +proc processCategory(r: var TResults, cat: Category, options: string) = + case cat.string.normalize + of "rodfiles": + compileRodFiles(r, cat, options) + runRodFiles(r, cat, options) + of "js": + # XXX JS doesn't need to be special anymore + jsTests(r, cat, options) + of "dll": + dllTests(r, cat, options) + of "gc": + gcTests(r, cat, options) + of "debugger": + debuggerTests(r, cat, options) + of "tools": + testSpec r, makeTest("compiler/c2nim/c2nim.nim", options, cat) + testSpec r, makeTest("compiler/pas2nim/pas2nim.nim", options, cat) + of "manyloc": + manyLoc r, cat, options + of "threads": + threadTests r, cat, options & " --threads:on" + of "io": + ioTests r, cat, options + of "stdlib": + testStdlib(r, "lib/pure/*.nim", options, cat) + testStdlib(r, "lib/packages/docutils/highlite", options, cat) + of "examples": + compileExample(r, "examples/*.nim", options, cat) + compileExample(r, "examples/gtk/*.nim", options, cat) + compileExample(r, "examples/talk/*.nim", options, cat) + else: + for name in os.walkFiles("tests" & DirSep &.? cat.string / "t*.nim"): + testSpec r, makeTest(name, options, cat) diff --git a/tests/css/boilerplate.css b/tests/testament/css/boilerplate.css index b209b5aa1..b209b5aa1 100644 --- a/tests/css/boilerplate.css +++ b/tests/testament/css/boilerplate.css diff --git a/tests/css/style.css b/tests/testament/css/style.css index 43a8add68..43a8add68 100644 --- a/tests/css/style.css +++ b/tests/testament/css/style.css diff --git a/tests/testament/htmlgen.nim b/tests/testament/htmlgen.nim new file mode 100644 index 000000000..bc2d8bd37 --- /dev/null +++ b/tests/testament/htmlgen.nim @@ -0,0 +1,161 @@ +# +# +# Nimrod Tester +# (c) Copyright 2014 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## HTML generator for the tester. + +import db_sqlite, cgi, backend, strutils + +const + TableHeader = """<table border="1"> + <tr><td>Test</td><td>Category</td><td>Target</td> + <td>Action</td> + <td>Expected</td> + <td>Given</td> + <td>Success</td></tr>""" + TableFooter = "</table>" + HtmlBegin = """<html> + <head> + <title>Test results</title> + <style type="text/css"> + <!--""" & slurp("css/boilerplate.css") & "\n" & + slurp("css/style.css") & + """ +ul#tabs { list-style-type: none; margin: 30px 0 0 0; padding: 0 0 0.3em 0; } +ul#tabs li { display: inline; } +ul#tabs li a { color: #42454a; background-color: #dedbde; + border: 1px solid #c9c3ba; border-bottom: none; + padding: 0.3em; text-decoration: none; } +ul#tabs li a:hover { background-color: #f1f0ee; } +ul#tabs li a.selected { color: #000; background-color: #f1f0ee; + font-weight: bold; padding: 0.7em 0.3em 0.38em 0.3em; } +div.tabContent { border: 1px solid #c9c3ba; + padding: 0.5em; background-color: #f1f0ee; } +div.tabContent.hide { display: none; } + --> + </style> + <script> + + var tabLinks = new Array(); + var contentDivs = new Array(); + + function init() { + // Grab the tab links and content divs from the page + var tabListItems = document.getElementById('tabs').childNodes; + for (var i = 0; i < tabListItems.length; i++) { + if (tabListItems[i].nodeName == "LI") { + var tabLink = getFirstChildWithTagName(tabListItems[i], 'A'); + var id = getHash(tabLink.getAttribute('href')); + tabLinks[id] = tabLink; + contentDivs[id] = document.getElementById(id); + } + } + // Assign onclick events to the tab links, and + // highlight the first tab + var i = 0; + for (var id in tabLinks) { + tabLinks[id].onclick = showTab; + tabLinks[id].onfocus = function() { this.blur() }; + if (i == 0) tabLinks[id].className = 'selected'; + i++; + } + // Hide all content divs except the first + var i = 0; + for (var id in contentDivs) { + if (i != 0) contentDivs[id].className = 'tabContent hide'; + i++; + } + } + + function showTab() { + var selectedId = getHash(this.getAttribute('href')); + + // Highlight the selected tab, and dim all others. + // Also show the selected content div, and hide all others. + for (var id in contentDivs) { + if (id == selectedId) { + tabLinks[id].className = 'selected'; + contentDivs[id].className = 'tabContent'; + } else { + tabLinks[id].className = ''; + contentDivs[id].className = 'tabContent hide'; + } + } + // Stop the browser following the link + return false; + } + + function getFirstChildWithTagName(element, tagName) { + for (var i = 0; i < element.childNodes.length; i++) { + if (element.childNodes[i].nodeName == tagName) return element.childNodes[i]; + } + } + function getHash(url) { + var hashPos = url.lastIndexOf('#'); + return url.substring(hashPos + 1); + } + </script> + + </head> + <body onload="init()">""" + + HtmlEnd = "</body></html>" + +proc td(s: string): string = + result = "<td>" & s.substr(0, 200).XMLEncode & "</td>" + +proc getCommit(db: TDbConn, c: int): string = + var commit = c + for thisCommit in db.rows(sql"select id from [Commit] order by id desc"): + if commit == 0: result = thisCommit[0] + inc commit + if result.isNil: + quit "cannot determine commit " & $c + +proc generateHtml*(filename: string, commit: int) = + const selRow = """select name, category, target, action, + expected, given, result + from TestResult + where [commit] = ? and machine = ? + order by category""" + var db = open(connection="testament.db", user="testament", password="", + database="testament") + # search for proper commit: + let lastCommit = db.getCommit(commit) + + var outfile = open(filename, fmWrite) + outfile.write(HtmlBegin) + + let commit = db.getValue(sql"select hash from [Commit] where id = ?", + lastCommit) + let branch = db.getValue(sql"select branch from [Commit] where id = ?", + lastCommit) + outfile.write("<p><b>$# $#</b></p>" % [branch, commit]) + + # generate navigation: + outfile.write("""<ul id="tabs">""") + for m in db.rows(sql"select id, name, os, cpu from Machine order by id"): + outfile.writeln """<li><a href="#$#">$#: $#, $#</a></li>""" % m + outfile.write("</ul>") + + for currentMachine in db.rows(sql"select id from Machine order by id"): + let m = currentMachine[0] + outfile.write("""<div class="tabContent" id="$#">""" % m) + + outfile.write(TableHeader) + for row in db.rows(sql(selRow), lastCommit, m): + outfile.write("<tr>") + for x in row: + outfile.write(x.td) + outfile.write("</tr>") + + outfile.write(TableFooter) + outfile.write("</div>") + outfile.write(HtmlEnd) + close(db) + close(outfile) diff --git a/tests/testament/specs.nim b/tests/testament/specs.nim new file mode 100644 index 000000000..e97015946 --- /dev/null +++ b/tests/testament/specs.nim @@ -0,0 +1,130 @@ +# +# +# Nimrod Tester +# (c) Copyright 2014 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +import parseutils, strutils, os, osproc, streams, parsecfg + +const + cmdTemplate* = r"nimrod cc --hints:on $# $#" + +type + TTestAction* = enum + actionCompile = "compile" + actionRun = "run" + actionReject = "reject" + TResultEnum* = enum + reNimrodcCrash, # nimrod compiler seems to have crashed + reMsgsDiffer, # error messages differ + reFilesDiffer, # expected and given filenames differ + reLinesDiffer, # expected and given line numbers differ + reOutputsDiffer, + reExitcodesDiffer, + reInvalidPeg, + reCodegenFailure, + reCodeNotFound, + reExeNotFound, + reIgnored, # test is ignored + reSuccess # test was successful + TTarget* = enum + targetC = "C" + targetCpp = "C++" + targetObjC = "ObjC" + targetJS = "JS" + + TSpec* = object + action*: TTestAction + file*, cmd*: string + outp*: string + line*, exitCode*: int + msg*: string + ccodeCheck*: string + err*: TResultEnum + substr*: bool + targets*: set[TTarget] + +const + targetToExt*: array[TTarget, string] = ["c", "cpp", "m", "js"] + +when not defined(parseCfgBool): + # candidate for the stdlib: + proc parseCfgBool(s: string): bool = + case normalize(s) + of "y", "yes", "true", "1", "on": result = true + of "n", "no", "false", "0", "off": result = false + else: raise newException(EInvalidValue, "cannot interpret as a bool: " & s) + +proc extractSpec(filename: string): string = + const tripleQuote = "\"\"\"" + var x = readFile(filename).string + var a = x.find(tripleQuote) + var b = x.find(tripleQuote, a+3) + # look for """ only in the first section + if a >= 0 and b > a and a < 40: + result = x.substr(a+3, b-1).replace("'''", tripleQuote) + else: + #echo "warning: file does not contain spec: " & filename + result = "" + +when not defined(nimhygiene): + {.pragma: inject.} + +template parseSpecAux(fillResult: stmt) {.immediate.} = + var ss = newStringStream(extractSpec(filename)) + var p {.inject.}: TCfgParser + open(p, ss, filename, 1) + while true: + var e {.inject.} = next(p) + case e.kind + of cfgEof: break + of cfgSectionStart, cfgOption, cfgError: + echo ignoreMsg(p, e) + of cfgKeyValuePair: + fillResult + close(p) + +proc parseSpec*(filename: string): TSpec = + result.file = filename + result.msg = "" + result.outp = "" + result.ccodeCheck = "" + result.cmd = cmdTemplate + parseSpecAux: + case normalize(e.key) + of "action": + case e.value.normalize + of "compile": result.action = actionCompile + of "run": result.action = actionRun + of "reject": result.action = actionReject + else: echo ignoreMsg(p, e) + of "file": result.file = e.value + of "line": discard parseInt(e.value, result.line) + of "output": + result.action = actionRun + result.outp = e.value + of "outputsub": + result.action = actionRun + result.outp = e.value + result.substr = true + of "exitcode": + discard parseInt(e.value, result.exitCode) + of "errormsg", "msg": + result.msg = e.value + result.action = actionReject + of "disabled": + if parseCfgBool(e.value): result.err = reIgnored + of "cmd": result.cmd = e.value + of "ccodecheck": result.ccodeCheck = e.value + of "target", "targets": + for v in e.value.normalize.split: + case v + of "c": result.targets.incl(targetC) + of "cpp", "c++": result.targets.incl(targetCpp) + of "objc": result.targets.incl(targetObjC) + of "js": result.targets.incl(targetJS) + else: echo ignoreMsg(p, e) + else: echo ignoreMsg(p, e) diff --git a/tests/testament/tester.nim b/tests/testament/tester.nim new file mode 100644 index 000000000..54a6de2d0 --- /dev/null +++ b/tests/testament/tester.nim @@ -0,0 +1,273 @@ +# +# +# Nimrod Tester +# (c) Copyright 2014 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This program verifies Nimrod against the testcases. + +import + parseutils, strutils, pegs, os, osproc, streams, parsecfg, json, + marshal, backend, parseopt, specs, htmlgen, browsers + +const + resultsFile = "testresults.html" + jsonFile = "testresults.json" + Usage = """Usage: + tester [options] command [arguments] + +Command: + all run all tests + c|category <category> run all the tests of a certain category + html [commit] generate $1 from the database; uses the latest + commit or a specific one (use -1 for the commit + before latest etc) +Arguments: + arguments are passed to the compiler +Options: + --print also print results to the console +""" % resultsFile + +type + Category = distinct string + TResults = object + total, passed, skipped: int + data: string + + TTest = object + name: string + cat: Category + options: string + target: TTarget + action: TTestAction + +# ---------------------------------------------------------------------------- + +let + pegLineError = + peg"{[^(]*} '(' {\d+} ', ' \d+ ') ' ('Error'/'Warning') ':' \s* {.*}" + pegOtherError = peg"'Error:' \s* {.*}" + pegSuccess = peg"'Hint: operation successful'.*" + pegOfInterest = pegLineError / pegOtherError + +proc callCompiler(cmdTemplate, filename, options: string): TSpec = + let c = parseCmdLine(cmdTemplate % [options, filename]) + var p = startProcess(command=c[0], args=c[1.. -1], + options={poStdErrToStdOut, poUseShell}) + let outp = p.outputStream + var suc = "" + var err = "" + var x = newStringOfCap(120) + while outp.readLine(x.TaintedString) or running(p): + if x =~ pegOfInterest: + # `err` should contain the last error/warning message + err = x + elif x =~ pegSuccess: + suc = x + close(p) + result.msg = "" + result.file = "" + result.outp = "" + result.line = -1 + if err =~ pegLineError: + result.file = extractFilename(matches[0]) + result.line = parseInt(matches[1]) + result.msg = matches[2] + elif err =~ pegOtherError: + result.msg = matches[0] + elif suc =~ pegSuccess: + result.err = reSuccess + +proc initResults: TResults = + result.total = 0 + result.passed = 0 + result.skipped = 0 + result.data = "" + +proc readResults(filename: string): TResults = + result = marshal.to[TResults](readFile(filename).string) + +proc writeResults(filename: string, r: TResults) = + writeFile(filename, $$r) + +proc `$`(x: TResults): string = + result = ("Tests passed: $1 / $3 <br />\n" & + "Tests skipped: $2 / $3 <br />\n") % + [$x.passed, $x.skipped, $x.total] + +proc addResult(r: var TResults, test: TTest, + expected, given: string, success: TResultEnum) = + let name = test.name.extractFilename & test.options + backend.writeTestResult(name = name, + category = test.cat.string, + target = $test.target, + action = $test.action, + result = $success, + expected = expected, + given = given) + r.data.addf("$#\t$#\t$#\t$#", name, expected, given, $success) + +proc cmpMsgs(r: var TResults, expected, given: TSpec, test: TTest) = + if strip(expected.msg) notin strip(given.msg): + r.addResult(test, expected.msg, given.msg, reMsgsDiffer) + elif extractFilename(expected.file) != extractFilename(given.file) and + "internal error:" notin expected.msg: + r.addResult(test, expected.file, given.file, reFilesDiffer) + elif expected.line != given.line and expected.line != 0: + r.addResult(test, $expected.line, $given.line, reLinesDiffer) + else: + r.addResult(test, expected.msg, given.msg, reSuccess) + inc(r.passed) + +proc generatedFile(path, name: string, target: TTarget): string = + let ext = targetToExt[target] + result = path / "nimcache" / + (if target == targetJS: path.splitPath.tail & "_" else: "") & + name.changeFileExt(ext) + +proc codegenCheck(test: TTest, check: string, given: var TSpec) = + if check.len > 0: + try: + let (path, name, ext2) = test.name.splitFile + let genFile = generatedFile(path, name, test.target) + echo genFile + let contents = readFile(genFile).string + if contents.find(check.peg) < 0: + given.err = reCodegenFailure + except EInvalidValue: + given.err = reInvalidPeg + except EIO: + given.err = reCodeNotFound + +proc testSpec(r: var TResults, test: TTest) = + # major entry point for a single test + let tname = test.name.addFileExt(".nim") + inc(r.total) + echo extractFilename(tname) + var expected = parseSpec(tname) + if expected.err == reIgnored: + r.addResult(test, "", "", reIgnored) + inc(r.skipped) + else: + case expected.action + of actionCompile: + var given = callCompiler(expected.cmd, test.name, test.options) + if given.err == reSuccess: + codegenCheck(test, expected.ccodeCheck, given) + r.addResult(test, "", given.msg, given.err) + if given.err == reSuccess: inc(r.passed) + of actionRun: + var given = callCompiler(expected.cmd, test.name, test.options) + if given.err != reSuccess: + r.addResult(test, "", given.msg, given.err) + else: + var exeFile: string + if test.target == targetJS: + let (dir, file, ext) = splitFile(tname) + exeFile = dir / "nimcache" / file & ".js" + else: + exeFile = changeFileExt(tname, ExeExt) + + if existsFile(exeFile): + var (buf, exitCode) = execCmdEx( + (if test.target==targetJS: "node " else: "") & exeFile) + if exitCode != expected.ExitCode: + r.addResult(test, "exitcode: " & $expected.exitCode, + "exitcode: " & $exitCode, reExitCodesDiffer) + else: + if strip(buf.string) != strip(expected.outp): + if not (expected.substr and expected.outp in buf.string): + given.err = reOutputsDiffer + if given.err == reSuccess: + codeGenCheck(test, expected.ccodeCheck, given) + if given.err == reSuccess: inc(r.passed) + r.addResult(test, expected.outp, buf.string, given.err) + else: + r.addResult(test, expected.outp, "executable not found", reExeNotFound) + of actionReject: + var given = callCompiler(expected.cmd, test.name, test.options) + cmpMsgs(r, expected, given, test) + +proc testNoSpec(r: var TResults, test: TTest) = + # does not extract the spec because the file is not supposed to have any + let tname = test.name.addFileExt(".nim") + inc(r.total) + echo extractFilename(tname) + let given = callCompiler(cmdTemplate, test.name, test.options) + r.addResult(test, "", given.msg, given.err) + if given.err == reSuccess: inc(r.passed) + +proc makeTest(test, options: string, cat: Category, action = actionCompile, + target = targetC): TTest = + # start with 'actionCompile', will be overwritten in the spec: + result = TTest(cat: cat, name: test, options: options, + target: target, action: action) + +include categories + +proc toJson(res: TResults): PJsonNode = + result = newJObject() + result["total"] = newJInt(res.total) + result["passed"] = newJInt(res.passed) + result["skipped"] = newJInt(res.skipped) + +proc outputJson(reject, compile, run: TResults) = + var doc = newJObject() + doc["reject"] = toJson(reject) + doc["compile"] = toJson(compile) + doc["run"] = toJson(run) + var s = pretty(doc) + writeFile(jsonFile, s) + +# proc runCaasTests(r: var TResults) = +# for test, output, status, mode in caasTestsRunner(): +# r.addResult(test, "", output & "-> " & $mode, +# if status: reSuccess else: reOutputsDiffer) + +proc main() = + os.putenv "NIMTEST_NO_COLOR", "1" + os.putenv "NIMTEST_OUTPUT_LVL", "PRINT_FAILURES" + + backend.open() + var optPrintResults = false + var p = initOptParser() + p.next() + if p.kind == cmdLongoption: + case p.key.string.normalize + of "print", "verbose": optPrintResults = true + else: quit usage + p.next() + if p.kind != cmdArgument: quit usage + var action = p.key.string.normalize + p.next() + var r = initResults() + case action + of "all": + for kind, dir in walkDir("tests"): + if kind == pcDir and dir notin ["testament", "testdata", "nimcache"]: + processCategory(r, Category(dir), p.cmdLineRest.string) + for a in AdditionalCategories: + processCategory(r, Category(a), p.cmdLineRest.string) + of "c", "cat", "category": + var cat = Category(p.key) + p.next + processCategory(r, cat, p.cmdLineRest.string) + of "html": + var commit = 0 + discard parseInt(p.cmdLineRest.string, commit) + generateHtml(resultsFile, commit) + else: + quit usage + + if optPrintResults: + if action == "html": openDefaultBrowser(resultsFile) + else: echo r, r.data + backend.close() + +if paramCount() == 0: + quit usage +main() + diff --git a/tests/reject/tdisallowif.nim b/tests/trmacros/tdisallowif.nim index 10f54288a..18dfd1c82 100644 --- a/tests/reject/tdisallowif.nim +++ b/tests/trmacros/tdisallowif.nim @@ -1,6 +1,7 @@ discard """ line: 24 errormsg: "usage of 'disallowIf' is a user-defined error" + disabled: true """ template optZero{x+x}(x: int): int = x*3 @@ -25,4 +26,4 @@ if s[0] != "hi": echo "do it" echo "more branches" else: - nil + discard diff --git a/tests/run/tanontuples.nim b/tests/tuples/tanontuples.nim index a2babf038..a2babf038 100644 --- a/tests/run/tanontuples.nim +++ b/tests/tuples/tanontuples.nim diff --git a/tests/reject/twrongtupleaccess.nim b/tests/tuples/twrongtupleaccess.nim index 1a9ae64a2..1a9ae64a2 100644 --- a/tests/reject/twrongtupleaccess.nim +++ b/tests/tuples/twrongtupleaccess.nim diff --git a/tests/compile/tcommontype.nim b/tests/typerel/tcommontype.nim index 8215ebd5e..8215ebd5e 100644 --- a/tests/compile/tcommontype.nim +++ b/tests/typerel/tcommontype.nim diff --git a/tests/reject/tno_int_in_bool_context.nim b/tests/typerel/tno_int_in_bool_context.nim index 755a02c0c..755a02c0c 100644 --- a/tests/reject/tno_int_in_bool_context.nim +++ b/tests/typerel/tno_int_in_bool_context.nim diff --git a/tests/compile/tnoargopenarray.nim b/tests/typerel/tnoargopenarray.nim index 872ec86d2..872ec86d2 100644 --- a/tests/compile/tnoargopenarray.nim +++ b/tests/typerel/tnoargopenarray.nim diff --git a/tests/reject/tnocontains.nim b/tests/typerel/tnocontains.nim index 4f4951478..4f4951478 100644 --- a/tests/reject/tnocontains.nim +++ b/tests/typerel/tnocontains.nim diff --git a/tests/compile/trectuple.nim b/tests/typerel/trectuple.nim index 7c43ec5ba..7c43ec5ba 100644 --- a/tests/compile/trectuple.nim +++ b/tests/typerel/trectuple.nim diff --git a/tests/compile/trectuples.nim b/tests/typerel/trectuples.nim index c59cfe880..c59cfe880 100644 --- a/tests/compile/trectuples.nim +++ b/tests/typerel/trectuples.nim diff --git a/tests/reject/trectype.nim b/tests/typerel/trectype.nim index 7bb12a3b6..7bb12a3b6 100644 --- a/tests/reject/trectype.nim +++ b/tests/typerel/trectype.nim diff --git a/tests/reject/trefs.nim b/tests/typerel/trefs.nim index b157ca2b5..b157ca2b5 100644 --- a/tests/reject/trefs.nim +++ b/tests/typerel/trefs.nim diff --git a/tests/run/trettypeinference.nim b/tests/typerel/trettypeinference.nim index 41b4aa5ef..41b4aa5ef 100644 --- a/tests/run/trettypeinference.nim +++ b/tests/typerel/trettypeinference.nim diff --git a/tests/compile/tsecondarrayproperty.nim b/tests/typerel/tsecondarrayproperty.nim index 07fdac1c4..07fdac1c4 100644 --- a/tests/compile/tsecondarrayproperty.nim +++ b/tests/typerel/tsecondarrayproperty.nim diff --git a/tests/compile/ttuple1.nim b/tests/typerel/ttuple1.nim index 5787cc309..5787cc309 100644 --- a/tests/compile/ttuple1.nim +++ b/tests/typerel/ttuple1.nim diff --git a/tests/reject/ttypelessemptyset.nim b/tests/typerel/ttypelessemptyset.nim index 3e171387b..3e171387b 100644 --- a/tests/reject/ttypelessemptyset.nim +++ b/tests/typerel/ttypelessemptyset.nim diff --git a/tests/reject/ttypenoval.nim b/tests/typerel/ttypenoval.nim index 214b35e29..214b35e29 100644 --- a/tests/reject/ttypenoval.nim +++ b/tests/typerel/ttypenoval.nim diff --git a/tests/reject/ttypenovalue.nim b/tests/typerel/ttypenovalue.nim index b86baf8b4..b86baf8b4 100644 --- a/tests/reject/ttypenovalue.nim +++ b/tests/typerel/ttypenovalue.nim diff --git a/tests/compile/tvoid.nim b/tests/typerel/tvoid.nim index bb569e7f8..bb569e7f8 100644 --- a/tests/compile/tvoid.nim +++ b/tests/typerel/tvoid.nim diff --git a/tests/compile/typalias.nim b/tests/typerel/typalias.nim index ba9f38ed9..ba9f38ed9 100644 --- a/tests/compile/typalias.nim +++ b/tests/typerel/typalias.nim diff --git a/tests/reject/typredef.nim b/tests/typerel/typredef.nim index b2182d116..0b6aed875 100644 --- a/tests/reject/typredef.nim +++ b/tests/typerel/typredef.nim @@ -3,8 +3,6 @@ discard """ line: 7 errormsg: "illegal recursion in type \'Uint8\'" """ -type - Uint8 = Uint8 #ERROR_MSG illegal recursion in type 'Uint8' - - +type + Uint8 = Uint8 #ERROR_MSG illegal recursion in type 'Uint8' diff --git a/tests/run/tfinalobj.nim b/tests/types/tfinalobj.nim index 1cd7fae28..1cd7fae28 100644 --- a/tests/run/tfinalobj.nim +++ b/tests/types/tfinalobj.nim diff --git a/tests/compile/tforwty.nim b/tests/types/tforwty.nim index 0f1d3697f..0f1d3697f 100644 --- a/tests/compile/tforwty.nim +++ b/tests/types/tforwty.nim diff --git a/tests/compile/tforwty2.nim b/tests/types/tforwty2.nim index 5d15e112a..5d15e112a 100644 --- a/tests/compile/tforwty2.nim +++ b/tests/types/tforwty2.nim diff --git a/tests/reject/tillegaltyperecursion.nim b/tests/types/tillegaltyperecursion.nim index 711f458bf..711f458bf 100644 --- a/tests/reject/tillegaltyperecursion.nim +++ b/tests/types/tillegaltyperecursion.nim diff --git a/tests/reject/tillrec.nim b/tests/types/tillrec.nim index 3f8fe60fc..1d1ec0622 100644 --- a/tests/reject/tillrec.nim +++ b/tests/types/tillrec.nim @@ -3,15 +3,14 @@ discard """ line: 13 errormsg: "illegal recursion in type \'TIllegal\'" """ -# test illegal recursive types - -type - TLegal {.final.} = object - x: int - kids: seq[TLegal] - - TIllegal {.final.} = object #ERROR_MSG illegal recursion in type 'TIllegal' - y: Int - x: array[0..3, TIllegal] +# test illegal recursive types +type + TLegal {.final.} = object + x: int + kids: seq[TLegal] + + TIllegal {.final.} = object #ERROR_MSG illegal recursion in type 'TIllegal' + y: Int + x: array[0..3, TIllegal] diff --git a/tests/compile/tinheritref.nim b/tests/types/tinheritref.nim index e5de6a4be..e5de6a4be 100644 --- a/tests/compile/tinheritref.nim +++ b/tests/types/tinheritref.nim diff --git a/tests/compile/tisop.nim b/tests/types/tisop.nim index 509cc4e95..509cc4e95 100644 --- a/tests/compile/tisop.nim +++ b/tests/types/tisop.nim diff --git a/tests/run/tisopr.nim b/tests/types/tisopr.nim index 6d3c51749..6d3c51749 100644 --- a/tests/run/tisopr.nim +++ b/tests/types/tisopr.nim diff --git a/tests/run/tusingstatement.nim b/tests/usingstmt/tusingstatement.nim index b9d466377..a33aced4c 100644 --- a/tests/run/tusingstatement.nim +++ b/tests/usingstmt/tusingstatement.nim @@ -8,25 +8,11 @@ import # This macro mimics the using statement from C# # -# XXX: -# It doen't match the C# version exactly yet. -# In particular, it's not recursive, which prevents it from dealing -# with exceptions thrown from the variable initializers when multiple. -# variables are used. +# It's kept only as a test for the macro system +# Nimrod's destructors offer a mechanism for automatic +# disposal of resources. # -# Also, since nimrod relies less on exceptions in general, a more -# idiomatic definition could be: -# var x = init() -# if opened(x): -# try: -# body -# finally: -# close(x) -# -# `opened` here could be an overloaded proc which any type can define. -# A common practice can be returing an Optional[Resource] obj for which -# `opened` is defined to `optional.hasValue` -macro using(e: expr): stmt {.immediate.} = +macro autoClose(e: expr): stmt {.immediate.} = let e = callsite() if e.len != 3: error "Using statement: unexpected number of arguments. Got " & @@ -97,7 +83,7 @@ proc close(r: var TResource) = proc use(r: var TResource) = write(stdout, "Using " & r.field & ".") -using(r = openResource("test")): +autoClose(r = openResource("test")): use r diff --git a/tests/reject/tvarres1.nim b/tests/varres/tvarres1.nim index de4a505d3..de4a505d3 100644 --- a/tests/reject/tvarres1.nim +++ b/tests/varres/tvarres1.nim diff --git a/tests/reject/tvarres2.nim b/tests/varres/tvarres2.nim index 165e4a36e..165e4a36e 100644 --- a/tests/reject/tvarres2.nim +++ b/tests/varres/tvarres2.nim diff --git a/tests/run/tvarres1.nim b/tests/varres/tvarres3.nim index a48c961df..a48c961df 100644 --- a/tests/run/tvarres1.nim +++ b/tests/varres/tvarres3.nim diff --git a/tests/run/tvarres2.nim b/tests/varres/tvarres4.nim index 119560e7b..119560e7b 100644 --- a/tests/run/tvarres2.nim +++ b/tests/varres/tvarres4.nim diff --git a/tests/run/tvartup.nim b/tests/varres/tvartup.nim index f885cdf37..f885cdf37 100644 --- a/tests/run/tvartup.nim +++ b/tests/varres/tvartup.nim diff --git a/tests/run/tlet.nim b/tests/varstmt/tlet.nim index ba355c5d8..ba355c5d8 100644 --- a/tests/run/tlet.nim +++ b/tests/varstmt/tlet.nim diff --git a/tests/run/tvardecl.nim b/tests/varstmt/tvardecl.nim index 5cc6f4960..5cc6f4960 100644 --- a/tests/run/tvardecl.nim +++ b/tests/varstmt/tvardecl.nim diff --git a/tests/compile/tconsteval.nim b/tests/vm/tconsteval.nim index 16fd8f4b8..16fd8f4b8 100644 --- a/tests/compile/tconsteval.nim +++ b/tests/vm/tconsteval.nim diff --git a/tests/compile/teval1.nim b/tests/vm/teval1.nim index a02f26592..a02f26592 100644 --- a/tests/compile/teval1.nim +++ b/tests/vm/teval1.nim diff --git a/tests/compile/tslurp.nim b/tests/vm/tslurp.nim index f9456ce6b..f9456ce6b 100644 --- a/tests/compile/tslurp.nim +++ b/tests/vm/tslurp.nim diff --git a/tests/reject/twrongconst.nim b/tests/vm/twrongconst.nim index 16fe3bff6..e5b8a15bd 100644 --- a/tests/reject/twrongconst.nim +++ b/tests/vm/twrongconst.nim @@ -1,6 +1,6 @@ discard """ - output: "Error: constant expression expected" - line: 7 + output: "Error: cannot evaluate at compile time: x" + line: 10 """ var x: array[100, char] diff --git a/todo.txt b/todo.txt index da7585500..067c376ad 100644 --- a/todo.txt +++ b/todo.txt @@ -1,26 +1,30 @@ version 0.9.4 ============= -- new VM: - - implement the glue to replace evals.nim - - implement missing magics - - implement overflow checking - - implement the FFI +- test&finish first class iterators: + * nested iterators +- ``--gc:none`` should complain about when you use the GC +- ensure (ref T)(a, b) works as a type conversion and type constructor +- document new templating symbol binding rules +- make '--implicitStatic:on' the default -- make 'bind' default for templates and introduce 'mixin' - special rule for ``[]=`` - ``=`` should be overloadable; requires specialization for ``=``; general lift mechanism in the compiler is already implemented for 'fields' - built-in 'getImpl' - optimize 'genericReset'; 'newException' leads to code bloat - stack-less GC +- fix eval in macros.nim Bugs ==== +- new VM: + - implement overflow checking +- bug: 'type T = ref T' not recognized as illegal recursion +- bug: type conversions concerning proc types are weird - compilation of niminst takes way too long. looks like a regression -- simple closure iterator doesn't work - docgen: sometimes effects are listed twice - 'result' is not properly cleaned for NRVO --> use uninit checking instead - sneaking with qualifiedLookup() is really broken! @@ -29,7 +33,6 @@ Bugs - blocks can "export" an identifier but the CCG generates {} for them ... - osproc execProcesses can deadlock if all processes fail (as experienced in c++ mode) -- result = result shr 8 for the "system()" wrapper version 0.9.x @@ -38,7 +41,6 @@ version 0.9.x - macros as type pragmas - implicit deref for parameter matching - lazy overloading resolution: - * get rid of ``expr[typ]``, use perhaps ``static[typ]`` instead * special case ``tyStmt`` - FFI: * test libffi on windows @@ -50,8 +52,6 @@ version 0.9.x version 0.9.X ============= -- test&finish first class iterators: - * nested iterators - implement the missing features wrt inheritance - better support for macros that rewrite procs - macros need access to types and symbols (partially implemented) @@ -86,7 +86,6 @@ Concurrency/Effect system version 0.9.XX ============== -- document nimdoc properly finally - make 'clamp' a magic for the range stuff - better type syntax for functions and tuples: tuple(int, int); (int,int)->int diff --git a/tools/cmerge.nim b/tools/cmerge.nim index ca221014f..003b0e555 100644 --- a/tools/cmerge.nim +++ b/tools/cmerge.nim @@ -34,7 +34,7 @@ proc main(dir, outfile: string) = else: quit("Cannot open for writing: " & outfile) -if ParamCount() != 2: +if paramCount() != 2: quit "Usage: cmerge directory outfile" else: - main(ParamStr(1), addFileExt(ParamStr(2), "c")) + main(paramStr(1), addFileExt(paramStr(2), "c")) diff --git a/tools/detect/detect.nim b/tools/detect/detect.nim index cf61c2823..87b682ad5 100644 --- a/tools/detect/detect.nim +++ b/tools/detect/detect.nim @@ -10,7 +10,7 @@ import os, strutils const - cc = "gcc -o $1 $1.c" + cc = "gcc -o $# $#.c" cfile = """ /* Generated by detect.nim */ @@ -37,6 +37,7 @@ var tl = "" proc myExec(cmd: string): bool = + echo "CMD ", cmd return execShellCmd(cmd) == 0 proc header(s: string): bool = @@ -46,7 +47,7 @@ proc header(s: string): bool = f.write("#include $1\n" % s) f.write("int main() { return 0; }\n") close(f) - result = myExec(cc % testh) + result = myExec(cc % [testh.addFileExt(ExeExt), testh]) removeFile(addFileExt(testh, "c")) if result: addf(hd, "#include $1\n", s) @@ -60,13 +61,16 @@ proc main = if open(f, addFileExt(gen, "c"), fmWrite): f.write(cfile % [hd, tl, system.hostOS, system.hostCPU]) close(f) - if not myExec(cc % gen): quit(1) - if not myExec("./" & gen): quit(1) - removeFile(addFileExt(gen, "c")) + if not myExec(cc % [gen.addFileExt(ExeExt), gen]): quit(1) + when defined(windows): + if not myExec(gen.addFileExt(ExeExt)): quit(1) + else: + if not myExec("./" & gen): quit(1) + #removeFile(addFileExt(gen, "c")) echo("Success") proc v(name: string, typ: TTypeKind=cint) = - var n = if name[0] == '_': copy(name, 1) else: name + var n = if name[0] == '_': substr(name, 1) else: name var t = $typ case typ of pointer: @@ -369,7 +373,7 @@ if header("<pthread.h>"): #v("PTHREAD_MUTEX_INITIALIZER") v("PTHREAD_MUTEX_NORMAL") v("PTHREAD_MUTEX_RECURSIVE") #{.importc, header: "<pthread.h>".}: cint - v("PTHREAD_ONCE_INIT") #{.importc, header: "<pthread.h>".}: cint + #v("PTHREAD_ONCE_INIT") #{.importc, header: "<pthread.h>".}: cint v("PTHREAD_PRIO_INHERIT") #{.importc, header: "<pthread.h>".}: cint v("PTHREAD_PRIO_NONE") #{.importc, header: "<pthread.h>".}: cint v("PTHREAD_PRIO_PROTECT") #{.importc, header: "<pthread.h>".}: cint @@ -820,5 +824,8 @@ if header("<spawn.h>"): v("POSIX_SPAWN_SETSIGDEF") v("POSIX_SPAWN_SETSIGMASK") -main() +if header("<stdio.h>"): + v "_IOFBF" + v "_IONBF" +main() diff --git a/tools/detect/linux_amd64_consts.nim b/tools/detect/linux_amd64_consts.nim new file mode 100644 index 000000000..eb85da045 --- /dev/null +++ b/tools/detect/linux_amd64_consts.nim @@ -0,0 +1,631 @@ +# Generated by detect.nim +const + AIO_ALLDONE* = cint(2) + AIO_CANCELED* = cint(0) + AIO_NOTCANCELED* = cint(1) + LIO_NOP* = cint(2) + LIO_NOWAIT* = cint(1) + LIO_READ* = cint(0) + LIO_WAIT* = cint(0) + LIO_WRITE* = cint(1) + RTLD_LAZY* = cint(1) + RTLD_NOW* = cint(2) + RTLD_GLOBAL* = cint(256) + RTLD_LOCAL* = cint(0) + E2BIG* = cint(7) + EACCES* = cint(13) + EADDRINUSE* = cint(98) + EADDRNOTAVAIL* = cint(99) + EAFNOSUPPORT* = cint(97) + EAGAIN* = cint(11) + EALREADY* = cint(114) + EBADF* = cint(9) + EBADMSG* = cint(74) + EBUSY* = cint(16) + ECANCELED* = cint(125) + ECHILD* = cint(10) + ECONNABORTED* = cint(103) + ECONNREFUSED* = cint(111) + ECONNRESET* = cint(104) + EDEADLK* = cint(35) + EDESTADDRREQ* = cint(89) + EDOM* = cint(33) + EDQUOT* = cint(122) + EEXIST* = cint(17) + EFAULT* = cint(14) + EFBIG* = cint(27) + EHOSTUNREACH* = cint(113) + EIDRM* = cint(43) + EILSEQ* = cint(84) + EINPROGRESS* = cint(115) + EINTR* = cint(4) + EINVAL* = cint(22) + EIO* = cint(5) + EISCONN* = cint(106) + EISDIR* = cint(21) + ELOOP* = cint(40) + EMFILE* = cint(24) + EMLINK* = cint(31) + EMSGSIZE* = cint(90) + EMULTIHOP* = cint(72) + ENAMETOOLONG* = cint(36) + ENETDOWN* = cint(100) + ENETRESET* = cint(102) + ENETUNREACH* = cint(101) + ENFILE* = cint(23) + ENOBUFS* = cint(105) + ENODATA* = cint(61) + ENODEV* = cint(19) + ENOENT* = cint(2) + ENOEXEC* = cint(8) + ENOLCK* = cint(37) + ENOLINK* = cint(67) + ENOMEM* = cint(12) + ENOMSG* = cint(42) + ENOPROTOOPT* = cint(92) + ENOSPC* = cint(28) + ENOSR* = cint(63) + ENOSTR* = cint(60) + ENOSYS* = cint(38) + ENOTCONN* = cint(107) + ENOTDIR* = cint(20) + ENOTEMPTY* = cint(39) + ENOTSOCK* = cint(88) + ENOTSUP* = cint(95) + ENOTTY* = cint(25) + ENXIO* = cint(6) + EOPNOTSUPP* = cint(95) + EOVERFLOW* = cint(75) + EPERM* = cint(1) + EPIPE* = cint(32) + EPROTO* = cint(71) + EPROTONOSUPPORT* = cint(93) + EPROTOTYPE* = cint(91) + ERANGE* = cint(34) + EROFS* = cint(30) + ESPIPE* = cint(29) + ESRCH* = cint(3) + ESTALE* = cint(116) + ETIME* = cint(62) + ETIMEDOUT* = cint(110) + ETXTBSY* = cint(26) + EWOULDBLOCK* = cint(11) + EXDEV* = cint(18) + F_DUPFD* = cint(0) + F_GETFD* = cint(1) + F_SETFD* = cint(2) + F_GETFL* = cint(3) + F_SETFL* = cint(4) + F_GETLK* = cint(5) + F_SETLK* = cint(6) + F_SETLKW* = cint(7) + F_GETOWN* = cint(9) + F_SETOWN* = cint(8) + FD_CLOEXEC* = cint(1) + F_RDLCK* = cint(0) + F_UNLCK* = cint(2) + F_WRLCK* = cint(1) + O_CREAT* = cint(64) + O_EXCL* = cint(128) + O_NOCTTY* = cint(256) + O_TRUNC* = cint(512) + O_APPEND* = cint(1024) + O_DSYNC* = cint(4096) + O_NONBLOCK* = cint(2048) + O_RSYNC* = cint(1052672) + O_SYNC* = cint(1052672) + O_ACCMODE* = cint(3) + O_RDONLY* = cint(0) + O_RDWR* = cint(2) + O_WRONLY* = cint(1) + POSIX_FADV_NORMAL* = cint(0) + POSIX_FADV_SEQUENTIAL* = cint(2) + POSIX_FADV_RANDOM* = cint(1) + POSIX_FADV_WILLNEED* = cint(3) + POSIX_FADV_DONTNEED* = cint(4) + POSIX_FADV_NOREUSE* = cint(5) + FE_DIVBYZERO* = cint(4) + FE_INEXACT* = cint(32) + FE_INVALID* = cint(1) + FE_OVERFLOW* = cint(8) + FE_UNDERFLOW* = cint(16) + FE_ALL_EXCEPT* = cint(61) + FE_DOWNWARD* = cint(1024) + FE_TONEAREST* = cint(0) + FE_TOWARDZERO* = cint(3072) + FE_UPWARD* = cint(2048) + FE_DFL_ENV* = cast[pointer](0xffffffffffffffff) + MM_HARD* = cint(1) + MM_SOFT* = cint(2) + MM_FIRM* = cint(4) + MM_APPL* = cint(8) + MM_UTIL* = cint(16) + MM_OPSYS* = cint(32) + MM_RECOVER* = cint(64) + MM_NRECOV* = cint(128) + MM_HALT* = cint(1) + MM_ERROR* = cint(2) + MM_WARNING* = cint(3) + MM_INFO* = cint(4) + MM_NOSEV* = cint(0) + MM_PRINT* = cint(256) + MM_CONSOLE* = cint(512) + MM_OK* = cint(0) + MM_NOTOK* = cint(-1) + MM_NOMSG* = cint(1) + MM_NOCON* = cint(4) + FNM_NOMATCH* = cint(1) + FNM_PATHNAME* = cint(1) + FNM_PERIOD* = cint(4) + FNM_NOESCAPE* = cint(2) + FTW_F* = cint(0) + FTW_D* = cint(1) + FTW_DNR* = cint(2) + FTW_NS* = cint(3) + FTW_SL* = cint(4) + GLOB_APPEND* = cint(32) + GLOB_DOOFFS* = cint(8) + GLOB_ERR* = cint(1) + GLOB_MARK* = cint(2) + GLOB_NOCHECK* = cint(16) + GLOB_NOESCAPE* = cint(64) + GLOB_NOSORT* = cint(4) + GLOB_ABORTED* = cint(2) + GLOB_NOMATCH* = cint(3) + GLOB_NOSPACE* = cint(1) + GLOB_NOSYS* = cint(4) + CODESET* = cint(14) + D_T_FMT* = cint(131112) + D_FMT* = cint(131113) + T_FMT* = cint(131114) + T_FMT_AMPM* = cint(131115) + AM_STR* = cint(131110) + PM_STR* = cint(131111) + DAY_1* = cint(131079) + DAY_2* = cint(131080) + DAY_3* = cint(131081) + DAY_4* = cint(131082) + DAY_5* = cint(131083) + DAY_6* = cint(131084) + DAY_7* = cint(131085) + ABDAY_1* = cint(131072) + ABDAY_2* = cint(131073) + ABDAY_3* = cint(131074) + ABDAY_4* = cint(131075) + ABDAY_5* = cint(131076) + ABDAY_6* = cint(131077) + ABDAY_7* = cint(131078) + MON_1* = cint(131098) + MON_2* = cint(131099) + MON_3* = cint(131100) + MON_4* = cint(131101) + MON_5* = cint(131102) + MON_6* = cint(131103) + MON_7* = cint(131104) + MON_8* = cint(131105) + MON_9* = cint(131106) + MON_10* = cint(131107) + MON_11* = cint(131108) + MON_12* = cint(131109) + ABMON_1* = cint(131086) + ABMON_2* = cint(131087) + ABMON_3* = cint(131088) + ABMON_4* = cint(131089) + ABMON_5* = cint(131090) + ABMON_6* = cint(131091) + ABMON_7* = cint(131092) + ABMON_8* = cint(131093) + ABMON_9* = cint(131094) + ABMON_10* = cint(131095) + ABMON_11* = cint(131096) + ABMON_12* = cint(131097) + ERA* = cint(131116) + ERA_D_FMT* = cint(131118) + ERA_D_T_FMT* = cint(131120) + ERA_T_FMT* = cint(131121) + ALT_DIGITS* = cint(131119) + RADIXCHAR* = cint(65536) + THOUSEP* = cint(65537) + YESEXPR* = cint(327680) + NOEXPR* = cint(327681) + CRNCYSTR* = cint(262159) + LC_ALL* = cint(6) + LC_COLLATE* = cint(3) + LC_CTYPE* = cint(0) + LC_MESSAGES* = cint(5) + LC_MONETARY* = cint(4) + LC_NUMERIC* = cint(1) + LC_TIME* = cint(2) + PTHREAD_BARRIER_SERIAL_THREAD* = cint(-1) + PTHREAD_CANCEL_ASYNCHRONOUS* = cint(1) + PTHREAD_CANCEL_ENABLE* = cint(0) + PTHREAD_CANCEL_DEFERRED* = cint(0) + PTHREAD_CANCEL_DISABLE* = cint(1) + PTHREAD_CREATE_DETACHED* = cint(1) + PTHREAD_CREATE_JOINABLE* = cint(0) + PTHREAD_EXPLICIT_SCHED* = cint(1) + PTHREAD_INHERIT_SCHED* = cint(0) + PTHREAD_PROCESS_SHARED* = cint(1) + PTHREAD_PROCESS_PRIVATE* = cint(0) + PTHREAD_SCOPE_PROCESS* = cint(1) + PTHREAD_SCOPE_SYSTEM* = cint(0) + POSIX_ASYNC_IO* = cint(1) + F_OK* = cint(0) + R_OK* = cint(4) + W_OK* = cint(2) + X_OK* = cint(1) + CS_PATH* = cint(0) + CS_POSIX_V6_ILP32_OFF32_CFLAGS* = cint(1116) + CS_POSIX_V6_ILP32_OFF32_LDFLAGS* = cint(1117) + CS_POSIX_V6_ILP32_OFF32_LIBS* = cint(1118) + CS_POSIX_V6_ILP32_OFFBIG_CFLAGS* = cint(1120) + CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS* = cint(1121) + CS_POSIX_V6_ILP32_OFFBIG_LIBS* = cint(1122) + CS_POSIX_V6_LP64_OFF64_CFLAGS* = cint(1124) + CS_POSIX_V6_LP64_OFF64_LDFLAGS* = cint(1125) + CS_POSIX_V6_LP64_OFF64_LIBS* = cint(1126) + CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS* = cint(1128) + CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS* = cint(1129) + CS_POSIX_V6_LPBIG_OFFBIG_LIBS* = cint(1130) + CS_POSIX_V6_WIDTH_RESTRICTED_ENVS* = cint(1) + F_LOCK* = cint(1) + F_TEST* = cint(3) + F_TLOCK* = cint(2) + F_ULOCK* = cint(0) + PC_2_SYMLINKS* = cint(20) + PC_ALLOC_SIZE_MIN* = cint(18) + PC_ASYNC_IO* = cint(10) + PC_CHOWN_RESTRICTED* = cint(6) + PC_FILESIZEBITS* = cint(13) + PC_LINK_MAX* = cint(0) + PC_MAX_CANON* = cint(1) + PC_MAX_INPUT* = cint(2) + PC_NAME_MAX* = cint(3) + PC_NO_TRUNC* = cint(7) + PC_PATH_MAX* = cint(4) + PC_PIPE_BUF* = cint(5) + PC_PRIO_IO* = cint(11) + PC_REC_INCR_XFER_SIZE* = cint(14) + PC_REC_MIN_XFER_SIZE* = cint(16) + PC_REC_XFER_ALIGN* = cint(17) + PC_SYMLINK_MAX* = cint(19) + PC_SYNC_IO* = cint(9) + PC_VDISABLE* = cint(8) + SC_2_C_BIND* = cint(47) + SC_2_C_DEV* = cint(48) + SC_2_CHAR_TERM* = cint(95) + SC_2_FORT_DEV* = cint(49) + SC_2_FORT_RUN* = cint(50) + SC_2_LOCALEDEF* = cint(52) + SC_2_PBS* = cint(168) + SC_2_PBS_ACCOUNTING* = cint(169) + SC_2_PBS_CHECKPOINT* = cint(175) + SC_2_PBS_LOCATE* = cint(170) + SC_2_PBS_MESSAGE* = cint(171) + SC_2_PBS_TRACK* = cint(172) + SC_2_SW_DEV* = cint(51) + SC_2_UPE* = cint(97) + SC_2_VERSION* = cint(46) + SC_ADVISORY_INFO* = cint(132) + SC_AIO_LISTIO_MAX* = cint(23) + SC_AIO_MAX* = cint(24) + SC_AIO_PRIO_DELTA_MAX* = cint(25) + SC_ARG_MAX* = cint(0) + SC_ASYNCHRONOUS_IO* = cint(12) + SC_ATEXIT_MAX* = cint(87) + SC_BARRIERS* = cint(133) + SC_BC_BASE_MAX* = cint(36) + SC_BC_DIM_MAX* = cint(37) + SC_BC_SCALE_MAX* = cint(38) + SC_BC_STRING_MAX* = cint(39) + SC_CHILD_MAX* = cint(1) + SC_CLK_TCK* = cint(2) + SC_CLOCK_SELECTION* = cint(137) + SC_COLL_WEIGHTS_MAX* = cint(40) + SC_CPUTIME* = cint(138) + SC_DELAYTIMER_MAX* = cint(26) + SC_EXPR_NEST_MAX* = cint(42) + SC_FSYNC* = cint(15) + SC_GETGR_R_SIZE_MAX* = cint(69) + SC_GETPW_R_SIZE_MAX* = cint(70) + SC_HOST_NAME_MAX* = cint(180) + SC_IOV_MAX* = cint(60) + SC_IPV6* = cint(235) + SC_JOB_CONTROL* = cint(7) + SC_LINE_MAX* = cint(43) + SC_LOGIN_NAME_MAX* = cint(71) + SC_MAPPED_FILES* = cint(16) + SC_MEMLOCK* = cint(17) + SC_MEMLOCK_RANGE* = cint(18) + SC_MEMORY_PROTECTION* = cint(19) + SC_MESSAGE_PASSING* = cint(20) + SC_MONOTONIC_CLOCK* = cint(149) + SC_MQ_OPEN_MAX* = cint(27) + SC_MQ_PRIO_MAX* = cint(28) + SC_NGROUPS_MAX* = cint(3) + SC_OPEN_MAX* = cint(4) + SC_PAGE_SIZE* = cint(30) + SC_PRIORITIZED_IO* = cint(13) + SC_PRIORITY_SCHEDULING* = cint(10) + SC_RAW_SOCKETS* = cint(236) + SC_RE_DUP_MAX* = cint(44) + SC_READER_WRITER_LOCKS* = cint(153) + SC_REALTIME_SIGNALS* = cint(9) + SC_REGEXP* = cint(155) + SC_RTSIG_MAX* = cint(31) + SC_SAVED_IDS* = cint(8) + SC_SEM_NSEMS_MAX* = cint(32) + SC_SEM_VALUE_MAX* = cint(33) + SC_SEMAPHORES* = cint(21) + SC_SHARED_MEMORY_OBJECTS* = cint(22) + SC_SHELL* = cint(157) + SC_SIGQUEUE_MAX* = cint(34) + SC_SPAWN* = cint(159) + SC_SPIN_LOCKS* = cint(154) + SC_SPORADIC_SERVER* = cint(160) + SC_SS_REPL_MAX* = cint(241) + SC_STREAM_MAX* = cint(5) + SC_SYMLOOP_MAX* = cint(173) + SC_SYNCHRONIZED_IO* = cint(14) + SC_THREAD_ATTR_STACKADDR* = cint(77) + SC_THREAD_ATTR_STACKSIZE* = cint(78) + SC_THREAD_CPUTIME* = cint(139) + SC_THREAD_DESTRUCTOR_ITERATIONS* = cint(73) + SC_THREAD_KEYS_MAX* = cint(74) + SC_THREAD_PRIO_INHERIT* = cint(80) + SC_THREAD_PRIO_PROTECT* = cint(81) + SC_THREAD_PRIORITY_SCHEDULING* = cint(79) + SC_THREAD_PROCESS_SHARED* = cint(82) + SC_THREAD_SAFE_FUNCTIONS* = cint(68) + SC_THREAD_SPORADIC_SERVER* = cint(161) + SC_THREAD_STACK_MIN* = cint(75) + SC_THREAD_THREADS_MAX* = cint(76) + SC_THREADS* = cint(67) + SC_TIMEOUTS* = cint(164) + SC_TIMER_MAX* = cint(35) + SC_TIMERS* = cint(11) + SC_TRACE* = cint(181) + SC_TRACE_EVENT_FILTER* = cint(182) + SC_TRACE_EVENT_NAME_MAX* = cint(242) + SC_TRACE_INHERIT* = cint(183) + SC_TRACE_LOG* = cint(184) + SC_TRACE_NAME_MAX* = cint(243) + SC_TRACE_SYS_MAX* = cint(244) + SC_TRACE_USER_EVENT_MAX* = cint(245) + SC_TTY_NAME_MAX* = cint(72) + SC_TYPED_MEMORY_OBJECTS* = cint(165) + SC_TZNAME_MAX* = cint(6) + SC_V6_ILP32_OFF32* = cint(176) + SC_V6_ILP32_OFFBIG* = cint(177) + SC_V6_LP64_OFF64* = cint(178) + SC_V6_LPBIG_OFFBIG* = cint(179) + SC_VERSION* = cint(29) + SC_XBS5_ILP32_OFF32* = cint(125) + SC_XBS5_ILP32_OFFBIG* = cint(126) + SC_XBS5_LP64_OFF64* = cint(127) + SC_XBS5_LPBIG_OFFBIG* = cint(128) + SC_XOPEN_CRYPT* = cint(92) + SC_XOPEN_ENH_I18N* = cint(93) + SC_XOPEN_LEGACY* = cint(129) + SC_XOPEN_REALTIME* = cint(130) + SC_XOPEN_REALTIME_THREADS* = cint(131) + SC_XOPEN_SHM* = cint(94) + SC_XOPEN_STREAMS* = cint(246) + SC_XOPEN_UNIX* = cint(91) + SC_XOPEN_VERSION* = cint(89) + SEEK_SET* = cint(0) + SEEK_CUR* = cint(1) + SEEK_END* = cint(2) + SEM_FAILED* = cast[pointer]((nil)) + IPC_CREAT* = cint(512) + IPC_EXCL* = cint(1024) + IPC_NOWAIT* = cint(2048) + IPC_PRIVATE* = cint(0) + IPC_RMID* = cint(0) + IPC_SET* = cint(1) + IPC_STAT* = cint(2) + S_IFMT* = cint(61440) + S_IFBLK* = cint(24576) + S_IFCHR* = cint(8192) + S_IFIFO* = cint(4096) + S_IFREG* = cint(32768) + S_IFDIR* = cint(16384) + S_IFLNK* = cint(40960) + S_IFSOCK* = cint(49152) + S_IRWXU* = cint(448) + S_IRUSR* = cint(256) + S_IWUSR* = cint(128) + S_IXUSR* = cint(64) + S_IRWXG* = cint(56) + S_IRGRP* = cint(32) + S_IWGRP* = cint(16) + S_IXGRP* = cint(8) + S_IRWXO* = cint(7) + S_IROTH* = cint(4) + S_IWOTH* = cint(2) + S_IXOTH* = cint(1) + S_ISUID* = cint(2048) + S_ISGID* = cint(1024) + S_ISVTX* = cint(512) + ST_RDONLY* = cint(1) + ST_NOSUID* = cint(2) + PROT_READ* = cint(1) + PROT_WRITE* = cint(2) + PROT_EXEC* = cint(4) + PROT_NONE* = cint(0) + MAP_SHARED* = cint(1) + MAP_PRIVATE* = cint(2) + MAP_FIXED* = cint(16) + MS_ASYNC* = cint(1) + MS_SYNC* = cint(4) + MS_INVALIDATE* = cint(2) + MCL_CURRENT* = cint(1) + MCL_FUTURE* = cint(2) + MAP_FAILED* = cast[pointer](0xffffffffffffffff) + POSIX_MADV_NORMAL* = cint(0) + POSIX_MADV_SEQUENTIAL* = cint(2) + POSIX_MADV_RANDOM* = cint(1) + POSIX_MADV_WILLNEED* = cint(3) + POSIX_MADV_DONTNEED* = cint(4) + CLOCKS_PER_SEC* = clong(1000000) + CLOCK_PROCESS_CPUTIME_ID* = cint(2) + CLOCK_THREAD_CPUTIME_ID* = cint(3) + CLOCK_REALTIME* = cint(0) + TIMER_ABSTIME* = cint(1) + CLOCK_MONOTONIC* = cint(1) + WNOHANG* = cint(1) + WUNTRACED* = cint(2) + WEXITED* = cint(4) + WSTOPPED* = cint(2) + WCONTINUED* = cint(8) + WNOWAIT* = cint(16777216) + SIGEV_NONE* = cint(1) + SIGEV_SIGNAL* = cint(0) + SIGEV_THREAD* = cint(2) + SIGABRT* = cint(6) + SIGALRM* = cint(14) + SIGBUS* = cint(7) + SIGCHLD* = cint(17) + SIGCONT* = cint(18) + SIGFPE* = cint(8) + SIGHUP* = cint(1) + SIGILL* = cint(4) + SIGINT* = cint(2) + SIGKILL* = cint(9) + SIGPIPE* = cint(13) + SIGQUIT* = cint(3) + SIGSEGV* = cint(11) + SIGSTOP* = cint(19) + SIGTERM* = cint(15) + SIGTSTP* = cint(20) + SIGTTIN* = cint(21) + SIGTTOU* = cint(22) + SIGUSR1* = cint(10) + SIGUSR2* = cint(12) + SIGPOLL* = cint(29) + SIGPROF* = cint(27) + SIGSYS* = cint(31) + SIGTRAP* = cint(5) + SIGURG* = cint(23) + SIGVTALRM* = cint(26) + SIGXCPU* = cint(24) + SIGXFSZ* = cint(25) + SA_NOCLDSTOP* = cint(1) + SIG_BLOCK* = cint(0) + SIG_UNBLOCK* = cint(1) + SIG_SETMASK* = cint(2) + SA_ONSTACK* = cint(134217728) + SA_RESETHAND* = cint(-2147483648) + SA_RESTART* = cint(268435456) + SA_SIGINFO* = cint(4) + SA_NOCLDWAIT* = cint(2) + SA_NODEFER* = cint(1073741824) + SS_ONSTACK* = cint(1) + SS_DISABLE* = cint(2) + MINSIGSTKSZ* = cint(2048) + SIGSTKSZ* = cint(8192) + NL_SETD* = cint(1) + NL_CAT_LOCALE* = cint(1) + SCHED_FIFO* = cint(1) + SCHED_RR* = cint(2) + SCHED_OTHER* = cint(0) + FD_SETSIZE* = cint(1024) + IF_NAMESIZE* = cint(16) + SCM_RIGHTS* = cint(1) + SOCK_DGRAM* = cint(2) + SOCK_RAW* = cint(3) + SOCK_SEQPACKET* = cint(5) + SOCK_STREAM* = cint(1) + SOL_SOCKET* = cint(1) + SO_ACCEPTCONN* = cint(30) + SO_BROADCAST* = cint(6) + SO_DEBUG* = cint(1) + SO_DONTROUTE* = cint(5) + SO_ERROR* = cint(4) + SO_KEEPALIVE* = cint(9) + SO_LINGER* = cint(13) + SO_OOBINLINE* = cint(10) + SO_RCVBUF* = cint(8) + SO_RCVLOWAT* = cint(18) + SO_RCVTIMEO* = cint(20) + SO_REUSEADDR* = cint(2) + SO_SNDBUF* = cint(7) + SO_SNDLOWAT* = cint(19) + SO_SNDTIMEO* = cint(21) + SO_TYPE* = cint(3) + SOMAXCONN* = cint(128) + MSG_CTRUNC* = cint(8) + MSG_DONTROUTE* = cint(4) + MSG_EOR* = cint(128) + MSG_OOB* = cint(1) + MSG_PEEK* = cint(2) + MSG_TRUNC* = cint(32) + MSG_WAITALL* = cint(256) + AF_INET* = cint(2) + AF_INET6* = cint(10) + AF_UNIX* = cint(1) + AF_UNSPEC* = cint(0) + SHUT_RD* = cint(0) + SHUT_RDWR* = cint(2) + SHUT_WR* = cint(1) + IPPROTO_IP* = cint(0) + IPPROTO_IPV6* = cint(41) + IPPROTO_ICMP* = cint(1) + IPPROTO_RAW* = cint(255) + IPPROTO_TCP* = cint(6) + IPPROTO_UDP* = cint(17) + INADDR_ANY* = cint(0) + INADDR_BROADCAST* = cint(-1) + INET_ADDRSTRLEN* = cint(16) + IPV6_JOIN_GROUP* = cint(20) + IPV6_LEAVE_GROUP* = cint(21) + IPV6_MULTICAST_HOPS* = cint(18) + IPV6_MULTICAST_IF* = cint(17) + IPV6_MULTICAST_LOOP* = cint(19) + IPV6_UNICAST_HOPS* = cint(16) + IPV6_V6ONLY* = cint(26) + IPPORT_RESERVED* = cint(1024) + HOST_NOT_FOUND* = cint(1) + NO_DATA* = cint(4) + NO_RECOVERY* = cint(3) + TRY_AGAIN* = cint(2) + AI_PASSIVE* = cint(1) + AI_CANONNAME* = cint(2) + AI_NUMERICHOST* = cint(4) + AI_NUMERICSERV* = cint(1024) + AI_V4MAPPED* = cint(8) + AI_ALL* = cint(16) + AI_ADDRCONFIG* = cint(32) + NI_NOFQDN* = cint(4) + NI_NUMERICHOST* = cint(1) + NI_NAMEREQD* = cint(8) + NI_NUMERICSERV* = cint(2) + NI_DGRAM* = cint(16) + EAI_AGAIN* = cint(-3) + EAI_BADFLAGS* = cint(-1) + EAI_FAIL* = cint(-4) + EAI_FAMILY* = cint(-6) + EAI_MEMORY* = cint(-10) + EAI_NONAME* = cint(-2) + EAI_SERVICE* = cint(-8) + EAI_SOCKTYPE* = cint(-7) + EAI_SYSTEM* = cint(-11) + EAI_OVERFLOW* = cint(-12) + POLLIN* = cshort(1) + POLLRDNORM* = cshort(64) + POLLRDBAND* = cshort(128) + POLLPRI* = cshort(2) + POLLOUT* = cshort(4) + POLLWRNORM* = cshort(256) + POLLWRBAND* = cshort(512) + POLLERR* = cshort(8) + POLLHUP* = cshort(16) + POLLNVAL* = cshort(32) + POSIX_SPAWN_RESETIDS* = cint(1) + POSIX_SPAWN_SETPGROUP* = cint(2) + POSIX_SPAWN_SETSCHEDPARAM* = cint(16) + POSIX_SPAWN_SETSCHEDULER* = cint(32) + POSIX_SPAWN_SETSIGDEF* = cint(4) + POSIX_SPAWN_SETSIGMASK* = cint(8) + IOFBF* = cint(0) + IONBF* = cint(2) diff --git a/tools/detect/macosx_consts.nim b/tools/detect/macosx_consts.nim new file mode 100644 index 000000000..e8be56e5f --- /dev/null +++ b/tools/detect/macosx_consts.nim @@ -0,0 +1,629 @@ +# Generated by detect.nim +const + AIO_ALLDONE* = cint(1) + AIO_CANCELED* = cint(2) + AIO_NOTCANCELED* = cint(4) + LIO_NOP* = cint(0) + LIO_NOWAIT* = cint(1) + LIO_READ* = cint(1) + LIO_WAIT* = cint(2) + LIO_WRITE* = cint(2) + RTLD_LAZY* = cint(1) + RTLD_NOW* = cint(2) + RTLD_GLOBAL* = cint(8) + RTLD_LOCAL* = cint(4) + E2BIG* = cint(7) + EACCES* = cint(13) + EADDRINUSE* = cint(48) + EADDRNOTAVAIL* = cint(49) + EAFNOSUPPORT* = cint(47) + EAGAIN* = cint(35) + EALREADY* = cint(37) + EBADF* = cint(9) + EBADMSG* = cint(94) + EBUSY* = cint(16) + ECANCELED* = cint(89) + ECHILD* = cint(10) + ECONNABORTED* = cint(53) + ECONNREFUSED* = cint(61) + ECONNRESET* = cint(54) + EDEADLK* = cint(11) + EDESTADDRREQ* = cint(39) + EDOM* = cint(33) + EDQUOT* = cint(69) + EEXIST* = cint(17) + EFAULT* = cint(14) + EFBIG* = cint(27) + EHOSTUNREACH* = cint(65) + EIDRM* = cint(90) + EILSEQ* = cint(92) + EINPROGRESS* = cint(36) + EINTR* = cint(4) + EINVAL* = cint(22) + EIO* = cint(5) + EISCONN* = cint(56) + EISDIR* = cint(21) + ELOOP* = cint(62) + EMFILE* = cint(24) + EMLINK* = cint(31) + EMSGSIZE* = cint(40) + EMULTIHOP* = cint(95) + ENAMETOOLONG* = cint(63) + ENETDOWN* = cint(50) + ENETRESET* = cint(52) + ENETUNREACH* = cint(51) + ENFILE* = cint(23) + ENOBUFS* = cint(55) + ENODATA* = cint(96) + ENODEV* = cint(19) + ENOENT* = cint(2) + ENOEXEC* = cint(8) + ENOLCK* = cint(77) + ENOLINK* = cint(97) + ENOMEM* = cint(12) + ENOMSG* = cint(91) + ENOPROTOOPT* = cint(42) + ENOSPC* = cint(28) + ENOSR* = cint(98) + ENOSTR* = cint(99) + ENOSYS* = cint(78) + ENOTCONN* = cint(57) + ENOTDIR* = cint(20) + ENOTEMPTY* = cint(66) + ENOTSOCK* = cint(38) + ENOTSUP* = cint(45) + ENOTTY* = cint(25) + ENXIO* = cint(6) + EOPNOTSUPP* = cint(102) + EOVERFLOW* = cint(84) + EPERM* = cint(1) + EPIPE* = cint(32) + EPROTO* = cint(100) + EPROTONOSUPPORT* = cint(43) + EPROTOTYPE* = cint(41) + ERANGE* = cint(34) + EROFS* = cint(30) + ESPIPE* = cint(29) + ESRCH* = cint(3) + ESTALE* = cint(70) + ETIME* = cint(101) + ETIMEDOUT* = cint(60) + ETXTBSY* = cint(26) + EWOULDBLOCK* = cint(35) + EXDEV* = cint(18) + F_DUPFD* = cint(0) + F_GETFD* = cint(1) + F_SETFD* = cint(2) + F_GETFL* = cint(3) + F_SETFL* = cint(4) + F_GETLK* = cint(7) + F_SETLK* = cint(8) + F_SETLKW* = cint(9) + F_GETOWN* = cint(5) + F_SETOWN* = cint(6) + FD_CLOEXEC* = cint(1) + F_RDLCK* = cint(1) + F_UNLCK* = cint(2) + F_WRLCK* = cint(3) + O_CREAT* = cint(512) + O_EXCL* = cint(2048) + O_NOCTTY* = cint(131072) + O_TRUNC* = cint(1024) + O_APPEND* = cint(8) + O_DSYNC* = cint(4194304) + O_NONBLOCK* = cint(4) + O_SYNC* = cint(128) + O_ACCMODE* = cint(3) + O_RDONLY* = cint(0) + O_RDWR* = cint(2) + O_WRONLY* = cint(1) + FE_DIVBYZERO* = cint(4) + FE_INEXACT* = cint(32) + FE_INVALID* = cint(1) + FE_OVERFLOW* = cint(8) + FE_UNDERFLOW* = cint(16) + FE_ALL_EXCEPT* = cint(63) + FE_DOWNWARD* = cint(1024) + FE_TONEAREST* = cint(0) + FE_TOWARDZERO* = cint(3072) + FE_UPWARD* = cint(2048) + FE_DFL_ENV* = when defined(amd64): cast[pointer](0x7fff9533b1b4) + else: cast[pointer](0x904797f4) + MM_HARD* = cint(1) + MM_SOFT* = cint(2) + MM_FIRM* = cint(4) + MM_APPL* = cint(16) + MM_UTIL* = cint(32) + MM_OPSYS* = cint(64) + MM_RECOVER* = cint(4096) + MM_NRECOV* = cint(8192) + MM_HALT* = cint(1) + MM_ERROR* = cint(2) + MM_WARNING* = cint(3) + MM_INFO* = cint(4) + MM_NOSEV* = cint(0) + MM_PRINT* = cint(256) + MM_CONSOLE* = cint(512) + MM_OK* = cint(0) + MM_NOTOK* = cint(3) + MM_NOMSG* = cint(1) + MM_NOCON* = cint(2) + FNM_NOMATCH* = cint(1) + FNM_PATHNAME* = cint(2) + FNM_PERIOD* = cint(4) + FNM_NOESCAPE* = cint(1) + FNM_NOSYS* = cint(-1) + FTW_F* = cint(0) + FTW_D* = cint(1) + FTW_DNR* = cint(2) + FTW_DP* = cint(3) + FTW_NS* = cint(4) + FTW_SL* = cint(5) + FTW_SLN* = cint(6) + FTW_PHYS* = cint(1) + FTW_MOUNT* = cint(2) + FTW_DEPTH* = cint(4) + FTW_CHDIR* = cint(8) + GLOB_APPEND* = cint(1) + GLOB_DOOFFS* = cint(2) + GLOB_ERR* = cint(4) + GLOB_MARK* = cint(8) + GLOB_NOCHECK* = cint(16) + GLOB_NOESCAPE* = cint(8192) + GLOB_NOSORT* = cint(32) + GLOB_ABORTED* = cint(-2) + GLOB_NOMATCH* = cint(-3) + GLOB_NOSPACE* = cint(-1) + GLOB_NOSYS* = cint(-4) + CODESET* = cint(0) + D_T_FMT* = cint(1) + D_FMT* = cint(2) + T_FMT* = cint(3) + T_FMT_AMPM* = cint(4) + AM_STR* = cint(5) + PM_STR* = cint(6) + DAY_1* = cint(7) + DAY_2* = cint(8) + DAY_3* = cint(9) + DAY_4* = cint(10) + DAY_5* = cint(11) + DAY_6* = cint(12) + DAY_7* = cint(13) + ABDAY_1* = cint(14) + ABDAY_2* = cint(15) + ABDAY_3* = cint(16) + ABDAY_4* = cint(17) + ABDAY_5* = cint(18) + ABDAY_6* = cint(19) + ABDAY_7* = cint(20) + MON_1* = cint(21) + MON_2* = cint(22) + MON_3* = cint(23) + MON_4* = cint(24) + MON_5* = cint(25) + MON_6* = cint(26) + MON_7* = cint(27) + MON_8* = cint(28) + MON_9* = cint(29) + MON_10* = cint(30) + MON_11* = cint(31) + MON_12* = cint(32) + ABMON_1* = cint(33) + ABMON_2* = cint(34) + ABMON_3* = cint(35) + ABMON_4* = cint(36) + ABMON_5* = cint(37) + ABMON_6* = cint(38) + ABMON_7* = cint(39) + ABMON_8* = cint(40) + ABMON_9* = cint(41) + ABMON_10* = cint(42) + ABMON_11* = cint(43) + ABMON_12* = cint(44) + ERA* = cint(45) + ERA_D_FMT* = cint(46) + ERA_D_T_FMT* = cint(47) + ERA_T_FMT* = cint(48) + ALT_DIGITS* = cint(49) + RADIXCHAR* = cint(50) + THOUSEP* = cint(51) + YESEXPR* = cint(52) + NOEXPR* = cint(53) + CRNCYSTR* = cint(56) + LC_ALL* = cint(0) + LC_COLLATE* = cint(1) + LC_CTYPE* = cint(2) + LC_MESSAGES* = cint(6) + LC_MONETARY* = cint(3) + LC_NUMERIC* = cint(4) + LC_TIME* = cint(5) + PTHREAD_CANCEL_ASYNCHRONOUS* = cint(0) + PTHREAD_CANCEL_ENABLE* = cint(1) + PTHREAD_CANCEL_DEFERRED* = cint(2) + PTHREAD_CANCEL_DISABLE* = cint(0) + PTHREAD_CREATE_DETACHED* = cint(2) + PTHREAD_CREATE_JOINABLE* = cint(1) + PTHREAD_EXPLICIT_SCHED* = cint(2) + PTHREAD_INHERIT_SCHED* = cint(1) + PTHREAD_MUTEX_DEFAULT* = cint(0) + PTHREAD_MUTEX_ERRORCHECK* = cint(1) + PTHREAD_MUTEX_NORMAL* = cint(0) + PTHREAD_MUTEX_RECURSIVE* = cint(2) + PTHREAD_PRIO_INHERIT* = cint(1) + PTHREAD_PRIO_NONE* = cint(0) + PTHREAD_PRIO_PROTECT* = cint(2) + PTHREAD_PROCESS_SHARED* = cint(1) + PTHREAD_PROCESS_PRIVATE* = cint(2) + PTHREAD_SCOPE_PROCESS* = cint(2) + PTHREAD_SCOPE_SYSTEM* = cint(1) + F_OK* = cint(0) + R_OK* = cint(4) + W_OK* = cint(2) + X_OK* = cint(1) + CS_PATH* = cint(1) + CS_POSIX_V6_ILP32_OFF32_CFLAGS* = cint(2) + CS_POSIX_V6_ILP32_OFF32_LDFLAGS* = cint(3) + CS_POSIX_V6_ILP32_OFF32_LIBS* = cint(4) + CS_POSIX_V6_ILP32_OFFBIG_CFLAGS* = cint(5) + CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS* = cint(6) + CS_POSIX_V6_ILP32_OFFBIG_LIBS* = cint(7) + CS_POSIX_V6_LP64_OFF64_CFLAGS* = cint(8) + CS_POSIX_V6_LP64_OFF64_LDFLAGS* = cint(9) + CS_POSIX_V6_LP64_OFF64_LIBS* = cint(10) + CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS* = cint(11) + CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS* = cint(12) + CS_POSIX_V6_LPBIG_OFFBIG_LIBS* = cint(13) + CS_POSIX_V6_WIDTH_RESTRICTED_ENVS* = cint(14) + F_LOCK* = cint(1) + F_TEST* = cint(3) + F_TLOCK* = cint(2) + F_ULOCK* = cint(0) + PC_2_SYMLINKS* = cint(15) + PC_ALLOC_SIZE_MIN* = cint(16) + PC_ASYNC_IO* = cint(17) + PC_CHOWN_RESTRICTED* = cint(7) + PC_FILESIZEBITS* = cint(18) + PC_LINK_MAX* = cint(1) + PC_MAX_CANON* = cint(2) + PC_MAX_INPUT* = cint(3) + PC_NAME_MAX* = cint(4) + PC_NO_TRUNC* = cint(8) + PC_PATH_MAX* = cint(5) + PC_PIPE_BUF* = cint(6) + PC_PRIO_IO* = cint(19) + PC_REC_INCR_XFER_SIZE* = cint(20) + PC_REC_MIN_XFER_SIZE* = cint(22) + PC_REC_XFER_ALIGN* = cint(23) + PC_SYMLINK_MAX* = cint(24) + PC_SYNC_IO* = cint(25) + PC_VDISABLE* = cint(9) + SC_2_C_BIND* = cint(18) + SC_2_C_DEV* = cint(19) + SC_2_CHAR_TERM* = cint(20) + SC_2_FORT_DEV* = cint(21) + SC_2_FORT_RUN* = cint(22) + SC_2_LOCALEDEF* = cint(23) + SC_2_PBS* = cint(59) + SC_2_PBS_ACCOUNTING* = cint(60) + SC_2_PBS_CHECKPOINT* = cint(61) + SC_2_PBS_LOCATE* = cint(62) + SC_2_PBS_MESSAGE* = cint(63) + SC_2_PBS_TRACK* = cint(64) + SC_2_SW_DEV* = cint(24) + SC_2_UPE* = cint(25) + SC_2_VERSION* = cint(17) + SC_ADVISORY_INFO* = cint(65) + SC_AIO_LISTIO_MAX* = cint(42) + SC_AIO_MAX* = cint(43) + SC_AIO_PRIO_DELTA_MAX* = cint(44) + SC_ARG_MAX* = cint(1) + SC_ASYNCHRONOUS_IO* = cint(28) + SC_ATEXIT_MAX* = cint(107) + SC_BARRIERS* = cint(66) + SC_BC_BASE_MAX* = cint(9) + SC_BC_DIM_MAX* = cint(10) + SC_BC_SCALE_MAX* = cint(11) + SC_BC_STRING_MAX* = cint(12) + SC_CHILD_MAX* = cint(2) + SC_CLK_TCK* = cint(3) + SC_CLOCK_SELECTION* = cint(67) + SC_COLL_WEIGHTS_MAX* = cint(13) + SC_CPUTIME* = cint(68) + SC_DELAYTIMER_MAX* = cint(45) + SC_EXPR_NEST_MAX* = cint(14) + SC_FSYNC* = cint(38) + SC_GETGR_R_SIZE_MAX* = cint(70) + SC_GETPW_R_SIZE_MAX* = cint(71) + SC_HOST_NAME_MAX* = cint(72) + SC_IOV_MAX* = cint(56) + SC_IPV6* = cint(118) + SC_JOB_CONTROL* = cint(6) + SC_LINE_MAX* = cint(15) + SC_LOGIN_NAME_MAX* = cint(73) + SC_MAPPED_FILES* = cint(47) + SC_MEMLOCK* = cint(30) + SC_MEMLOCK_RANGE* = cint(31) + SC_MEMORY_PROTECTION* = cint(32) + SC_MESSAGE_PASSING* = cint(33) + SC_MONOTONIC_CLOCK* = cint(74) + SC_MQ_OPEN_MAX* = cint(46) + SC_MQ_PRIO_MAX* = cint(75) + SC_NGROUPS_MAX* = cint(4) + SC_OPEN_MAX* = cint(5) + SC_PAGE_SIZE* = cint(29) + SC_PRIORITIZED_IO* = cint(34) + SC_PRIORITY_SCHEDULING* = cint(35) + SC_RAW_SOCKETS* = cint(119) + SC_RE_DUP_MAX* = cint(16) + SC_READER_WRITER_LOCKS* = cint(76) + SC_REALTIME_SIGNALS* = cint(36) + SC_REGEXP* = cint(77) + SC_RTSIG_MAX* = cint(48) + SC_SAVED_IDS* = cint(7) + SC_SEM_NSEMS_MAX* = cint(49) + SC_SEM_VALUE_MAX* = cint(50) + SC_SEMAPHORES* = cint(37) + SC_SHARED_MEMORY_OBJECTS* = cint(39) + SC_SHELL* = cint(78) + SC_SIGQUEUE_MAX* = cint(51) + SC_SPAWN* = cint(79) + SC_SPIN_LOCKS* = cint(80) + SC_SPORADIC_SERVER* = cint(81) + SC_SS_REPL_MAX* = cint(126) + SC_STREAM_MAX* = cint(26) + SC_SYMLOOP_MAX* = cint(120) + SC_SYNCHRONIZED_IO* = cint(40) + SC_THREAD_ATTR_STACKADDR* = cint(82) + SC_THREAD_ATTR_STACKSIZE* = cint(83) + SC_THREAD_CPUTIME* = cint(84) + SC_THREAD_DESTRUCTOR_ITERATIONS* = cint(85) + SC_THREAD_KEYS_MAX* = cint(86) + SC_THREAD_PRIO_INHERIT* = cint(87) + SC_THREAD_PRIO_PROTECT* = cint(88) + SC_THREAD_PRIORITY_SCHEDULING* = cint(89) + SC_THREAD_PROCESS_SHARED* = cint(90) + SC_THREAD_SAFE_FUNCTIONS* = cint(91) + SC_THREAD_SPORADIC_SERVER* = cint(92) + SC_THREAD_STACK_MIN* = cint(93) + SC_THREAD_THREADS_MAX* = cint(94) + SC_THREADS* = cint(96) + SC_TIMEOUTS* = cint(95) + SC_TIMER_MAX* = cint(52) + SC_TIMERS* = cint(41) + SC_TRACE* = cint(97) + SC_TRACE_EVENT_FILTER* = cint(98) + SC_TRACE_EVENT_NAME_MAX* = cint(127) + SC_TRACE_INHERIT* = cint(99) + SC_TRACE_LOG* = cint(100) + SC_TRACE_NAME_MAX* = cint(128) + SC_TRACE_SYS_MAX* = cint(129) + SC_TRACE_USER_EVENT_MAX* = cint(130) + SC_TTY_NAME_MAX* = cint(101) + SC_TYPED_MEMORY_OBJECTS* = cint(102) + SC_TZNAME_MAX* = cint(27) + SC_V6_ILP32_OFF32* = cint(103) + SC_V6_ILP32_OFFBIG* = cint(104) + SC_V6_LP64_OFF64* = cint(105) + SC_V6_LPBIG_OFFBIG* = cint(106) + SC_VERSION* = cint(8) + SC_XBS5_ILP32_OFF32* = cint(122) + SC_XBS5_ILP32_OFFBIG* = cint(123) + SC_XBS5_LP64_OFF64* = cint(124) + SC_XBS5_LPBIG_OFFBIG* = cint(125) + SC_XOPEN_CRYPT* = cint(108) + SC_XOPEN_ENH_I18N* = cint(109) + SC_XOPEN_LEGACY* = cint(110) + SC_XOPEN_REALTIME* = cint(111) + SC_XOPEN_REALTIME_THREADS* = cint(112) + SC_XOPEN_SHM* = cint(113) + SC_XOPEN_STREAMS* = cint(114) + SC_XOPEN_UNIX* = cint(115) + SC_XOPEN_VERSION* = cint(116) + SEEK_SET* = cint(0) + SEEK_CUR* = cint(1) + SEEK_END* = cint(2) + SEM_FAILED* = cast[pointer](-1) + IPC_CREAT* = cint(512) + IPC_EXCL* = cint(1024) + IPC_NOWAIT* = cint(2048) + IPC_PRIVATE* = cint(0) + IPC_RMID* = cint(0) + IPC_SET* = cint(1) + IPC_STAT* = cint(2) + S_IFMT* = cint(61440) + S_IFBLK* = cint(24576) + S_IFCHR* = cint(8192) + S_IFIFO* = cint(4096) + S_IFREG* = cint(32768) + S_IFDIR* = cint(16384) + S_IFLNK* = cint(40960) + S_IFSOCK* = cint(49152) + S_IRWXU* = cint(448) + S_IRUSR* = cint(256) + S_IWUSR* = cint(128) + S_IXUSR* = cint(64) + S_IRWXG* = cint(56) + S_IRGRP* = cint(32) + S_IWGRP* = cint(16) + S_IXGRP* = cint(8) + S_IRWXO* = cint(7) + S_IROTH* = cint(4) + S_IWOTH* = cint(2) + S_IXOTH* = cint(1) + S_ISUID* = cint(2048) + S_ISGID* = cint(1024) + S_ISVTX* = cint(512) + ST_RDONLY* = cint(1) + ST_NOSUID* = cint(2) + PROT_READ* = cint(1) + PROT_WRITE* = cint(2) + PROT_EXEC* = cint(4) + PROT_NONE* = cint(0) + MAP_SHARED* = cint(1) + MAP_PRIVATE* = cint(2) + MAP_FIXED* = cint(16) + MS_ASYNC* = cint(1) + MS_SYNC* = cint(16) + MS_INVALIDATE* = cint(2) + MCL_CURRENT* = cint(1) + MCL_FUTURE* = cint(2) + MAP_FAILED* = cast[pointer](-1) + POSIX_MADV_NORMAL* = cint(0) + POSIX_MADV_SEQUENTIAL* = cint(2) + POSIX_MADV_RANDOM* = cint(1) + POSIX_MADV_WILLNEED* = cint(3) + POSIX_MADV_DONTNEED* = cint(4) + CLOCKS_PER_SEC* = clong(1000000) + WNOHANG* = cint(1) + WUNTRACED* = cint(2) + WEXITED* = cint(4) + WSTOPPED* = cint(8) + WCONTINUED* = cint(16) + WNOWAIT* = cint(32) + SIGEV_NONE* = cint(0) + SIGEV_SIGNAL* = cint(1) + SIGEV_THREAD* = cint(3) + SIGABRT* = cint(6) + SIGALRM* = cint(14) + SIGBUS* = cint(10) + SIGCHLD* = cint(20) + SIGCONT* = cint(19) + SIGFPE* = cint(8) + SIGHUP* = cint(1) + SIGILL* = cint(4) + SIGINT* = cint(2) + SIGKILL* = cint(9) + SIGPIPE* = cint(13) + SIGQUIT* = cint(3) + SIGSEGV* = cint(11) + SIGSTOP* = cint(17) + SIGTERM* = cint(15) + SIGTSTP* = cint(18) + SIGTTIN* = cint(21) + SIGTTOU* = cint(22) + SIGUSR1* = cint(30) + SIGUSR2* = cint(31) + SIGPROF* = cint(27) + SIGSYS* = cint(12) + SIGTRAP* = cint(5) + SIGURG* = cint(16) + SIGVTALRM* = cint(26) + SIGXCPU* = cint(24) + SIGXFSZ* = cint(25) + SA_NOCLDSTOP* = cint(8) + SIG_BLOCK* = cint(1) + SIG_UNBLOCK* = cint(2) + SIG_SETMASK* = cint(3) + SA_ONSTACK* = cint(1) + SA_RESETHAND* = cint(4) + SA_RESTART* = cint(2) + SA_SIGINFO* = cint(64) + SA_NOCLDWAIT* = cint(32) + SA_NODEFER* = cint(16) + SS_ONSTACK* = cint(1) + SS_DISABLE* = cint(4) + MINSIGSTKSZ* = cint(32768) + SIGSTKSZ* = cint(131072) + NL_SETD* = cint(1) + NL_CAT_LOCALE* = cint(1) + SCHED_FIFO* = cint(4) + SCHED_RR* = cint(2) + SCHED_OTHER* = cint(1) + FD_SETSIZE* = cint(1024) + SCM_RIGHTS* = cint(1) + SOCK_DGRAM* = cint(2) + SOCK_RAW* = cint(3) + SOCK_SEQPACKET* = cint(5) + SOCK_STREAM* = cint(1) + SOL_SOCKET* = cint(65535) + SO_ACCEPTCONN* = cint(2) + SO_BROADCAST* = cint(32) + SO_DEBUG* = cint(1) + SO_DONTROUTE* = cint(16) + SO_ERROR* = cint(4103) + SO_KEEPALIVE* = cint(8) + SO_LINGER* = cint(128) + SO_OOBINLINE* = cint(256) + SO_RCVBUF* = cint(4098) + SO_RCVLOWAT* = cint(4100) + SO_RCVTIMEO* = cint(4102) + SO_REUSEADDR* = cint(4) + SO_SNDBUF* = cint(4097) + SO_SNDLOWAT* = cint(4099) + SO_SNDTIMEO* = cint(4101) + SO_TYPE* = cint(4104) + SOMAXCONN* = cint(128) + MSG_CTRUNC* = cint(32) + MSG_DONTROUTE* = cint(4) + MSG_EOR* = cint(8) + MSG_OOB* = cint(1) + MSG_PEEK* = cint(2) + MSG_TRUNC* = cint(16) + MSG_WAITALL* = cint(64) + AF_INET* = cint(2) + AF_INET6* = cint(30) + AF_UNIX* = cint(1) + AF_UNSPEC* = cint(0) + SHUT_RD* = cint(0) + SHUT_RDWR* = cint(2) + SHUT_WR* = cint(1) + IPPROTO_IP* = cint(0) + IPPROTO_IPV6* = cint(41) + IPPROTO_ICMP* = cint(1) + IPPROTO_RAW* = cint(255) + IPPROTO_TCP* = cint(6) + IPPROTO_UDP* = cint(17) + INADDR_ANY* = cint(0) + INADDR_BROADCAST* = cint(-1) + INET_ADDRSTRLEN* = cint(16) + IPV6_JOIN_GROUP* = cint(12) + IPV6_LEAVE_GROUP* = cint(13) + IPV6_MULTICAST_HOPS* = cint(10) + IPV6_MULTICAST_IF* = cint(9) + IPV6_MULTICAST_LOOP* = cint(11) + IPV6_UNICAST_HOPS* = cint(4) + IPV6_V6ONLY* = cint(27) + IPPORT_RESERVED* = cint(1024) + HOST_NOT_FOUND* = cint(1) + NO_DATA* = cint(4) + NO_RECOVERY* = cint(3) + TRY_AGAIN* = cint(2) + AI_PASSIVE* = cint(1) + AI_CANONNAME* = cint(2) + AI_NUMERICHOST* = cint(4) + AI_NUMERICSERV* = cint(4096) + AI_V4MAPPED* = cint(2048) + AI_ALL* = cint(256) + AI_ADDRCONFIG* = cint(1024) + NI_NOFQDN* = cint(1) + NI_NUMERICHOST* = cint(2) + NI_NAMEREQD* = cint(4) + NI_NUMERICSERV* = cint(8) + NI_DGRAM* = cint(16) + EAI_AGAIN* = cint(2) + EAI_BADFLAGS* = cint(3) + EAI_FAIL* = cint(4) + EAI_FAMILY* = cint(5) + EAI_MEMORY* = cint(6) + EAI_NONAME* = cint(8) + EAI_SERVICE* = cint(9) + EAI_SOCKTYPE* = cint(10) + EAI_SYSTEM* = cint(11) + EAI_OVERFLOW* = cint(14) + POLLIN* = cshort(1) + POLLRDNORM* = cshort(64) + POLLRDBAND* = cshort(128) + POLLPRI* = cshort(2) + POLLOUT* = cshort(4) + POLLWRNORM* = cshort(4) + POLLWRBAND* = cshort(256) + POLLERR* = cshort(8) + POLLHUP* = cshort(16) + POLLNVAL* = cshort(32) + POSIX_SPAWN_RESETIDS* = cint(1) + POSIX_SPAWN_SETPGROUP* = cint(2) + POSIX_SPAWN_SETSIGDEF* = cint(4) + POSIX_SPAWN_SETSIGMASK* = cint(8) + IOFBF* = cint(0) + IONBF* = cint(2) + diff --git a/tools/detect/windows_amd64_consts.nim b/tools/detect/windows_amd64_consts.nim new file mode 100644 index 000000000..d72c9786d --- /dev/null +++ b/tools/detect/windows_amd64_consts.nim @@ -0,0 +1,152 @@ +# Generated by detect.nim +const + E2BIG* = cint(7) + EACCES* = cint(13) + EADDRINUSE* = cint(100) + EADDRNOTAVAIL* = cint(101) + EAFNOSUPPORT* = cint(102) + EAGAIN* = cint(11) + EALREADY* = cint(103) + EBADF* = cint(9) + EBUSY* = cint(16) + ECANCELED* = cint(105) + ECHILD* = cint(10) + ECONNABORTED* = cint(106) + ECONNREFUSED* = cint(107) + ECONNRESET* = cint(108) + EDEADLK* = cint(36) + EDESTADDRREQ* = cint(109) + EDOM* = cint(33) + EEXIST* = cint(17) + EFAULT* = cint(14) + EFBIG* = cint(27) + EHOSTUNREACH* = cint(110) + EILSEQ* = cint(42) + EINPROGRESS* = cint(112) + EINTR* = cint(4) + EINVAL* = cint(22) + EIO* = cint(5) + EISCONN* = cint(113) + EISDIR* = cint(21) + ELOOP* = cint(114) + EMFILE* = cint(24) + EMLINK* = cint(31) + EMSGSIZE* = cint(115) + ENAMETOOLONG* = cint(38) + ENETDOWN* = cint(116) + ENETRESET* = cint(117) + ENETUNREACH* = cint(118) + ENFILE* = cint(23) + ENOBUFS* = cint(119) + ENODEV* = cint(19) + ENOENT* = cint(2) + ENOEXEC* = cint(8) + ENOLCK* = cint(39) + ENOMEM* = cint(12) + ENOPROTOOPT* = cint(123) + ENOSPC* = cint(28) + ENOSYS* = cint(40) + ENOTCONN* = cint(126) + ENOTDIR* = cint(20) + ENOTEMPTY* = cint(41) + ENOTSOCK* = cint(128) + ENOTSUP* = cint(129) + ENOTTY* = cint(25) + ENXIO* = cint(6) + EOPNOTSUPP* = cint(130) + EOVERFLOW* = cint(132) + EPERM* = cint(1) + EPIPE* = cint(32) + EPROTO* = cint(134) + EPROTONOSUPPORT* = cint(135) + EPROTOTYPE* = cint(136) + ERANGE* = cint(34) + EROFS* = cint(30) + ESPIPE* = cint(29) + ESRCH* = cint(3) + ETIMEDOUT* = cint(138) + EWOULDBLOCK* = cint(140) + EXDEV* = cint(18) + O_CREAT* = cint(256) + O_EXCL* = cint(1024) + O_TRUNC* = cint(512) + O_APPEND* = cint(8) + O_ACCMODE* = cint(3) + O_RDONLY* = cint(0) + O_RDWR* = cint(2) + O_WRONLY* = cint(1) + FE_DIVBYZERO* = cint(4) + FE_INEXACT* = cint(32) + FE_INVALID* = cint(1) + FE_OVERFLOW* = cint(8) + FE_UNDERFLOW* = cint(16) + FE_ALL_EXCEPT* = cint(63) + FE_DOWNWARD* = cint(1024) + FE_TONEAREST* = cint(0) + FE_TOWARDZERO* = cint(3072) + FE_UPWARD* = cint(2048) + FE_DFL_ENV* = pointer(nil) + LC_ALL* = cint(0) + LC_COLLATE* = cint(1) + LC_CTYPE* = cint(2) + LC_MONETARY* = cint(3) + LC_NUMERIC* = cint(4) + LC_TIME* = cint(5) + PTHREAD_BARRIER_SERIAL_THREAD* = cint(1) + PTHREAD_CANCEL_ASYNCHRONOUS* = cint(2) + PTHREAD_CANCEL_ENABLE* = cint(1) + PTHREAD_CANCEL_DEFERRED* = cint(0) + PTHREAD_CANCEL_DISABLE* = cint(0) + PTHREAD_CREATE_DETACHED* = cint(4) + PTHREAD_CREATE_JOINABLE* = cint(0) + PTHREAD_EXPLICIT_SCHED* = cint(0) + PTHREAD_INHERIT_SCHED* = cint(8) + PTHREAD_MUTEX_DEFAULT* = cint(0) + PTHREAD_MUTEX_ERRORCHECK* = cint(1) + PTHREAD_MUTEX_NORMAL* = cint(0) + PTHREAD_MUTEX_RECURSIVE* = cint(2) + PTHREAD_PRIO_INHERIT* = cint(8) + PTHREAD_PRIO_NONE* = cint(0) + PTHREAD_PRIO_PROTECT* = cint(16) + PTHREAD_PROCESS_SHARED* = cint(1) + PTHREAD_PROCESS_PRIVATE* = cint(0) + PTHREAD_SCOPE_PROCESS* = cint(0) + PTHREAD_SCOPE_SYSTEM* = cint(16) + F_OK* = cint(0) + R_OK* = cint(4) + W_OK* = cint(2) + X_OK* = cint(1) + SEEK_SET* = cint(0) + SEEK_CUR* = cint(1) + SEEK_END* = cint(2) + SEM_FAILED* = pointer(nil) + S_IFMT* = cint(61440) + S_IFBLK* = cint(12288) + S_IFCHR* = cint(8192) + S_IFIFO* = cint(4096) + S_IFREG* = cint(32768) + S_IFDIR* = cint(16384) + S_IRWXU* = cint(448) + S_IRUSR* = cint(256) + S_IWUSR* = cint(128) + S_IXUSR* = cint(64) + CLOCKS_PER_SEC* = clong(1000) + CLOCK_PROCESS_CPUTIME_ID* = cint(2) + CLOCK_THREAD_CPUTIME_ID* = cint(3) + CLOCK_REALTIME* = cint(0) + TIMER_ABSTIME* = cint(1) + CLOCK_MONOTONIC* = cint(1) + SIGABRT* = cint(22) + SIGFPE* = cint(8) + SIGILL* = cint(4) + SIGINT* = cint(2) + SIGSEGV* = cint(11) + SIGTERM* = cint(15) + SIG_BLOCK* = cint(0) + SIG_UNBLOCK* = cint(1) + SIG_SETMASK* = cint(2) + SCHED_FIFO* = cint(1) + SCHED_RR* = cint(2) + SCHED_OTHER* = cint(0) + IOFBF* = cint(0) + IONBF* = cint(4) diff --git a/tools/detect/windows_i386_consts.nim b/tools/detect/windows_i386_consts.nim new file mode 100644 index 000000000..cd6c475f4 --- /dev/null +++ b/tools/detect/windows_i386_consts.nim @@ -0,0 +1,96 @@ +# Generated by detect.nim +const + E2BIG* = cint(7) + EACCES* = cint(13) + EAGAIN* = cint(11) + EBADF* = cint(9) + EBUSY* = cint(16) + ECHILD* = cint(10) + EDEADLK* = cint(36) + EDOM* = cint(33) + EEXIST* = cint(17) + EFAULT* = cint(14) + EFBIG* = cint(27) + EILSEQ* = cint(42) + EINTR* = cint(4) + EINVAL* = cint(22) + EIO* = cint(5) + EISDIR* = cint(21) + EMFILE* = cint(24) + EMLINK* = cint(31) + ENAMETOOLONG* = cint(38) + ENFILE* = cint(23) + ENODEV* = cint(19) + ENOENT* = cint(2) + ENOEXEC* = cint(8) + ENOLCK* = cint(39) + ENOMEM* = cint(12) + ENOSPC* = cint(28) + ENOSYS* = cint(40) + ENOTDIR* = cint(20) + ENOTEMPTY* = cint(41) + ENOTSUP* = cint(48) + ENOTTY* = cint(25) + ENXIO* = cint(6) + EPERM* = cint(1) + EPIPE* = cint(32) + ERANGE* = cint(34) + EROFS* = cint(30) + ESPIPE* = cint(29) + ESRCH* = cint(3) + ETIMEDOUT* = cint(10060) + EXDEV* = cint(18) + O_CREAT* = cint(256) + O_EXCL* = cint(1024) + O_TRUNC* = cint(512) + O_APPEND* = cint(8) + O_ACCMODE* = cint(3) + O_RDONLY* = cint(0) + O_RDWR* = cint(2) + O_WRONLY* = cint(1) + FE_DIVBYZERO* = cint(4) + FE_INEXACT* = cint(32) + FE_INVALID* = cint(1) + FE_OVERFLOW* = cint(8) + FE_UNDERFLOW* = cint(16) + FE_ALL_EXCEPT* = cint(63) + FE_DOWNWARD* = cint(1024) + FE_TONEAREST* = cint(0) + FE_TOWARDZERO* = cint(3072) + FE_UPWARD* = cint(2048) + FE_DFL_ENV* = pointer(nil) + LC_ALL* = cint(0) + LC_COLLATE* = cint(1) + LC_CTYPE* = cint(2) + LC_MONETARY* = cint(3) + LC_NUMERIC* = cint(4) + LC_TIME* = cint(5) + F_OK* = cint(0) + R_OK* = cint(4) + W_OK* = cint(2) + X_OK* = cint(1) + SEEK_SET* = cint(0) + SEEK_CUR* = cint(1) + SEEK_END* = cint(2) + S_IFMT* = cint(61440) + S_IFBLK* = cint(12288) + S_IFCHR* = cint(8192) + S_IFIFO* = cint(4096) + S_IFREG* = cint(32768) + S_IFDIR* = cint(16384) + S_IRWXU* = cint(448) + S_IRUSR* = cint(256) + S_IWUSR* = cint(128) + S_IXUSR* = cint(64) + CLOCKS_PER_SEC* = clong(1000) + SIGABRT* = cint(22) + SIGFPE* = cint(8) + SIGILL* = cint(4) + SIGINT* = cint(2) + SIGSEGV* = cint(11) + SIGTERM* = cint(15) + SIG_BLOCK* = cint(0) + SIG_UNBLOCK* = cint(1) + SIG_SETMASK* = cint(2) + IOFBF* = cint(0) + IONBF* = cint(4) diff --git a/tools/nimgrep.nim b/tools/nimgrep.nim index c7893fe78..b20e86a68 100644 --- a/tools/nimgrep.nim +++ b/tools/nimgrep.nim @@ -56,7 +56,7 @@ var proc ask(msg: string): string = stdout.write(msg) - result = stdin.readline() + result = stdin.readLine() proc Confirm: TConfirmEnum = while true: @@ -66,7 +66,7 @@ proc Confirm: TConfirmEnum = of "l", "all": return ceAll of "n", "no": return ceNo of "e", "none": return ceNone - else: nil + else: discard proc countLines(s: string, first, last: int): int = var i = first @@ -308,7 +308,7 @@ checkOptions({optIgnoreCase, optIgnoreStyle}, "ignore_case", "ignore_style") if optStdin in options: pattern = ask("pattern [ENTER to exit]: ") - if IsNil(pattern) or pattern.len == 0: quit(0) + if isNil(pattern) or pattern.len == 0: quit(0) if optReplace in options: replacement = ask("replacement [supports $1, $# notations]: ") diff --git a/tools/niminst/buildbat.tmpl b/tools/niminst/buildbat.tmpl index 712ebc794..9a19fc70b 100644 --- a/tools/niminst/buildbat.tmpl +++ b/tools/niminst/buildbat.tmpl @@ -1,5 +1,5 @@ #! stdtmpl(subsChar='?') | standard -#proc GenerateBuildBatchScript(c: TConfigData, winIndex, cpuIndex: int): string = +#proc generateBuildBatchScript(c: TConfigData, winIndex, cpuIndex: int): string = # result = "@echo off\nREM Generated by niminst\n" SET CC=gcc SET LINKER=gcc diff --git a/tools/niminst/buildsh.tmpl b/tools/niminst/buildsh.tmpl index 8fe5fea9f..4966af07a 100644 --- a/tools/niminst/buildsh.tmpl +++ b/tools/niminst/buildsh.tmpl @@ -1,5 +1,5 @@ #! stdtmpl(subsChar='?') | standard -#proc GenerateBuildShellScript(c: TConfigData): string = +#proc generateBuildShellScript(c: TConfigData): string = # result = "#! /bin/sh\n# Generated from niminst\n" & # "# Template is in tools/buildsh.tmpl\n" & # "# To regenerate run ``niminst csource`` or ``koch csource``\n" diff --git a/tools/niminst/debcreation.nim b/tools/niminst/debcreation.nim index 982bfaf3d..1f4a8630e 100644 --- a/tools/niminst/debcreation.nim +++ b/tools/niminst/debcreation.nim @@ -101,7 +101,7 @@ proc createChangelog(pkgName, version, maintainer: string): string = addN(" * Initial release.") addN("") addN(" -- " & maintainer & " " & - formatDateTime(getGmTime(getTime()), "+0000")) + formatDateTime(getGMTime(getTime()), "+0000")) proc createRules(): string = ## Creates a nimrod application-agnostic rules file for building deb packages. diff --git a/tools/niminst/deinstall.tmpl b/tools/niminst/deinstall.tmpl index d9abf9228..15f912af6 100644 --- a/tools/niminst/deinstall.tmpl +++ b/tools/niminst/deinstall.tmpl @@ -1,5 +1,5 @@ #! stdtmpl(subsChar='?') | standard -#proc GenerateDeinstallScript(c: TConfigData): string = +#proc generateDeinstallScript(c: TConfigData): string = # result = "#! /bin/sh\n# Generated by niminst\n" # var proj = c.name.toLower diff --git a/tools/niminst/inno.tmpl b/tools/niminst/inno.tmpl index 40edcc790..b9d04755e 100644 --- a/tools/niminst/inno.tmpl +++ b/tools/niminst/inno.tmpl @@ -1,5 +1,5 @@ #! stdtmpl | standard -#proc GenerateInnoSetup(c: TConfigData): string = +#proc generateInnoSetup(c: TConfigData): string = # result = "" ; Default Template for NimInst [Setup] diff --git a/tools/niminst/install.tmpl b/tools/niminst/install.tmpl index fa61eea5e..437e13dfb 100644 --- a/tools/niminst/install.tmpl +++ b/tools/niminst/install.tmpl @@ -1,5 +1,5 @@ #! stdtmpl(subsChar = '?') | standard -#proc GenerateInstallScript(c: TConfigData): string = +#proc generateInstallScript(c: TConfigData): string = # result = "#! /bin/sh\n# Generated by niminst\n" # var proj = c.name.toLower diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim index 96815ebe4..bf8a7a84f 100644 --- a/tools/niminst/niminst.nim +++ b/tools/niminst/niminst.nim @@ -111,7 +111,7 @@ proc skipRoot(f: string): string = # "abc/def/xyz" --> "def/xyz" var i = 0 result = "" - for component in split(f, {dirsep, altsep}): + for component in split(f, {DirSep, AltSep}): if i > 0: result = result / component inc i if result.len == 0: result = f @@ -126,7 +126,7 @@ include "deinstall.tmpl" const Version = "0.9" - Usage = "niminst - Nimrod Installation Generator Version " & version & """ + Usage = "niminst - Nimrod Installation Generator Version " & Version & """ (c) 2013 Andreas Rumpf Usage: @@ -168,7 +168,7 @@ proc parseCmdLine(c: var TConfigData) = c.infile = addFileExt(key.string, "ini") c.nimrodArgs = cmdLineRest(p).string break - of cmdLongOption, cmdShortOption: + of cmdLongoption, cmdShortOption: case normalize(key.string) of "help", "h": stdout.write(Usage) @@ -188,7 +188,7 @@ proc parseCmdLine(c: var TConfigData) = proc walkDirRecursively(s: var seq[string], root: string) = for k, f in walkDir(root): case k - of pcFile, pcLinkToFile: add(s, UnixToNativePath(f)) + of pcFile, pcLinkToFile: add(s, unixToNativePath(f)) of pcDir: walkDirRecursively(s, f) of pcLinkToDir: nil @@ -199,7 +199,7 @@ proc addFiles(s: var seq[string], patterns: seq[string]) = else: var i = 0 for f in walkFiles(p): - add(s, UnixToNativePath(f)) + add(s, unixToNativePath(f)) inc(i) if i == 0: echo("[Warning] No file found that matches: " & p) @@ -286,7 +286,7 @@ proc parseIniFile(c: var TConfigData) = of "console": c.app = appConsole of "gui": c.app = appGUI else: quit(errorStr(p, "expected: console or gui")) - of "license": c.license = UnixToNativePath(k.value) + of "license": c.license = unixToNativePath(k.value) else: quit(errorStr(p, "unknown variable: " & k.key)) of "var": nil of "winbin": filesOnly(p, k.key, v, c.cat[fcWinBin]) @@ -312,7 +312,7 @@ proc parseIniFile(c: var TConfigData) = of "uninstallscript": c.uninstallScript = yesno(p, v) else: quit(errorStr(p, "unknown variable: " & k.key)) of "unixbin": filesOnly(p, k.key, v, c.cat[fcUnixBin]) - of "innosetup": pathFlags(p, k.key, v, c.innoSetup) + of "innosetup": pathFlags(p, k.key, v, c.innosetup) of "ccompiler": pathFlags(p, k.key, v, c.ccompiler) of "linker": pathFlags(p, k.key, v, c.linker) of "deb": @@ -483,11 +483,11 @@ proc setupDist(c: var TConfigData) = var n = "build" / "install_$#_$#.iss" % [toLower(c.name), c.version] writeFile(n, scrpt, "\13\10") when defined(windows): - if c.innoSetup.path.len == 0: - c.innoSetup.path = "iscc.exe" + if c.innosetup.path.len == 0: + c.innosetup.path = "iscc.exe" var outcmd = if c.outdir.len == 0: "build" else: c.outdir - var cmd = "$# $# /O$# $#" % [quoteShell(c.innoSetup.path), - c.innoSetup.flags, outcmd, n] + var cmd = "$# $# /O$# $#" % [quoteShell(c.innosetup.path), + c.innosetup.flags, outcmd, n] echo(cmd) if execShellCmd(cmd) == 0: removeFile(n) @@ -582,7 +582,7 @@ if actionScripts in c.actions: writeInstallScripts(c) if actionZip in c.actions: when haveZipLib: - zipdist(c) + zipDist(c) else: quit("libzip is not installed") if actionDeb in c.actions: diff --git a/tools/nimweb.nim b/tools/nimweb.nim index c5d510eac..84b790248 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -200,32 +200,32 @@ proc parseIniFile(c: var TConfigData) = # ------------------- main ---------------------------------------------------- -proc Exec(cmd: string) = +proc exec(cmd: string) = echo(cmd) if os.execShellCmd(cmd) != 0: quit("external program failed") proc buildDoc(c: var TConfigData, destPath: string) = # call nim for the documentation: for d in items(c.doc): - Exec("nimrod rst2html $# -o:$# --index:on $#" % + exec("nimrod rst2html $# -o:$# --index:on $#" % [c.nimrodArgs, destPath / changeFileExt(splitFile(d).name, "html"), d]) for d in items(c.srcdoc): - Exec("nimrod doc $# -o:$# --index:on $#" % + exec("nimrod doc $# -o:$# --index:on $#" % [c.nimrodArgs, destPath / changeFileExt(splitFile(d).name, "html"), d]) for d in items(c.srcdoc2): - Exec("nimrod doc2 $# -o:$# --index:on $#" % + exec("nimrod doc2 $# -o:$# --index:on $#" % [c.nimrodArgs, destPath / changeFileExt(splitFile(d).name, "html"), d]) - Exec("nimrod buildIndex -o:$1/theindex.html $1" % [destPath]) + exec("nimrod buildIndex -o:$1/theindex.html $1" % [destPath]) proc buildPdfDoc(c: var TConfigData, destPath: string) = if os.execShellCmd("pdflatex -version") != 0: echo "pdflatex not found; no PDF documentation generated" else: for d in items(c.pdf): - Exec("nimrod rst2tex $# $#" % [c.nimrodArgs, d]) + exec("nimrod rst2tex $# $#" % [c.nimrodArgs, d]) # call LaTeX twice to get cross references right: - Exec("pdflatex " & changeFileExt(d, "tex")) - Exec("pdflatex " & changeFileExt(d, "tex")) + exec("pdflatex " & changeFileExt(d, "tex")) + exec("pdflatex " & changeFileExt(d, "tex")) # delete all the crappy temporary files: var pdf = splitFile(d).name & ".pdf" moveFile(dest=destPath / pdf, source=pdf) @@ -239,7 +239,7 @@ proc buildPdfDoc(c: var TConfigData, destPath: string) = proc buildAddDoc(c: var TConfigData, destPath: string) = # build additional documentation (without the index): for d in items(c.webdoc): - Exec("nimrod doc $# -o:$# $#" % + exec("nimrod doc $# -o:$# $#" % [c.nimrodArgs, destPath / changeFileExt(splitFile(d).name, "html"), d]) proc parseNewsTitles(inputFilename: string): seq[TRssItem] = @@ -253,7 +253,7 @@ proc parseNewsTitles(inputFilename: string): seq[TRssItem] = if not open(input, inputFilename): quit("Could not read $1 for rss generation" % [inputFilename]) finally: input.close() - while input.readline(line): + while input.readLine(line): if line =~ reYearMonthDayTitle: result.add(TRssItem(year: matches[0], month: matches[1], day: matches[2], title: matches[3])) @@ -332,7 +332,7 @@ proc main(c: var TConfigData) = for i in 0..c.tabs.len-1: var file = c.tabs[i].val let rss = if file in ["news", "index"]: extractFilename(rssUrl) else: "" - Exec(cmd % [c.nimrodArgs, file]) + exec(cmd % [c.nimrodArgs, file]) var temp = "web" / changeFileExt(file, "temp") var content: string try: diff --git a/web/news.txt b/web/news.txt index 4f40d6484..c518bfc95 100644 --- a/web/news.txt +++ b/web/news.txt @@ -28,6 +28,16 @@ Changes affecting backwards compatibility require an error code to be passed to them. This error code can be retrieved using the new ``OSLastError`` proc. - ``os.parentDir`` now returns "" if there is no parent dir. +- In CGI scripts stacktraces are shown user only if cgi.setStackTraceStdout + is used. +- The symbol binding rules for clean templates changed: ``bind`` for any + symbol that's not a parameter is now the default. ``mixin`` can be used + to require instantiation scope for a symbol. +- ``quoteIfContainsWhite`` now escapes argument in such way that it can be safely + passed to shell, instead of just adding double quotes. +- ``macros.dumpTree`` and ``macros.dumpLisp`` have been made ``immediate``, + ``dumpTreeImm`` and ``dumpLispImm`` are now deprecated. + Compiler Additions ------------------ @@ -40,21 +50,24 @@ Compiler Additions over the generated code. - The compiler now supports a ``computedGoto`` pragma to support very fast dispatching for interpreters and the like. -- In CGI scripts stacktraces are shown user only if cgi.setStackTraceStdout - is used. +- The old evaluation engine has been replaced by a proper register based + virtual machine. This fixes numerous bugs for ``nimrod i`` and for macro + evaluation. + Language Additions ------------------ - Arrays can now be declared with a single integer literal ``N`` instead of a range; the range is then ``0..N-1``. -- ``macros.dumpTree`` and ``macros.dumpLisp`` have been made ``immediate``, - ``dumpTreeImm`` and ``dumpLispImm`` are now deprecated. - Added ``requiresInit`` pragma to enforce explicit initialization. -- Added ``using statement`` for better authoring domain-specific languages and - OOP-like syntactic sugar. -- Added ``delegator pragma`` for handling calls to missing procs and fields at - compile-time. +- Exported templates are allowed to access hidden fields. +- The ``using statement`` enables you to more easily author domain-specific + languages and libraries providing OOP-like syntactic sugar. +- Added a new ``delegator pragma`` for handling calls to missing procs and + fields at compile-time. +- The overload resolution now supports ``static[T]`` params that must be + evaluatable at compile-time. - Support for user-defined type classes have been added. diff --git a/web/nimrod.ini b/web/nimrod.ini index f10a4b2f2..6942f20a9 100644 --- a/web/nimrod.ini +++ b/web/nimrod.ini @@ -45,7 +45,7 @@ srcdoc2: "impure/re;pure/sockets" srcdoc: "system/threads.nim;system/channels.nim;js/dom" srcdoc2: "pure/os;pure/strutils;pure/math;pure/matchers;pure/algorithm" srcdoc2: "pure/complex;pure/times;pure/osproc;pure/pegs;pure/dynlib" -srcdoc2: "pure/parseopt;pure/hashes;pure/strtabs;pure/lexbase" +srcdoc2: "pure/parseopt;pure/parseopt2;pure/hashes;pure/strtabs;pure/lexbase" srcdoc2: "pure/parsecfg;pure/parsexml;pure/parsecsv;pure/parsesql" srcdoc2: "pure/streams;pure/terminal;pure/cgi;impure/web;pure/unicode" srcdoc2: "impure/zipfiles;pure/htmlgen;pure/parseutils;pure/browsers" |