diff --git a/build.bat b/build.bat
index ed2a177eaa..494c37497f 100755
--- a/build.bat
+++ b/build.bat
@@ -143,8 +143,12 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\aliases.c -o build\1_1\aliases.o
%CC% %COMP_FLAGS% -Ibuild -c build\1_1\aliases.c -o build\1_1\aliases.o
ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\docgen.c -o build\1_1\docgen.o
%CC% %COMP_FLAGS% -Ibuild -c build\1_1\docgen.c -o build\1_1\docgen.o
+ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\rstast.c -o build\1_1\rstast.o
+%CC% %COMP_FLAGS% -Ibuild -c build\1_1\rstast.c -o build\1_1\rstast.o
ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\rst.c -o build\1_1\rst.o
%CC% %COMP_FLAGS% -Ibuild -c build\1_1\rst.c -o build\1_1\rst.o
+ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\rstgen.c -o build\1_1\rstgen.o
+%CC% %COMP_FLAGS% -Ibuild -c build\1_1\rstgen.c -o build\1_1\rstgen.o
ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\highlite.c -o build\1_1\highlite.o
%CC% %COMP_FLAGS% -Ibuild -c build\1_1\highlite.c -o build\1_1\highlite.o
ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\cgen.c -o build\1_1\cgen.o
@@ -164,8 +168,8 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\depends.c -o build\1_1\depends.o
ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\parseopt.c -o build\1_1\parseopt.o
%CC% %COMP_FLAGS% -Ibuild -c build\1_1\parseopt.c -o build\1_1\parseopt.o
-ECHO %LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_1\nim__dat.o build\1_1\system.o build\1_1\nimrod.o build\1_1\times.o build\1_1\strutils.o build\1_1\parseutils.o build\1_1\winlean.o build\1_1\commands.o build\1_1\os.o build\1_1\msgs.o build\1_1\options.o build\1_1\lists.o build\1_1\strtabs.o build\1_1\hashes.o build\1_1\tables.o build\1_1\math.o build\1_1\nversion.o build\1_1\condsyms.o build\1_1\ast.o build\1_1\crc.o build\1_1\ropes.o build\1_1\platform.o build\1_1\idents.o build\1_1\intsets.o build\1_1\idgen.o build\1_1\astalgo.o build\1_1\rodutils.o build\1_1\extccomp.o build\1_1\osproc.o build\1_1\streams.o build\1_1\wordrecg.o build\1_1\lexer.o build\1_1\lexbase.o build\1_1\llstream.o build\1_1\nimconf.o build\1_1\main.o build\1_1\syntaxes.o build\1_1\parser.o build\1_1\pbraces.o build\1_1\filters.o build\1_1\renderer.o build\1_1\filter_tmpl.o build\1_1\rodread.o build\1_1\memfiles.o build\1_1\rodwrite.o build\1_1\passes.o build\1_1\types.o build\1_1\trees.o build\1_1\magicsys.o build\1_1\nimsets.o build\1_1\bitsets.o build\1_1\semthreads.o build\1_1\importer.o build\1_1\lookups.o build\1_1\semdata.o build\1_1\treetab.o build\1_1\evals.o build\1_1\semfold.o build\1_1\transf.o build\1_1\cgmeth.o build\1_1\sem.o build\1_1\procfind.o build\1_1\pragmas.o build\1_1\semtypinst.o build\1_1\sigmatch.o build\1_1\suggest.o build\1_1\aliases.o build\1_1\docgen.o build\1_1\rst.o build\1_1\highlite.o build\1_1\cgen.o build\1_1\ccgutils.o build\1_1\cgendata.o build\1_1\ccgmerge.o build\1_1\ecmasgen.o build\1_1\passaux.o build\1_1\depends.o build\1_1\parseopt.o
-%LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_1\nim__dat.o build\1_1\system.o build\1_1\nimrod.o build\1_1\times.o build\1_1\strutils.o build\1_1\parseutils.o build\1_1\winlean.o build\1_1\commands.o build\1_1\os.o build\1_1\msgs.o build\1_1\options.o build\1_1\lists.o build\1_1\strtabs.o build\1_1\hashes.o build\1_1\tables.o build\1_1\math.o build\1_1\nversion.o build\1_1\condsyms.o build\1_1\ast.o build\1_1\crc.o build\1_1\ropes.o build\1_1\platform.o build\1_1\idents.o build\1_1\intsets.o build\1_1\idgen.o build\1_1\astalgo.o build\1_1\rodutils.o build\1_1\extccomp.o build\1_1\osproc.o build\1_1\streams.o build\1_1\wordrecg.o build\1_1\lexer.o build\1_1\lexbase.o build\1_1\llstream.o build\1_1\nimconf.o build\1_1\main.o build\1_1\syntaxes.o build\1_1\parser.o build\1_1\pbraces.o build\1_1\filters.o build\1_1\renderer.o build\1_1\filter_tmpl.o build\1_1\rodread.o build\1_1\memfiles.o build\1_1\rodwrite.o build\1_1\passes.o build\1_1\types.o build\1_1\trees.o build\1_1\magicsys.o build\1_1\nimsets.o build\1_1\bitsets.o build\1_1\semthreads.o build\1_1\importer.o build\1_1\lookups.o build\1_1\semdata.o build\1_1\treetab.o build\1_1\evals.o build\1_1\semfold.o build\1_1\transf.o build\1_1\cgmeth.o build\1_1\sem.o build\1_1\procfind.o build\1_1\pragmas.o build\1_1\semtypinst.o build\1_1\sigmatch.o build\1_1\suggest.o build\1_1\aliases.o build\1_1\docgen.o build\1_1\rst.o build\1_1\highlite.o build\1_1\cgen.o build\1_1\ccgutils.o build\1_1\cgendata.o build\1_1\ccgmerge.o build\1_1\ecmasgen.o build\1_1\passaux.o build\1_1\depends.o build\1_1\parseopt.o
+ECHO %LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_1\nim__dat.o build\1_1\system.o build\1_1\nimrod.o build\1_1\times.o build\1_1\strutils.o build\1_1\parseutils.o build\1_1\winlean.o build\1_1\commands.o build\1_1\os.o build\1_1\msgs.o build\1_1\options.o build\1_1\lists.o build\1_1\strtabs.o build\1_1\hashes.o build\1_1\tables.o build\1_1\math.o build\1_1\nversion.o build\1_1\condsyms.o build\1_1\ast.o build\1_1\crc.o build\1_1\ropes.o build\1_1\platform.o build\1_1\idents.o build\1_1\intsets.o build\1_1\idgen.o build\1_1\astalgo.o build\1_1\rodutils.o build\1_1\extccomp.o build\1_1\osproc.o build\1_1\streams.o build\1_1\wordrecg.o build\1_1\lexer.o build\1_1\lexbase.o build\1_1\llstream.o build\1_1\nimconf.o build\1_1\main.o build\1_1\syntaxes.o build\1_1\parser.o build\1_1\pbraces.o build\1_1\filters.o build\1_1\renderer.o build\1_1\filter_tmpl.o build\1_1\rodread.o build\1_1\memfiles.o build\1_1\rodwrite.o build\1_1\passes.o build\1_1\types.o build\1_1\trees.o build\1_1\magicsys.o build\1_1\nimsets.o build\1_1\bitsets.o build\1_1\semthreads.o build\1_1\importer.o build\1_1\lookups.o build\1_1\semdata.o build\1_1\treetab.o build\1_1\evals.o build\1_1\semfold.o build\1_1\transf.o build\1_1\cgmeth.o build\1_1\sem.o build\1_1\procfind.o build\1_1\pragmas.o build\1_1\semtypinst.o build\1_1\sigmatch.o build\1_1\suggest.o build\1_1\aliases.o build\1_1\docgen.o build\1_1\rstast.o build\1_1\rst.o build\1_1\rstgen.o build\1_1\highlite.o build\1_1\cgen.o build\1_1\ccgutils.o build\1_1\cgendata.o build\1_1\ccgmerge.o build\1_1\ecmasgen.o build\1_1\passaux.o build\1_1\depends.o build\1_1\parseopt.o
+%LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_1\nim__dat.o build\1_1\system.o build\1_1\nimrod.o build\1_1\times.o build\1_1\strutils.o build\1_1\parseutils.o build\1_1\winlean.o build\1_1\commands.o build\1_1\os.o build\1_1\msgs.o build\1_1\options.o build\1_1\lists.o build\1_1\strtabs.o build\1_1\hashes.o build\1_1\tables.o build\1_1\math.o build\1_1\nversion.o build\1_1\condsyms.o build\1_1\ast.o build\1_1\crc.o build\1_1\ropes.o build\1_1\platform.o build\1_1\idents.o build\1_1\intsets.o build\1_1\idgen.o build\1_1\astalgo.o build\1_1\rodutils.o build\1_1\extccomp.o build\1_1\osproc.o build\1_1\streams.o build\1_1\wordrecg.o build\1_1\lexer.o build\1_1\lexbase.o build\1_1\llstream.o build\1_1\nimconf.o build\1_1\main.o build\1_1\syntaxes.o build\1_1\parser.o build\1_1\pbraces.o build\1_1\filters.o build\1_1\renderer.o build\1_1\filter_tmpl.o build\1_1\rodread.o build\1_1\memfiles.o build\1_1\rodwrite.o build\1_1\passes.o build\1_1\types.o build\1_1\trees.o build\1_1\magicsys.o build\1_1\nimsets.o build\1_1\bitsets.o build\1_1\semthreads.o build\1_1\importer.o build\1_1\lookups.o build\1_1\semdata.o build\1_1\treetab.o build\1_1\evals.o build\1_1\semfold.o build\1_1\transf.o build\1_1\cgmeth.o build\1_1\sem.o build\1_1\procfind.o build\1_1\pragmas.o build\1_1\semtypinst.o build\1_1\sigmatch.o build\1_1\suggest.o build\1_1\aliases.o build\1_1\docgen.o build\1_1\rstast.o build\1_1\rst.o build\1_1\rstgen.o build\1_1\highlite.o build\1_1\cgen.o build\1_1\ccgutils.o build\1_1\cgendata.o build\1_1\ccgmerge.o build\1_1\ecmasgen.o build\1_1\passaux.o build\1_1\depends.o build\1_1\parseopt.o
ECHO SUCCESS
diff --git a/build64.bat b/build64.bat
index aa981feb9a..edc5a8301d 100644
--- a/build64.bat
+++ b/build64.bat
@@ -143,8 +143,12 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\aliases.c -o build\1_2\aliases.o
%CC% %COMP_FLAGS% -Ibuild -c build\1_2\aliases.c -o build\1_2\aliases.o
ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\docgen.c -o build\1_2\docgen.o
%CC% %COMP_FLAGS% -Ibuild -c build\1_2\docgen.c -o build\1_2\docgen.o
+ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\rstast.c -o build\1_2\rstast.o
+%CC% %COMP_FLAGS% -Ibuild -c build\1_2\rstast.c -o build\1_2\rstast.o
ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\rst.c -o build\1_2\rst.o
%CC% %COMP_FLAGS% -Ibuild -c build\1_2\rst.c -o build\1_2\rst.o
+ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\rstgen.c -o build\1_2\rstgen.o
+%CC% %COMP_FLAGS% -Ibuild -c build\1_2\rstgen.c -o build\1_2\rstgen.o
ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\highlite.c -o build\1_2\highlite.o
%CC% %COMP_FLAGS% -Ibuild -c build\1_2\highlite.c -o build\1_2\highlite.o
ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\cgen.c -o build\1_2\cgen.o
@@ -164,8 +168,8 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\depends.c -o build\1_2\depends.o
ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\parseopt.c -o build\1_2\parseopt.o
%CC% %COMP_FLAGS% -Ibuild -c build\1_2\parseopt.c -o build\1_2\parseopt.o
-ECHO %LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_2\nim__dat.o build\1_2\system.o build\1_2\nimrod.o build\1_2\times.o build\1_2\strutils.o build\1_2\parseutils.o build\1_2\winlean.o build\1_2\commands.o build\1_2\os.o build\1_2\msgs.o build\1_2\options.o build\1_2\lists.o build\1_2\strtabs.o build\1_2\hashes.o build\1_2\tables.o build\1_2\math.o build\1_2\nversion.o build\1_2\condsyms.o build\1_2\ast.o build\1_2\crc.o build\1_2\ropes.o build\1_2\platform.o build\1_2\idents.o build\1_2\intsets.o build\1_2\idgen.o build\1_2\astalgo.o build\1_2\rodutils.o build\1_2\extccomp.o build\1_2\osproc.o build\1_2\streams.o build\1_2\wordrecg.o build\1_2\lexer.o build\1_2\lexbase.o build\1_2\llstream.o build\1_2\nimconf.o build\1_2\main.o build\1_2\syntaxes.o build\1_2\parser.o build\1_2\pbraces.o build\1_2\filters.o build\1_2\renderer.o build\1_2\filter_tmpl.o build\1_2\rodread.o build\1_2\memfiles.o build\1_2\rodwrite.o build\1_2\passes.o build\1_2\types.o build\1_2\trees.o build\1_2\magicsys.o build\1_2\nimsets.o build\1_2\bitsets.o build\1_2\semthreads.o build\1_2\importer.o build\1_2\lookups.o build\1_2\semdata.o build\1_2\treetab.o build\1_2\evals.o build\1_2\semfold.o build\1_2\transf.o build\1_2\cgmeth.o build\1_2\sem.o build\1_2\procfind.o build\1_2\pragmas.o build\1_2\semtypinst.o build\1_2\sigmatch.o build\1_2\suggest.o build\1_2\aliases.o build\1_2\docgen.o build\1_2\rst.o build\1_2\highlite.o build\1_2\cgen.o build\1_2\ccgutils.o build\1_2\cgendata.o build\1_2\ccgmerge.o build\1_2\ecmasgen.o build\1_2\passaux.o build\1_2\depends.o build\1_2\parseopt.o
-%LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_2\nim__dat.o build\1_2\system.o build\1_2\nimrod.o build\1_2\times.o build\1_2\strutils.o build\1_2\parseutils.o build\1_2\winlean.o build\1_2\commands.o build\1_2\os.o build\1_2\msgs.o build\1_2\options.o build\1_2\lists.o build\1_2\strtabs.o build\1_2\hashes.o build\1_2\tables.o build\1_2\math.o build\1_2\nversion.o build\1_2\condsyms.o build\1_2\ast.o build\1_2\crc.o build\1_2\ropes.o build\1_2\platform.o build\1_2\idents.o build\1_2\intsets.o build\1_2\idgen.o build\1_2\astalgo.o build\1_2\rodutils.o build\1_2\extccomp.o build\1_2\osproc.o build\1_2\streams.o build\1_2\wordrecg.o build\1_2\lexer.o build\1_2\lexbase.o build\1_2\llstream.o build\1_2\nimconf.o build\1_2\main.o build\1_2\syntaxes.o build\1_2\parser.o build\1_2\pbraces.o build\1_2\filters.o build\1_2\renderer.o build\1_2\filter_tmpl.o build\1_2\rodread.o build\1_2\memfiles.o build\1_2\rodwrite.o build\1_2\passes.o build\1_2\types.o build\1_2\trees.o build\1_2\magicsys.o build\1_2\nimsets.o build\1_2\bitsets.o build\1_2\semthreads.o build\1_2\importer.o build\1_2\lookups.o build\1_2\semdata.o build\1_2\treetab.o build\1_2\evals.o build\1_2\semfold.o build\1_2\transf.o build\1_2\cgmeth.o build\1_2\sem.o build\1_2\procfind.o build\1_2\pragmas.o build\1_2\semtypinst.o build\1_2\sigmatch.o build\1_2\suggest.o build\1_2\aliases.o build\1_2\docgen.o build\1_2\rst.o build\1_2\highlite.o build\1_2\cgen.o build\1_2\ccgutils.o build\1_2\cgendata.o build\1_2\ccgmerge.o build\1_2\ecmasgen.o build\1_2\passaux.o build\1_2\depends.o build\1_2\parseopt.o
+ECHO %LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_2\nim__dat.o build\1_2\system.o build\1_2\nimrod.o build\1_2\times.o build\1_2\strutils.o build\1_2\parseutils.o build\1_2\winlean.o build\1_2\commands.o build\1_2\os.o build\1_2\msgs.o build\1_2\options.o build\1_2\lists.o build\1_2\strtabs.o build\1_2\hashes.o build\1_2\tables.o build\1_2\math.o build\1_2\nversion.o build\1_2\condsyms.o build\1_2\ast.o build\1_2\crc.o build\1_2\ropes.o build\1_2\platform.o build\1_2\idents.o build\1_2\intsets.o build\1_2\idgen.o build\1_2\astalgo.o build\1_2\rodutils.o build\1_2\extccomp.o build\1_2\osproc.o build\1_2\streams.o build\1_2\wordrecg.o build\1_2\lexer.o build\1_2\lexbase.o build\1_2\llstream.o build\1_2\nimconf.o build\1_2\main.o build\1_2\syntaxes.o build\1_2\parser.o build\1_2\pbraces.o build\1_2\filters.o build\1_2\renderer.o build\1_2\filter_tmpl.o build\1_2\rodread.o build\1_2\memfiles.o build\1_2\rodwrite.o build\1_2\passes.o build\1_2\types.o build\1_2\trees.o build\1_2\magicsys.o build\1_2\nimsets.o build\1_2\bitsets.o build\1_2\semthreads.o build\1_2\importer.o build\1_2\lookups.o build\1_2\semdata.o build\1_2\treetab.o build\1_2\evals.o build\1_2\semfold.o build\1_2\transf.o build\1_2\cgmeth.o build\1_2\sem.o build\1_2\procfind.o build\1_2\pragmas.o build\1_2\semtypinst.o build\1_2\sigmatch.o build\1_2\suggest.o build\1_2\aliases.o build\1_2\docgen.o build\1_2\rstast.o build\1_2\rst.o build\1_2\rstgen.o build\1_2\highlite.o build\1_2\cgen.o build\1_2\ccgutils.o build\1_2\cgendata.o build\1_2\ccgmerge.o build\1_2\ecmasgen.o build\1_2\passaux.o build\1_2\depends.o build\1_2\parseopt.o
+%LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_2\nim__dat.o build\1_2\system.o build\1_2\nimrod.o build\1_2\times.o build\1_2\strutils.o build\1_2\parseutils.o build\1_2\winlean.o build\1_2\commands.o build\1_2\os.o build\1_2\msgs.o build\1_2\options.o build\1_2\lists.o build\1_2\strtabs.o build\1_2\hashes.o build\1_2\tables.o build\1_2\math.o build\1_2\nversion.o build\1_2\condsyms.o build\1_2\ast.o build\1_2\crc.o build\1_2\ropes.o build\1_2\platform.o build\1_2\idents.o build\1_2\intsets.o build\1_2\idgen.o build\1_2\astalgo.o build\1_2\rodutils.o build\1_2\extccomp.o build\1_2\osproc.o build\1_2\streams.o build\1_2\wordrecg.o build\1_2\lexer.o build\1_2\lexbase.o build\1_2\llstream.o build\1_2\nimconf.o build\1_2\main.o build\1_2\syntaxes.o build\1_2\parser.o build\1_2\pbraces.o build\1_2\filters.o build\1_2\renderer.o build\1_2\filter_tmpl.o build\1_2\rodread.o build\1_2\memfiles.o build\1_2\rodwrite.o build\1_2\passes.o build\1_2\types.o build\1_2\trees.o build\1_2\magicsys.o build\1_2\nimsets.o build\1_2\bitsets.o build\1_2\semthreads.o build\1_2\importer.o build\1_2\lookups.o build\1_2\semdata.o build\1_2\treetab.o build\1_2\evals.o build\1_2\semfold.o build\1_2\transf.o build\1_2\cgmeth.o build\1_2\sem.o build\1_2\procfind.o build\1_2\pragmas.o build\1_2\semtypinst.o build\1_2\sigmatch.o build\1_2\suggest.o build\1_2\aliases.o build\1_2\docgen.o build\1_2\rstast.o build\1_2\rst.o build\1_2\rstgen.o build\1_2\highlite.o build\1_2\cgen.o build\1_2\ccgutils.o build\1_2\cgendata.o build\1_2\ccgmerge.o build\1_2\ecmasgen.o build\1_2\passaux.o build\1_2\depends.o build\1_2\parseopt.o
ECHO SUCCESS
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 834f5efb54..fc8c54ed1a 100755
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -52,9 +52,15 @@ type
nkInt16Lit,
nkInt32Lit,
nkInt64Lit,
+ nkUIntLit, # an unsigned integer literal
+ nkUInt8Lit,
+ nkUInt16Lit,
+ nkUInt32Lit,
+ nkUInt64Lit,
nkFloatLit, # a floating point literal
nkFloat32Lit,
nkFloat64Lit,
+ nkFloat128Lit,
nkStrLit, # a string literal ""
nkRStrLit, # a raw string literal r""
nkTripleStrLit, # a triple string literal """
@@ -237,6 +243,7 @@ type
sfNamedParamCall, # symbol needs named parameter call syntax in target
# language; for interfacing with Objective C
sfDiscardable # returned value may be discarded implicitely
+ sfDestructor # proc is destructor
TSymFlags* = set[TSymFlag]
@@ -325,6 +332,8 @@ type
tfEnumHasHoles, # enum cannot be mapped into a range
tfShallow, # type can be shallow copied on assignment
tfThread, # proc type is marked as ``thread``
+ tfUniIntLit # type represents literal value that could be either
+ # singed or unsigned integer (e.g. 100)
tfFromGeneric # type is an instantiation of a generic; this is needed
# because for instantiations of objects, structural
# type equality has to be used
@@ -408,8 +417,11 @@ type
mNewString, mNewStringOfCap,
mReset,
mArray, mOpenArray, mRange, mSet, mSeq,
- mOrdinal, mInt, mInt8, mInt16, mInt32,
- mInt64, mFloat, mFloat32, mFloat64, mBool, mChar, mString, mCstring,
+ mOrdinal,
+ mInt, mInt8, mInt16, mInt32, mInt64,
+ mUInt, mUInt8, mUInt16, mUInt32, mUInt64,
+ mFloat, mFloat32, mFloat64, mFloat128,
+ mBool, mChar, mString, mCstring,
mPointer, mEmptySet, mIntSetBaseType, mNil, mExpr, mStmt, mTypeDesc,
mVoidType, mPNimrodNode,
mIsMainModule, mCompileDate, mCompileTime, mNimrodVersion, mNimrodMajor,
@@ -464,11 +476,11 @@ type
info*: TLineInfo
flags*: TNodeFlags
case Kind*: TNodeKind
- of nkCharLit..nkInt64Lit:
+ of nkCharLit..nkUInt64Lit:
intVal*: biggestInt
- of nkFloatLit..nkFloat64Lit:
+ of nkFloatLit..nkFloat128Lit:
floatVal*: biggestFloat
- of nkStrLit..nkTripleStrLit:
+ of nkStrLit..nkTripleStrLit:
strVal*: string
of nkSym:
sym*: PSym
@@ -765,8 +777,8 @@ const # for all kind of hash tables:
proc ValueToString*(a: PNode): string =
case a.kind
- of nkCharLit..nkInt64Lit: result = $(a.intVal)
- of nkFloatLit, nkFloat32Lit, nkFloat64Lit: result = $(a.floatVal)
+ of nkCharLit..nkUInt64Lit: result = $(a.intVal)
+ of nkFloatLit..nkFloat128Lit: result = $(a.floatVal)
of nkStrLit..nkTripleStrLit: result = a.strVal
else:
InternalError(a.info, "valueToString")
@@ -888,6 +900,7 @@ proc assignType(dest, src: PType) =
dest.size = src.size
dest.align = src.align
dest.containerID = src.containerID
+ dest.destructor = src.destructor
# this fixes 'type TLock = TSysLock':
if src.sym != nil:
if dest.sym != nil:
@@ -1020,8 +1033,8 @@ proc copyNode(src: PNode): PNode =
result.typ = src.typ
result.flags = src.flags * PersistentNodeFlags
case src.Kind
- of nkCharLit..nkInt64Lit: result.intVal = src.intVal
- of nkFloatLit, nkFloat32Lit, nkFloat64Lit: result.floatVal = src.floatVal
+ 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
@@ -1035,8 +1048,8 @@ proc shallowCopy*(src: PNode): PNode =
result.typ = src.typ
result.flags = src.flags * PersistentNodeFlags
case src.Kind
- of nkCharLit..nkInt64Lit: result.intVal = src.intVal
- of nkFloatLit, nkFloat32Lit, nkFloat64Lit: result.floatVal = src.floatVal
+ 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
@@ -1051,8 +1064,8 @@ proc copyTree(src: PNode): PNode =
result.typ = src.typ
result.flags = src.flags * PersistentNodeFlags
case src.Kind
- of nkCharLit..nkInt64Lit: result.intVal = src.intVal
- of nkFloatLit, nkFloat32Lit, nkFloat64Lit: result.floatVal = src.floatVal
+ 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
@@ -1102,14 +1115,14 @@ proc sonsNotNil(n: PNode): bool =
proc getInt*(a: PNode): biggestInt =
case a.kind
- of nkIntLit..nkInt64Lit: result = a.intVal
+ of nkIntLit..nkUInt64Lit: result = a.intVal
else:
internalError(a.info, "getInt")
result = 0
proc getFloat*(a: PNode): biggestFloat =
case a.kind
- of nkFloatLit..nkFloat64Lit: result = a.floatVal
+ of nkFloatLit..nkFloat128Lit: result = a.floatVal
else:
internalError(a.info, "getFloat")
result = 0.0
diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim
index 7b5c5be259..41fbd3cf13 100755
--- a/compiler/astalgo.nim
+++ b/compiler/astalgo.nim
@@ -274,10 +274,10 @@ proc strTableToYaml(n: TStrTable, marker: var TIntSet, indent: int,
for i in countup(0, high(n.data)):
if n.data[i] != nil:
if mycount > 0: app(result, ",")
- appf(result, "$n$1$2",
+ appf(result, "$N$1$2",
[istr, symToYamlAux(n.data[i], marker, indent + 2, maxRecDepth - 1)])
inc(mycount)
- if mycount > 0: appf(result, "$n$1", [spaces(indent)])
+ if mycount > 0: appf(result, "$N$1", [spaces(indent)])
app(result, "]")
assert(mycount == n.counter)
@@ -288,9 +288,9 @@ proc ropeConstr(indent: int, c: openarray[PRope]): PRope =
var i = 0
while i <= high(c):
if i > 0: app(result, ",")
- appf(result, "$n$1\"$2\": $3", [istr, c[i], c[i + 1]])
+ appf(result, "$N$1\"$2\": $3", [istr, c[i], c[i + 1]])
inc(i, 2)
- appf(result, "$n$1}", [spaces(indent)])
+ appf(result, "$N$1}", [spaces(indent)])
proc symToYamlAux(n: PSym, marker: var TIntSet, indent: int,
maxRecDepth: int): PRope =
@@ -325,9 +325,9 @@ proc typeToYamlAux(n: PType, marker: var TIntSet, indent: int,
result = toRope("[")
for i in countup(0, sonsLen(n) - 1):
if i > 0: app(result, ",")
- appf(result, "$n$1$2", [spaces(indent + 4), typeToYamlAux(n.sons[i],
+ appf(result, "$N$1$2", [spaces(indent + 4), typeToYamlAux(n.sons[i],
marker, indent + 4, maxRecDepth - 1)])
- appf(result, "$n$1]", [spaces(indent + 2)])
+ appf(result, "$N$1]", [spaces(indent + 2)])
else:
result = toRope("null")
result = ropeConstr(indent, [toRope("kind"),
@@ -347,36 +347,36 @@ proc treeToYamlAux(n: PNode, marker: var TIntSet, indent: int,
result = toRope("null")
else:
var istr = spaces(indent + 2)
- result = ropef("{$n$1\"kind\": $2", [istr, makeYamlString($n.kind)])
+ result = ropef("{$N$1\"kind\": $2", [istr, makeYamlString($n.kind)])
if maxRecDepth != 0:
- appf(result, ",$n$1\"info\": $2", [istr, lineInfoToStr(n.info)])
+ appf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)])
case n.kind
of nkCharLit..nkInt64Lit:
- appf(result, ",$n$1\"intVal\": $2", [istr, toRope(n.intVal)])
+ appf(result, ",$N$1\"intVal\": $2", [istr, toRope(n.intVal)])
of nkFloatLit, nkFloat32Lit, nkFloat64Lit:
- appf(result, ",$n$1\"floatVal\": $2",
+ appf(result, ",$N$1\"floatVal\": $2",
[istr, toRope(n.floatVal.ToStrMaxPrecision)])
of nkStrLit..nkTripleStrLit:
- appf(result, ",$n$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
+ appf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
of nkSym:
- appf(result, ",$n$1\"sym\": $2",
+ appf(result, ",$N$1\"sym\": $2",
[istr, symToYamlAux(n.sym, marker, indent + 2, maxRecDepth)])
of nkIdent:
if n.ident != nil:
- appf(result, ",$n$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
+ appf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
else:
- appf(result, ",$n$1\"ident\": null", [istr])
+ appf(result, ",$N$1\"ident\": null", [istr])
else:
if sonsLen(n) > 0:
- appf(result, ",$n$1\"sons\": [", [istr])
+ appf(result, ",$N$1\"sons\": [", [istr])
for i in countup(0, sonsLen(n) - 1):
if i > 0: app(result, ",")
- appf(result, "$n$1$2", [spaces(indent + 4), treeToYamlAux(n.sons[i],
+ appf(result, "$N$1$2", [spaces(indent + 4), treeToYamlAux(n.sons[i],
marker, indent + 4, maxRecDepth - 1)])
- appf(result, "$n$1]", [istr])
- appf(result, ",$n$1\"typ\": $2",
+ appf(result, "$N$1]", [istr])
+ appf(result, ",$N$1\"typ\": $2",
[istr, typeToYamlAux(n.typ, marker, indent + 2, maxRecDepth)])
- appf(result, "$n$1}", [spaces(indent)])
+ appf(result, "$N$1}", [spaces(indent)])
proc treeToYaml(n: PNode, indent: int = 0, maxRecDepth: int = - 1): PRope =
var marker = InitIntSet()
@@ -413,34 +413,34 @@ proc debugTree(n: PNode, indent: int, maxRecDepth: int): PRope =
result = toRope("null")
else:
var istr = spaces(indent + 2)
- result = ropef("{$n$1\"kind\": $2",
+ result = ropef("{$N$1\"kind\": $2",
[istr, makeYamlString($n.kind)])
if maxRecDepth != 0:
case n.kind
of nkCharLit..nkInt64Lit:
- appf(result, ",$n$1\"intVal\": $2", [istr, toRope(n.intVal)])
+ appf(result, ",$N$1\"intVal\": $2", [istr, toRope(n.intVal)])
of nkFloatLit, nkFloat32Lit, nkFloat64Lit:
- appf(result, ",$n$1\"floatVal\": $2",
+ appf(result, ",$N$1\"floatVal\": $2",
[istr, toRope(n.floatVal.ToStrMaxPrecision)])
of nkStrLit..nkTripleStrLit:
- appf(result, ",$n$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
+ appf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
of nkSym:
- appf(result, ",$n$1\"sym\": $2_$3",
+ appf(result, ",$N$1\"sym\": $2_$3",
[istr, toRope(n.sym.name.s), toRope(n.sym.id)])
of nkIdent:
if n.ident != nil:
- appf(result, ",$n$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
+ appf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
else:
- appf(result, ",$n$1\"ident\": null", [istr])
+ appf(result, ",$N$1\"ident\": null", [istr])
else:
if sonsLen(n) > 0:
- appf(result, ",$n$1\"sons\": [", [istr])
+ appf(result, ",$N$1\"sons\": [", [istr])
for i in countup(0, sonsLen(n) - 1):
if i > 0: app(result, ",")
- appf(result, "$n$1$2", [spaces(indent + 4), debugTree(n.sons[i],
+ appf(result, "$N$1$2", [spaces(indent + 4), debugTree(n.sons[i],
indent + 4, maxRecDepth - 1)])
- appf(result, "$n$1]", [istr])
- appf(result, "$n$1}", [spaces(indent)])
+ appf(result, "$N$1]", [istr])
+ appf(result, "$N$1}", [spaces(indent)])
proc debug(n: PSym) =
#writeln(stdout, ropeToStr(symToYaml(n, 0, 1)))
diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim
index 17139f0555..fca708aee3 100644
--- a/compiler/ccgcalls.nim
+++ b/compiler/ccgcalls.nim
@@ -33,16 +33,14 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc, pl: PRope) =
# reset before pass as 'result' var:
resetLoc(p, d)
app(pl, addrLoc(d))
- app(pl, ")")
- app(p.s(cpsStmts), pl)
- appf(p.s(cpsStmts), ";$n")
+ appf(pl, ");$n")
+ line(p, cpsStmts, pl)
else:
var tmp: TLoc
getTemp(p, typ.sons[0], tmp)
app(pl, addrLoc(tmp))
- app(pl, ")")
- app(p.s(cpsStmts), pl)
- appf(p.s(cpsStmts), ";$n")
+ appf(pl, ");$n")
+ line(p, cpsStmts, pl)
genAssignment(p, d, tmp, {}) # no need for deep copying
else:
app(pl, ")")
@@ -53,9 +51,8 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc, pl: PRope) =
list.r = pl
genAssignment(p, d, list, {}) # no need for deep copying
else:
- app(pl, ")")
- app(p.s(cpsStmts), pl)
- appf(p.s(cpsStmts), ";$n")
+ appf(pl, ");$n")
+ line(p, cpsStmts, pl)
proc isInCurrentFrame(p: BProc, n: PNode): bool =
# checks if `n` is an expression that refers to the current frame;
@@ -148,7 +145,7 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
proc addComma(r: PRope): PRope =
result = if r == nil: r else: con(r, ", ")
- const CallPattern = "$1.ClEnv? $1.ClPrc($3$1.ClEnv) : (($4)($1.ClPrc))($2)"
+ const CallPattern = "$1.ClEnv? $1.ClPrc($3$1.ClEnv) : (($4)($1.ClPrc))($2);$n"
var op: TLoc
initLocExpr(p, ri.sons[0], op)
var pl: PRope
@@ -166,7 +163,7 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
if i < length - 1: app(pl, ", ")
template genCallPattern =
- appf(p.s(cpsStmts), CallPattern, op.r, pl, pl.addComma, rawProc)
+ lineF(p, cpsStmts, CallPattern, op.r, pl, pl.addComma, rawProc)
let rawProc = getRawProcType(p, typ)
if typ.sons[0] != nil:
@@ -181,13 +178,11 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
resetLoc(p, d)
app(pl, addrLoc(d))
genCallPattern()
- appf(p.s(cpsStmts), ";$n")
else:
var tmp: TLoc
getTemp(p, typ.sons[0], tmp)
- app(pl, addrLoc(tmp))
+ app(pl, addrLoc(tmp))
genCallPattern()
- appf(p.s(cpsStmts), ";$n")
genAssignment(p, d, tmp, {}) # no need for deep copying
else:
if d.k == locNone: getTemp(p, typ.sons[0], d)
@@ -198,7 +193,6 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
genAssignment(p, d, list, {}) # no need for deep copying
else:
genCallPattern()
- appf(p.s(cpsStmts), ";$n")
proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) =
var op, a: TLoc
@@ -264,16 +258,14 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
if d.k == locNone: getTemp(p, typ.sons[0], d)
app(pl, "Result: ")
app(pl, addrLoc(d))
- app(pl, "]")
- app(p.s(cpsStmts), pl)
- appf(p.s(cpsStmts), ";$n")
+ appf(pl, "];$n")
+ line(p, cpsStmts, pl)
else:
var tmp: TLoc
getTemp(p, typ.sons[0], tmp)
app(pl, addrLoc(tmp))
- app(pl, "]")
- app(p.s(cpsStmts), pl)
- appf(p.s(cpsStmts), ";$n")
+ appf(pl, "];$n")
+ line(p, cpsStmts, pl)
genAssignment(p, d, tmp, {}) # no need for deep copying
else:
app(pl, "]")
@@ -284,9 +276,8 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
list.r = pl
genAssignment(p, d, list, {}) # no need for deep copying
else:
- app(pl, "]")
- app(p.s(cpsStmts), pl)
- appf(p.s(cpsStmts), ";$n")
+ appf(pl, "];$n")
+ line(p, cpsStmts, pl)
proc genCall(p: BProc, e: PNode, d: var TLoc) =
if e.sons[0].typ.callConv == ccClosure:
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 7a0face5e5..1e1bf8072a 100755
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -34,7 +34,7 @@ proc int32Literal(i: Int): PRope =
proc genHexLiteral(v: PNode): PRope =
# hex literals are unsigned in C
# so we don't generate hex literals any longer.
- if not (v.kind in {nkIntLit..nkInt64Lit}):
+ if not (v.kind in {nkIntLit..nkUInt64Lit}):
internalError(v.info, "genHexLiteral")
result = intLiteral(v.intVal)
@@ -47,7 +47,7 @@ proc getStrLit(m: BModule, s: string): PRope =
proc genLiteral(p: BProc, v: PNode, ty: PType): PRope =
if ty == nil: internalError(v.info, "genLiteral: ty is nil")
case v.kind
- of nkCharLit..nkInt64Lit:
+ of nkCharLit..nkUInt64Lit:
case skipTypes(ty, abstractVarRange).kind
of tyChar, tyInt64, tyNil:
result = intLiteral(v.intVal)
@@ -160,7 +160,7 @@ proc getStorageLoc(n: PNode): TStorageLoc =
proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
if dest.s == OnStack or optRefcGC notin gGlobalOptions:
- appf(p.s(cpsStmts), "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
+ lineF(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
if needToKeepAlive in flags: keepAlive(p, dest)
elif dest.s == OnHeap:
# location is on heap
@@ -168,25 +168,25 @@ proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
#
# if afSrcIsNotNil in flags:
# UseMagic(p.module, 'nimGCref')
- # appf(p.s[cpsStmts], 'nimGCref($1);$n', [rdLoc(src)])
+ # lineF(p, cpsStmts, 'nimGCref($1);$n', [rdLoc(src)])
# elif afSrcIsNil notin flags:
# UseMagic(p.module, 'nimGCref')
- # appf(p.s[cpsStmts], 'if ($1) nimGCref($1);$n', [rdLoc(src)])
+ # lineF(p, cpsStmts, 'if ($1) nimGCref($1);$n', [rdLoc(src)])
# if afDestIsNotNil in flags:
# UseMagic(p.module, 'nimGCunref')
- # appf(p.s[cpsStmts], 'nimGCunref($1);$n', [rdLoc(dest)])
+ # lineF(p, cpsStmts, 'nimGCunref($1);$n', [rdLoc(dest)])
# elif afDestIsNil notin flags:
# UseMagic(p.module, 'nimGCunref')
- # appf(p.s[cpsStmts], 'if ($1) nimGCunref($1);$n', [rdLoc(dest)])
- # appf(p.s[cpsStmts], '$1 = $2;$n', [rdLoc(dest), rdLoc(src)])
+ # lineF(p, cpsStmts, 'if ($1) nimGCunref($1);$n', [rdLoc(dest)])
+ # lineF(p, cpsStmts, '$1 = $2;$n', [rdLoc(dest), rdLoc(src)])
if canFormAcycle(dest.t):
- appcg(p.module, p.s(cpsStmts), "#asgnRef((void**) $1, $2);$n",
+ lineCg(p, cpsStmts, "#asgnRef((void**) $1, $2);$n",
[addrLoc(dest), rdLoc(src)])
else:
- appcg(p.module, p.s(cpsStmts), "#asgnRefNoCycle((void**) $1, $2);$n",
+ lineCg(p, cpsStmts, "#asgnRefNoCycle((void**) $1, $2);$n",
[addrLoc(dest), rdLoc(src)])
else:
- appcg(p.module, p.s(cpsStmts), "#unsureAsgnRef((void**) $1, $2);$n",
+ lineCg(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n",
[addrLoc(dest), rdLoc(src)])
if needToKeepAlive in flags: keepAlive(p, dest)
@@ -200,15 +200,15 @@ proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
if needToCopy notin flags or
tfShallow in skipTypes(dest.t, abstractVarRange).flags:
if dest.s == OnStack or optRefcGC notin gGlobalOptions:
- appcg(p, cpsStmts,
+ lineCg(p, cpsStmts,
"memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
[addrLoc(dest), addrLoc(src), rdLoc(dest)])
if needToKeepAlive in flags: keepAlive(p, dest)
else:
- appcg(p, cpsStmts, "#genericShallowAssign((void*)$1, (void*)$2, $3);$n",
+ lineCg(p, cpsStmts, "#genericShallowAssign((void*)$1, (void*)$2, $3);$n",
[addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)])
else:
- appcg(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n",
+ lineCg(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n",
[addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)])
proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
@@ -216,7 +216,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
# the assignment operation in C.
if src.t != nil and src.t.kind == tyPtr:
# little HACK to support the new 'var T' as return type:
- appcg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
+ lineCg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
return
var ty = skipTypes(dest.t, abstractVarRange)
case ty.kind
@@ -226,24 +226,24 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
if needToCopy notin flags:
genRefAssign(p, dest, src, flags)
else:
- appcg(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n",
+ lineCg(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n",
[addrLoc(dest), rdLoc(src), genTypeInfo(p.module, dest.t)])
of tyString:
if needToCopy notin flags:
genRefAssign(p, dest, src, flags)
else:
if dest.s == OnStack or optRefcGC notin gGlobalOptions:
- appcg(p, cpsStmts, "$1 = #copyString($2);$n", [dest.rdLoc, src.rdLoc])
+ lineCg(p, cpsStmts, "$1 = #copyString($2);$n", [dest.rdLoc, src.rdLoc])
if needToKeepAlive in flags: keepAlive(p, dest)
elif dest.s == OnHeap:
# we use a temporary to care for the dreaded self assignment:
var tmp: TLoc
getTemp(p, ty, tmp)
- appcg(p, cpsStmts, "$3 = $1; $1 = #copyStringRC1($2);$n",
+ lineCg(p, cpsStmts, "$3 = $1; $1 = #copyStringRC1($2);$n",
[dest.rdLoc, src.rdLoc, tmp.rdLoc])
- appcg(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", tmp.rdLoc)
+ lineCg(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", tmp.rdLoc)
else:
- appcg(p, cpsStmts, "#unsureAsgnRef((void**) $1, #copyString($2));$n",
+ lineCg(p, cpsStmts, "#unsureAsgnRef((void**) $1, #copyString($2));$n",
[addrLoc(dest), rdLoc(src)])
if needToKeepAlive in flags: keepAlive(p, dest)
of tyTuple, tyObject, tyProc:
@@ -251,34 +251,34 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
if needsComplexAssignment(dest.t):
genGenericAsgn(p, dest, src, flags)
else:
- appcg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
+ lineCg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
of tyArray, tyArrayConstr:
if needsComplexAssignment(dest.t):
genGenericAsgn(p, dest, src, flags)
else:
- appcg(p, cpsStmts,
+ lineCg(p, cpsStmts,
"memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1));$n",
[rdLoc(dest), rdLoc(src)])
of tyOpenArray:
# open arrays are always on the stack - really? What if a sequence is
# passed to an open array?
if needsComplexAssignment(dest.t):
- appcg(p, cpsStmts, # XXX: is this correct for arrays?
+ lineCg(p, cpsStmts, # XXX: is this correct for arrays?
"#genericAssignOpenArray((void*)$1, (void*)$2, $1Len0, $3);$n",
[addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)])
else:
- appcg(p, cpsStmts,
+ lineCg(p, cpsStmts,
"memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1[0])*$1Len0);$n",
[rdLoc(dest), rdLoc(src)])
of tySet:
if mapType(ty) == ctArray:
- appcg(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, $3);$n",
+ lineCg(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, $3);$n",
[rdLoc(dest), rdLoc(src), toRope(getSize(dest.t))])
else:
- appcg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
+ lineCg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
of tyPtr, tyPointer, tyChar, tyBool, tyEnum, tyCString,
- tyInt..tyFloat128, tyRange:
- appcg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
+ tyInt..tyUInt64, tyRange:
+ lineCg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
else: InternalError("genAssignment(" & $ty.kind & ')')
proc expr(p: BProc, e: PNode, d: var TLoc)
@@ -317,20 +317,20 @@ proc binaryStmt(p: BProc, e: PNode, d: var TLoc, frmt: string) =
if d.k != locNone: InternalError(e.info, "binaryStmt")
InitLocExpr(p, e.sons[1], d)
InitLocExpr(p, e.sons[2], b)
- appcg(p, cpsStmts, frmt, [rdLoc(d), rdLoc(b)])
+ lineCg(p, cpsStmts, frmt, [rdLoc(d), 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)
- appcg(p, cpsStmts, frmt, [rdLoc(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)
- appcg(p, cpsStmts, frmt, [rdCharLoc(a), rdCharLoc(b)])
+ lineCg(p, cpsStmts, frmt, [rdCharLoc(a), rdCharLoc(b)])
proc binaryExpr(p: BProc, e: PNode, d: var TLoc, frmt: string) =
var a, b: TLoc
@@ -382,11 +382,11 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
else:
storage = getTypeDesc(p.module, t)
var tmp = getTempName()
- appcg(p, cpsLocals, "$1 $2;$n", [storage, tmp])
- appcg(p, cpsStmts, "$1 = #$2($3, $4);$n", [tmp, toRope(prc[m]),
+ lineCg(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}:
- appcg(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n",
+ lineCg(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]))
@@ -404,7 +404,7 @@ proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
InitLocExpr(p, e.sons[1], a)
t = skipTypes(e.typ, abstractRange)
if optOverflowCheck in p.options:
- appcg(p, cpsStmts, "if ($1 == $2) #raiseOverflow();$n",
+ lineCg(p, cpsStmts, "if ($1 == $2) #raiseOverflow();$n",
[rdLoc(a), intLiteral(firstOrd(t))])
putIntoDest(p, d, e.typ, ropef(opr[m], [rdLoc(a), toRope(getSize(t) * 8)]))
@@ -582,7 +582,7 @@ proc genTupleElem(p: BProc, e: PNode, d: var TLoc) =
var ty = a.t
var r = rdLoc(a)
case e.sons[1].kind
- of nkIntLit..nkInt64Lit: i = int(e.sons[1].intVal)
+ of nkIntLit..nkUInt64Lit: i = int(e.sons[1].intVal)
else: internalError(e.info, "genTupleElem")
when false:
if ty.n != nil:
@@ -634,11 +634,11 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
if id == gBackendId: strLit = getStrLit(p.module, field.name.s)
else: strLit = con("TMP", toRope(id))
if op.magic == mNot:
- appcg(p, cpsStmts,
+ lineCg(p, cpsStmts,
"if ($1) #raiseFieldError(((#NimStringDesc*) &$2));$n",
[rdLoc(test), strLit])
else:
- appcg(p, cpsStmts,
+ lineCg(p, cpsStmts,
"if (!($1)) #raiseFieldError(((#NimStringDesc*) &$2));$n",
[rdLoc(test), strLit])
appf(r, ".$1", [field.loc.r])
@@ -658,10 +658,10 @@ proc genArrayElem(p: BProc, e: PNode, d: var TLoc) =
# semantic pass has already checked for const index expressions
if firstOrd(ty) == 0:
if (firstOrd(b.t) < firstOrd(ty)) or (lastOrd(b.t) > lastOrd(ty)):
- appcg(p, cpsStmts, "if ((NU)($1) > (NU)($2)) #raiseIndexError();$n",
+ lineCg(p, cpsStmts, "if ((NU)($1) > (NU)($2)) #raiseIndexError();$n",
[rdCharLoc(b), intLiteral(lastOrd(ty))])
else:
- appcg(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError();$n",
+ lineCg(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError();$n",
[rdCharLoc(b), first, intLiteral(lastOrd(ty))])
if d.k == locNone: d.s = a.s
putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)),
@@ -681,7 +681,7 @@ proc genOpenArrayElem(p: BProc, e: PNode, d: var TLoc) =
initLocExpr(p, e.sons[0], a)
initLocExpr(p, e.sons[1], b) # emit range check:
if optBoundsCheck in p.options:
- appcg(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len0)) #raiseIndexError();$n",
+ lineCg(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len0)) #raiseIndexError();$n",
[rdLoc(b), rdLoc(a)]) # BUGFIX: ``>=`` and not ``>``!
if d.k == locNone: d.s = a.s
putIntoDest(p, d, elemType(skipTypes(a.t, abstractVar)),
@@ -696,11 +696,11 @@ proc genSeqElem(p: BPRoc, e: PNode, d: var TLoc) =
ty = skipTypes(ty.sons[0], abstractVarRange) # emit range check:
if optBoundsCheck in p.options:
if ty.kind == tyString:
- appcg(p, cpsStmts,
+ lineCg(p, cpsStmts,
"if ((NU)($1) > (NU)($2->$3)) #raiseIndexError();$n",
[rdLoc(b), rdLoc(a), lenField()])
else:
- appcg(p, cpsStmts,
+ lineCg(p, cpsStmts,
"if ((NU)($1) >= (NU)($2->$3)) #raiseIndexError();$n",
[rdLoc(b), rdLoc(a), lenField()])
if d.k == locNone: d.s = OnHeap
@@ -737,9 +737,9 @@ proc genAndOr(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
expr(p, e.sons[1], tmp)
L = getLabel(p)
if m == mOr:
- appf(p.s(cpsStmts), "if ($1) goto $2;$n", [rdLoc(tmp), L])
+ lineF(p, cpsStmts, "if ($1) goto $2;$n", [rdLoc(tmp), L])
else:
- appf(p.s(cpsStmts), "if (!($1)) goto $2;$n", [rdLoc(tmp), L])
+ lineF(p, cpsStmts, "if (!($1)) goto $2;$n", [rdLoc(tmp), L])
expr(p, e.sons[2], tmp)
fixLabel(p, L)
if d.k == locNone:
@@ -772,9 +772,9 @@ proc genIfExpr(p: BProc, n: PNode, d: var TLoc) =
of nkElifExpr:
initLocExpr(p, it.sons[0], a)
Lelse = getLabel(p)
- appf(p.s(cpsStmts), "if (!$1) goto $2;$n", [rdLoc(a), Lelse])
+ lineF(p, cpsStmts, "if (!$1) goto $2;$n", [rdLoc(a), Lelse])
expr(p, it.sons[1], tmp)
- appf(p.s(cpsStmts), "goto $1;$n", [Lend])
+ lineF(p, cpsStmts, "goto $1;$n", [Lend])
fixLabel(p, Lelse)
of nkElseExpr:
expr(p, it.sons[0], tmp)
@@ -793,7 +793,7 @@ proc genEcho(p: BProc, n: PNode) =
for i in countup(1, n.len-1):
initLocExpr(p, n.sons[i], a)
appf(args, ", ($1)->data", [rdLoc(a)])
- appcg(p, cpsStmts, "printf($1$2);$n", [
+ lineCg(p, cpsStmts, "printf($1$2);$n", [
makeCString(repeatStr(n.len-1, "%s") & tnl), args])
include ccgcalls
@@ -825,14 +825,14 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
initLocExpr(p, e.sons[i + 1], a)
if skipTypes(e.sons[i + 1].Typ, abstractVarRange).kind == tyChar:
Inc(L)
- appcg(p.module, appends, "#appendChar($1, $2);$n", [tmp.r, rdLoc(a)])
+ appLineCg(p, appends, "#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))
else:
appf(lens, "$1->$2 + ", [rdLoc(a), lenField()])
- appcg(p.module, appends, "#appendString($1, $2);$n", [tmp.r, rdLoc(a)])
- appcg(p, cpsStmts, "$1 = #rawNewString($2$3);$n", [tmp.r, lens, toRope(L)])
+ appLineCg(p, appends, "#appendString($1, $2);$n", [tmp.r, rdLoc(a)])
+ lineCg(p, cpsStmts, "$1 = #rawNewString($2$3);$n", [tmp.r, lens, toRope(L)])
app(p.s(cpsStmts), appends)
if d.k == locNone:
d = tmp
@@ -863,16 +863,16 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) =
initLocExpr(p, e.sons[i + 2], a)
if skipTypes(e.sons[i + 2].Typ, abstractVarRange).kind == tyChar:
Inc(L)
- appcg(p.module, appends, "#appendChar($1, $2);$n",
+ appLineCg(p, appends, "#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))
else:
appf(lens, "$1->$2 + ", [rdLoc(a), lenField()])
- appcg(p.module, appends, "#appendString($1, $2);$n",
+ appLineCg(p, appends, "#appendString($1, $2);$n",
[rdLoc(dest), rdLoc(a)])
- appcg(p, cpsStmts, "$1 = #resizeString($1, $2$3);$n",
+ lineCg(p, cpsStmts, "$1 = #resizeString($1, $2$3);$n",
[rdLoc(dest), lens, toRope(L)])
keepAlive(p, dest)
app(p.s(cpsStmts), appends)
@@ -881,10 +881,15 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
# seq &= x -->
# seq = (typeof seq) incrSeq(&seq->Sup, sizeof(x));
# seq->data[seq->len-1] = x;
+ let seqAppendPattern = if gCmd != cmdCompileToCpp:
+ "$1 = ($2) #incrSeq(&($1)->Sup, sizeof($3));$n"
+ 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)
- appcg(p, cpsStmts, "$1 = ($2) #incrSeq(&($1)->Sup, sizeof($3));$n", [
+ lineCg(p, cpsStmts, seqAppendPattern, [
rdLoc(a),
getTypeDesc(p.module, skipTypes(e.sons[1].typ, abstractVar)),
getTypeDesc(p.module, skipTypes(e.sons[2].Typ, abstractVar))])
@@ -896,7 +901,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)
- appcg(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
+ lineCg(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
[addrLoc(a), genTypeInfo(p.module, skipTypes(a.t, abstractVarRange))])
proc genNew(p: BProc, e: PNode) =
@@ -912,11 +917,11 @@ proc genNew(p: BProc, e: PNode) =
if a.s == OnHeap and optRefcGc in gGlobalOptions:
# use newObjRC1 as an optimization; and we don't need 'keepAlive' either
if canFormAcycle(a.t):
- appcg(p, cpsStmts, "if ($1) #nimGCunref($1);$n", a.rdLoc)
+ lineCg(p, cpsStmts, "if ($1) #nimGCunref($1);$n", a.rdLoc)
else:
- appcg(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", a.rdLoc)
+ lineCg(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", a.rdLoc)
b.r = ropecg(p.module, "($1) #newObjRC1($2, sizeof($3))", args)
- appcg(p, cpsStmts, "$1 = $2;$n", a.rdLoc, b.rdLoc)
+ lineCg(p, cpsStmts, "$1 = $2;$n", a.rdLoc, b.rdLoc)
else:
b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", args)
genAssignment(p, a, b, {needToKeepAlive}) # set the object type:
@@ -930,9 +935,9 @@ proc genNewSeqAux(p: BProc, dest: TLoc, length: PRope) =
var call: TLoc
initLoc(call, locExpr, dest.t, OnHeap)
if dest.s == OnHeap and optRefcGc in gGlobalOptions:
- appcg(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", dest.rdLoc)
+ lineCg(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", dest.rdLoc)
call.r = ropecg(p.module, "($1) #newSeqRC1($2, $3)", args)
- appcg(p, cpsStmts, "$1 = $2;$n", dest.rdLoc, call.rdLoc)
+ lineCg(p, cpsStmts, "$1 = $2;$n", dest.rdLoc, call.rdLoc)
else:
call.r = ropecg(p.module, "($1) #newSeq($2, $3)", args)
genAssignment(p, dest, call, {needToKeepAlive})
@@ -1114,8 +1119,12 @@ proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) =
InitLocExpr(p, e.sons[1], a)
InitLocExpr(p, e.sons[2], b)
var t = skipTypes(e.sons[1].typ, abstractVar)
- appcg(p, cpsStmts,
- "$1 = ($3) #setLengthSeq(&($1)->Sup, sizeof($4), $2);$n", [
+ let setLenPattern = if gCmd != cmdCompileToCpp:
+ "$1 = ($3) #setLengthSeq(&($1)->Sup, sizeof($4), $2);$n"
+ else:
+ "$1 = ($3) #setLengthSeq($1, sizeof($4), $2);$n"
+
+ lineCg(p, cpsStmts, setLenPattern, [
rdLoc(a), rdLoc(b), getTypeDesc(p.module, t),
getTypeDesc(p.module, t.sons[0])])
keepAlive(p, a)
@@ -1172,7 +1181,7 @@ proc binaryStmtInExcl(p: BProc, e: PNode, d: var TLoc, frmt: string) =
assert(d.k == locNone)
InitLocExpr(p, e.sons[1], a)
InitLocExpr(p, e.sons[2], b)
- appf(p.s(cpsStmts), frmt, [rdLoc(a), rdSetElemLoc(b, a.t)])
+ 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
@@ -1248,7 +1257,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
initLocExpr(p, e.sons[1], a)
initLocExpr(p, e.sons[2], b)
if d.k == locNone: getTemp(p, a.t, d)
- appf(p.s(cpsStmts), lookupOpr[op],
+ lineF(p, cpsStmts, lookupOpr[op],
[rdLoc(i), toRope(size), rdLoc(d), rdLoc(a), rdLoc(b)])
of mEqSet:
binaryExprChar(p, e, d, "(memcmp($1, $2, " & $(size) & ")==0)")
@@ -1258,7 +1267,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
initLocExpr(p, e.sons[1], a)
initLocExpr(p, e.sons[2], b)
if d.k == locNone: getTemp(p, a.t, d)
- appf(p.s(cpsStmts),
+ lineF(p, cpsStmts,
"for ($1 = 0; $1 < $2; $1++) $n" &
" $3[$1] = $4[$1] $6 $5[$1];$n", [
rdLoc(i), toRope(size), rdLoc(d), rdLoc(a), rdLoc(b),
@@ -1347,9 +1356,9 @@ proc binaryFloatArith(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
putIntoDest(p, d, e.typ, ropef("($2 $1 $3)", [
toRope(opr[m]), rdLoc(a), rdLoc(b)]))
if optNanCheck in p.options:
- appcg(p, cpsStmts, "#nanCheck($1);$n", [rdLoc(d)])
+ lineCg(p, cpsStmts, "#nanCheck($1);$n", [rdLoc(d)])
if optInfCheck in p.options:
- appcg(p, cpsStmts, "#infCheck($1);$n", [rdLoc(d)])
+ lineCg(p, cpsStmts, "#infCheck($1);$n", [rdLoc(d)])
else:
binaryArith(p, e, d, m)
@@ -1470,35 +1479,35 @@ proc genSetConstr(p: BProc, e: PNode, d: var TLoc) =
if d.k == locNone: getTemp(p, e.typ, d)
if getSize(e.typ) > 8:
# big set:
- appf(p.s(cpsStmts), "memset($1, 0, sizeof($1));$n", [rdLoc(d)])
+ lineF(p, cpsStmts, "memset($1, 0, sizeof($1));$n", [rdLoc(d)])
for i in countup(0, sonsLen(e) - 1):
if e.sons[i].kind == nkRange:
getTemp(p, getSysType(tyInt), idx) # our counter
initLocExpr(p, e.sons[i].sons[0], a)
initLocExpr(p, e.sons[i].sons[1], b)
- appf(p.s(cpsStmts), "for ($1 = $3; $1 <= $4; $1++) $n" &
+ lineF(p, cpsStmts, "for ($1 = $3; $1 <= $4; $1++) $n" &
"$2[$1/8] |=(1<<($1%8));$n", [rdLoc(idx), rdLoc(d),
rdSetElemLoc(a, e.typ), rdSetElemLoc(b, e.typ)])
else:
initLocExpr(p, e.sons[i], a)
- appf(p.s(cpsStmts), "$1[$2/8] |=(1<<($2%8));$n",
+ lineF(p, cpsStmts, "$1[$2/8] |=(1<<($2%8));$n",
[rdLoc(d), rdSetElemLoc(a, e.typ)])
else:
# small set
var ts = "NI" & $(getSize(e.typ) * 8)
- appf(p.s(cpsStmts), "$1 = 0;$n", [rdLoc(d)])
+ lineF(p, cpsStmts, "$1 = 0;$n", [rdLoc(d)])
for i in countup(0, sonsLen(e) - 1):
if e.sons[i].kind == nkRange:
getTemp(p, getSysType(tyInt), idx) # our counter
initLocExpr(p, e.sons[i].sons[0], a)
initLocExpr(p, e.sons[i].sons[1], b)
- appf(p.s(cpsStmts), "for ($1 = $3; $1 <= $4; $1++) $n" &
+ lineF(p, cpsStmts, "for ($1 = $3; $1 <= $4; $1++) $n" &
"$2 |=(1<<((" & ts & ")($1)%(sizeof(" & ts & ")*8)));$n", [
rdLoc(idx), rdLoc(d), rdSetElemLoc(a, e.typ),
rdSetElemLoc(b, e.typ)])
else:
initLocExpr(p, e.sons[i], a)
- appf(p.s(cpsStmts),
+ lineF(p, cpsStmts,
"$1 |=(1<<((" & ts & ")($2)%(sizeof(" & ts & ")*8)));$n",
[rdLoc(d), rdSetElemLoc(a, e.typ)])
@@ -1539,7 +1548,7 @@ proc genClosure(p: BProc, n: PNode, d: var TLoc) =
initLocExpr(p, n.sons[0], a)
initLocExpr(p, n.sons[1], b)
getTemp(p, n.typ, tmp)
- appcg(p, cpsStmts, "$1.ClPrc = $2; $1.ClEnv = $3;$n",
+ lineCg(p, cpsStmts, "$1.ClPrc = $2; $1.ClEnv = $3;$n",
tmp.rdLoc, a.rdLoc, b.rdLoc)
putLocIntoDest(p, d, tmp)
@@ -1579,10 +1588,10 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
app(r, ".Sup")
t = skipTypes(t.sons[0], abstractInst)
if nilCheck != nil:
- appcg(p, cpsStmts, "if ($1) #chckObj($2.m_type, $3);$n",
+ lineCg(p, cpsStmts, "if ($1) #chckObj($2.m_type, $3);$n",
[nilCheck, r, genTypeInfo(p.module, dest)])
else:
- appcg(p, cpsStmts, "#chckObj($1.m_type, $2);$n",
+ lineCg(p, cpsStmts, "#chckObj($1.m_type, $2);$n",
[r, genTypeInfo(p.module, dest)])
if n.sons[0].typ.kind != tyObject:
putIntoDest(p, d, n.typ,
@@ -1675,8 +1684,8 @@ proc expr(p: BProc, e: PNode, d: var TLoc) =
InternalError(e.info, "expr: param not init " & sym.name.s)
putLocIntoDest(p, d, sym.loc)
else: InternalError(e.info, "expr(" & $sym.kind & "); unknown symbol")
- of nkStrLit..nkTripleStrLit, nkIntLit..nkInt64Lit, nkFloatLit..nkFloat64Lit,
- nkNilLit, nkCharLit:
+ of nkStrLit..nkTripleStrLit, nkIntLit..nkUInt64Lit,
+ nkFloatLit..nkFloat128Lit, nkNilLit, nkCharLit:
putIntoDest(p, d, e.typ, genLiteral(p, e))
of nkCall, nkHiddenCallConv, nkInfix, nkPrefix, nkPostfix, nkCommand,
nkCallStrLit:
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index 46e4f75dff..591dd70893 100755
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -49,12 +49,12 @@ proc loadInto(p: BProc, le, ri: PNode, a: var TLoc) {.inline.} =
proc startBlock(p: BProc, start: TFormatStr = "{$n",
args: openarray[PRope]): int {.discardable.} =
+ lineCg(p, cpsStmts, start, args)
inc(p.labels)
result = len(p.blocks)
setlen(p.blocks, result + 1)
p.blocks[result].id = p.labels
p.blocks[result].nestedTryStmts = p.nestedTryStmts.len
- appcg(p, cpsLocals, start, args)
proc assignLabel(b: var TBlock): PRope {.inline.} =
b.label = con("LA", b.id.toRope)
@@ -70,7 +70,7 @@ proc endBlock(p: BProc, blockEnd: PRope) =
setlen(p.blocks, topBlock)
# this is done after the block is popped so $n is
# properly indented when pretty printing is enabled
- app(p.s(cpsStmts), blockEnd)
+ line(p, cpsStmts, blockEnd)
var gBlockEndBracket = ropef("}$n")
@@ -184,12 +184,12 @@ proc genIfStmt(p: BProc, n: PNode) =
initLocExpr(p, it.sons[0], a)
Lelse = getLabel(p)
inc(p.labels)
- appff(p.s(cpsStmts), "if (!$1) goto $2;$n",
- "br i1 $1, label %LOC$3, label %$2$n" & "LOC$3: $n",
+ lineFF(p, cpsStmts, "if (!$1) goto $2;$n",
+ "br i1 $1, label %LOC$3, label %$2$n" & "LOC$3: $n",
[rdLoc(a), Lelse, toRope(p.labels)])
genSimpleBlock(p, it.sons[1])
if sonsLen(n) > 1:
- appff(p.s(cpsStmts), "goto $1;$n", "br label %$1$n", [Lend])
+ lineFF(p, cpsStmts, "goto $1;$n", "br label %$1$n", [Lend])
fixLabel(p, Lelse)
of nkElse:
genSimpleBlock(p, it.sons[0])
@@ -205,23 +205,29 @@ proc blockLeaveActions(p: BProc, howMany: int) =
stack[i-1] = p.nestedTryStmts[L-i]
setLen(p.nestedTryStmts, L-howMany)
+ var alreadyPoppedCnt = p.inExceptBlock
for tryStmt in items(stack):
- appcg(p, cpsStmts, "#popSafePoint();$n", [])
+ if gCmd != cmdCompileToCpp:
+ if alreadyPoppedCnt > 0:
+ dec alreadyPoppedCnt
+ else:
+ lineCg(p, cpsStmts, "#popSafePoint();$n", [])
var finallyStmt = lastSon(tryStmt)
if finallyStmt.kind == nkFinally:
genStmts(p, finallyStmt.sons[0])
# push old elements again:
for i in countdown(howMany-1, 0):
p.nestedTryStmts.add(stack[i])
- for i in countdown(p.popCurrExc-1, 0):
- appcg(p, cpsStmts, "#popCurrentException();$n", [])
+ if gCmd != cmdCompileToCpp:
+ for i in countdown(p.inExceptBlock-1, 0):
+ lineCg(p, cpsStmts, "#popCurrentException();$n", [])
proc genReturnStmt(p: BProc, t: PNode) =
p.beforeRetNeeded = true
genLineDir(p, t)
if (t.sons[0].kind != nkEmpty): genStmts(p, t.sons[0])
blockLeaveActions(p, min(1, p.nestedTryStmts.len))
- appff(p.s(cpsStmts), "goto BeforeRet;$n", "br label %BeforeRet$n", [])
+ lineFF(p, cpsStmts, "goto BeforeRet;$n", "br label %BeforeRet$n", [])
proc genWhileStmt(p: BProc, t: PNode) =
# we don't generate labels here as for example GCC would produce
@@ -239,7 +245,7 @@ proc genWhileStmt(p: BProc, t: PNode) =
initLocExpr(p, t.sons[0], a)
if (t.sons[0].kind != nkIntLit) or (t.sons[0].intVal == 0):
let label = assignLabel(p.blocks[p.breakIdx])
- appf(p.s(cpsStmts), "if (!$1) goto $2;$n", [rdLoc(a), label])
+ lineF(p, cpsStmts, "if (!$1) goto $2;$n", [rdLoc(a), label])
genStmts(p, t.sons[1])
endBlock(p)
@@ -273,7 +279,7 @@ proc genParForStmt(p: BProc, t: PNode) =
initLocExpr(p, call.sons[1], rangeA)
initLocExpr(p, call.sons[2], rangeB)
- appf(p.s(cpsStmts), "#pragma omp parallel for $4$n" &
+ lineF(p, cpsStmts, "#pragma omp parallel for $4$n" &
"for ($1 = $2; $1 <= $3; ++$1)",
forLoopVar.loc.rdLoc,
rangeA.rdLoc, rangeB.rdLoc,
@@ -302,29 +308,35 @@ proc genBreakStmt(p: BProc, t: PNode) =
let label = assignLabel(p.blocks[idx])
blockLeaveActions(p, p.nestedTryStmts.len - p.blocks[idx].nestedTryStmts)
genLineDir(p, t)
- appf(p.s(cpsStmts), "goto $1;$n", [label])
+ lineF(p, cpsStmts, "goto $1;$n", [label])
proc getRaiseFrmt(p: BProc): string =
- #if gCmd == cmdCompileToCpp:
- # result = "throw #nimException($1, $2);$n"
- #else:
- result = "#raiseException((#E_Base*)$1, $2);$n"
+ if gCmd == cmdCompileToCpp:
+ result = "throw NimException($1, $2);$n"
+ else:
+ result = "#raiseException((#E_Base*)$1, $2);$n"
-proc genRaiseStmt(p: BProc, t: PNode) =
+proc genRaiseStmt(p: BProc, t: PNode) =
+ if p.inExceptBlock > 0:
+ # if the current try stmt have a finally block,
+ # we must execute it before reraising
+ var finallyBlock = p.nestedTryStmts[p.nestedTryStmts.len - 1].lastSon
+ if finallyBlock.kind == nkFinally:
+ genSimpleBlock(p, finallyBlock.sons[0])
if t.sons[0].kind != nkEmpty:
var a: TLoc
InitLocExpr(p, t.sons[0], a)
var e = rdLoc(a)
var typ = skipTypes(t.sons[0].typ, abstractPtrs)
genLineDir(p, t)
- appcg(p, cpsStmts, getRaiseFrmt(p), [e, makeCString(typ.sym.name.s)])
+ lineCg(p, cpsStmts, getRaiseFrmt(p), [e, makeCString(typ.sym.name.s)])
else:
genLineDir(p, t)
# reraise the last exception:
- #if gCmd == cmdCompileToCpp:
- # appcg(p, cpsStmts, "throw;$n")
- #else:
- appcg(p, cpsStmts, "#reraiseException();$n")
+ if gCmd == cmdCompileToCpp:
+ lineCg(p, cpsStmts, "throw;$n")
+ else:
+ lineCg(p, cpsStmts, "#reraiseException();$n")
proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
rangeFormat, eqFormat: TFormatStr, labl: TLabel) =
@@ -335,20 +347,20 @@ proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
if b.sons[i].kind == nkRange:
initLocExpr(p, b.sons[i].sons[0], x)
initLocExpr(p, b.sons[i].sons[1], y)
- appcg(p, cpsStmts, rangeFormat,
+ lineCg(p, cpsStmts, rangeFormat,
[rdCharLoc(e), rdCharLoc(x), rdCharLoc(y), labl])
else:
initLocExpr(p, b.sons[i], x)
- appcg(p, cpsStmts, eqFormat, [rdCharLoc(e), rdCharLoc(x), labl])
+ lineCg(p, cpsStmts, eqFormat, [rdCharLoc(e), rdCharLoc(x), labl])
proc genCaseSecondPass(p: BProc, t: PNode, labId, until: int): TLabel =
var Lend = getLabel(p)
for i in 1..until:
- appf(p.s(cpsStmts), "LA$1: ;$n", [toRope(labId + i)])
+ lineF(p, cpsStmts, "LA$1: ;$n", [toRope(labId + i)])
if t.sons[i].kind == nkOfBranch:
var length = sonsLen(t.sons[i])
genSimpleBlock(p, t.sons[i].sons[length - 1])
- appf(p.s(cpsStmts), "goto $1;$n", [Lend])
+ lineF(p, cpsStmts, "goto $1;$n", [Lend])
else:
genSimpleBlock(p, t.sons[i].sons[0])
result = Lend
@@ -363,13 +375,13 @@ proc genIfForCaseUntil(p: BProc, t: PNode, rangeFormat, eqFormat: TFormatStr,
genCaseGenericBranch(p, t.sons[i], a, rangeFormat, eqFormat,
con("LA", toRope(p.labels)))
else:
- appf(p.s(cpsStmts), "goto LA$1;$n", [toRope(p.labels)])
+ lineF(p, cpsStmts, "goto LA$1;$n", [toRope(p.labels)])
if until < t.len-1:
inc(p.labels)
var gotoTarget = p.labels
- appf(p.s(cpsStmts), "goto LA$1;$n", [toRope(gotoTarget)])
+ lineF(p, cpsStmts, "goto LA$1;$n", [toRope(gotoTarget)])
result = genCaseSecondPass(p, t, labId, until)
- appf(p.s(cpsStmts), "LA$1: ;$n", [toRope(gotoTarget)])
+ lineF(p, cpsStmts, "LA$1: ;$n", [toRope(gotoTarget)])
else:
result = genCaseSecondPass(p, t, labId, until)
@@ -411,7 +423,7 @@ proc genStringCase(p: BProc, t: PNode) =
else:
# else statement: nothing to do yet
# but we reserved a label, which we use later
- appcg(p, cpsStmts, "switch (#hashString($1) & $2) {$n",
+ lineCg(p, cpsStmts, "switch (#hashString($1) & $2) {$n",
[rdLoc(a), toRope(bitMask)])
for j in countup(0, high(branches)):
when false:
@@ -421,11 +433,11 @@ proc genStringCase(p: BProc, t: PNode) =
if interior != brn:
echo "BUG! ", interior, "-", brn
if branches[j] != nil:
- appf(p.s(cpsStmts), "case $1: $n$2break;$n",
+ lineF(p, cpsStmts, "case $1: $n$2break;$n",
[intLiteral(j), branches[j]])
- appf(p.s(cpsStmts), "}$n") # else statement:
+ lineF(p, cpsStmts, "}$n") # else statement:
if t.sons[sonsLen(t) - 1].kind != nkOfBranch:
- appf(p.s(cpsStmts), "goto LA$1;$n", [toRope(p.labels)])
+ lineF(p, cpsStmts, "goto LA$1;$n", [toRope(p.labels)])
# third pass: generate statements
var Lend = genCaseSecondPass(p, t, labId, sonsLen(t)-1)
fixLabel(p, Lend)
@@ -454,16 +466,16 @@ proc genCaseRange(p: BProc, branch: PNode) =
for j in 0 .. length-2:
if branch[j].kind == nkRange:
if hasSwitchRange in CC[ccompiler].props:
- appf(p.s(cpsStmts), "case $1 ... $2:$n", [
+ lineF(p, cpsStmts, "case $1 ... $2:$n", [
genLiteral(p, branch[j][0]),
genLiteral(p, branch[j][1])])
else:
var v = copyNode(branch[j][0])
while v.intVal <= branch[j][1].intVal:
- appf(p.s(cpsStmts), "case $1:$n", [genLiteral(p, v)])
+ lineF(p, cpsStmts, "case $1:$n", [genLiteral(p, v)])
Inc(v.intVal)
else:
- appf(p.s(cpsStmts), "case $1:$n", [genLiteral(p, branch[j])])
+ lineF(p, cpsStmts, "case $1:$n", [genLiteral(p, branch[j])])
proc genOrdinalCase(p: BProc, n: PNode) =
# analyse 'case' statement:
@@ -479,7 +491,7 @@ proc genOrdinalCase(p: BProc, n: PNode) =
# generate switch part (might be empty):
if splitPoint+1 < n.len:
- appf(p.s(cpsStmts), "switch ($1) {$n", [rdCharLoc(a)])
+ lineF(p, cpsStmts, "switch ($1) {$n", [rdCharLoc(a)])
var hasDefault = false
for i in splitPoint+1 .. < n.len:
var branch = n[i]
@@ -488,13 +500,13 @@ proc genOrdinalCase(p: BProc, n: PNode) =
genSimpleBlock(p, branch.lastSon)
else:
# else part of case statement:
- appf(p.s(cpsStmts), "default:$n")
+ lineF(p, cpsStmts, "default:$n")
genSimpleBlock(p, branch[0])
hasDefault = true
- appf(p.s(cpsStmts), "break;$n")
+ lineF(p, cpsStmts, "break;$n")
if (hasAssume in CC[ccompiler].props) and not hasDefault:
- appf(p.s(cpsStmts), "default: __assume(0);$n")
- appf(p.s(cpsStmts), "}$n")
+ lineF(p, cpsStmts, "default: __assume(0);$n")
+ lineF(p, cpsStmts, "}$n")
if Lend != nil: fixLabel(p, Lend)
proc genCaseStmt(p: BProc, t: PNode) =
@@ -518,80 +530,86 @@ proc hasGeneralExceptSection(t: PNode): bool =
inc(i)
result = false
-proc genTryStmtCpp(p: BProc, t: PNode) =
+proc genTryStmtCpp(p: BProc, t: PNode) =
# code to generate:
#
- # bool tmpRethrow = false;
+ # XXX: There should be a standard dispatch algorithm
+ # that's used both here and with multi-methods
+ #
# try
# {
# myDiv(4, 9);
- # } catch (NimException& tmp) {
- # tmpRethrow = true;
- # switch (tmp.exc)
- # {
- # case DIVIDE_BY_ZERO:
- # tmpRethrow = false;
- # printf("Division by Zero\n");
- # break;
- # default: // used for general except!
- # generalExceptPart();
- # tmpRethrow = false;
+ # } catch (NimException& exp) {
+ # if (isObj(exp, EIO) {
+ # ...
+ # } else if (isObj(exp, ESystem) {
+ # ...
+ # finallyPart()
+ # raise;
+ # } else {
+ # // general handler
# }
# }
- # excHandler = excHandler->prev; // we handled the exception
# finallyPart();
- # if (tmpRethrow) throw;
- #
- # XXX: push blocks
- var
- rethrowFlag: PRope
+ var
exc: PRope
i, length, blen: int
genLineDir(p, t)
- rethrowFlag = nil
exc = getTempName()
- if not hasGeneralExceptSection(t):
- rethrowFlag = getTempName()
- appf(p.s(cpsLocals), "volatile NIM_BOOL $1 = NIM_FALSE;$n", [rethrowFlag])
- if optStackTrace in p.Options:
- appcg(p, cpsStmts, "#setFrame((TFrame*)&F);$n")
- appf(p.s(cpsStmts), "try {$n")
+ discard cgsym(p.module, "E_Base")
add(p.nestedTryStmts, t)
+ startBlock(p, "try {$n")
genStmts(p, t.sons[0])
length = sonsLen(t)
- if t.sons[1].kind == nkExceptBranch:
- appf(p.s(cpsStmts), "} catch (NimException& $1) {$n", [exc])
- if rethrowFlag != nil:
- appf(p.s(cpsStmts), "$1 = NIM_TRUE;$n", [rethrowFlag])
- appf(p.s(cpsStmts), "if ($1.sp.exc) {$n", [exc])
+ endBlock(p, ropecg(p.module, "} catch (NimException& $1) {$n", [exc]))
+ if optStackTrace in p.Options:
+ lineCg(p, cpsStmts, "#setFrame((TFrame*)&F);$n")
+ inc p.inExceptBlock
i = 1
- while (i < length) and (t.sons[i].kind == nkExceptBranch):
+ var catchAllPresent = false
+ while (i < length) and (t.sons[i].kind == nkExceptBranch):
blen = sonsLen(t.sons[i])
- if blen == 1:
+ if i > 1: appf(p.s(cpsStmts), "else ")
+ if blen == 1:
# general except section:
- appf(p.s(cpsStmts), "default:$n")
- genStmts(p, t.sons[i].sons[0])
- else:
- for j in countup(0, blen - 2):
+ catchAllPresent = true
+ genSimpleBlock(p, t.sons[i].sons[0])
+ else:
+ var orExpr: PRope = nil
+ for j in countup(0, blen - 2):
assert(t.sons[i].sons[j].kind == nkType)
- appf(p.s(cpsStmts), "case $1:$n", [toRope(t.sons[i].sons[j].typ.id)])
- genStmts(p, t.sons[i].sons[blen - 1])
- if rethrowFlag != nil:
- appf(p.s(cpsStmts), "$1 = NIM_FALSE; ", [rethrowFlag])
- appf(p.s(cpsStmts), "break;$n")
+ if orExpr != nil: app(orExpr, "||")
+ appcg(p.module, orExpr,
+ "#isObj($1.exp->m_type, $2)",
+ [exc, genTypeInfo(p.module, t.sons[i].sons[j].typ)])
+ lineF(p, cpsStmts, "if ($1) ", [orExpr])
+ genSimpleBlock(p, t.sons[i].sons[blen-1])
inc(i)
- if t.sons[1].kind == nkExceptBranch:
- appf(p.s(cpsStmts), "}}$n") # end of catch-switch statement
- appcg(p, cpsStmts, "#popSafePoint();")
+
+ # reraise the exception if there was no catch all
+ # and none of the handlers matched
+ if not catchAllPresent:
+ if i > 1: lineF(p, cpsStmts, "else ")
+ startBlock(p)
+ var finallyBlock = t.lastSon
+ if finallyBlock.kind == nkFinally:
+ genStmts(p, finallyBlock.sons[0])
+ lineCg(p, cpsStmts, "throw;$n")
+ endBlock(p)
+
+ lineF(p, cpsStmts, "}$n") # end of catch block
+ dec p.inExceptBlock
+
discard pop(p.nestedTryStmts)
- if (i < length) and (t.sons[i].kind == nkFinally):
- genStmts(p, t.sons[i].sons[0])
- if rethrowFlag != nil:
- appf(p.s(cpsStmts), "if ($1) { throw; }$n", [rethrowFlag])
-
+ if (i < length) and (t.sons[i].kind == nkFinally):
+ genSimpleBlock(p, t.sons[i].sons[0])
+
proc genTryStmt(p: BProc, t: PNode) =
# code to generate:
#
+ # XXX: There should be a standard dispatch algorithm
+ # that's used both here and with multi-methods
+ #
# TSafePoint sp;
# pushSafePoint(&sp);
# sp.status = setjmp(sp.context);
@@ -618,50 +636,52 @@ proc genTryStmt(p: BProc, t: PNode) =
genLineDir(p, t)
var safePoint = getTempName()
discard cgsym(p.module, "E_Base")
- appcg(p, cpsLocals, "#TSafePoint $1;$n", [safePoint])
- appcg(p, cpsStmts, "#pushSafePoint(&$1);$n" &
- "$1.status = setjmp($1.context);$n", [safePoint])
- if optStackTrace in p.Options:
- appcg(p, cpsStmts, "#setFrame((TFrame*)&F);$n")
+ lineCg(p, cpsLocals, "#TSafePoint $1;$n", [safePoint])
+ lineCg(p, cpsStmts, "#pushSafePoint(&$1);$n", [safePoint])
+ lineF(p, cpsStmts, "$1.status = setjmp($1.context);$n", [safePoint])
startBlock(p, "if ($1.status == 0) {$n", [safePoint])
var length = sonsLen(t)
add(p.nestedTryStmts, t)
genStmts(p, t.sons[0])
- endBlock(p, ropecg(p.module, "#popSafePoint();$n } else {$n#popSafePoint();$n"))
- discard pop(p.nestedTryStmts)
+ linecg(p, cpsStmts, "#popSafePoint();$n")
+ endBlock(p)
+ startBlock(p, "else {$n")
+ lineCg(p, cpsStmts, "#popSafePoint();$n")
+ if optStackTrace in p.Options:
+ lineCg(p, cpsStmts, "#setFrame((TFrame*)&F);$n")
+ inc p.inExceptBlock
var i = 1
- while (i < length) and (t.sons[i].kind == nkExceptBranch):
+ while (i < length) and (t.sons[i].kind == nkExceptBranch):
var blen = sonsLen(t.sons[i])
- if blen == 1:
+ if blen == 1:
# general except section:
- if i > 1: appf(p.s(cpsStmts), "else")
+ if i > 1: lineF(p, cpsStmts, "else")
startBlock(p)
- appcg(p, cpsStmts, "$1.status = 0;$n", [safePoint])
- inc p.popCurrExc
+ lineCg(p, cpsStmts, "$1.status = 0;$n", [safePoint])
genStmts(p, t.sons[i].sons[0])
- dec p.popCurrExc
- appcg(p, cpsStmts, "#popCurrentException();$n", [])
+ lineCg(p, cpsStmts, "#popCurrentException();$n")
endBlock(p)
else:
- inc p.popCurrExc
var orExpr: PRope = nil
- for j in countup(0, blen - 2):
+ for j in countup(0, blen - 2):
assert(t.sons[i].sons[j].kind == nkType)
if orExpr != nil: app(orExpr, "||")
- appcg(p.module, orExpr,
- "#isObj(#getCurrentException()->Sup.m_type, $1)",
+ appcg(p.module, orExpr,
+ "#isObj(#getCurrentException()->Sup.m_type, $1)",
[genTypeInfo(p.module, t.sons[i].sons[j].typ)])
- if i > 1: app(p.s(cpsStmts), "else ")
+ if i > 1: line(p, cpsStmts, "else ")
startBlock(p, "if ($1) {$n", [orExpr])
- appcg(p, cpsStmts, "$1.status = 0;$n", [safePoint])
+ lineCg(p, cpsStmts, "$1.status = 0;$n", [safePoint])
genStmts(p, t.sons[i].sons[blen-1])
- dec p.popCurrExc
- endBlock(p, ropecg(p.module, "#popCurrentException();}$n"))
+ lineCg(p, cpsStmts, "#popCurrentException();$n")
+ endBlock(p)
inc(i)
- appf(p.s(cpsStmts), "}$n") # end of else block
+ dec p.inExceptBlock
+ discard pop(p.nestedTryStmts)
+ endBlock(p) # end of else block
if i < length and t.sons[i].kind == nkFinally:
genSimpleBlock(p, t.sons[i].sons[0])
- appcg(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", [safePoint])
+ lineCg(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", [safePoint])
proc genAsmOrEmitStmt(p: BProc, t: PNode): PRope =
for i in countup(0, sonsLen(t) - 1):
@@ -688,7 +708,7 @@ proc genAsmStmt(p: BProc, t: PNode) =
assert(t.kind == nkAsmStmt)
genLineDir(p, t)
var s = genAsmOrEmitStmt(p, t)
- appf(p.s(cpsStmts), CC[ccompiler].asmStmtFrmt, [s])
+ lineF(p, cpsStmts, CC[ccompiler].asmStmtFrmt, [s])
proc genEmit(p: BProc, t: PNode) =
genLineDir(p, t)
@@ -697,7 +717,7 @@ proc genEmit(p: BProc, t: PNode) =
# top level emit pragma?
app(p.module.s[cfsProcHeaders], s)
else:
- app(p.s(cpsStmts), s)
+ line(p, cpsStmts, s)
var
breakPointId: int = 0
@@ -723,7 +743,7 @@ proc genWatchpoint(p: BProc, n: PNode) =
var a: TLoc
initLocExpr(p, n.sons[1], a)
let typ = skipTypes(n.sons[1].typ, abstractVarRange)
- appcg(p, cpsStmts, "#dbgRegisterWatchpoint($1, (NCSTRING)$2, $3);$n",
+ lineCg(p, cpsStmts, "#dbgRegisterWatchpoint($1, (NCSTRING)$2, $3);$n",
[a.addrLoc, makeCString(renderTree(n.sons[1])),
genTypeInfo(p.module, typ)])
@@ -763,7 +783,7 @@ proc genDiscriminantCheck(p: BProc, a, tmp: TLoc, objtype: PType,
if not ContainsOrIncl(p.module.declaredThings, field.id):
appcg(p.module, cfsVars, "extern $1",
discriminatorTableDecl(p.module, t, field))
- appcg(p, cpsStmts,
+ lineCg(p, cpsStmts,
"#FieldDiscriminantCheck((NI)(NU)($1), (NI)(NU)($2), $3, $4);$n",
[rdLoc(a), rdLoc(tmp), discriminatorTableName(p.module, t, field),
intLiteral(L+1)])
@@ -820,9 +840,8 @@ proc genStmts(p: BProc, t: PNode) =
initLocExpr(p, t.sons[0], a)
of nkAsmStmt: genAsmStmt(p, t)
of nkTryStmt:
- #if gCmd == cmdCompileToCpp: genTryStmtCpp(p, t)
- #else:
- genTryStmt(p, t)
+ if gCmd == cmdCompileToCpp: genTryStmtCpp(p, t)
+ else: genTryStmt(p, t)
of nkRaiseStmt: genRaiseStmt(p, t)
of nkTypeSection:
# we have to emit the type information for object types here to support
diff --git a/compiler/ccgthreadvars.nim b/compiler/ccgthreadvars.nim
index 38c5c0f5e3..4785402e75 100755
--- a/compiler/ccgthreadvars.nim
+++ b/compiler/ccgthreadvars.nim
@@ -19,10 +19,10 @@ proc AccessThreadLocalVar(p: BProc, s: PSym) =
if emulatedThreadVars() and not p.ThreadVarAccessed:
p.ThreadVarAccessed = true
p.module.usesThreadVars = true
- appf(p.procSec(cpsLocals), "NimThreadVars* NimTV;$n")
+ appf(p.procSec(cpsLocals), "\tNimThreadVars* NimTV;$n")
app(p.procSec(cpsInit),
- ropecg(p.module, "NimTV=(NimThreadVars*)#GetThreadLocalVars();$n"))
-
+ ropecg(p.module, "\tNimTV = (NimThreadVars*) #GetThreadLocalVars();$n"))
+
var
nimtv: PRope # nimrod thread vars; the struct body
nimtvDeps: seq[PType] = @[] # type deps: every module needs whole struct
diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim
index d95ea8b09b..75357ff46a 100644
--- a/compiler/ccgtrav.nim
+++ b/compiler/ccgtrav.nim
@@ -31,17 +31,17 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, n: PNode) =
if (n.sons[0].kind != nkSym): InternalError(n.info, "genTraverseProc")
var p = c.p
let disc = n.sons[0].sym
- p.s(cpsStmts).appf("switch ($1.$2) {$n", accessor, disc.loc.r)
+ lineF(p, cpsStmts, "switch ($1.$2) {$n", accessor, disc.loc.r)
for i in countup(1, sonsLen(n) - 1):
let branch = n.sons[i]
assert branch.kind in {nkOfBranch, nkElse}
if branch.kind == nkOfBranch:
genCaseRange(c.p, branch)
else:
- p.s(cpsStmts).appf("default:$n")
+ lineF(p, cpsStmts, "default:$n")
genTraverseProc(c, accessor, lastSon(branch))
- p.s(cpsStmts).appf("break;$n")
- p.s(cpsStmts).appf("} $n")
+ lineF(p, cpsStmts, "break;$n")
+ lineF(p, cpsStmts, "} $n")
of nkSym:
let field = n.sym
genTraverseProc(c, ropef("$1.$2", accessor, field.loc.r), field.loc.t)
@@ -63,10 +63,10 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType) =
let arraySize = lengthOrd(typ.sons[0])
var i: TLoc
getTemp(p, getSysType(tyInt), i)
- appf(p.s(cpsStmts), "for ($1 = 0; $1 < $2; $1++) {$n",
+ lineF(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n",
i.r, arraySize.toRope)
genTraverseProc(c, ropef("$1[$2]", accessor, i.r), typ.sons[1])
- appf(p.s(cpsStmts), "}$n")
+ lineF(p, cpsStmts, "}$n")
of tyObject:
for i in countup(0, sonsLen(typ) - 1):
genTraverseProc(c, accessor.parentObj, typ.sons[i])
@@ -79,7 +79,7 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType) =
for i in countup(0, sonsLen(typ) - 1):
genTraverseProc(c, ropef("$1.Field$2", accessor, i.toRope), typ.sons[i])
of tyRef, tyString, tySequence:
- appcg(p, cpsStmts, c.visitorFrmt, accessor)
+ lineCg(p, cpsStmts, c.visitorFrmt, accessor)
else:
# no marker procs for closures yet
nil
@@ -89,10 +89,10 @@ proc genTraverseProcSeq(c: var TTraversalClosure, accessor: PRope, typ: PType) =
assert typ.kind == tySequence
var i: TLoc
getTemp(p, getSysType(tyInt), i)
- appf(p.s(cpsStmts), "for ($1 = 0; $1 < $2->$3; $1++) {$n",
+ lineF(p, cpsStmts, "for ($1 = 0; $1 < $2->$3; $1++) {$n",
i.r, accessor, toRope(if gCmd != cmdCompileToCpp: "Sup.len" else: "len"))
genTraverseProc(c, ropef("$1->data[$2]", accessor, i.r), typ.sons[0])
- appf(p.s(cpsStmts), "}$n")
+ lineF(p, cpsStmts, "}$n")
proc genTraverseProc(m: BModule, typ: PType, reason: TTypeInfoReason): PRope =
var c: TTraversalClosure
@@ -106,8 +106,8 @@ proc genTraverseProc(m: BModule, typ: PType, reason: TTypeInfoReason): PRope =
let header = ropef("N_NIMCALL(void, $1)(void* p, NI op)", result)
let t = getTypeDesc(m, typ)
- p.s(cpsLocals).appf("$1 a;$n", t)
- p.s(cpsInit).appf("a = ($1)p;$n", t)
+ lineF(p, cpsLocals, "$1 a;$n", t)
+ lineF(p, cpsInit, "a = ($1)p;$n", t)
c.p = p
if typ.kind == tySequence:
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 4492c2fea2..e456a1eaa8 100755
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -174,7 +174,7 @@ proc mapType(typ: PType): TCTypeKind =
of tyProc: result = if typ.callConv != ccClosure: ctProc else: ctStruct
of tyString: result = ctNimStr
of tyCString: result = ctCString
- of tyInt..tyFloat128:
+ of tyInt..tyUInt64:
result = TCTypeKind(ord(typ.kind) - ord(tyInt) + ord(ctInt))
else: InternalError("mapType")
@@ -313,8 +313,10 @@ proc typeNameOrLiteral(t: PType, literal: string): PRope =
proc getSimpleTypeDesc(m: BModule, typ: PType): PRope =
const
- NumericalTypeToStr: array[tyInt..tyFloat128, string] = ["NI", "NI8",
- "NI16", "NI32", "NI64", "NF", "NF32", "NF64", "NF128"]
+ NumericalTypeToStr: array[tyInt..tyUInt64, string] = [
+ "NI", "NI8", "NI16", "NI32", "NI64",
+ "NF", "NF32", "NF64", "NF128",
+ "NU", "NU8", "NU16", "NU32", "NU64",]
case typ.Kind
of tyPointer:
result = typeNameOrLiteral(typ, "void*")
@@ -337,7 +339,7 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): PRope =
of tyBool: result = typeNameOrLiteral(typ, "NIM_BOOL")
of tyChar: result = typeNameOrLiteral(typ, "NIM_CHAR")
of tyNil: result = typeNameOrLiteral(typ, "0")
- of tyInt..tyFloat128, tyUInt..tyUInt64:
+ of tyInt..tyUInt64:
result = typeNameOrLiteral(typ, NumericalTypeToStr[typ.Kind])
of tyRange: result = getSimpleTypeDesc(m, typ.sons[0])
else: result = nil
@@ -871,7 +873,7 @@ proc genTypeInfo(m: BModule, typ: PType): PRope =
if dataGenerated: return
case t.kind
of tyEmpty: result = toRope"0"
- of tyPointer, tyBool, tyChar, tyCString, tyString, tyInt..tyFloat128, tyVar:
+ of tyPointer, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64, tyVar:
genTypeInfoAuxBase(gNimDat, t, result, toRope"0")
of tyProc:
if t.callConv != ccClosure:
diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim
index 5ba5230702..de49897c51 100755
--- a/compiler/ccgutils.nim
+++ b/compiler/ccgutils.nim
@@ -70,9 +70,7 @@ proc GetUniqueType*(key: PType): PType =
var k = key.kind
case k
of tyBool, tyChar,
- tyInt, tyInt8, tyInt16, tyInt32, tyInt64,
- tyFloat, tyFloat32, tyFloat64, tyFloat128,
- tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64:
+ tyInt..tyUInt64:
# no canonicalization for integral types, so that e.g. ``pid_t`` is
# produced instead of ``NI``.
result = key
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 73bd79ce89..51f538a970 100755
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -153,6 +153,34 @@ proc appcg(p: BProc, s: TCProcSection, frmt: TFormatStr,
args: openarray[PRope]) =
app(p.s(s), ropecg(p.module, frmt, args))
+var indent = "\t".toRope
+proc indentLine(p: BProc, r: PRope): PRope =
+ result = r
+ for i in countup(0, p.blocks.len-1): prepend(result, indent)
+
+proc line(p: BProc, s: TCProcSection, r: PRope) =
+ app(p.s(s), indentLine(p, r))
+
+proc line(p: BProc, s: TCProcSection, r: string) =
+ app(p.s(s), indentLine(p, r.toRope))
+
+proc lineF(p: BProc, s: TCProcSection, frmt: TFormatStr,
+ args: openarray[PRope]) =
+ app(p.s(s), indentLine(p, ropef(frmt, args)))
+
+proc lineCg(p: BProc, s: TCProcSection, frmt: TFormatStr,
+ args: openarray[PRope]) =
+ app(p.s(s), indentLine(p, ropecg(p.module, frmt, args)))
+
+proc appLineCg(p: BProc, r: var PRope, frmt: TFormatStr,
+ args: openarray[PRope]) =
+ app(r, indentLine(p, ropecg(p.module, frmt, args)))
+
+proc lineFF(p: BProc, s: TCProcSection, cformat, llvmformat: string,
+ args: openarray[PRope]) =
+ if gCmd == cmdCompileToLLVM: lineF(p, s, llvmformat, args)
+ else: lineF(p, s, cformat, args)
+
proc safeLineNm(info: TLineInfo): int =
result = toLinenumber(info)
if result < 0: result = 0 # negative numbers are not allowed in #line
@@ -171,11 +199,11 @@ proc genLineDir(p: BProc, t: PNode) =
genCLineDir(p.s(cpsStmts), t.info.toFullPath, line)
if ({optStackTrace, optEndb} * p.Options == {optStackTrace, optEndb}) and
(p.prc == nil or sfPure notin p.prc.flags):
- appcg(p, cpsStmts, "#endb($1);$n", [toRope(line)])
+ lineCg(p, cpsStmts, "#endb($1);$n", [toRope(line)])
elif ({optLineTrace, optStackTrace} * p.Options ==
{optLineTrace, optStackTrace}) and
(p.prc == nil or sfPure notin p.prc.flags):
- appf(p.s(cpsStmts), "F.line = $1;F.filename = $2;$n",
+ lineF(p, cpsStmts, "F.line = $1;F.filename = $2;$n",
[toRope(line), makeCString(toFilename(t.info).extractFilename)])
include "ccgtypes.nim"
@@ -211,11 +239,11 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
while (s.kind == tyObject) and (s.sons[0] != nil):
app(r, ".Sup")
s = skipTypes(s.sons[0], abstractInst)
- appcg(p, section, "$1.m_type = $2;$n", [r, genTypeInfo(p.module, t)])
+ lineCg(p, section, "$1.m_type = $2;$n", [r, genTypeInfo(p.module, t)])
of frEmbedded:
# worst case for performance:
var r = if takeAddr: addrLoc(a) else: rdLoc(a)
- appcg(p, section, "#objectInit($1, $2);$n", [r, genTypeInfo(p.module, t)])
+ lineCg(p, section, "#objectInit($1, $2);$n", [r, genTypeInfo(p.module, t)])
type
TAssignmentFlag = enum
@@ -238,16 +266,16 @@ proc resetLoc(p: BProc, loc: var TLoc) =
nilLoc.r = toRope("NIM_NIL")
genRefAssign(p, loc, nilLoc, {afSrcIsNil})
else:
- appf(p.s(cpsStmts), "$1 = 0;$n", [rdLoc(loc)])
+ lineF(p, cpsStmts, "$1 = 0;$n", [rdLoc(loc)])
else:
if loc.s != OnStack:
- appcg(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
+ lineCg(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
[addrLoc(loc), genTypeInfo(p.module, loc.t)])
# XXX: generated reset procs should not touch the m_type
# field, so disabling this should be safe:
genObjectInit(p, cpsStmts, loc.t, loc, true)
else:
- appf(p.s(cpsStmts), "memset((void*)$1, 0, sizeof($2));$n",
+ lineF(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n",
[addrLoc(loc), rdLoc(loc)])
# XXX: We can be extra clever here and call memset only
# on the bytes following the m_type field?
@@ -255,9 +283,9 @@ proc resetLoc(p: BProc, loc: var TLoc) =
proc constructLoc(p: BProc, loc: TLoc, section = cpsStmts) =
if not isComplexValueType(skipTypes(loc.t, abstractVarRange)):
- appf(p.s(section), "$1 = 0;$n", [rdLoc(loc)])
+ lineF(p, section, "$1 = 0;$n", [rdLoc(loc)])
else:
- appf(p.s(section), "memset((void*)$1, 0, sizeof($2));$n",
+ lineF(p, section, "memset((void*)$1, 0, sizeof($2));$n",
[addrLoc(loc), rdLoc(loc)])
genObjectInit(p, section, loc.t, loc, true)
@@ -285,7 +313,7 @@ proc getTemp(p: BProc, t: PType, result: var TLoc) =
result.r = con("%LOC", toRope(p.labels))
else:
result.r = con("LOC", toRope(p.labels))
- appf(p.s(cpsLocals), "$1 $2;$n", [getTypeDesc(p.module, t), result.r])
+ lineF(p, cpsLocals, "$1 $2;$n", [getTypeDesc(p.module, t), result.r])
result.k = locTemp
result.a = - 1
result.t = getUniqueType(t)
@@ -311,9 +339,9 @@ proc keepAlive(p: BProc, toKeepAlive: TLoc) =
result.flags = {}
if not isComplexValueType(skipTypes(toKeepAlive.t, abstractVarRange)):
- appf(p.s[cpsStmts], "$1 = $2;$n", [rdLoc(result), rdLoc(toKeepAlive)])
+ lineF(p, cpsStmts, "$1 = $2;$n", [rdLoc(result), rdLoc(toKeepAlive)])
else:
- appcg(p, cpsStmts,
+ lineCg(p, cpsStmts,
"memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
[addrLoc(result), addrLoc(toKeepAlive), rdLoc(result)])
@@ -355,7 +383,7 @@ proc allocParam(p: BProc, s: PSym) =
var tmp = con("%LOC", toRope(p.labels))
incl(s.loc.flags, lfParamCopy)
incl(s.loc.flags, lfIndirect)
- appf(p.s(cpsInit), "$1 = alloca $3$n" & "store $3 $2, $3* $1$n",
+ lineF(p, cpsInit, "$1 = alloca $3$n" & "store $3 $2, $3* $1$n",
[tmp, s.loc.r, getTypeDesc(p.module, s.loc.t)])
s.loc.r = tmp
@@ -365,7 +393,7 @@ proc localDebugInfo(p: BProc, s: PSym) =
if skipTypes(s.typ, abstractVar).kind == tyOpenArray: return
var a = con("&", s.loc.r)
if (s.kind == skParam) and ccgIntroducedPtr(s): a = s.loc.r
- appf(p.s(cpsInit),
+ lineF(p, cpsInit,
"F.s[$1].address = (void*)$3; F.s[$1].typ = $4; F.s[$1].name = $2;$n",
[toRope(p.frameLen), makeCString(normalize(s.name.s)), a,
genTypeInfo(p.module, s.loc.t)])
@@ -378,13 +406,14 @@ proc assignLocalVar(p: BProc, s: PSym) =
if s.loc.k == locNone:
fillLoc(s.loc, locLocalVar, s.typ, mangleName(s), OnStack)
if s.kind == skLet: incl(s.loc.flags, lfNoDeepCopy)
- app(p.s(cpsLocals), getTypeDesc(p.module, s.loc.t))
- if sfRegister in s.flags: app(p.s(cpsLocals), " register")
+ var decl = getTypeDesc(p.module, s.loc.t)
+ if sfRegister in s.flags: app(decl, " register")
#elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds:
- # app(p.s[cpsLocals], " GC_GUARD")
+ # app(decl, " GC_GUARD")
if (sfVolatile in s.flags) or (p.nestedTryStmts.len > 0):
- app(p.s(cpsLocals), " volatile")
- appf(p.s(cpsLocals), " $1;$n", [s.loc.r])
+ app(decl, " volatile")
+ appf(decl, " $1;$n", [s.loc.r])
+ line(p, cpsLocals, decl)
localDebugInfo(p, s)
include ccgthreadvars
@@ -427,7 +456,7 @@ proc getLabel(p: BProc): TLabel =
result = con("LA", toRope(p.labels))
proc fixLabel(p: BProc, labl: TLabel) =
- appf(p.s(cpsStmts), "$1: ;$n", [labl])
+ lineF(p, cpsStmts, "$1: ;$n", [labl])
proc genVarPrototype(m: BModule, sym: PSym)
proc requestConstImpl(p: BProc, sym: PSym)
@@ -545,28 +574,28 @@ proc getFrameDecl(p: BProc) =
[toRope(p.frameLen)])
else:
slots = nil
- appff(p.s(cpsLocals), "volatile struct {TFrame* prev;" &
- "NCSTRING procname;NI line;NCSTRING filename;" &
- "NI len;$n$1} F;$n",
+ lineFF(p, cpsLocals, "volatile struct {TFrame* prev;" &
+ "NCSTRING procname;NI line;NCSTRING filename;" &
+ "NI len;$1} F;$n",
"%TF = type {%TFrame*, i8*, %NI, %NI$1}$n" &
"%F = alloca %TF$n", [slots])
inc(p.labels)
- prepend(p.s(cpsInit), ropeff("F.len = $1;$n",
+ prepend(p.s(cpsInit), indentLine(p, ropeff("F.len = $1;$n",
"%LOC$2 = getelementptr %TF %F, %NI 4$n" &
- "store %NI $1, %NI* %LOC$2$n", [toRope(p.frameLen), toRope(p.labels)]))
+ "store %NI $1, %NI* %LOC$2$n", [toRope(p.frameLen), toRope(p.labels)])))
proc retIsNotVoid(s: PSym): bool =
result = (s.typ.sons[0] != nil) and not isInvalidReturnType(s.typ.sons[0])
proc initFrame(p: BProc, procname, filename: PRope): PRope =
result = ropecg(p.module,
- "F.procname = $1;$n" &
- "F.filename = $2;$n" &
- "F.line = 0;$n" &
- "#pushFrame((TFrame*)&F);$n", [procname, filename])
+ "\tF.procname = $1;$n" &
+ "\tF.filename = $2;$n" &
+ "\tF.line = 0;$n" &
+ "\t#pushFrame((TFrame*)&F);$n", [procname, filename])
proc deinitFrame(p: BProc): PRope =
- result = ropecg(p.module, "#popFrame();$n")
+ result = ropecg(p.module, "\t#popFrame();$n")
proc closureSetup(p: BProc, prc: PSym) =
if prc.typ.callConv != ccClosure: return
@@ -578,8 +607,8 @@ proc closureSetup(p: BProc, prc: PSym) =
#echo "created environment: ", env.id, " for ", prc.name.s
assignLocalVar(p, env)
# generate cast assignment:
- appcg(p, cpsStmts, "$1 = ($2) ClEnv;$n", rdLoc(env.loc),
- getTypeDesc(p.module, env.typ))
+ lineCg(p, cpsStmts, "$1 = ($2) ClEnv;$n", rdLoc(env.loc),
+ getTypeDesc(p.module, env.typ))
proc genProcAux(m: BModule, prc: PSym) =
var p = newProc(prc, m)
@@ -593,7 +622,7 @@ proc genProcAux(m: BModule, prc: PSym) =
# declare the result symbol:
assignLocalVar(p, res)
assert(res.loc.r != nil)
- returnStmt = ropeff("return $1;$n", "ret $1$n", [rdLoc(res.loc)])
+ returnStmt = ropeff("\treturn $1;$n", "ret $1$n", [rdLoc(res.loc)])
initLocalVar(p, res, immediateAsgn=false)
else:
fillResult(res)
@@ -609,10 +638,10 @@ proc genProcAux(m: BModule, prc: PSym) =
genStmts(p, prc.getBody) # modifies p.locals, p.init, etc.
var generatedProc: PRope
if sfPure in prc.flags:
- generatedProc = ropeff("$1 {$n$2$3$4}$n", "define $1 {$n$2$3$4}$n",
+ generatedProc = ropeff("$N$1 {$n$2$3$4}$N$N", "define $1 {$n$2$3$4}$N",
[header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)])
else:
- generatedProc = ropeff("$1 {$n", "define $1 {$n", [header])
+ generatedProc = ropeff("$N$1 {$N", "$Ndefine $1 {$N", [header])
app(generatedProc, initGCFrame(p))
if optStackTrace in prc.options:
getFrameDecl(p)
@@ -626,25 +655,25 @@ proc genProcAux(m: BModule, prc: PSym) =
if gProcProfile >= 64 * 1024:
InternalError(prc.info, "too many procedures for profiling")
discard cgsym(m, "profileData")
- appf(p.s(cpsLocals), "ticks NIM_profilingStart;$n")
+ appf(p.s(cpsLocals), "\tticks NIM_profilingStart;$n")
if prc.loc.a < 0:
- appf(m.s[cfsDebugInit], "profileData[$1].procname = $2;$n", [
+ appf(m.s[cfsDebugInit], "\tprofileData[$1].procname = $2;$n", [
toRope(gProcProfile),
makeCString(prc.name.s)])
prc.loc.a = gProcProfile
inc(gProcProfile)
- prepend(p.s(cpsInit), ropef("NIM_profilingStart = getticks();$n"))
+ prepend(p.s(cpsInit), ropef("\tNIM_profilingStart = getticks();$n"))
app(generatedProc, p.s(cpsInit))
app(generatedProc, p.s(cpsStmts))
- if p.beforeRetNeeded: appf(generatedProc, "BeforeRet: $n;")
+ if p.beforeRetNeeded: appf(generatedProc, "\tBeforeRet: ;$n")
app(generatedProc, deinitGCFrame(p))
if optStackTrace in prc.options: app(generatedProc, deinitFrame(p))
if (optProfiler in prc.options) and (gCmd != cmdCompileToLLVM):
appf(generatedProc,
- "profileData[$1].total += elapsed(getticks(), NIM_profilingStart);$n",
+ "\tprofileData[$1].total += elapsed(getticks(), NIM_profilingStart);$n",
[toRope(prc.loc.a)])
app(generatedProc, returnStmt)
- appf(generatedProc, "}$n")
+ appf(generatedProc, "}$N")
app(m.s[cfsProcs], generatedProc)
proc genProcPrototype(m: BModule, sym: PSym) =
diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim
index a22c13f3aa..72c7ceae50 100644
--- a/compiler/cgendata.nim
+++ b/compiler/cgendata.nim
@@ -37,9 +37,11 @@ type
cfsDynLibDeinit # section for deinitialization of dynamic
# libraries
TCTypeKind* = enum # describes the type kind of a C type
- ctVoid, ctChar, ctBool, ctUInt, ctUInt8, ctUInt16, ctUInt32, ctUInt64,
- ctInt, ctInt8, ctInt16, ctInt32, ctInt64, ctFloat, ctFloat32, ctFloat64,
- ctFloat128, ctArray, ctStruct, ctPtr, ctNimStr, ctNimSeq, ctProc, ctCString
+ ctVoid, ctChar, ctBool,
+ ctInt, ctInt8, ctInt16, ctInt32, ctInt64,
+ ctFloat, ctFloat32, ctFloat64, ctFloat128,
+ ctUInt, ctUInt8, ctUInt16, ctUInt32, ctUInt64,
+ ctArray, ctStruct, ctPtr, ctNimStr, ctNimSeq, ctProc, ctCString
TCFileSections* = array[TCFileSection, PRope] # represents a generated C file
TCProcSection* = enum # the sections a generated C proc consists of
cpsLocals, # section of local variables for C proc
@@ -62,8 +64,9 @@ type
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)
- popCurrExc*: Natural # how often to emit 'popCurrentException()'
- # before 'break'|'return'
+ inExceptBlock*: int # are we currently inside an except block?
+ # leaving such scopes by raise or by return must
+ # execute any applicable finally blocks
labels*: Natural # for generating unique labels in the C proc
blocks*: seq[TBlock] # nested blocks
breakIdx*: int # the block that will be exited
diff --git a/compiler/docgen.nim b/compiler/docgen.nim
index 6e249b888b..ae654fda45 100755
--- a/compiler/docgen.nim
+++ b/compiler/docgen.nim
@@ -206,10 +206,10 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
of tkCharLit:
dispA(result, "$1", "\\spanCharLit{$1}",
[toRope(esc(d.target, literal))])
- of tkIntLit..tkInt64Lit:
+ of tkIntLit..tkUInt64Lit:
dispA(result, "$1",
"\\spanDecNumber{$1}", [toRope(esc(d.target, literal))])
- of tkFloatLit..tkFloat64Lit:
+ of tkFloatLit..tkFloat128Lit:
dispA(result, "$1",
"\\spanFloatNumber{$1}", [toRope(esc(d.target, literal))])
of tkSymbol:
diff --git a/compiler/evals.nim b/compiler/evals.nim
index eb193cb9e6..45adcbc197 100755
--- a/compiler/evals.nim
+++ b/compiler/evals.nim
@@ -235,6 +235,8 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
case t.kind
of tyBool, tyEnum, tyChar, tyInt..tyInt64:
result = newNodeIT(nkIntLit, info, t)
+ of tyUInt..tyUInt64:
+ result = newNodeIT(nkUIntLit, info, t)
of tyFloat..tyFloat128:
result = newNodeIt(nkFloatLit, info, t)
of tyVar, tyPointer, tyPtr, tyRef, tyCString, tySequence, tyString, tyExpr,
diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim
index fb2e5f3f52..2872f28a77 100755
--- a/compiler/extccomp.nim
+++ b/compiler/extccomp.nim
@@ -597,7 +597,7 @@ proc CallCCompiler*(projectfile: string) =
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) =
diff --git a/compiler/lexer.nim b/compiler/lexer.nim
index a17871e3a7..afa52d6212 100755
--- a/compiler/lexer.nim
+++ b/compiler/lexer.nim
@@ -45,8 +45,10 @@ type
tkTemplate,
tkTry, tkTuple, tkType, tkVar, tkWhen, tkWhile, tkWith, tkWithout, tkXor,
tkYield, # end of keywords
- tkIntLit, tkInt8Lit, tkInt16Lit, tkInt32Lit, tkInt64Lit, tkFloatLit,
- tkFloat32Lit, tkFloat64Lit, tkStrLit, tkRStrLit, tkTripleStrLit,
+ tkIntLit, tkInt8Lit, tkInt16Lit, tkInt32Lit, tkInt64Lit,
+ tkUIntLit, tkUInt8Lit, tkUInt16Lit, tkUInt32Lit, tkUInt64Lit,
+ tkFloatLit, tkFloat32Lit, tkFloat64Lit, tkFloat128Lit,
+ tkStrLit, tkRStrLit, tkTripleStrLit,
tkGStrLit, tkGTripleStrLit, tkCharLit, tkParLe, tkParRi, tkBracketLe,
tkBracketRi, tkCurlyLe, tkCurlyRi,
tkBracketDotLe, tkBracketDotRi, # [. and .]
@@ -77,8 +79,10 @@ const
"template",
"try", "tuple", "type", "var", "when", "while", "with", "without", "xor",
"yield",
- "tkIntLit", "tkInt8Lit", "tkInt16Lit", "tkInt32Lit", "tkInt64Lit",
- "tkFloatLit", "tkFloat32Lit", "tkFloat64Lit", "tkStrLit", "tkRStrLit",
+ "tkIntLit", "tkInt8Lit", "tkInt16Lit", "tkInt32Lit", "tkInt64Lit",
+ "tkUIntLit", "tkUInt8Lit", "tkUInt16Lit", "tkUInt32Lit", "tkUInt64Lit",
+ "tkFloatLit", "tkFloat32Lit", "tkFloat64Lit", "tkFloat128Lit",
+ "tkStrLit", "tkRStrLit",
"tkTripleStrLit", "tkGStrLit", "tkGTripleStrLit", "tkCharLit", "(",
")", "[", "]", "{", "}", "[.", ".]", "{.", ".}", "(.", ".)",
",", ";",
@@ -283,12 +287,17 @@ proc GetNumber(L: var TLexer): TToken =
case L.buf[endpos]
of 'f', 'F':
inc(endpos)
- if (L.buf[endpos] == '6') and (L.buf[endpos + 1] == '4'):
- result.tokType = tkFloat64Lit
- inc(endpos, 2)
- elif (L.buf[endpos] == '3') and (L.buf[endpos + 1] == '2'):
+ if (L.buf[endpos] == '3') and (L.buf[endpos + 1] == '2'):
result.tokType = tkFloat32Lit
inc(endpos, 2)
+ elif (L.buf[endpos] == '6') and (L.buf[endpos + 1] == '4'):
+ result.tokType = tkFloat64Lit
+ inc(endpos, 2)
+ elif (L.buf[endpos] == '1') and
+ (L.buf[endpos + 1] == '2') and
+ (L.buf[endpos + 2] == '8'):
+ result.tokType = tkFloat128Lit
+ inc(endpos, 3)
else:
lexMessage(L, errInvalidNumber, result.literal & "'f" & L.buf[endpos])
of 'i', 'I':
@@ -307,6 +316,22 @@ proc GetNumber(L: var TLexer): TToken =
inc(endpos)
else:
lexMessage(L, errInvalidNumber, result.literal & "'i" & L.buf[endpos])
+ of 'u', 'U':
+ inc(endpos)
+ if (L.buf[endpos] == '6') and (L.buf[endpos + 1] == '4'):
+ result.tokType = tkUInt64Lit
+ inc(endpos, 2)
+ elif (L.buf[endpos] == '3') and (L.buf[endpos + 1] == '2'):
+ result.tokType = tkUInt32Lit
+ inc(endpos, 2)
+ elif (L.buf[endpos] == '1') and (L.buf[endpos + 1] == '6'):
+ result.tokType = tkUInt16Lit
+ inc(endpos, 2)
+ elif (L.buf[endpos] == '8'):
+ result.tokType = tkUInt8Lit
+ inc(endpos)
+ else:
+ result.tokType = tkUIntLit
else: lexMessage(L, errInvalidNumber, result.literal & "'" & L.buf[endpos])
else:
L.bufpos = pos # restore position
@@ -378,6 +403,10 @@ proc GetNumber(L: var TLexer): TToken =
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 tkFloat32Lit:
result.fNumber = (cast[PFloat32](addr(xi)))[]
# note: this code is endian neutral!
diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim
index 5b9987efaf..a69b40fbfb 100755
--- a/compiler/magicsys.nim
+++ b/compiler/magicsys.nim
@@ -53,9 +53,15 @@ proc getSysType(kind: TTypeKind): PType =
of tyInt16: result = sysTypeFromName("int16")
of tyInt32: result = sysTypeFromName("int32")
of tyInt64: result = sysTypeFromName("int64")
+ of tyUInt: result = sysTypeFromName("uint")
+ of tyUInt8: result = sysTypeFromName("uint8")
+ of tyUInt16: result = sysTypeFromName("uint16")
+ of tyUInt32: result = sysTypeFromName("uint32")
+ of tyUInt64: result = sysTypeFromName("uint64")
of tyFloat: result = sysTypeFromName("float")
of tyFloat32: result = sysTypeFromName("float32")
of tyFloat64: result = sysTypeFromName("float64")
+ of tyFloat128: result = sysTypeFromName("float128")
of tyBool: result = sysTypeFromName("bool")
of tyChar: result = sysTypeFromName("char")
of tyString: result = sysTypeFromName("string")
diff --git a/compiler/parser.nim b/compiler/parser.nim
index 4baee5b434..d1042b04d4 100755
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -416,6 +416,26 @@ proc identOrLiteral(p: var TParser): PNode =
result = newIntNodeP(nkInt64Lit, p.tok.iNumber, p)
setBaseFlags(result, p.tok.base)
getTok(p)
+ of tkUIntLit:
+ result = newIntNodeP(nkUIntLit, p.tok.iNumber, p)
+ setBaseFlags(result, p.tok.base)
+ getTok(p)
+ of tkUInt8Lit:
+ result = newIntNodeP(nkUInt8Lit, p.tok.iNumber, p)
+ setBaseFlags(result, p.tok.base)
+ getTok(p)
+ of tkUInt16Lit:
+ result = newIntNodeP(nkUInt16Lit, p.tok.iNumber, p)
+ setBaseFlags(result, p.tok.base)
+ getTok(p)
+ of tkUInt32Lit:
+ result = newIntNodeP(nkUInt32Lit, p.tok.iNumber, p)
+ setBaseFlags(result, p.tok.base)
+ getTok(p)
+ of tkUInt64Lit:
+ result = newIntNodeP(nkUInt64Lit, p.tok.iNumber, p)
+ setBaseFlags(result, p.tok.base)
+ getTok(p)
of tkFloatLit:
result = newFloatNodeP(nkFloatLit, p.tok.fNumber, p)
setBaseFlags(result, p.tok.base)
@@ -428,6 +448,10 @@ proc identOrLiteral(p: var TParser): PNode =
result = newFloatNodeP(nkFloat64Lit, p.tok.fNumber, p)
setBaseFlags(result, p.tok.base)
getTok(p)
+ of tkFloat128Lit:
+ result = newFloatNodeP(nkFloat128Lit, p.tok.fNumber, p)
+ setBaseFlags(result, p.tok.base)
+ getTok(p)
of tkStrLit:
result = newStrNodeP(nkStrLit, p.tok.literal, p)
getTok(p)
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index fe8bff34b5..96ae9d701f 100755
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -23,7 +23,7 @@ const
wMagic, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader,
wCompilerProc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
- wNoStackFrame, wError, wDiscardable, wNoInit}
+ wNoStackFrame, wError, wDiscardable, wNoInit, wDestructor}
converterPragmas* = procPragmas
methodPragmas* = procPragmas
templatePragmas* = {wImmediate, wDeprecated, wError}
@@ -508,6 +508,11 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
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:
+ if sym.typ.sons.len == 2:
+ sym.flags.incl sfDestructor
+ else:
+ invalidPragma(it)
of wNosideeffect:
noVal(it)
incl(sym.flags, sfNoSideEffect)
diff --git a/compiler/renderer.nim b/compiler/renderer.nim
index a5e79762c3..21b0f2287d 100755
--- a/compiler/renderer.nim
+++ b/compiler/renderer.nim
@@ -705,9 +705,15 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
of nkInt16Lit: put(g, tkInt16Lit, atom(n))
of nkInt32Lit: put(g, tkInt32Lit, atom(n))
of nkInt64Lit: put(g, tkInt64Lit, atom(n))
+ of nkUIntLit: put(g, tkUIntLit, atom(n))
+ of nkUInt8Lit: put(g, tkUInt8Lit, atom(n))
+ of nkUInt16Lit: put(g, tkUInt16Lit, atom(n))
+ of nkUInt32Lit: put(g, tkUInt32Lit, atom(n))
+ of nkUInt64Lit: put(g, tkUInt64Lit, atom(n))
of nkFloatLit: put(g, tkFloatLit, atom(n))
of nkFloat32Lit: put(g, tkFloat32Lit, atom(n))
of nkFloat64Lit: put(g, tkFloat64Lit, atom(n))
+ of nkFloat128Lit: put(g, tkFloat128Lit, atom(n))
of nkStrLit: put(g, tkStrLit, atom(n))
of nkRStrLit: put(g, tkRStrLit, atom(n))
of nkCharLit: put(g, tkCharLit, atom(n))
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index 81e45f71c9..c28c8c7a17 100755
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -212,7 +212,11 @@ proc markUsed*(n: PNode, s: PSym) =
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)
-
+
+proc useSym*(sym: PSym): PNode =
+ result = newSymNode(sym)
+ markUsed(result, sym)
+
proc illFormedAst*(n: PNode) =
GlobalError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index ac9075d4f9..cd97e74b17 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -132,10 +132,10 @@ proc checkConversionBetweenObjects(info: TLineInfo, castDest, src: PType) =
proc checkConvertible(info: TLineInfo, castDest, src: PType) =
const
- IntegralTypes = {tyBool, tyEnum, tyChar, tyInt..tyFloat128}
+ IntegralTypes = {tyBool, tyEnum, tyChar, tyInt..tyUInt64}
if sameType(castDest, src) and castDest.sym == src.sym:
# don't annoy conversions that may be needed on another processor:
- if not (castDest.kind in {tyInt..tyFloat128, tyNil}):
+ if not (castDest.kind in {tyInt..tyUInt64, tyNil}):
Message(info, hintConvFromXtoItselfNotNeeded, typeToString(castDest))
return
var d = skipTypes(castDest, abstractVar)
@@ -143,7 +143,7 @@ proc checkConvertible(info: TLineInfo, castDest, src: PType) =
while (d != nil) and (d.Kind in {tyPtr, tyRef}) and (d.Kind == s.Kind):
d = base(d)
s = base(s)
- if d == nil:
+ if d == nil:
GlobalError(info, errGenerated, msgKindToString(errIllegalConvFromXtoY) % [
src.typeToString, castDest.typeToString])
elif d.Kind == tyObject and s.Kind == tyObject:
@@ -1283,6 +1283,20 @@ proc semMacroStmt(c: PContext, n: PNode, semCheck = true): PNode =
GlobalError(n.info, errInvalidExpressionX,
renderTree(a, {renderNoComments}))
+proc uniIntType(kind: TTypeKind): PType =
+ result = getSysType(kind).copyType(getCurrOwner(), true)
+ result.flags.incl(tfUniIntLit)
+
+template memoize(e: expr): expr =
+ var `*guard` {.global.} = false
+ var `*memo` {.global.} : type(e)
+
+ if not `*guard`:
+ `*memo` = e
+ `*guard` = true
+
+ `*memo`
+
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
result = n
if gCmd == cmdIdeTools: suggestExpr(c, n)
@@ -1303,9 +1317,15 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
if result.typ == nil:
let i = result.intVal
if i >= low(int32) and i <= high(int32):
- result.typ = getSysType(tyInt)
+ if i >= 0:
+ result.typ = uniIntType(tyInt).memoize
+ else:
+ result.typ = getSysType(tyInt)
else:
- result.typ = getSysType(tyInt64)
+ if i >= 0:
+ result.typ = uniIntType(tyInt64).memoize
+ else:
+ result.typ = getSysType(tyInt64)
of nkInt8Lit:
if result.typ == nil: result.typ = getSysType(tyInt8)
of nkInt16Lit:
@@ -1314,12 +1334,24 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
if result.typ == nil: result.typ = getSysType(tyInt32)
of nkInt64Lit:
if result.typ == nil: result.typ = getSysType(tyInt64)
+ of nkUIntLit:
+ if result.typ == nil: result.typ = getSysType(tyUInt)
+ of nkUInt8Lit:
+ if result.typ == nil: result.typ = getSysType(tyUInt8)
+ of nkUInt16Lit:
+ if result.typ == nil: result.typ = getSysType(tyUInt16)
+ of nkUInt32Lit:
+ if result.typ == nil: result.typ = getSysType(tyUInt32)
+ of nkUInt64Lit:
+ if result.typ == nil: result.typ = getSysType(tyUInt64)
of nkFloatLit:
if result.typ == nil: result.typ = getSysType(tyFloat)
of nkFloat32Lit:
if result.typ == nil: result.typ = getSysType(tyFloat32)
of nkFloat64Lit:
if result.typ == nil: result.typ = getSysType(tyFloat64)
+ of nkFloat128Lit:
+ if result.typ == nil: result.typ = getSysType(tyFloat128)
of nkStrLit..nkTripleStrLit:
if result.typ == nil: result.typ = getSysType(tyString)
of nkCharLit:
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index 565155791b..f67e58e2f3 100755
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -258,15 +258,15 @@ proc partialOrExpr(c: PSym, n: PNode): PNode =
proc leValueConv(a, b: PNode): bool =
result = false
case a.kind
- of nkCharLit..nkInt64Lit:
+ of nkCharLit..nkUInt64Lit:
case b.kind
- of nkCharLit..nkInt64Lit: result = a.intVal <= b.intVal
- of nkFloatLit..nkFloat64Lit: result = a.intVal <= round(b.floatVal)
+ of nkCharLit..nkUInt64Lit: result = a.intVal <= b.intVal
+ of nkFloatLit..nkFloat128Lit: result = a.intVal <= round(b.floatVal)
else: InternalError(a.info, "leValueConv")
- of nkFloatLit..nkFloat64Lit:
+ of nkFloatLit..nkFloat128Lit:
case b.kind
- of nkFloatLit..nkFloat64Lit: result = a.floatVal <= b.floatVal
- of nkCharLit..nkInt64Lit: result = a.floatVal <= toFloat(int(b.intVal))
+ 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")
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 82f43e7875..27d7d405ba 100755
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -681,7 +681,9 @@ proc semLambda(c: PContext, n: PNode): PNode =
closeScope(c.tab) # close scope for parameters
popOwner()
result.typ = s.typ
-
+
+proc instantiateDestructor*(c: PContext, typ: PType): bool
+
proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
validPragmas: TSpecialWords): PNode =
result = n
@@ -743,6 +745,19 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
popOwner()
pushOwner(s)
s.options = gOptions
+ if sfDestructor in s.flags:
+ let t = s.typ.sons[1].skipTypes({tyVar})
+ t.destructor = s
+ # automatically insert calls to base classes' destructors
+ if n.sons[bodyPos].kind != nkEmpty:
+ for i in countup(0, t.sonsLen - 1):
+ # when inheriting directly from object
+ # there will be a single nil son
+ if t.sons[i] == nil: continue
+ if instantiateDestructor(c, t.sons[i]):
+ n.sons[bodyPos].addSon(newNode(nkCall, t.sym.info, @[
+ useSym(t.sons[i].destructor),
+ n.sons[paramsPos][1][0]]))
if n.sons[bodyPos].kind != nkEmpty:
# for DLL generation it is annoying to check for sfImportc!
if sfBorrow in s.flags:
@@ -772,10 +787,6 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
incl(s.flags, sfForward)
elif sfBorrow in s.flags: semBorrow(c, n, s)
sideEffectsCheck(c, s)
- if result.sons[namePos].sym.name.id == ord(wDestroy):
- if s.typ.sons.len == 2:
- let typ = s.typ.sons[1].skipTypes({tyVar})
- typ.destructor = s
if s.typ.callConv == ccClosure and s.owner.kind == skModule:
localError(s.info, errXCannotBeClosure, s.name.s)
closeScope(c.tab) # close scope for parameters
@@ -864,6 +875,134 @@ proc semStaticStmt(c: PContext, n: PNode): PNode =
if result.isNil:
LocalError(n.info, errCannotInterpretNodeX, renderTree(n))
+# special marker values that indicates that we are
+# 1) AnalyzingDestructor: currenlty analyzing the type for destructor
+# generation (needed for recursive types)
+# 2) DestructorIsTrivial: completed the anlysis before and determined
+# that the type has a trivial destructor
+var AnalyzingDestructor, DestructorIsTrivial: PSym
+new(AnalyzingDestructor)
+new(DestructorIsTrivial)
+
+var
+ destructorName = getIdent"destroy_"
+ destructorParam = getIdent"this_"
+ destructorPragma = newIdentNode(getIdent"destructor", UnknownLineInfo())
+ rangeDestructorProc: PSym
+
+proc destroyField(c: PContext, field: PSym, holder: PNode): PNode =
+ if instantiateDestructor(c, field.typ):
+ result = newNode(nkCall, field.info, @[
+ useSym(field.typ.destructor),
+ newNode(nkDotExpr, field.info, @[holder, useSym(field)])])
+
+proc destroyCase(c: PContext, n: PNode, holder: PNode): PNode =
+ var nonTrivialFields = 0
+ result = newNode(nkCaseStmt, n.info, @[])
+ # case x.kind
+ result.addSon(newNode(nkDotExpr, n.info, @[holder, n.sons[0]]))
+ for i in countup(1, n.len - 1):
+ # of A, B:
+ var caseBranch = newNode(n[i].kind, n[i].info, n[i].sons[0 .. -2])
+ let recList = n[i].lastSon
+ var destroyRecList = newNode(nkStmtList, n[i].info, @[])
+ template addField(f: expr): stmt =
+ let stmt = destroyField(c, f, holder)
+ if stmt != nil:
+ destroyRecList.addSon(stmt)
+ inc nonTrivialFields
+
+ case recList.kind
+ of nkSym:
+ addField(recList.sym)
+ of nkRecList:
+ for j in countup(0, recList.len - 1):
+ addField(recList[j].sym)
+ else:
+ internalAssert false
+
+ caseBranch.addSon(destroyRecList)
+ result.addSon(caseBranch)
+ # maybe no fields were destroyed?
+ if nonTrivialFields == 0:
+ result = nil
+
+proc generateDestructor(c: PContext, t: PType): PNode =
+ ## generate a destructor for a user-defined object ot tuple type
+ ## returns nil if the destructor turns out to be trivial
+
+ template addLine(e: expr): stmt =
+ if result == nil: result = newNode(nkStmtList)
+ result.addSon(e)
+
+ # XXX: This may be true for some C-imported types such as
+ # Tposix_spawnattr
+ if t.n == nil or t.n.sons == nil: return
+ internalAssert t.n.kind == nkRecList
+ 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
+ of nkRecCase:
+ let stmt = destroyCase(c, t.n.sons[s], destructedObj)
+ if stmt != nil: addLine(stmt)
+ of nkSym:
+ let stmt = destroyField(c, t.n.sons[s].sym, destructedObj)
+ if stmt != nil: addLine(stmt)
+ else:
+ internalAssert false
+
+ # 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})
+
+ if t.destructor != nil:
+ # XXX: This is not entirely correct for recursive types, but we need
+ # it temporarily to hide the "destroy is alrady defined" problem
+ return t.destructor notin [AnalyzingDestructor, DestructorIsTrivial]
+
+ case t.kind
+ of tySequence, tyArray, tyArrayConstr, tyOpenArray:
+ if instantiateDestructor(c, t.sons[0]):
+ if rangeDestructorProc == nil:
+ rangeDestructorProc = SymtabGet(c.tab, getIdent"nimDestroyRange")
+ t.destructor = rangeDestructorProc
+ return true
+ else:
+ return false
+ of tyTuple, tyObject:
+ t.destructor = AnalyzingDestructor
+ let generated = generateDestructor(c, t)
+ if generated != nil:
+ internalAssert t.sym != nil
+ var i = t.sym.info
+ let fullDef = newNode(nkProcDef, i, @[
+ newIdentNode(destructorName, i),
+ emptyNode,
+ newNode(nkFormalParams, i, @[
+ emptyNode,
+ newNode(nkIdentDefs, i, @[
+ newIdentNode(destructorParam, i),
+ useSym(t.sym),
+ emptyNode]),
+ ]),
+ newNode(nkPragma, i, @[destructorPragma]),
+ generated
+ ])
+ discard semProc(c, fullDef)
+ internalAssert t.destructor != nil
+ return true
+ else:
+ t.destructor = DestructorIsTrivial
+ return false
+ else:
+ return false
+
proc insertDestructors(c: PContext, varSection: PNode):
tuple[outer: PNode, inner: PNode] =
# Accepts a var or let section.
@@ -889,7 +1028,7 @@ proc insertDestructors(c: PContext, varSection: PNode):
varTyp = varId.sym.typ
info = varId.info
- if varTyp != nil and instantiateDestructor(varTyp):
+ if varTyp != nil and instantiateDestructor(c, varTyp):
var tryStmt = newNodeI(nkTryStmt, info)
if j < totalVars - 1:
@@ -910,8 +1049,8 @@ proc insertDestructors(c: PContext, varSection: PNode):
tryStmt.addSon(
newNode(nkFinally, info, @[
semStmt(c, newNode(nkCall, info, @[
- semSym(c, varId, varTyp.destructor, {}),
- semSym(c, varId, varId.sym, {})]))]))
+ useSym(varTyp.destructor),
+ useSym(varId.sym)]))]))
result.outer = newNodeI(nkStmtList, info)
varSection.sons.setLen(j+1)
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index af023e3297..5e2e9e218d 100755
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -306,7 +306,9 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
covered: var biggestInt) =
for i in countup(0, sonsLen(branch) - 2):
var b = branch.sons[i]
- if isRange(b):
+ if b.kind == nkRange:
+ branch.sons[i] = b
+ elif isRange(b):
branch.sons[i] = semCaseBranchRange(c, t, b, covered)
else:
var r = semConstExpr(c, b)
@@ -825,9 +827,15 @@ proc processMagicType(c: PContext, m: PSym) =
of mInt16: setMagicType(m, tyInt16, 2)
of mInt32: setMagicType(m, tyInt32, 4)
of mInt64: setMagicType(m, tyInt64, 8)
+ of mUInt: setMagicType(m, tyUInt, intSize)
+ of mUInt8: setMagicType(m, tyUInt8, 1)
+ of mUInt16: setMagicType(m, tyUInt16, 2)
+ of mUInt32: setMagicType(m, tyUInt32, 4)
+ of mUInt64: setMagicType(m, tyUInt64, 8)
of mFloat: setMagicType(m, tyFloat, floatSize)
of mFloat32: setMagicType(m, tyFloat32, 4)
of mFloat64: setMagicType(m, tyFloat64, 8)
+ of mFloat128: setMagicType(m, tyFloat128, 16)
of mBool: setMagicType(m, tyBool, 1)
of mChar: setMagicType(m, tyChar, 1)
of mString:
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 9881e84a30..7e985e9815 100755
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -163,6 +163,9 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
var k = skipTypes(a, {tyRange}).kind
if k == f.kind: result = isSubtype
elif f.kind == tyInt and k in {tyInt..tyInt32}: result = isIntConv
+ elif f.kind == tyUInt and k in {tyUInt..tyUInt32}: result = isIntConv
+ elif f.kind in {tyUInt..tyUInt64} and k == tyInt and tfUniIntLit in a.flags:
+ result = isIntConv
elif k >= min and k <= max: result = isConvertible
else: result = isNone
@@ -306,6 +309,11 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
of tyInt16: result = handleRange(f, a, tyInt8, tyInt16)
of tyInt32: result = handleRange(f, a, tyInt, tyInt32)
of tyInt64: result = handleRange(f, a, tyInt, tyInt64)
+ of tyUInt: result = handleRange(f, a, tyUInt8, tyUInt32)
+ of tyUInt8: result = handleRange(f, a, tyUInt8, tyUInt8)
+ of tyUInt16: result = handleRange(f, a, tyUInt8, tyUInt16)
+ of tyUInt32: result = handleRange(f, a, tyUInt, tyUInt32)
+ of tyUInt64: result = handleRange(f, a, tyUInt, tyUInt64)
of tyFloat: result = handleFloatRange(f, a)
of tyFloat32: result = handleFloatRange(f, a)
of tyFloat64: result = handleFloatRange(f, a)
diff --git a/compiler/types.nim b/compiler/types.nim
index 2f201b9de6..fb0e9a123f 100755
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -141,7 +141,7 @@ proc skipTypes(t: PType, kinds: TTypeKinds): PType =
proc isOrdinalType(t: PType): bool =
assert(t != nil)
- result = (t.Kind in {tyChar, tyInt..tyInt64, tyBool, tyEnum}) or
+ result = (t.Kind in {tyChar, tyInt..tyInt64, tyUInt..tyUInt64, tyBool, tyEnum}) or
(t.Kind in {tyRange, tyOrdinal, tyConst, tyMutable, tyGenericInst}) and
isOrdinalType(t.sons[0])
@@ -386,10 +386,11 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
"GenericInvokation", "GenericBody", "GenericInst", "GenericParam",
"distinct $1", "enum", "ordinal[$1]", "array[$1, $2]", "object", "tuple",
"set[$1]", "range[$1]", "ptr ", "ref ", "var ", "seq[$1]", "proc",
- "pointer", "OpenArray[$1]", "string", "CString", "Forward", "int", "int8",
- "int16", "int32", "int64", "float", "float32", "float64", "float128",
-
- "uint", "uint8", "uint16", "uint32", "uint64", "bignum", "const ",
+ "pointer", "OpenArray[$1]", "string", "CString", "Forward",
+ "int", "int8", "int16", "int32", "int64",
+ "float", "float32", "float64", "float128",
+ "uint", "uint8", "uint16", "uint32", "uint64",
+ "bignum", "const ",
"!", "varargs[$1]", "iter[$1]", "proxy[$1]", "TypeClass" ]
var t = typ
result = ""
@@ -494,6 +495,7 @@ proc firstOrd(t: PType): biggestInt =
of tyInt16: result = - 32768
of tyInt32: result = - 2147483646 - 2
of tyInt64: result = 0x8000000000000000'i64
+ of tyUInt..tyUInt64: result = 0
of tyEnum:
# if basetype <> nil then return firstOrd of basetype
if (sonsLen(t) > 0) and (t.sons[0] != nil):
@@ -524,6 +526,13 @@ proc lastOrd(t: PType): biggestInt =
of tyInt16: result = 0x00007FFF
of tyInt32: result = 0x7FFFFFFF
of tyInt64: result = 0x7FFFFFFFFFFFFFFF'i64
+ of tyUInt:
+ if platform.intSize == 4: result = 0xFFFFFFFF
+ else: result = 0x7FFFFFFFFFFFFFFF'i64
+ of tyUInt8: result = 0x7F # XXX: Fix these
+ of tyUInt16: result = 0x7FFF
+ of tyUInt32: result = 0x7FFFFFFF
+ of tyUInt64: result = 0x7FFFFFFFFFFFFFFF'i64
of tyEnum:
assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
result = t.n.sons[sonsLen(t.n) - 1].sym.position
@@ -980,6 +989,9 @@ proc computeSizeAux(typ: PType, a: var biggestInt): biggestInt =
of tyInt64, tyUInt64, tyFloat64:
result = 8
a = result
+ of tyFloat128:
+ result = 16
+ a = result
of tyFloat:
result = floatSize
a = result
@@ -1062,10 +1074,3 @@ proc getSize(typ: PType): biggestInt =
result = computeSize(typ)
if result < 0: InternalError("getSize(" & $typ.kind & ')')
-proc instantiateDestructor*(typ: PType): bool =
- # return true if the type already had a user-defined
- # destructor or if the compiler generated a default
- # member-wise one
- if typ.destructor != nil: return true
- return false
-
diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim
index af482966bf..cec76c9988 100755
--- a/compiler/wordrecg.nim
+++ b/compiler/wordrecg.nim
@@ -39,7 +39,7 @@ type
wDestroy,
- wImmediate, wImportCpp, wImportObjC,
+ wImmediate, wDestructor, wImportCpp, wImportObjC,
wImportCompilerProc,
wImportc, wExportc, wIncompleteStruct,
wAlign, wNodecl, wPure, wSideeffect, wHeader,
@@ -117,7 +117,7 @@ const
"destroy",
- "immediate", "importcpp", "importobjc",
+ "immediate", "destructor", "importcpp", "importobjc",
"importcompilerproc", "importc", "exportc", "incompletestruct",
"align", "nodecl", "pure", "sideeffect",
"header", "nosideeffect", "noreturn", "merge", "lib", "dynlib",
diff --git a/config/nimrod.cfg b/config/nimrod.cfg
index c98f30f021..fdab40c6c2 100755
--- a/config/nimrod.cfg
+++ b/config/nimrod.cfg
@@ -62,6 +62,7 @@ hint[LineTooLong]=off
@if not bsd:
# -fopenmp
gcc.options.linker = "-ldl"
+ gpp.options.linker = "-ldl"
clang.options.linker = "-ldl"
tcc.options.linker = "-ldl"
@else:
@@ -83,24 +84,23 @@ icc.options.linker = "-cxxlib"
tlsEmulation:on
@end
@end
-gcc.options.debug = "-g3 -O0"
@if macosx:
tlsEmulation:on
- @if not release:
- gcc.options.always = "-w -fasm-blocks -O1"
- @else:
- gcc.options.always = "-w -fasm-blocks"
- @end
+ gcc.options.always = "-w -fasm-blocks"
+ gpp.options.always = "-w -fasm-blocks"
@else:
- @if not release:
- gcc.options.always = "-w"
- @else:
- gcc.options.always = "-w"
- @end
+ gcc.options.always = "-w"
+ gpp.options.always = "-w"
@end
+
gcc.options.speed = "-O3 -fno-strict-aliasing"
gcc.options.size = "-Os"
+gcc.options.debug = "-g3 -O0"
+
+gpp.options.speed = "-O3 -fno-strict-aliasing"
+gpp.options.size = "-Os"
+gpp.options.debug = "-g3 -O0"
#passl = "-pg"
# Configuration for the LLVM GCC compiler:
diff --git a/install.sh b/install.sh
index fde6c82a24..4feabbb77a 100755
--- a/install.sh
+++ b/install.sh
@@ -1,6 +1,8 @@
#! /bin/sh
# Generated by niminst
+set -e
+
if [ $# -eq 1 ] ; then
if test -f bin/nimrod
then
@@ -43,692 +45,573 @@ if [ $# -eq 1 ] ; then
docdir="$1/nimrod/doc"
datadir="$1/nimrod/data"
- mkdir -p $1/nimrod || exit 1
- mkdir -p $bindir || exit 1
- mkdir -p $configdir || exit 1
+ mkdir -p $1/nimrod
+ mkdir -p $bindir
+ mkdir -p $configdir
;;
esac
- mkdir -p $libdir || exit 1
- mkdir -p $docdir || exit 1
+ mkdir -p $libdir
+ mkdir -p $docdir
echo "copying files..."
- mkdir -p $libdir/system || exit 1
- mkdir -p $libdir/core || exit 1
- mkdir -p $libdir/pure || exit 1
- mkdir -p $libdir/pure/collections || exit 1
- mkdir -p $libdir/impure || exit 1
- mkdir -p $libdir/wrappers || exit 1
- mkdir -p $libdir/wrappers/cairo || exit 1
- mkdir -p $libdir/wrappers/gtk || exit 1
- mkdir -p $libdir/wrappers/lua || exit 1
- mkdir -p $libdir/wrappers/opengl || exit 1
- mkdir -p $libdir/wrappers/sdl || exit 1
- mkdir -p $libdir/wrappers/x11 || exit 1
- mkdir -p $libdir/wrappers/zip || exit 1
- mkdir -p $libdir/windows || exit 1
- mkdir -p $libdir/posix || exit 1
- mkdir -p $libdir/ecmas || exit 1
+ mkdir -p $libdir/system
+ mkdir -p $libdir/core
+ mkdir -p $libdir/pure
+ mkdir -p $libdir/pure/collections
+ mkdir -p $libdir/impure
+ mkdir -p $libdir/wrappers
+ mkdir -p $libdir/wrappers/cairo
+ mkdir -p $libdir/wrappers/gtk
+ mkdir -p $libdir/wrappers/lua
+ mkdir -p $libdir/wrappers/opengl
+ mkdir -p $libdir/wrappers/readline
+ mkdir -p $libdir/wrappers/sdl
+ mkdir -p $libdir/wrappers/x11
+ mkdir -p $libdir/wrappers/zip
+ mkdir -p $libdir/windows
+ mkdir -p $libdir/posix
+ mkdir -p $libdir/ecmas
- cp bin/nimrod $bindir/nimrod || exit 1
+ cp bin/nimrod $bindir/nimrod
chmod 755 $bindir/nimrod
- cp config/nimrod.cfg $configdir/nimrod.cfg || exit 1
+ cp config/nimrod.cfg $configdir/nimrod.cfg
chmod 644 $configdir/nimrod.cfg
- cp config/nimdoc.cfg $configdir/nimdoc.cfg || exit 1
+ cp config/nimdoc.cfg $configdir/nimdoc.cfg
chmod 644 $configdir/nimdoc.cfg
- cp config/nimdoc.tex.cfg $configdir/nimdoc.tex.cfg || exit 1
+ cp config/nimdoc.tex.cfg $configdir/nimdoc.tex.cfg
chmod 644 $configdir/nimdoc.tex.cfg
- cp doc/abstypes.txt $docdir/abstypes.txt || exit 1
- chmod 644 $docdir/abstypes.txt
- cp doc/advopt.txt $docdir/advopt.txt || exit 1
- chmod 644 $docdir/advopt.txt
- cp doc/apis.txt $docdir/apis.txt || exit 1
- chmod 644 $docdir/apis.txt
- cp doc/astspec.txt $docdir/astspec.txt || exit 1
- chmod 644 $docdir/astspec.txt
- cp doc/basicopt.txt $docdir/basicopt.txt || exit 1
- chmod 644 $docdir/basicopt.txt
- cp doc/c2nim.txt $docdir/c2nim.txt || exit 1
- chmod 644 $docdir/c2nim.txt
- cp doc/docs.txt $docdir/docs.txt || exit 1
- chmod 644 $docdir/docs.txt
- cp doc/effects.txt $docdir/effects.txt || exit 1
- chmod 644 $docdir/effects.txt
- cp doc/endb.txt $docdir/endb.txt || exit 1
- chmod 644 $docdir/endb.txt
- cp doc/filelist.txt $docdir/filelist.txt || exit 1
- chmod 644 $docdir/filelist.txt
- cp doc/filters.txt $docdir/filters.txt || exit 1
- chmod 644 $docdir/filters.txt
- cp doc/grammar.txt $docdir/grammar.txt || exit 1
- chmod 644 $docdir/grammar.txt
- cp doc/intern.txt $docdir/intern.txt || exit 1
- chmod 644 $docdir/intern.txt
- cp doc/keywords.txt $docdir/keywords.txt || exit 1
- chmod 644 $docdir/keywords.txt
- cp doc/lib.txt $docdir/lib.txt || exit 1
- chmod 644 $docdir/lib.txt
- cp doc/manual.txt $docdir/manual.txt || exit 1
- chmod 644 $docdir/manual.txt
- cp doc/niminst.txt $docdir/niminst.txt || exit 1
- chmod 644 $docdir/niminst.txt
- cp doc/nimrodc.txt $docdir/nimrodc.txt || exit 1
- chmod 644 $docdir/nimrodc.txt
- cp doc/overview.txt $docdir/overview.txt || exit 1
- chmod 644 $docdir/overview.txt
- cp doc/pegdocs.txt $docdir/pegdocs.txt || exit 1
- chmod 644 $docdir/pegdocs.txt
- cp doc/readme.txt $docdir/readme.txt || exit 1
- chmod 644 $docdir/readme.txt
- cp doc/regexprs.txt $docdir/regexprs.txt || exit 1
- chmod 644 $docdir/regexprs.txt
- cp doc/rst.txt $docdir/rst.txt || exit 1
- chmod 644 $docdir/rst.txt
- cp doc/subexes.txt $docdir/subexes.txt || exit 1
- chmod 644 $docdir/subexes.txt
- cp doc/targets.txt $docdir/targets.txt || exit 1
- chmod 644 $docdir/targets.txt
- cp doc/theindex.txt $docdir/theindex.txt || exit 1
- chmod 644 $docdir/theindex.txt
- cp doc/tools.txt $docdir/tools.txt || exit 1
- chmod 644 $docdir/tools.txt
- cp doc/tut1.txt $docdir/tut1.txt || exit 1
- chmod 644 $docdir/tut1.txt
- cp doc/tut2.txt $docdir/tut2.txt || exit 1
- chmod 644 $docdir/tut2.txt
- cp doc/actors.html $docdir/actors.html || exit 1
- chmod 644 $docdir/actors.html
- cp doc/algorithm.html $docdir/algorithm.html || exit 1
- chmod 644 $docdir/algorithm.html
- cp doc/apis.html $docdir/apis.html || exit 1
- chmod 644 $docdir/apis.html
- cp doc/asyncio.html $docdir/asyncio.html || exit 1
- chmod 644 $docdir/asyncio.html
- cp doc/base64.html $docdir/base64.html || exit 1
- chmod 644 $docdir/base64.html
- cp doc/browsers.html $docdir/browsers.html || exit 1
- chmod 644 $docdir/browsers.html
- cp doc/c2nim.html $docdir/c2nim.html || exit 1
- chmod 644 $docdir/c2nim.html
- cp doc/cgi.html $docdir/cgi.html || exit 1
- chmod 644 $docdir/cgi.html
- cp doc/channels.html $docdir/channels.html || exit 1
- chmod 644 $docdir/channels.html
- cp doc/colors.html $docdir/colors.html || exit 1
- chmod 644 $docdir/colors.html
- cp doc/complex.html $docdir/complex.html || exit 1
- chmod 644 $docdir/complex.html
- cp doc/critbits.html $docdir/critbits.html || exit 1
- chmod 644 $docdir/critbits.html
- cp doc/db_mysql.html $docdir/db_mysql.html || exit 1
- chmod 644 $docdir/db_mysql.html
- cp doc/db_postgres.html $docdir/db_postgres.html || exit 1
- chmod 644 $docdir/db_postgres.html
- cp doc/db_sqlite.html $docdir/db_sqlite.html || exit 1
- chmod 644 $docdir/db_sqlite.html
- cp doc/dom.html $docdir/dom.html || exit 1
- chmod 644 $docdir/dom.html
- cp doc/dynlib.html $docdir/dynlib.html || exit 1
- chmod 644 $docdir/dynlib.html
- cp doc/encodings.html $docdir/encodings.html || exit 1
- chmod 644 $docdir/encodings.html
- cp doc/endb.html $docdir/endb.html || exit 1
- chmod 644 $docdir/endb.html
- cp doc/events.html $docdir/events.html || exit 1
- chmod 644 $docdir/events.html
- cp doc/filters.html $docdir/filters.html || exit 1
- chmod 644 $docdir/filters.html
- cp doc/ftpclient.html $docdir/ftpclient.html || exit 1
- chmod 644 $docdir/ftpclient.html
- cp doc/graphics.html $docdir/graphics.html || exit 1
- chmod 644 $docdir/graphics.html
- cp doc/hashes.html $docdir/hashes.html || exit 1
- chmod 644 $docdir/hashes.html
- cp doc/htmlgen.html $docdir/htmlgen.html || exit 1
- chmod 644 $docdir/htmlgen.html
- cp doc/htmlparser.html $docdir/htmlparser.html || exit 1
- chmod 644 $docdir/htmlparser.html
- cp doc/httpclient.html $docdir/httpclient.html || exit 1
- chmod 644 $docdir/httpclient.html
- cp doc/httpserver.html $docdir/httpserver.html || exit 1
- chmod 644 $docdir/httpserver.html
- cp doc/intern.html $docdir/intern.html || exit 1
- chmod 644 $docdir/intern.html
- cp doc/intsets.html $docdir/intsets.html || exit 1
- chmod 644 $docdir/intsets.html
- cp doc/irc.html $docdir/irc.html || exit 1
- chmod 644 $docdir/irc.html
- cp doc/json.html $docdir/json.html || exit 1
- chmod 644 $docdir/json.html
- cp doc/lexbase.html $docdir/lexbase.html || exit 1
- chmod 644 $docdir/lexbase.html
- cp doc/lib.html $docdir/lib.html || exit 1
- chmod 644 $docdir/lib.html
- cp doc/lists.html $docdir/lists.html || exit 1
- chmod 644 $docdir/lists.html
- cp doc/locks.html $docdir/locks.html || exit 1
- chmod 644 $docdir/locks.html
- cp doc/macros.html $docdir/macros.html || exit 1
- chmod 644 $docdir/macros.html
- cp doc/manual.html $docdir/manual.html || exit 1
- chmod 644 $docdir/manual.html
- cp doc/marshal.html $docdir/marshal.html || exit 1
- chmod 644 $docdir/marshal.html
- cp doc/matchers.html $docdir/matchers.html || exit 1
- chmod 644 $docdir/matchers.html
- cp doc/math.html $docdir/math.html || exit 1
- chmod 644 $docdir/math.html
- cp doc/memfiles.html $docdir/memfiles.html || exit 1
- chmod 644 $docdir/memfiles.html
- cp doc/niminst.html $docdir/niminst.html || exit 1
- chmod 644 $docdir/niminst.html
- cp doc/nimrodc.html $docdir/nimrodc.html || exit 1
- chmod 644 $docdir/nimrodc.html
- cp doc/os.html $docdir/os.html || exit 1
- chmod 644 $docdir/os.html
- cp doc/osproc.html $docdir/osproc.html || exit 1
- chmod 644 $docdir/osproc.html
- cp doc/overview.html $docdir/overview.html || exit 1
- chmod 644 $docdir/overview.html
- cp doc/parsecfg.html $docdir/parsecfg.html || exit 1
- chmod 644 $docdir/parsecfg.html
- cp doc/parsecsv.html $docdir/parsecsv.html || exit 1
- chmod 644 $docdir/parsecsv.html
- cp doc/parseopt.html $docdir/parseopt.html || exit 1
- chmod 644 $docdir/parseopt.html
- cp doc/parsesql.html $docdir/parsesql.html || exit 1
- chmod 644 $docdir/parsesql.html
- cp doc/parseutils.html $docdir/parseutils.html || exit 1
- chmod 644 $docdir/parseutils.html
- cp doc/parsexml.html $docdir/parsexml.html || exit 1
- chmod 644 $docdir/parsexml.html
- cp doc/pegs.html $docdir/pegs.html || exit 1
- chmod 644 $docdir/pegs.html
- cp doc/queues.html $docdir/queues.html || exit 1
- chmod 644 $docdir/queues.html
- cp doc/rdstdin.html $docdir/rdstdin.html || exit 1
- chmod 644 $docdir/rdstdin.html
- cp doc/re.html $docdir/re.html || exit 1
- chmod 644 $docdir/re.html
- cp doc/redis.html $docdir/redis.html || exit 1
- chmod 644 $docdir/redis.html
- cp doc/ropes.html $docdir/ropes.html || exit 1
- chmod 644 $docdir/ropes.html
- cp doc/scgi.html $docdir/scgi.html || exit 1
- chmod 644 $docdir/scgi.html
- cp doc/sequtils.html $docdir/sequtils.html || exit 1
- chmod 644 $docdir/sequtils.html
- cp doc/sets.html $docdir/sets.html || exit 1
- chmod 644 $docdir/sets.html
- cp doc/smtp.html $docdir/smtp.html || exit 1
- chmod 644 $docdir/smtp.html
- cp doc/sockets.html $docdir/sockets.html || exit 1
- chmod 644 $docdir/sockets.html
- cp doc/sphinx.html $docdir/sphinx.html || exit 1
- chmod 644 $docdir/sphinx.html
- cp doc/ssl.html $docdir/ssl.html || exit 1
- chmod 644 $docdir/ssl.html
- cp doc/streams.html $docdir/streams.html || exit 1
- chmod 644 $docdir/streams.html
- cp doc/strtabs.html $docdir/strtabs.html || exit 1
- chmod 644 $docdir/strtabs.html
- cp doc/strutils.html $docdir/strutils.html || exit 1
- chmod 644 $docdir/strutils.html
- cp doc/subexes.html $docdir/subexes.html || exit 1
- chmod 644 $docdir/subexes.html
- cp doc/system.html $docdir/system.html || exit 1
- chmod 644 $docdir/system.html
- cp doc/tables.html $docdir/tables.html || exit 1
- chmod 644 $docdir/tables.html
- cp doc/terminal.html $docdir/terminal.html || exit 1
- chmod 644 $docdir/terminal.html
- cp doc/theindex.html $docdir/theindex.html || exit 1
- chmod 644 $docdir/theindex.html
- cp doc/threads.html $docdir/threads.html || exit 1
- chmod 644 $docdir/threads.html
- cp doc/times.html $docdir/times.html || exit 1
- chmod 644 $docdir/times.html
- cp doc/tools.html $docdir/tools.html || exit 1
- chmod 644 $docdir/tools.html
- cp doc/tut1.html $docdir/tut1.html || exit 1
- chmod 644 $docdir/tut1.html
- cp doc/tut2.html $docdir/tut2.html || exit 1
- chmod 644 $docdir/tut2.html
- cp doc/typeinfo.html $docdir/typeinfo.html || exit 1
- chmod 644 $docdir/typeinfo.html
- cp doc/unicode.html $docdir/unicode.html || exit 1
- chmod 644 $docdir/unicode.html
- cp doc/unidecode.html $docdir/unidecode.html || exit 1
- chmod 644 $docdir/unidecode.html
- cp doc/web.html $docdir/web.html || exit 1
- chmod 644 $docdir/web.html
- cp doc/xmldom.html $docdir/xmldom.html || exit 1
- chmod 644 $docdir/xmldom.html
- cp doc/xmldomparser.html $docdir/xmldomparser.html || exit 1
- chmod 644 $docdir/xmldomparser.html
- cp doc/xmlparser.html $docdir/xmlparser.html || exit 1
- chmod 644 $docdir/xmlparser.html
- cp doc/xmltree.html $docdir/xmltree.html || exit 1
- chmod 644 $docdir/xmltree.html
- cp doc/zipfiles.html $docdir/zipfiles.html || exit 1
- chmod 644 $docdir/zipfiles.html
- cp doc/zmq.html $docdir/zmq.html || exit 1
- chmod 644 $docdir/zmq.html
- cp doc/mytest.cfg $docdir/mytest.cfg || exit 1
- chmod 644 $docdir/mytest.cfg
- cp doc/c2nim.pdf $docdir/c2nim.pdf || exit 1
- chmod 644 $docdir/c2nim.pdf
- cp doc/lib.pdf $docdir/lib.pdf || exit 1
- chmod 644 $docdir/lib.pdf
- cp doc/manual.pdf $docdir/manual.pdf || exit 1
- chmod 644 $docdir/manual.pdf
- cp doc/niminst.pdf $docdir/niminst.pdf || exit 1
- chmod 644 $docdir/niminst.pdf
- cp doc/nimrodc.pdf $docdir/nimrodc.pdf || exit 1
- chmod 644 $docdir/nimrodc.pdf
- cp doc/tut1.pdf $docdir/tut1.pdf || exit 1
- chmod 644 $docdir/tut1.pdf
- cp doc/tut2.pdf $docdir/tut2.pdf || exit 1
- chmod 644 $docdir/tut2.pdf
- cp doc/nimrod.ini $docdir/nimrod.ini || exit 1
- chmod 644 $docdir/nimrod.ini
- cp lib/nimbase.h $libdir/nimbase.h || exit 1
+ if [ -f doc/abstypes.txt ]; then
+ cp doc/abstypes.txt $docdir/abstypes.txt
+ chmod 644 $docdir/abstypes.txt
+ fi
+ if [ -f doc/advopt.txt ]; then
+ cp doc/advopt.txt $docdir/advopt.txt
+ chmod 644 $docdir/advopt.txt
+ fi
+ if [ -f doc/apis.txt ]; then
+ cp doc/apis.txt $docdir/apis.txt
+ chmod 644 $docdir/apis.txt
+ fi
+ if [ -f doc/astspec.txt ]; then
+ cp doc/astspec.txt $docdir/astspec.txt
+ chmod 644 $docdir/astspec.txt
+ fi
+ if [ -f doc/basicopt.txt ]; then
+ cp doc/basicopt.txt $docdir/basicopt.txt
+ chmod 644 $docdir/basicopt.txt
+ fi
+ if [ -f doc/c2nim.txt ]; then
+ cp doc/c2nim.txt $docdir/c2nim.txt
+ chmod 644 $docdir/c2nim.txt
+ fi
+ if [ -f doc/docs.txt ]; then
+ cp doc/docs.txt $docdir/docs.txt
+ chmod 644 $docdir/docs.txt
+ fi
+ if [ -f doc/effects.txt ]; then
+ cp doc/effects.txt $docdir/effects.txt
+ chmod 644 $docdir/effects.txt
+ fi
+ if [ -f doc/endb.txt ]; then
+ cp doc/endb.txt $docdir/endb.txt
+ chmod 644 $docdir/endb.txt
+ fi
+ if [ -f doc/filelist.txt ]; then
+ cp doc/filelist.txt $docdir/filelist.txt
+ chmod 644 $docdir/filelist.txt
+ fi
+ if [ -f doc/filters.txt ]; then
+ cp doc/filters.txt $docdir/filters.txt
+ chmod 644 $docdir/filters.txt
+ fi
+ if [ -f doc/gc.txt ]; then
+ cp doc/gc.txt $docdir/gc.txt
+ chmod 644 $docdir/gc.txt
+ fi
+ if [ -f doc/grammar.txt ]; then
+ cp doc/grammar.txt $docdir/grammar.txt
+ chmod 644 $docdir/grammar.txt
+ fi
+ if [ -f doc/intern.txt ]; then
+ cp doc/intern.txt $docdir/intern.txt
+ chmod 644 $docdir/intern.txt
+ fi
+ if [ -f doc/keywords.txt ]; then
+ cp doc/keywords.txt $docdir/keywords.txt
+ chmod 644 $docdir/keywords.txt
+ fi
+ if [ -f doc/lib.txt ]; then
+ cp doc/lib.txt $docdir/lib.txt
+ chmod 644 $docdir/lib.txt
+ fi
+ if [ -f doc/manual.txt ]; then
+ cp doc/manual.txt $docdir/manual.txt
+ chmod 644 $docdir/manual.txt
+ fi
+ if [ -f doc/nimgrep.txt ]; then
+ cp doc/nimgrep.txt $docdir/nimgrep.txt
+ chmod 644 $docdir/nimgrep.txt
+ fi
+ if [ -f doc/niminst.txt ]; then
+ cp doc/niminst.txt $docdir/niminst.txt
+ chmod 644 $docdir/niminst.txt
+ fi
+ if [ -f doc/nimrodc.txt ]; then
+ cp doc/nimrodc.txt $docdir/nimrodc.txt
+ chmod 644 $docdir/nimrodc.txt
+ fi
+ if [ -f doc/overview.txt ]; then
+ cp doc/overview.txt $docdir/overview.txt
+ chmod 644 $docdir/overview.txt
+ fi
+ if [ -f doc/pegdocs.txt ]; then
+ cp doc/pegdocs.txt $docdir/pegdocs.txt
+ chmod 644 $docdir/pegdocs.txt
+ fi
+ if [ -f doc/readme.txt ]; then
+ cp doc/readme.txt $docdir/readme.txt
+ chmod 644 $docdir/readme.txt
+ fi
+ if [ -f doc/regexprs.txt ]; then
+ cp doc/regexprs.txt $docdir/regexprs.txt
+ chmod 644 $docdir/regexprs.txt
+ fi
+ if [ -f doc/rst.txt ]; then
+ cp doc/rst.txt $docdir/rst.txt
+ chmod 644 $docdir/rst.txt
+ fi
+ if [ -f doc/subexes.txt ]; then
+ cp doc/subexes.txt $docdir/subexes.txt
+ chmod 644 $docdir/subexes.txt
+ fi
+ if [ -f doc/tools.txt ]; then
+ cp doc/tools.txt $docdir/tools.txt
+ chmod 644 $docdir/tools.txt
+ fi
+ if [ -f doc/tut1.txt ]; then
+ cp doc/tut1.txt $docdir/tut1.txt
+ chmod 644 $docdir/tut1.txt
+ fi
+ if [ -f doc/tut2.txt ]; then
+ cp doc/tut2.txt $docdir/tut2.txt
+ chmod 644 $docdir/tut2.txt
+ fi
+ if [ -f doc/mytest.cfg ]; then
+ cp doc/mytest.cfg $docdir/mytest.cfg
+ chmod 644 $docdir/mytest.cfg
+ fi
+ cp lib/nimbase.h $libdir/nimbase.h
chmod 644 $libdir/nimbase.h
- cp lib/cycle.h $libdir/cycle.h || exit 1
+ cp lib/cycle.h $libdir/cycle.h
chmod 644 $libdir/cycle.h
- cp lib/nimrtl.nim $libdir/nimrtl.nim || exit 1
+ cp lib/nimrtl.nim $libdir/nimrtl.nim
chmod 644 $libdir/nimrtl.nim
- cp lib/prelude.nim $libdir/prelude.nim || exit 1
+ cp lib/prelude.nim $libdir/prelude.nim
chmod 644 $libdir/prelude.nim
- cp lib/system.nim $libdir/system.nim || exit 1
+ cp lib/system.nim $libdir/system.nim
chmod 644 $libdir/system.nim
- cp lib/nimrtl.nimrod.cfg $libdir/nimrtl.nimrod.cfg || exit 1
+ cp lib/nimrtl.nimrod.cfg $libdir/nimrtl.nimrod.cfg
chmod 644 $libdir/nimrtl.nimrod.cfg
- cp lib/system/alloc.nim $libdir/system/alloc.nim || exit 1
+ cp lib/system/alloc.nim $libdir/system/alloc.nim
chmod 644 $libdir/system/alloc.nim
- cp lib/system/ansi_c.nim $libdir/system/ansi_c.nim || exit 1
+ cp lib/system/ansi_c.nim $libdir/system/ansi_c.nim
chmod 644 $libdir/system/ansi_c.nim
- cp lib/system/arithm.nim $libdir/system/arithm.nim || exit 1
+ cp lib/system/arithm.nim $libdir/system/arithm.nim
chmod 644 $libdir/system/arithm.nim
- cp lib/system/assign.nim $libdir/system/assign.nim || exit 1
+ cp lib/system/assign.nim $libdir/system/assign.nim
chmod 644 $libdir/system/assign.nim
- cp lib/system/atomics.nim $libdir/system/atomics.nim || exit 1
+ cp lib/system/atomics.nim $libdir/system/atomics.nim
chmod 644 $libdir/system/atomics.nim
- cp lib/system/avltree.nim $libdir/system/avltree.nim || exit 1
+ cp lib/system/avltree.nim $libdir/system/avltree.nim
chmod 644 $libdir/system/avltree.nim
- cp lib/system/cellsets.nim $libdir/system/cellsets.nim || exit 1
+ cp lib/system/cellsets.nim $libdir/system/cellsets.nim
chmod 644 $libdir/system/cellsets.nim
- cp lib/system/cgprocs.nim $libdir/system/cgprocs.nim || exit 1
+ cp lib/system/cgprocs.nim $libdir/system/cgprocs.nim
chmod 644 $libdir/system/cgprocs.nim
- cp lib/system/channels.nim $libdir/system/channels.nim || exit 1
+ cp lib/system/channels.nim $libdir/system/channels.nim
chmod 644 $libdir/system/channels.nim
- cp lib/system/debugger.nim $libdir/system/debugger.nim || exit 1
+ cp lib/system/debugger.nim $libdir/system/debugger.nim
chmod 644 $libdir/system/debugger.nim
- cp lib/system/dyncalls.nim $libdir/system/dyncalls.nim || exit 1
+ cp lib/system/dyncalls.nim $libdir/system/dyncalls.nim
chmod 644 $libdir/system/dyncalls.nim
- cp lib/system/ecmasys.nim $libdir/system/ecmasys.nim || exit 1
+ cp lib/system/ecmasys.nim $libdir/system/ecmasys.nim
chmod 644 $libdir/system/ecmasys.nim
- cp lib/system/embedded.nim $libdir/system/embedded.nim || exit 1
+ cp lib/system/embedded.nim $libdir/system/embedded.nim
chmod 644 $libdir/system/embedded.nim
- cp lib/system/excpt.nim $libdir/system/excpt.nim || exit 1
+ cp lib/system/excpt.nim $libdir/system/excpt.nim
chmod 644 $libdir/system/excpt.nim
- cp lib/system/gc.nim $libdir/system/gc.nim || exit 1
+ cp lib/system/gc.nim $libdir/system/gc.nim
chmod 644 $libdir/system/gc.nim
- cp lib/system/hti.nim $libdir/system/hti.nim || exit 1
+ cp lib/system/hti.nim $libdir/system/hti.nim
chmod 644 $libdir/system/hti.nim
- cp lib/system/inclrtl.nim $libdir/system/inclrtl.nim || exit 1
+ cp lib/system/inclrtl.nim $libdir/system/inclrtl.nim
chmod 644 $libdir/system/inclrtl.nim
- cp lib/system/mmdisp.nim $libdir/system/mmdisp.nim || exit 1
+ cp lib/system/mmdisp.nim $libdir/system/mmdisp.nim
chmod 644 $libdir/system/mmdisp.nim
- cp lib/system/profiler.nim $libdir/system/profiler.nim || exit 1
+ cp lib/system/profiler.nim $libdir/system/profiler.nim
chmod 644 $libdir/system/profiler.nim
- cp lib/system/repr.nim $libdir/system/repr.nim || exit 1
+ cp lib/system/repr.nim $libdir/system/repr.nim
chmod 644 $libdir/system/repr.nim
- cp lib/system/reprjs.nim $libdir/system/reprjs.nim || exit 1
+ cp lib/system/reprjs.nim $libdir/system/reprjs.nim
chmod 644 $libdir/system/reprjs.nim
- cp lib/system/sets.nim $libdir/system/sets.nim || exit 1
+ cp lib/system/sets.nim $libdir/system/sets.nim
chmod 644 $libdir/system/sets.nim
- cp lib/system/sysio.nim $libdir/system/sysio.nim || exit 1
+ cp lib/system/sysio.nim $libdir/system/sysio.nim
chmod 644 $libdir/system/sysio.nim
- cp lib/system/syslocks.nim $libdir/system/syslocks.nim || exit 1
+ cp lib/system/syslocks.nim $libdir/system/syslocks.nim
chmod 644 $libdir/system/syslocks.nim
- cp lib/system/sysstr.nim $libdir/system/sysstr.nim || exit 1
+ cp lib/system/sysstr.nim $libdir/system/sysstr.nim
chmod 644 $libdir/system/sysstr.nim
- cp lib/system/threads.nim $libdir/system/threads.nim || exit 1
+ cp lib/system/threads.nim $libdir/system/threads.nim
chmod 644 $libdir/system/threads.nim
- cp lib/system/widestrs.nim $libdir/system/widestrs.nim || exit 1
+ cp lib/system/timers.nim $libdir/system/timers.nim
+ chmod 644 $libdir/system/timers.nim
+ cp lib/system/widestrs.nim $libdir/system/widestrs.nim
chmod 644 $libdir/system/widestrs.nim
- cp lib/core/locks.nim $libdir/core/locks.nim || exit 1
+ cp lib/core/locks.nim $libdir/core/locks.nim
chmod 644 $libdir/core/locks.nim
- cp lib/core/macros.nim $libdir/core/macros.nim || exit 1
+ cp lib/core/macros.nim $libdir/core/macros.nim
chmod 644 $libdir/core/macros.nim
- cp lib/core/typeinfo.nim $libdir/core/typeinfo.nim || exit 1
+ cp lib/core/typeinfo.nim $libdir/core/typeinfo.nim
chmod 644 $libdir/core/typeinfo.nim
- cp lib/pure/actors.nim $libdir/pure/actors.nim || exit 1
+ cp lib/pure/actors.nim $libdir/pure/actors.nim
chmod 644 $libdir/pure/actors.nim
- cp lib/pure/algorithm.nim $libdir/pure/algorithm.nim || exit 1
+ cp lib/pure/algorithm.nim $libdir/pure/algorithm.nim
chmod 644 $libdir/pure/algorithm.nim
- cp lib/pure/asyncio.nim $libdir/pure/asyncio.nim || exit 1
+ cp lib/pure/asyncio.nim $libdir/pure/asyncio.nim
chmod 644 $libdir/pure/asyncio.nim
- cp lib/pure/base64.nim $libdir/pure/base64.nim || exit 1
+ cp lib/pure/base64.nim $libdir/pure/base64.nim
chmod 644 $libdir/pure/base64.nim
- cp lib/pure/browsers.nim $libdir/pure/browsers.nim || exit 1
+ cp lib/pure/browsers.nim $libdir/pure/browsers.nim
chmod 644 $libdir/pure/browsers.nim
- cp lib/pure/bson.nim $libdir/pure/bson.nim || exit 1
- chmod 644 $libdir/pure/bson.nim
- cp lib/pure/cgi.nim $libdir/pure/cgi.nim || exit 1
+ cp lib/pure/cgi.nim $libdir/pure/cgi.nim
chmod 644 $libdir/pure/cgi.nim
- cp lib/pure/colors.nim $libdir/pure/colors.nim || exit 1
+ cp lib/pure/colors.nim $libdir/pure/colors.nim
chmod 644 $libdir/pure/colors.nim
- cp lib/pure/complex.nim $libdir/pure/complex.nim || exit 1
+ cp lib/pure/complex.nim $libdir/pure/complex.nim
chmod 644 $libdir/pure/complex.nim
- cp lib/pure/cookies.nim $libdir/pure/cookies.nim || exit 1
+ cp lib/pure/cookies.nim $libdir/pure/cookies.nim
chmod 644 $libdir/pure/cookies.nim
- cp lib/pure/dynlib.nim $libdir/pure/dynlib.nim || exit 1
+ cp lib/pure/dynlib.nim $libdir/pure/dynlib.nim
chmod 644 $libdir/pure/dynlib.nim
- cp lib/pure/encodings.nim $libdir/pure/encodings.nim || exit 1
+ cp lib/pure/encodings.nim $libdir/pure/encodings.nim
chmod 644 $libdir/pure/encodings.nim
- cp lib/pure/endians.nim $libdir/pure/endians.nim || exit 1
+ cp lib/pure/endians.nim $libdir/pure/endians.nim
chmod 644 $libdir/pure/endians.nim
- cp lib/pure/events.nim $libdir/pure/events.nim || exit 1
+ cp lib/pure/events.nim $libdir/pure/events.nim
chmod 644 $libdir/pure/events.nim
- cp lib/pure/ftpclient.nim $libdir/pure/ftpclient.nim || exit 1
+ cp lib/pure/ftpclient.nim $libdir/pure/ftpclient.nim
chmod 644 $libdir/pure/ftpclient.nim
- cp lib/pure/gentabs.nim $libdir/pure/gentabs.nim || exit 1
+ cp lib/pure/gentabs.nim $libdir/pure/gentabs.nim
chmod 644 $libdir/pure/gentabs.nim
- cp lib/pure/hashes.nim $libdir/pure/hashes.nim || exit 1
+ cp lib/pure/hashes.nim $libdir/pure/hashes.nim
chmod 644 $libdir/pure/hashes.nim
- cp lib/pure/htmlgen.nim $libdir/pure/htmlgen.nim || exit 1
+ cp lib/pure/htmlgen.nim $libdir/pure/htmlgen.nim
chmod 644 $libdir/pure/htmlgen.nim
- cp lib/pure/htmlparser.nim $libdir/pure/htmlparser.nim || exit 1
+ cp lib/pure/htmlparser.nim $libdir/pure/htmlparser.nim
chmod 644 $libdir/pure/htmlparser.nim
- cp lib/pure/httpclient.nim $libdir/pure/httpclient.nim || exit 1
+ cp lib/pure/httpclient.nim $libdir/pure/httpclient.nim
chmod 644 $libdir/pure/httpclient.nim
- cp lib/pure/httpserver.nim $libdir/pure/httpserver.nim || exit 1
+ cp lib/pure/httpserver.nim $libdir/pure/httpserver.nim
chmod 644 $libdir/pure/httpserver.nim
- cp lib/pure/irc.nim $libdir/pure/irc.nim || exit 1
+ cp lib/pure/irc.nim $libdir/pure/irc.nim
chmod 644 $libdir/pure/irc.nim
- cp lib/pure/json.nim $libdir/pure/json.nim || exit 1
+ cp lib/pure/json.nim $libdir/pure/json.nim
chmod 644 $libdir/pure/json.nim
- cp lib/pure/lexbase.nim $libdir/pure/lexbase.nim || exit 1
+ cp lib/pure/lexbase.nim $libdir/pure/lexbase.nim
chmod 644 $libdir/pure/lexbase.nim
- cp lib/pure/marshal.nim $libdir/pure/marshal.nim || exit 1
+ cp lib/pure/marshal.nim $libdir/pure/marshal.nim
chmod 644 $libdir/pure/marshal.nim
- cp lib/pure/matchers.nim $libdir/pure/matchers.nim || exit 1
+ cp lib/pure/matchers.nim $libdir/pure/matchers.nim
chmod 644 $libdir/pure/matchers.nim
- cp lib/pure/math.nim $libdir/pure/math.nim || exit 1
+ cp lib/pure/math.nim $libdir/pure/math.nim
chmod 644 $libdir/pure/math.nim
- cp lib/pure/md5.nim $libdir/pure/md5.nim || exit 1
+ cp lib/pure/md5.nim $libdir/pure/md5.nim
chmod 644 $libdir/pure/md5.nim
- cp lib/pure/memfiles.nim $libdir/pure/memfiles.nim || exit 1
+ cp lib/pure/memfiles.nim $libdir/pure/memfiles.nim
chmod 644 $libdir/pure/memfiles.nim
- cp lib/pure/oids.nim $libdir/pure/oids.nim || exit 1
+ cp lib/pure/mimetypes.nim $libdir/pure/mimetypes.nim
+ chmod 644 $libdir/pure/mimetypes.nim
+ cp lib/pure/oids.nim $libdir/pure/oids.nim
chmod 644 $libdir/pure/oids.nim
- cp lib/pure/os.nim $libdir/pure/os.nim || exit 1
+ cp lib/pure/os.nim $libdir/pure/os.nim
chmod 644 $libdir/pure/os.nim
- cp lib/pure/osproc.nim $libdir/pure/osproc.nim || exit 1
+ cp lib/pure/osproc.nim $libdir/pure/osproc.nim
chmod 644 $libdir/pure/osproc.nim
- cp lib/pure/parsecfg.nim $libdir/pure/parsecfg.nim || exit 1
+ cp lib/pure/parsecfg.nim $libdir/pure/parsecfg.nim
chmod 644 $libdir/pure/parsecfg.nim
- cp lib/pure/parsecsv.nim $libdir/pure/parsecsv.nim || exit 1
+ cp lib/pure/parsecsv.nim $libdir/pure/parsecsv.nim
chmod 644 $libdir/pure/parsecsv.nim
- cp lib/pure/parseopt.nim $libdir/pure/parseopt.nim || exit 1
+ cp lib/pure/parseopt.nim $libdir/pure/parseopt.nim
chmod 644 $libdir/pure/parseopt.nim
- cp lib/pure/parsesql.nim $libdir/pure/parsesql.nim || exit 1
+ cp lib/pure/parsesql.nim $libdir/pure/parsesql.nim
chmod 644 $libdir/pure/parsesql.nim
- cp lib/pure/parseurl.nim $libdir/pure/parseurl.nim || exit 1
+ cp lib/pure/parseurl.nim $libdir/pure/parseurl.nim
chmod 644 $libdir/pure/parseurl.nim
- cp lib/pure/parseutils.nim $libdir/pure/parseutils.nim || exit 1
+ cp lib/pure/parseutils.nim $libdir/pure/parseutils.nim
chmod 644 $libdir/pure/parseutils.nim
- cp lib/pure/parsexml.nim $libdir/pure/parsexml.nim || exit 1
+ cp lib/pure/parsexml.nim $libdir/pure/parsexml.nim
chmod 644 $libdir/pure/parsexml.nim
- cp lib/pure/pegs.nim $libdir/pure/pegs.nim || exit 1
+ cp lib/pure/pegs.nim $libdir/pure/pegs.nim
chmod 644 $libdir/pure/pegs.nim
- cp lib/pure/redis.nim $libdir/pure/redis.nim || exit 1
+ cp lib/pure/redis.nim $libdir/pure/redis.nim
chmod 644 $libdir/pure/redis.nim
- cp lib/pure/romans.nim $libdir/pure/romans.nim || exit 1
+ cp lib/pure/romans.nim $libdir/pure/romans.nim
chmod 644 $libdir/pure/romans.nim
- cp lib/pure/ropes.nim $libdir/pure/ropes.nim || exit 1
+ cp lib/pure/ropes.nim $libdir/pure/ropes.nim
chmod 644 $libdir/pure/ropes.nim
- cp lib/pure/scgi.nim $libdir/pure/scgi.nim || exit 1
+ cp lib/pure/scgi.nim $libdir/pure/scgi.nim
chmod 644 $libdir/pure/scgi.nim
- cp lib/pure/smtp.nim $libdir/pure/smtp.nim || exit 1
+ cp lib/pure/smtp.nim $libdir/pure/smtp.nim
chmod 644 $libdir/pure/smtp.nim
- cp lib/pure/sockets.nim $libdir/pure/sockets.nim || exit 1
+ cp lib/pure/sockets.nim $libdir/pure/sockets.nim
chmod 644 $libdir/pure/sockets.nim
- cp lib/pure/streams.nim $libdir/pure/streams.nim || exit 1
+ cp lib/pure/streams.nim $libdir/pure/streams.nim
chmod 644 $libdir/pure/streams.nim
- cp lib/pure/strtabs.nim $libdir/pure/strtabs.nim || exit 1
+ cp lib/pure/strtabs.nim $libdir/pure/strtabs.nim
chmod 644 $libdir/pure/strtabs.nim
- cp lib/pure/strutils.nim $libdir/pure/strutils.nim || exit 1
+ cp lib/pure/strutils.nim $libdir/pure/strutils.nim
chmod 644 $libdir/pure/strutils.nim
- cp lib/pure/subexes.nim $libdir/pure/subexes.nim || exit 1
+ cp lib/pure/subexes.nim $libdir/pure/subexes.nim
chmod 644 $libdir/pure/subexes.nim
- cp lib/pure/terminal.nim $libdir/pure/terminal.nim || exit 1
+ cp lib/pure/templateutil.nim $libdir/pure/templateutil.nim
+ chmod 644 $libdir/pure/templateutil.nim
+ cp lib/pure/terminal.nim $libdir/pure/terminal.nim
chmod 644 $libdir/pure/terminal.nim
- cp lib/pure/times.nim $libdir/pure/times.nim || exit 1
+ cp lib/pure/times.nim $libdir/pure/times.nim
chmod 644 $libdir/pure/times.nim
- cp lib/pure/unicode.nim $libdir/pure/unicode.nim || exit 1
+ cp lib/pure/typetraits.nim $libdir/pure/typetraits.nim
+ chmod 644 $libdir/pure/typetraits.nim
+ cp lib/pure/unicode.nim $libdir/pure/unicode.nim
chmod 644 $libdir/pure/unicode.nim
- cp lib/pure/unittest.nim $libdir/pure/unittest.nim || exit 1
+ cp lib/pure/unittest.nim $libdir/pure/unittest.nim
chmod 644 $libdir/pure/unittest.nim
- cp lib/pure/xmldom.nim $libdir/pure/xmldom.nim || exit 1
+ cp lib/pure/uri.nim $libdir/pure/uri.nim
+ chmod 644 $libdir/pure/uri.nim
+ cp lib/pure/xmldom.nim $libdir/pure/xmldom.nim
chmod 644 $libdir/pure/xmldom.nim
- cp lib/pure/xmldomparser.nim $libdir/pure/xmldomparser.nim || exit 1
+ cp lib/pure/xmldomparser.nim $libdir/pure/xmldomparser.nim
chmod 644 $libdir/pure/xmldomparser.nim
- cp lib/pure/xmlparser.nim $libdir/pure/xmlparser.nim || exit 1
+ cp lib/pure/xmlparser.nim $libdir/pure/xmlparser.nim
chmod 644 $libdir/pure/xmlparser.nim
- cp lib/pure/xmltree.nim $libdir/pure/xmltree.nim || exit 1
+ cp lib/pure/xmltree.nim $libdir/pure/xmltree.nim
chmod 644 $libdir/pure/xmltree.nim
- cp lib/pure/collections/critbits.nim $libdir/pure/collections/critbits.nim || exit 1
+ cp lib/pure/collections/critbits.nim $libdir/pure/collections/critbits.nim
chmod 644 $libdir/pure/collections/critbits.nim
- cp lib/pure/collections/intsets.nim $libdir/pure/collections/intsets.nim || exit 1
+ cp lib/pure/collections/intsets.nim $libdir/pure/collections/intsets.nim
chmod 644 $libdir/pure/collections/intsets.nim
- cp lib/pure/collections/lists.nim $libdir/pure/collections/lists.nim || exit 1
+ cp lib/pure/collections/lists.nim $libdir/pure/collections/lists.nim
chmod 644 $libdir/pure/collections/lists.nim
- cp lib/pure/collections/queues.nim $libdir/pure/collections/queues.nim || exit 1
+ cp lib/pure/collections/queues.nim $libdir/pure/collections/queues.nim
chmod 644 $libdir/pure/collections/queues.nim
- cp lib/pure/collections/sequtils.nim $libdir/pure/collections/sequtils.nim || exit 1
+ cp lib/pure/collections/sequtils.nim $libdir/pure/collections/sequtils.nim
chmod 644 $libdir/pure/collections/sequtils.nim
- cp lib/pure/collections/sets.nim $libdir/pure/collections/sets.nim || exit 1
+ cp lib/pure/collections/sets.nim $libdir/pure/collections/sets.nim
chmod 644 $libdir/pure/collections/sets.nim
- cp lib/pure/collections/tables.nim $libdir/pure/collections/tables.nim || exit 1
+ cp lib/pure/collections/tables.nim $libdir/pure/collections/tables.nim
chmod 644 $libdir/pure/collections/tables.nim
- cp lib/impure/db_mysql.nim $libdir/impure/db_mysql.nim || exit 1
+ cp lib/impure/db_mongo.nim $libdir/impure/db_mongo.nim
+ chmod 644 $libdir/impure/db_mongo.nim
+ cp lib/impure/db_mysql.nim $libdir/impure/db_mysql.nim
chmod 644 $libdir/impure/db_mysql.nim
- cp lib/impure/db_postgres.nim $libdir/impure/db_postgres.nim || exit 1
+ cp lib/impure/db_postgres.nim $libdir/impure/db_postgres.nim
chmod 644 $libdir/impure/db_postgres.nim
- cp lib/impure/db_sqlite.nim $libdir/impure/db_sqlite.nim || exit 1
+ cp lib/impure/db_sqlite.nim $libdir/impure/db_sqlite.nim
chmod 644 $libdir/impure/db_sqlite.nim
- cp lib/impure/dialogs.nim $libdir/impure/dialogs.nim || exit 1
+ cp lib/impure/dialogs.nim $libdir/impure/dialogs.nim
chmod 644 $libdir/impure/dialogs.nim
- cp lib/impure/fpc.nim $libdir/impure/fpc.nim || exit 1
- chmod 644 $libdir/impure/fpc.nim
- cp lib/impure/graphics.nim $libdir/impure/graphics.nim || exit 1
+ cp lib/impure/graphics.nim $libdir/impure/graphics.nim
chmod 644 $libdir/impure/graphics.nim
- cp lib/impure/osinfo_posix.nim $libdir/impure/osinfo_posix.nim || exit 1
+ cp lib/impure/osinfo_posix.nim $libdir/impure/osinfo_posix.nim
chmod 644 $libdir/impure/osinfo_posix.nim
- cp lib/impure/osinfo_win.nim $libdir/impure/osinfo_win.nim || exit 1
+ cp lib/impure/osinfo_win.nim $libdir/impure/osinfo_win.nim
chmod 644 $libdir/impure/osinfo_win.nim
- cp lib/impure/rdstdin.nim $libdir/impure/rdstdin.nim || exit 1
+ cp lib/impure/rdstdin.nim $libdir/impure/rdstdin.nim
chmod 644 $libdir/impure/rdstdin.nim
- cp lib/impure/re.nim $libdir/impure/re.nim || exit 1
+ cp lib/impure/re.nim $libdir/impure/re.nim
chmod 644 $libdir/impure/re.nim
- cp lib/impure/ssl.nim $libdir/impure/ssl.nim || exit 1
+ cp lib/impure/ssl.nim $libdir/impure/ssl.nim
chmod 644 $libdir/impure/ssl.nim
- cp lib/impure/web.nim $libdir/impure/web.nim || exit 1
+ cp lib/impure/web.nim $libdir/impure/web.nim
chmod 644 $libdir/impure/web.nim
- cp lib/impure/zipfiles.nim $libdir/impure/zipfiles.nim || exit 1
+ cp lib/impure/zipfiles.nim $libdir/impure/zipfiles.nim
chmod 644 $libdir/impure/zipfiles.nim
- cp lib/wrappers/claro.nim $libdir/wrappers/claro.nim || exit 1
+ cp lib/wrappers/claro.nim $libdir/wrappers/claro.nim
chmod 644 $libdir/wrappers/claro.nim
- cp lib/wrappers/expat.nim $libdir/wrappers/expat.nim || exit 1
+ cp lib/wrappers/expat.nim $libdir/wrappers/expat.nim
chmod 644 $libdir/wrappers/expat.nim
- cp lib/wrappers/iup.nim $libdir/wrappers/iup.nim || exit 1
+ cp lib/wrappers/iup.nim $libdir/wrappers/iup.nim
chmod 644 $libdir/wrappers/iup.nim
- cp lib/wrappers/joyent_http_parser.nim $libdir/wrappers/joyent_http_parser.nim || exit 1
+ cp lib/wrappers/joyent_http_parser.nim $libdir/wrappers/joyent_http_parser.nim
chmod 644 $libdir/wrappers/joyent_http_parser.nim
- cp lib/wrappers/libcurl.nim $libdir/wrappers/libcurl.nim || exit 1
+ cp lib/wrappers/libcurl.nim $libdir/wrappers/libcurl.nim
chmod 644 $libdir/wrappers/libcurl.nim
- cp lib/wrappers/libsvm.nim $libdir/wrappers/libsvm.nim || exit 1
+ cp lib/wrappers/libsvm.nim $libdir/wrappers/libsvm.nim
chmod 644 $libdir/wrappers/libsvm.nim
- cp lib/wrappers/libuv.nim $libdir/wrappers/libuv.nim || exit 1
+ cp lib/wrappers/libuv.nim $libdir/wrappers/libuv.nim
chmod 644 $libdir/wrappers/libuv.nim
- cp lib/wrappers/mongo.nim $libdir/wrappers/mongo.nim || exit 1
+ cp lib/wrappers/mongo.nim $libdir/wrappers/mongo.nim
chmod 644 $libdir/wrappers/mongo.nim
- cp lib/wrappers/mysql.nim $libdir/wrappers/mysql.nim || exit 1
+ cp lib/wrappers/mysql.nim $libdir/wrappers/mysql.nim
chmod 644 $libdir/wrappers/mysql.nim
- cp lib/wrappers/odbcsql.nim $libdir/wrappers/odbcsql.nim || exit 1
+ cp lib/wrappers/odbcsql.nim $libdir/wrappers/odbcsql.nim
chmod 644 $libdir/wrappers/odbcsql.nim
- cp lib/wrappers/openssl.nim $libdir/wrappers/openssl.nim || exit 1
+ cp lib/wrappers/openssl.nim $libdir/wrappers/openssl.nim
chmod 644 $libdir/wrappers/openssl.nim
- cp lib/wrappers/pcre.nim $libdir/wrappers/pcre.nim || exit 1
+ cp lib/wrappers/pcre.nim $libdir/wrappers/pcre.nim
chmod 644 $libdir/wrappers/pcre.nim
- cp lib/wrappers/postgres.nim $libdir/wrappers/postgres.nim || exit 1
+ cp lib/wrappers/postgres.nim $libdir/wrappers/postgres.nim
chmod 644 $libdir/wrappers/postgres.nim
- cp lib/wrappers/python.nim $libdir/wrappers/python.nim || exit 1
+ cp lib/wrappers/python.nim $libdir/wrappers/python.nim
chmod 644 $libdir/wrappers/python.nim
- cp lib/wrappers/sphinx.nim $libdir/wrappers/sphinx.nim || exit 1
+ cp lib/wrappers/sphinx.nim $libdir/wrappers/sphinx.nim
chmod 644 $libdir/wrappers/sphinx.nim
- cp lib/wrappers/sqlite3.nim $libdir/wrappers/sqlite3.nim || exit 1
+ cp lib/wrappers/sqlite3.nim $libdir/wrappers/sqlite3.nim
chmod 644 $libdir/wrappers/sqlite3.nim
- cp lib/wrappers/tcl.nim $libdir/wrappers/tcl.nim || exit 1
+ cp lib/wrappers/tcl.nim $libdir/wrappers/tcl.nim
chmod 644 $libdir/wrappers/tcl.nim
- cp lib/wrappers/tinyc.nim $libdir/wrappers/tinyc.nim || exit 1
+ cp lib/wrappers/tinyc.nim $libdir/wrappers/tinyc.nim
chmod 644 $libdir/wrappers/tinyc.nim
- cp lib/wrappers/tre.nim $libdir/wrappers/tre.nim || exit 1
+ cp lib/wrappers/tre.nim $libdir/wrappers/tre.nim
chmod 644 $libdir/wrappers/tre.nim
- cp lib/wrappers/zmq.nim $libdir/wrappers/zmq.nim || exit 1
+ cp lib/wrappers/zmq.nim $libdir/wrappers/zmq.nim
chmod 644 $libdir/wrappers/zmq.nim
- cp lib/wrappers/cairo/cairo.nim $libdir/wrappers/cairo/cairo.nim || exit 1
+ cp lib/wrappers/cairo/cairo.nim $libdir/wrappers/cairo/cairo.nim
chmod 644 $libdir/wrappers/cairo/cairo.nim
- cp lib/wrappers/cairo/cairoft.nim $libdir/wrappers/cairo/cairoft.nim || exit 1
+ cp lib/wrappers/cairo/cairoft.nim $libdir/wrappers/cairo/cairoft.nim
chmod 644 $libdir/wrappers/cairo/cairoft.nim
- cp lib/wrappers/cairo/cairowin32.nim $libdir/wrappers/cairo/cairowin32.nim || exit 1
+ cp lib/wrappers/cairo/cairowin32.nim $libdir/wrappers/cairo/cairowin32.nim
chmod 644 $libdir/wrappers/cairo/cairowin32.nim
- cp lib/wrappers/cairo/cairoxlib.nim $libdir/wrappers/cairo/cairoxlib.nim || exit 1
+ cp lib/wrappers/cairo/cairoxlib.nim $libdir/wrappers/cairo/cairoxlib.nim
chmod 644 $libdir/wrappers/cairo/cairoxlib.nim
- cp lib/wrappers/gtk/atk.nim $libdir/wrappers/gtk/atk.nim || exit 1
+ cp lib/wrappers/gtk/atk.nim $libdir/wrappers/gtk/atk.nim
chmod 644 $libdir/wrappers/gtk/atk.nim
- cp lib/wrappers/gtk/gdk2.nim $libdir/wrappers/gtk/gdk2.nim || exit 1
+ cp lib/wrappers/gtk/gdk2.nim $libdir/wrappers/gtk/gdk2.nim
chmod 644 $libdir/wrappers/gtk/gdk2.nim
- cp lib/wrappers/gtk/gdk2pixbuf.nim $libdir/wrappers/gtk/gdk2pixbuf.nim || exit 1
+ cp lib/wrappers/gtk/gdk2pixbuf.nim $libdir/wrappers/gtk/gdk2pixbuf.nim
chmod 644 $libdir/wrappers/gtk/gdk2pixbuf.nim
- cp lib/wrappers/gtk/gdkglext.nim $libdir/wrappers/gtk/gdkglext.nim || exit 1
+ cp lib/wrappers/gtk/gdkglext.nim $libdir/wrappers/gtk/gdkglext.nim
chmod 644 $libdir/wrappers/gtk/gdkglext.nim
- cp lib/wrappers/gtk/glib2.nim $libdir/wrappers/gtk/glib2.nim || exit 1
+ cp lib/wrappers/gtk/glib2.nim $libdir/wrappers/gtk/glib2.nim
chmod 644 $libdir/wrappers/gtk/glib2.nim
- cp lib/wrappers/gtk/gtk2.nim $libdir/wrappers/gtk/gtk2.nim || exit 1
+ cp lib/wrappers/gtk/gtk2.nim $libdir/wrappers/gtk/gtk2.nim
chmod 644 $libdir/wrappers/gtk/gtk2.nim
- cp lib/wrappers/gtk/gtkglext.nim $libdir/wrappers/gtk/gtkglext.nim || exit 1
+ cp lib/wrappers/gtk/gtkglext.nim $libdir/wrappers/gtk/gtkglext.nim
chmod 644 $libdir/wrappers/gtk/gtkglext.nim
- cp lib/wrappers/gtk/gtkhtml.nim $libdir/wrappers/gtk/gtkhtml.nim || exit 1
+ cp lib/wrappers/gtk/gtkhtml.nim $libdir/wrappers/gtk/gtkhtml.nim
chmod 644 $libdir/wrappers/gtk/gtkhtml.nim
- cp lib/wrappers/gtk/libglade2.nim $libdir/wrappers/gtk/libglade2.nim || exit 1
+ cp lib/wrappers/gtk/libglade2.nim $libdir/wrappers/gtk/libglade2.nim
chmod 644 $libdir/wrappers/gtk/libglade2.nim
- cp lib/wrappers/gtk/pango.nim $libdir/wrappers/gtk/pango.nim || exit 1
+ cp lib/wrappers/gtk/pango.nim $libdir/wrappers/gtk/pango.nim
chmod 644 $libdir/wrappers/gtk/pango.nim
- cp lib/wrappers/gtk/pangoutils.nim $libdir/wrappers/gtk/pangoutils.nim || exit 1
+ cp lib/wrappers/gtk/pangoutils.nim $libdir/wrappers/gtk/pangoutils.nim
chmod 644 $libdir/wrappers/gtk/pangoutils.nim
- cp lib/wrappers/lua/lauxlib.nim $libdir/wrappers/lua/lauxlib.nim || exit 1
+ cp lib/wrappers/lua/lauxlib.nim $libdir/wrappers/lua/lauxlib.nim
chmod 644 $libdir/wrappers/lua/lauxlib.nim
- cp lib/wrappers/lua/lua.nim $libdir/wrappers/lua/lua.nim || exit 1
+ cp lib/wrappers/lua/lua.nim $libdir/wrappers/lua/lua.nim
chmod 644 $libdir/wrappers/lua/lua.nim
- cp lib/wrappers/lua/lualib.nim $libdir/wrappers/lua/lualib.nim || exit 1
+ cp lib/wrappers/lua/lualib.nim $libdir/wrappers/lua/lualib.nim
chmod 644 $libdir/wrappers/lua/lualib.nim
- cp lib/wrappers/opengl/gl.nim $libdir/wrappers/opengl/gl.nim || exit 1
+ cp lib/wrappers/opengl/gl.nim $libdir/wrappers/opengl/gl.nim
chmod 644 $libdir/wrappers/opengl/gl.nim
- cp lib/wrappers/opengl/glext.nim $libdir/wrappers/opengl/glext.nim || exit 1
+ cp lib/wrappers/opengl/glext.nim $libdir/wrappers/opengl/glext.nim
chmod 644 $libdir/wrappers/opengl/glext.nim
- cp lib/wrappers/opengl/glu.nim $libdir/wrappers/opengl/glu.nim || exit 1
+ cp lib/wrappers/opengl/glu.nim $libdir/wrappers/opengl/glu.nim
chmod 644 $libdir/wrappers/opengl/glu.nim
- cp lib/wrappers/opengl/glut.nim $libdir/wrappers/opengl/glut.nim || exit 1
+ cp lib/wrappers/opengl/glut.nim $libdir/wrappers/opengl/glut.nim
chmod 644 $libdir/wrappers/opengl/glut.nim
- cp lib/wrappers/opengl/glx.nim $libdir/wrappers/opengl/glx.nim || exit 1
+ cp lib/wrappers/opengl/glx.nim $libdir/wrappers/opengl/glx.nim
chmod 644 $libdir/wrappers/opengl/glx.nim
- cp lib/wrappers/opengl/opengl.nim $libdir/wrappers/opengl/opengl.nim || exit 1
+ cp lib/wrappers/opengl/opengl.nim $libdir/wrappers/opengl/opengl.nim
chmod 644 $libdir/wrappers/opengl/opengl.nim
- cp lib/wrappers/opengl/wingl.nim $libdir/wrappers/opengl/wingl.nim || exit 1
+ cp lib/wrappers/opengl/wingl.nim $libdir/wrappers/opengl/wingl.nim
chmod 644 $libdir/wrappers/opengl/wingl.nim
- cp lib/wrappers/sdl/sdl.nim $libdir/wrappers/sdl/sdl.nim || exit 1
+ cp lib/wrappers/readline/history.nim $libdir/wrappers/readline/history.nim
+ chmod 644 $libdir/wrappers/readline/history.nim
+ cp lib/wrappers/readline/readline.nim $libdir/wrappers/readline/readline.nim
+ chmod 644 $libdir/wrappers/readline/readline.nim
+ cp lib/wrappers/readline/rltypedefs.nim $libdir/wrappers/readline/rltypedefs.nim
+ chmod 644 $libdir/wrappers/readline/rltypedefs.nim
+ cp lib/wrappers/sdl/sdl.nim $libdir/wrappers/sdl/sdl.nim
chmod 644 $libdir/wrappers/sdl/sdl.nim
- cp lib/wrappers/sdl/sdl_gfx.nim $libdir/wrappers/sdl/sdl_gfx.nim || exit 1
+ cp lib/wrappers/sdl/sdl_gfx.nim $libdir/wrappers/sdl/sdl_gfx.nim
chmod 644 $libdir/wrappers/sdl/sdl_gfx.nim
- cp lib/wrappers/sdl/sdl_image.nim $libdir/wrappers/sdl/sdl_image.nim || exit 1
+ cp lib/wrappers/sdl/sdl_image.nim $libdir/wrappers/sdl/sdl_image.nim
chmod 644 $libdir/wrappers/sdl/sdl_image.nim
- cp lib/wrappers/sdl/sdl_mixer.nim $libdir/wrappers/sdl/sdl_mixer.nim || exit 1
+ cp lib/wrappers/sdl/sdl_mixer.nim $libdir/wrappers/sdl/sdl_mixer.nim
chmod 644 $libdir/wrappers/sdl/sdl_mixer.nim
- cp lib/wrappers/sdl/sdl_mixer_nosmpeg.nim $libdir/wrappers/sdl/sdl_mixer_nosmpeg.nim || exit 1
+ cp lib/wrappers/sdl/sdl_mixer_nosmpeg.nim $libdir/wrappers/sdl/sdl_mixer_nosmpeg.nim
chmod 644 $libdir/wrappers/sdl/sdl_mixer_nosmpeg.nim
- cp lib/wrappers/sdl/sdl_net.nim $libdir/wrappers/sdl/sdl_net.nim || exit 1
+ cp lib/wrappers/sdl/sdl_net.nim $libdir/wrappers/sdl/sdl_net.nim
chmod 644 $libdir/wrappers/sdl/sdl_net.nim
- cp lib/wrappers/sdl/sdl_ttf.nim $libdir/wrappers/sdl/sdl_ttf.nim || exit 1
+ cp lib/wrappers/sdl/sdl_ttf.nim $libdir/wrappers/sdl/sdl_ttf.nim
chmod 644 $libdir/wrappers/sdl/sdl_ttf.nim
- cp lib/wrappers/sdl/smpeg.nim $libdir/wrappers/sdl/smpeg.nim || exit 1
+ cp lib/wrappers/sdl/smpeg.nim $libdir/wrappers/sdl/smpeg.nim
chmod 644 $libdir/wrappers/sdl/smpeg.nim
- cp lib/wrappers/x11/cursorfont.nim $libdir/wrappers/x11/cursorfont.nim || exit 1
+ cp lib/wrappers/x11/cursorfont.nim $libdir/wrappers/x11/cursorfont.nim
chmod 644 $libdir/wrappers/x11/cursorfont.nim
- cp lib/wrappers/x11/keysym.nim $libdir/wrappers/x11/keysym.nim || exit 1
+ cp lib/wrappers/x11/keysym.nim $libdir/wrappers/x11/keysym.nim
chmod 644 $libdir/wrappers/x11/keysym.nim
- cp lib/wrappers/x11/x.nim $libdir/wrappers/x11/x.nim || exit 1
+ cp lib/wrappers/x11/x.nim $libdir/wrappers/x11/x.nim
chmod 644 $libdir/wrappers/x11/x.nim
- cp lib/wrappers/x11/xatom.nim $libdir/wrappers/x11/xatom.nim || exit 1
+ cp lib/wrappers/x11/xatom.nim $libdir/wrappers/x11/xatom.nim
chmod 644 $libdir/wrappers/x11/xatom.nim
- cp lib/wrappers/x11/xcms.nim $libdir/wrappers/x11/xcms.nim || exit 1
+ cp lib/wrappers/x11/xcms.nim $libdir/wrappers/x11/xcms.nim
chmod 644 $libdir/wrappers/x11/xcms.nim
- cp lib/wrappers/x11/xf86dga.nim $libdir/wrappers/x11/xf86dga.nim || exit 1
+ cp lib/wrappers/x11/xf86dga.nim $libdir/wrappers/x11/xf86dga.nim
chmod 644 $libdir/wrappers/x11/xf86dga.nim
- cp lib/wrappers/x11/xf86vmode.nim $libdir/wrappers/x11/xf86vmode.nim || exit 1
+ cp lib/wrappers/x11/xf86vmode.nim $libdir/wrappers/x11/xf86vmode.nim
chmod 644 $libdir/wrappers/x11/xf86vmode.nim
- cp lib/wrappers/x11/xi.nim $libdir/wrappers/x11/xi.nim || exit 1
+ cp lib/wrappers/x11/xi.nim $libdir/wrappers/x11/xi.nim
chmod 644 $libdir/wrappers/x11/xi.nim
- cp lib/wrappers/x11/xinerama.nim $libdir/wrappers/x11/xinerama.nim || exit 1
+ cp lib/wrappers/x11/xinerama.nim $libdir/wrappers/x11/xinerama.nim
chmod 644 $libdir/wrappers/x11/xinerama.nim
- cp lib/wrappers/x11/xkb.nim $libdir/wrappers/x11/xkb.nim || exit 1
+ cp lib/wrappers/x11/xkb.nim $libdir/wrappers/x11/xkb.nim
chmod 644 $libdir/wrappers/x11/xkb.nim
- cp lib/wrappers/x11/xkblib.nim $libdir/wrappers/x11/xkblib.nim || exit 1
+ cp lib/wrappers/x11/xkblib.nim $libdir/wrappers/x11/xkblib.nim
chmod 644 $libdir/wrappers/x11/xkblib.nim
- cp lib/wrappers/x11/xlib.nim $libdir/wrappers/x11/xlib.nim || exit 1
+ cp lib/wrappers/x11/xlib.nim $libdir/wrappers/x11/xlib.nim
chmod 644 $libdir/wrappers/x11/xlib.nim
- cp lib/wrappers/x11/xrandr.nim $libdir/wrappers/x11/xrandr.nim || exit 1
+ cp lib/wrappers/x11/xrandr.nim $libdir/wrappers/x11/xrandr.nim
chmod 644 $libdir/wrappers/x11/xrandr.nim
- cp lib/wrappers/x11/xrender.nim $libdir/wrappers/x11/xrender.nim || exit 1
+ cp lib/wrappers/x11/xrender.nim $libdir/wrappers/x11/xrender.nim
chmod 644 $libdir/wrappers/x11/xrender.nim
- cp lib/wrappers/x11/xresource.nim $libdir/wrappers/x11/xresource.nim || exit 1
+ cp lib/wrappers/x11/xresource.nim $libdir/wrappers/x11/xresource.nim
chmod 644 $libdir/wrappers/x11/xresource.nim
- cp lib/wrappers/x11/xshm.nim $libdir/wrappers/x11/xshm.nim || exit 1
+ cp lib/wrappers/x11/xshm.nim $libdir/wrappers/x11/xshm.nim
chmod 644 $libdir/wrappers/x11/xshm.nim
- cp lib/wrappers/x11/xutil.nim $libdir/wrappers/x11/xutil.nim || exit 1
+ cp lib/wrappers/x11/xutil.nim $libdir/wrappers/x11/xutil.nim
chmod 644 $libdir/wrappers/x11/xutil.nim
- cp lib/wrappers/x11/xv.nim $libdir/wrappers/x11/xv.nim || exit 1
+ cp lib/wrappers/x11/xv.nim $libdir/wrappers/x11/xv.nim
chmod 644 $libdir/wrappers/x11/xv.nim
- cp lib/wrappers/x11/xvlib.nim $libdir/wrappers/x11/xvlib.nim || exit 1
+ cp lib/wrappers/x11/xvlib.nim $libdir/wrappers/x11/xvlib.nim
chmod 644 $libdir/wrappers/x11/xvlib.nim
- cp lib/wrappers/zip/libzip.nim $libdir/wrappers/zip/libzip.nim || exit 1
+ cp lib/wrappers/zip/libzip.nim $libdir/wrappers/zip/libzip.nim
chmod 644 $libdir/wrappers/zip/libzip.nim
- cp lib/wrappers/zip/zlib.nim $libdir/wrappers/zip/zlib.nim || exit 1
+ cp lib/wrappers/zip/zlib.nim $libdir/wrappers/zip/zlib.nim
chmod 644 $libdir/wrappers/zip/zlib.nim
- cp lib/wrappers/zip/zzip.nim $libdir/wrappers/zip/zzip.nim || exit 1
+ cp lib/wrappers/zip/zzip.nim $libdir/wrappers/zip/zzip.nim
chmod 644 $libdir/wrappers/zip/zzip.nim
- cp lib/wrappers/zip/libzip_all.c $libdir/wrappers/zip/libzip_all.c || exit 1
+ cp lib/wrappers/zip/libzip_all.c $libdir/wrappers/zip/libzip_all.c
chmod 644 $libdir/wrappers/zip/libzip_all.c
- cp lib/windows/mmsystem.nim $libdir/windows/mmsystem.nim || exit 1
+ cp lib/windows/mmsystem.nim $libdir/windows/mmsystem.nim
chmod 644 $libdir/windows/mmsystem.nim
- cp lib/windows/nb30.nim $libdir/windows/nb30.nim || exit 1
+ cp lib/windows/nb30.nim $libdir/windows/nb30.nim
chmod 644 $libdir/windows/nb30.nim
- cp lib/windows/ole2.nim $libdir/windows/ole2.nim || exit 1
+ cp lib/windows/ole2.nim $libdir/windows/ole2.nim
chmod 644 $libdir/windows/ole2.nim
- cp lib/windows/psapi.nim $libdir/windows/psapi.nim || exit 1
+ cp lib/windows/psapi.nim $libdir/windows/psapi.nim
chmod 644 $libdir/windows/psapi.nim
- cp lib/windows/shellapi.nim $libdir/windows/shellapi.nim || exit 1
+ cp lib/windows/shellapi.nim $libdir/windows/shellapi.nim
chmod 644 $libdir/windows/shellapi.nim
- cp lib/windows/shfolder.nim $libdir/windows/shfolder.nim || exit 1
+ cp lib/windows/shfolder.nim $libdir/windows/shfolder.nim
chmod 644 $libdir/windows/shfolder.nim
- cp lib/windows/windows.nim $libdir/windows/windows.nim || exit 1
+ cp lib/windows/windows.nim $libdir/windows/windows.nim
chmod 644 $libdir/windows/windows.nim
- cp lib/windows/winlean.nim $libdir/windows/winlean.nim || exit 1
+ cp lib/windows/winlean.nim $libdir/windows/winlean.nim
chmod 644 $libdir/windows/winlean.nim
- cp lib/posix/posix.nim $libdir/posix/posix.nim || exit 1
+ cp lib/posix/posix.nim $libdir/posix/posix.nim
chmod 644 $libdir/posix/posix.nim
- cp lib/ecmas/dom.nim $libdir/ecmas/dom.nim || exit 1
+ cp lib/ecmas/dom.nim $libdir/ecmas/dom.nim
chmod 644 $libdir/ecmas/dom.nim
echo "installation successful"
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index b0f237924d..9d0994c2f5 100755
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -17,8 +17,9 @@ type
TNimrodNodeKind* = enum
nnkNone, nnkEmpty, nnkIdent, nnkSym,
nnkType, nnkCharLit, nnkIntLit, nnkInt8Lit,
- nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkFloatLit,
- nnkFloat32Lit, nnkFloat64Lit, nnkStrLit, nnkRStrLit,
+ nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkUIntLit, nnkUInt8Lit,
+ nnkUInt16Lit, nnkUInt32Lit, nnkUInt64Lit, nnkFloatLit,
+ nnkFloat32Lit, nnkFloat64Lit, nnkFloat128Lit, nnkStrLit, nnkRStrLit,
nnkTripleStrLit, nnkNilLit, nnkMetaNode, nnkDotCall,
nnkCommand, nnkCall, nnkCallStrLit, nnkExprEqExpr,
nnkExprColonExpr, nnkIdentDefs, nnkVarTuple, nnkInfix,
diff --git a/lib/core/typeinfo.nim b/lib/core/typeinfo.nim
index ca2b68cc3f..549e4724a7 100755
--- a/lib/core/typeinfo.nim
+++ b/lib/core/typeinfo.nim
@@ -43,8 +43,13 @@ type
akFloat = 36, ## any represents a float
akFloat32 = 37, ## any represents a float32
akFloat64 = 38, ## any represents a float64
- akFloat128 = 39 ## any represents a float128
-
+ akFloat128 = 39, ## any represents a float128
+ akUInt = 40, ## any represents an unsigned int
+ akUInt8 = 41, ## any represents an unsigned int8
+ akUInt16 = 42, ## any represents an unsigned in16
+ akUInt32 = 43, ## any represents an unsigned int32
+ akUInt64 = 44, ## any represents an unsigned int64
+
TAny* = object {.pure.} ## can represent any nimrod value; NOTE: the wrapped
## value can be modified with its wrapper! This means
## that ``TAny`` keeps a non-traced pointer to its
diff --git a/lib/impure/ssl.nim b/lib/impure/ssl.nim
index 5fe986b14f..4a101ca92e 100755
--- a/lib/impure/ssl.nim
+++ b/lib/impure/ssl.nim
@@ -10,6 +10,8 @@
## This module provides an easy to use sockets-style
## nimrod interface to the OpenSSL library.
+{.deprecate.}
+
import openssl, strutils, os
type
diff --git a/lib/nimbase.h b/lib/nimbase.h
index a114430abb..a73933a408 100755
--- a/lib/nimbase.h
+++ b/lib/nimbase.h
@@ -192,7 +192,7 @@ __clang__
** long int lrint (double x);
*/
-#if defined(__LCC__) || (defined(__GNUC__) && defined(WIN32))
+#if defined(__LCC__) || (defined(__GNUC__))
/* Linux' GCC does not seem to have these. Why? */
# define HAVE_LRINT
# define HAVE_LRINTF
@@ -281,6 +281,13 @@ static unsigned long nimInf[2]={0xffffffff, 0x7fffffff};
# endif
# define NIM_BOOL bool
# define NIM_NIL 0
+struct NimException
+{
+ NimException(struct E_Base* exp, const char* msg): exp(exp), msg(msg) {}
+
+ struct E_Base* exp;
+ const char* msg;
+};
#else
# ifdef bool
# define NIM_BOOL bool
diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim
index 3af08f040b..184bca867b 100755
--- a/lib/pure/httpclient.nim
+++ b/lib/pure/httpclient.nim
@@ -42,6 +42,14 @@
## body.add("--xyz--")
##
## echo(postContent("http://validator.w3.org/check", headers, body))
+##
+## SSL/TLS support
+## ===============
+## This requires the OpenSSL library, fortunately it's widely used and installed
+## on many operating systems. httpclient will use SSL automatically if you give
+## any of the functions a url with the ``https`` schema, for example:
+## ``https://github.com/``, you also have to compile with ``ssl`` defined like so:
+## ``nimrod c -d:ssl ...``.
import sockets, strutils, parseurl, parseutils, strtabs
@@ -79,10 +87,11 @@ proc charAt(d: var string, i: var int, s: TSocket): char {.inline.} =
i = 0
result = d[i]
-proc parseChunks(d: var string, start: int, s: TSocket): string =
+proc parseChunks(s: TSocket): string =
# get chunks:
- var i = start
+ var i = 0
result = ""
+ var d = s.recv().string
while true:
var chunkSize = 0
var digitFound = false
@@ -128,88 +137,87 @@ proc parseChunks(d: var string, start: int, s: TSocket): string =
# skip trailing CR-LF:
while charAt(d, i, s) in {'\C', '\L'}: inc(i)
-proc parseBody(d: var string, start: int, s: TSocket,
+proc parseBody(s: TSocket,
headers: PStringTable): string =
+ result = ""
if headers["Transfer-Encoding"] == "chunked":
- result = parseChunks(d, start, s)
+ result = parseChunks(s)
else:
- result = substr(d, start)
# -REGION- Content-Length
# (http://tools.ietf.org/html/rfc2616#section-4.4) NR.3
var contentLengthHeader = headers["Content-Length"]
if contentLengthHeader != "":
var length = contentLengthHeader.parseint()
- while result.len() < length: result.add(s.recv.string)
+ result = newString(length)
+ var received = 0
+ while true:
+ if received >= length: break
+ let r = s.recv(addr(result[received]), length-received)
+ if r == 0: break
+ received += r
+ if received != length:
+ httpError("Got invalid content length. Expected: " & $length &
+ " got: " & $received)
else:
# (http://tools.ietf.org/html/rfc2616#section-4.4) NR.4 TODO
# -REGION- Connection: Close
# (http://tools.ietf.org/html/rfc2616#section-4.4) NR.5
if headers["Connection"] == "close":
+ var buf = ""
while True:
- var moreData = recv(s).string
- if moreData.len == 0: break
- result.add(moreData)
+ buf = newString(4000)
+ let r = s.recv(addr(buf[0]), 4000)
+ if r == 0: break
+ buf.setLen(r)
+ result.add(buf)
-proc parseResponse(s: TSocket): TResponse =
- var d = s.recv.string
- var i = 0
-
- # Parse the version
- # Parses the first line of the headers
- # ``HTTP/1.1`` 200 OK
- var L = skipIgnoreCase(d, "HTTP/1.1", i)
- if L > 0:
- result.version = "1.1"
- inc(i, L)
- else:
- L = skipIgnoreCase(d, "HTTP/1.0", i)
- if L > 0:
- result.version = "1.0"
- inc(i, L)
- else:
- httpError("invalid HTTP header")
- L = skipWhiteSpace(d, i)
- if L <= 0: httpError("invalid HTTP header")
- inc(i, L)
-
- result.status = ""
- while d[i] notin {'\C', '\L', '\0'}:
- result.status.add(d[i])
- inc(i)
- if d[i] == '\C': inc(i)
- if d[i] == '\L': inc(i)
- else: httpError("invalid HTTP header, CR-LF expected")
-
- # Parse the headers
- # Everything after the first line leading up to the body
- # htype: hvalue
+proc parseResponse(s: TSocket, getBody: bool): TResponse =
+ var parsedStatus = false
+ var linei = 0
+ var fullyRead = false
+ var line = ""
result.headers = newStringTable(modeCaseInsensitive)
- while true:
- var key = ""
- while d[i] != ':':
- if d[i] == '\0': httpError("invalid HTTP header, ':' expected")
- key.add(d[i])
- inc(i)
- inc(i) # skip ':'
- if d[i] == ' ': inc(i) # skip if the character is a space
- var val = ""
- while d[i] notin {'\C', '\L', '\0'}:
- val.add(d[i])
- inc(i)
-
- result.headers[key] = val
-
- if d[i] == '\C': inc(i)
- if d[i] == '\L': inc(i)
- else: httpError("invalid HTTP header, CR-LF expected")
-
- if d[i] == '\C': inc(i)
- if d[i] == '\L':
- inc(i)
- break
-
- result.body = parseBody(d, i, s, result.headers)
+ while True:
+ line = ""
+ linei = 0
+ if s.recvLine(line):
+ if line == "": break # We've been disconnected.
+ if line == "\c\L":
+ fullyRead = true
+ break
+ if not parsedStatus:
+ # Parse HTTP version info and status code.
+ var le = skipIgnoreCase(line, "HTTP/", linei)
+ if le <= 0: httpError("invalid http version")
+ inc(linei, le)
+ le = skipIgnoreCase(line, "1.1", linei)
+ if le > 0: result.version = "1.1"
+ else:
+ le = skipIgnoreCase(line, "1.0", linei)
+ if le <= 0: httpError("unsupported http version")
+ result.version = "1.0"
+ inc(linei, le)
+ # Status code
+ linei.inc skipWhitespace(line, linei)
+ result.status = line[linei .. -1]
+ parsedStatus = true
+ else:
+ # Parse headers
+ var name = ""
+ var le = parseUntil(line, name, ':', linei)
+ if le <= 0: httpError("invalid headers")
+ inc(linei, le)
+ if line[linei] != ':': httpError("invalid headers")
+ inc(linei) # Skip :
+ linei += skipWhitespace(line, linei)
+
+ result.headers[name] = line[linei.. -1]
+ if not fullyRead: httpError("Connection was closed before full request has been made")
+ if getBody:
+ result.body = parseBody(s, result.headers)
+ else:
+ result.body = ""
type
THttpMethod* = enum ## the requested HttpMethod
@@ -238,6 +246,7 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "",
var headers = substr($httpMethod, len("http"))
headers.add(" /" & r.path & r.query)
+
headers.add(" HTTP/1.1\c\L")
add(headers, "Host: " & r.hostname & "\c\L")
@@ -245,12 +254,21 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "",
add(headers, "\c\L")
var s = socket()
- s.connect(r.hostname, TPort(80))
+ var port = TPort(80)
+ if r.scheme == "https":
+ when defined(ssl):
+ s.wrapSocket(verifyMode = CVerifyNone)
+ else:
+ raise newException(EHttpRequestErr, "SSL support was not compiled in. Cannot connect over SSL.")
+ port = TPort(443)
+ if r.port != "":
+ port = TPort(r.port.parseInt)
+ s.connect(r.hostname, port)
s.send(headers)
if body != "":
s.send(body)
- result = parseResponse(s)
+ result = parseResponse(s, httpMethod != httpHEAD)
s.close()
proc redirection(status: string): bool =
diff --git a/lib/pure/marshal.nim b/lib/pure/marshal.nim
index fd67fb8499..e8c30331a0 100755
--- a/lib/pure/marshal.nim
+++ b/lib/pure/marshal.nim
@@ -8,25 +8,25 @@
#
## This module contains procs for serialization and deseralization of
-## arbitrary Nimrod data structures. The serialization format uses JSON.
-##
-## **Restriction**: For objects their type is **not** serialized. This means
-## essentially that it does not work if the object has some other runtime
-## type than its compiletime type:
-##
-## .. code-block:: nimrod
-##
-## type
-## TA = object
-## TB = object of TA
-## f: int
-##
-## var
-## a: ref TA
-## b: ref TB
-##
-## new(b)
-## a = b
+## arbitrary Nimrod data structures. The serialization format uses JSON.
+##
+## **Restriction**: For objects their type is **not** serialized. This means
+## essentially that it does not work if the object has some other runtime
+## type than its compiletime type:
+##
+## .. code-block:: nimrod
+##
+## type
+## TA = object
+## TB = object of TA
+## f: int
+##
+## var
+## a: ref TA
+## b: ref TB
+##
+## new(b)
+## a = b
## echo($$a[]) # produces "{}", not "{f: 0}"
import streams, typeinfo, json, intsets, tables
@@ -86,7 +86,7 @@ proc storeAny(s: PStream, a: TAny, stored: var TIntSet) =
var x = getString(a)
if IsNil(x): s.write("null")
else: s.write(escapeJson(x))
- of akInt..akInt64: s.write($getBiggestInt(a))
+ of akInt..akInt64, akUInt..akUInt64: s.write($getBiggestInt(a))
of akFloat..akFloat128: s.write($getBiggestFloat(a))
proc loadAny(p: var TJsonParser, a: TAny, t: var TTable[biggestInt, pointer]) =
@@ -128,18 +128,18 @@ proc loadAny(p: var TJsonParser, a: TAny, t: var TTable[biggestInt, pointer]) =
next(p)
of jsonArrayStart:
next(p)
- invokeNewSeq(a, 0)
- var i = 0
+ invokeNewSeq(a, 0)
+ var i = 0
while p.kind != jsonArrayEnd and p.kind != jsonEof:
- extendSeq(a)
+ extendSeq(a)
loadAny(p, a[i], t)
inc(i)
if p.kind == jsonArrayEnd: next(p)
else: raiseParseErr(p, "")
- else:
+ else:
raiseParseErr(p, "'[' expected for a seq")
of akObject, akTuple:
- if a.kind == akObject: setObjectRuntimeType(a)
+ if a.kind == akObject: setObjectRuntimeType(a)
if p.kind != jsonObjectStart: raiseParseErr(p, "'{' expected for an object")
next(p)
while p.kind != jsonObjectEnd and p.kind != jsonEof:
@@ -169,13 +169,13 @@ proc loadAny(p: var TJsonParser, a: TAny, t: var TTable[biggestInt, pointer]) =
next(p)
of jsonArrayStart:
next(p)
- if a.kind == akRef: invokeNew(a)
- else: setPointer(a, alloc0(a.baseTypeSize))
- if p.kind == jsonInt:
- t[p.getInt] = getPointer(a)
- next(p)
- else: raiseParseErr(p, "index for ref type expected")
- loadAny(p, a[], t)
+ if a.kind == akRef: invokeNew(a)
+ else: setPointer(a, alloc0(a.baseTypeSize))
+ if p.kind == jsonInt:
+ t[p.getInt] = getPointer(a)
+ next(p)
+ else: raiseParseErr(p, "index for ref type expected")
+ loadAny(p, a[], t)
if p.kind == jsonArrayEnd: next(p)
else: raiseParseErr(p, "']' end of ref-address pair expected")
else: raiseParseErr(p, "int for pointer type expected")
@@ -197,7 +197,7 @@ proc loadAny(p: var TJsonParser, a: TAny, t: var TTable[biggestInt, pointer]) =
setString(a, p.str)
next(p)
else: raiseParseErr(p, "string expected")
- of akInt..akInt64:
+ of akInt..akInt64, akUInt..akUInt64:
if p.kind == jsonInt:
setBiggestInt(a, getInt(p))
next(p)
@@ -208,7 +208,7 @@ proc loadAny(p: var TJsonParser, a: TAny, t: var TTable[biggestInt, pointer]) =
setBiggestFloat(a, getFloat(p))
next(p)
return
- raiseParseErr(p, "float expected")
+ raiseParseErr(p, "float expected")
of akRange: loadAny(p, a.skipRange, t)
proc loadAny(s: PStream, a: TAny, t: var TTable[biggestInt, pointer]) =
@@ -220,7 +220,7 @@ proc loadAny(s: PStream, a: TAny, t: var TTable[biggestInt, pointer]) =
proc load*[T](s: PStream, data: var T) =
## loads `data` from the stream `s`. Raises `EIO` in case of an error.
- var tab = initTable[biggestInt, pointer]()
+ var tab = initTable[biggestInt, pointer]()
loadAny(s, toAny(data), tab)
proc store*[T](s: PStream, data: T) =
@@ -229,91 +229,91 @@ proc store*[T](s: PStream, data: T) =
var d: T
shallowCopy(d, data)
storeAny(s, toAny(d), stored)
-
-proc `$$`*[T](x: T): string =
- ## returns a string representation of `x`.
+
+proc `$$`*[T](x: T): string =
+ ## returns a string representation of `x`.
var stored = initIntSet()
var d: T
shallowCopy(d, x)
- var s = newStringStream()
+ var s = newStringStream()
storeAny(s, toAny(d), stored)
- result = s.data
-
-proc to*[T](data: string): T =
- ## reads data and transforms it to a ``T``.
- var tab = initTable[biggestInt, pointer]()
+ result = s.data
+
+proc to*[T](data: string): T =
+ ## reads data and transforms it to a ``T``.
+ var tab = initTable[biggestInt, pointer]()
loadAny(newStringStream(data), toAny(result), tab)
-when isMainModule:
- template testit(x: expr) = echo($$to[type(x)]($$x))
-
+when isMainModule:
+ template testit(x: expr) = echo($$to[type(x)]($$x))
+
var x: array[0..4, array[0..4, string]] = [
["test", "1", "2", "3", "4"], ["test", "1", "2", "3", "4"],
["test", "1", "2", "3", "4"], ["test", "1", "2", "3", "4"],
["test", "1", "2", "3", "4"]]
testit(x)
- var test2: tuple[name: string, s: int] = ("tuple test", 56)
- testit(test2)
-
- type
- TE = enum
- blah, blah2
-
- TestObj = object
- test, asd: int
- case test2: TE
- of blah:
- help: string
- else:
- nil
-
- PNode = ref TNode
- TNode = object
- next, prev: PNode
- data: string
-
- proc buildList(): PNode =
- new(result)
- new(result.next)
- new(result.prev)
- result.data = "middle"
- result.next.data = "next"
- result.prev.data = "prev"
- result.next.next = result.prev
- result.next.prev = result
- result.prev.next = result
- result.prev.prev = result.next
-
- var test3: TestObj
- test3.test = 42
- test3.test2 = blah
- testit(test3)
-
- var test4: ref tuple[a, b: string]
- new(test4)
- test4.a = "ref string test: A"
- test4.b = "ref string test: B"
- testit(test4)
-
- var test5 = @[(0,1),(2,3),(4,5)]
- testit(test5)
-
- var test6: set[char] = {'A'..'Z', '_'}
- testit(test6)
-
- var test7 = buildList()
- echo($$test7)
- testit(test7)
-
- type
- TA = object
- TB = object of TA
- f: int
-
- var
- a: ref TA
- b: ref TB
- new(b)
- a = b
+ var test2: tuple[name: string, s: int] = ("tuple test", 56)
+ testit(test2)
+
+ type
+ TE = enum
+ blah, blah2
+
+ TestObj = object
+ test, asd: int
+ case test2: TE
+ of blah:
+ help: string
+ else:
+ nil
+
+ PNode = ref TNode
+ TNode = object
+ next, prev: PNode
+ data: string
+
+ proc buildList(): PNode =
+ new(result)
+ new(result.next)
+ new(result.prev)
+ result.data = "middle"
+ result.next.data = "next"
+ result.prev.data = "prev"
+ result.next.next = result.prev
+ result.next.prev = result
+ result.prev.next = result
+ result.prev.prev = result.next
+
+ var test3: TestObj
+ test3.test = 42
+ test3.test2 = blah
+ testit(test3)
+
+ var test4: ref tuple[a, b: string]
+ new(test4)
+ test4.a = "ref string test: A"
+ test4.b = "ref string test: B"
+ testit(test4)
+
+ var test5 = @[(0,1),(2,3),(4,5)]
+ testit(test5)
+
+ var test6: set[char] = {'A'..'Z', '_'}
+ testit(test6)
+
+ var test7 = buildList()
+ echo($$test7)
+ testit(test7)
+
+ type
+ TA = object
+ TB = object of TA
+ f: int
+
+ var
+ a: ref TA
+ b: ref TB
+ new(b)
+ a = b
echo($$a[]) # produces "{}", not "{f: 0}"
-
+
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index 6a1fc00634..6f3135d133 100755
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -186,10 +186,12 @@ when not defined(ECMAScript):
proc trunc*(x: float): float {.importc: "trunc", nodecl.}
proc floor*(x: float): float {.importc: "floor", nodecl.}
+ proc ceil*(x: float): float {.importc: "ceil", nodecl.}
else:
proc mathrandom(): float {.importc: "Math.random", nodecl.}
proc floor*(x: float): float {.importc: "Math.floor", nodecl.}
+ proc ceil*(x: float): float {.importc: "Math.ceil", nodecl.}
proc random*(max: int): int = return int(floor(mathrandom() * float(max)))
proc randomize*() = nil
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index 570bf3e8a4..19a2fc7116 100755
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -1346,11 +1346,15 @@ when defined(linux) or defined(solaris) or defined(bsd) or defined(aix):
setlen(result, len)
when defined(macosx):
+ type
+ cuint32* {.importc: "unsigned int", nodecl.} = int
+ ## This is the same as the type ``uint32_t`` in *C*.
+
# a really hacky solution: since we like to include 2 headers we have to
# define two procs which in reality are the same
- proc getExecPath1(c: cstring, size: var int32) {.
+ proc getExecPath1(c: cstring, size: var cuint32) {.
importc: "_NSGetExecutablePath", header: "".}
- proc getExecPath2(c: cstring, size: var int32): bool {.
+ proc getExecPath2(c: cstring, size: var cuint32): bool {.
importc: "_NSGetExecutablePath", header: "".}
proc getAppFilename*(): string {.rtl, extern: "nos$1".} =
@@ -1379,7 +1383,7 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1".} =
elif defined(bsd):
result = getApplAux("/proc/" & $getpid() & "/file")
elif defined(macosx):
- var size: int32
+ var size: cuint32
getExecPath1(nil, size)
result = newString(int(size))
if getExecPath2(result, size):
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index 2807743fe9..808c0735e9 100755
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -123,7 +123,7 @@ when defined(macosx) or defined(bsd):
HW_AVAILCPU = 25
HW_NCPU = 3
proc sysctl(x: ptr array[0..3, cint], y: cint, z: pointer,
- a: var int, b: pointer, c: int): cint {.
+ a: var csize, b: pointer, c: int): cint {.
importc: "sysctl", header: "".}
proc countProcessors*(): int {.rtl, extern: "nosp$1".} =
@@ -135,7 +135,8 @@ proc countProcessors*(): int {.rtl, extern: "nosp$1".} =
elif defined(macosx) or defined(bsd):
var
mib: array[0..3, cint]
- len, numCPU: int
+ numCPU: int
+ len: csize
mib[0] = CTL_HW
mib[1] = HW_AVAILCPU
len = sizeof(numCPU)
diff --git a/lib/pure/smtp.nim b/lib/pure/smtp.nim
index 7eeb026d3f..58c1d4b586 100755
--- a/lib/pure/smtp.nim
+++ b/lib/pure/smtp.nim
@@ -25,20 +25,17 @@
## smtp.sendmail("username@gmail.com", @["foo@gmail.com"], $msg)
##
##
-## For SSL support this module relies on the SSL module. If you want to
-## disable SSL, compile with ``-d:NoSSL``.
+## For SSL support this module relies on OpenSSL. If you want to
+## enable SSL, compile with ``-d:ssl``.
+
+when not defined(ssl):
+ {.error: "The SMTP module should be compiled with SSL support. Compile with -d:ssl."}
import sockets, strutils, strtabs, base64, os
-when not defined(noSSL):
- import ssl
-
type
TSMTP* {.final.} = object
sock: TSocket
- when not defined(noSSL):
- sslSock: TSecureSocket
- ssl: Bool
debug: Bool
TMessage* {.final.} = object
@@ -53,20 +50,13 @@ type
proc debugSend(smtp: TSMTP, cmd: string) =
if smtp.debug:
echo("C:" & cmd)
- if not smtp.ssl:
- smtp.sock.send(cmd)
- else:
- when not defined(noSSL):
- smtp.sslSock.send(cmd)
+ smtp.sock.send(cmd)
-proc debugRecv(smtp: TSMTP): TaintedString =
+proc debugRecv(smtp: var TSMTP): TaintedString =
var line = TaintedString""
var ret = False
- if not smtp.ssl:
- ret = smtp.sock.recvLine(line)
- else:
- when not defined(noSSL):
- ret = smtp.sslSock.recvLine(line)
+ ret = smtp.sock.recvLine(line)
+
if ret:
if smtp.debug:
echo("S:" & line.string)
@@ -79,7 +69,7 @@ proc quitExcpt(smtp: TSMTP, msg: string) =
smtp.debugSend("QUIT")
raise newException(EInvalidReply, msg)
-proc checkReply(smtp: TSMTP, reply: string) =
+proc checkReply(smtp: var TSMTP, reply: string) =
var line = smtp.debugRecv()
if not line.string.startswith(reply):
quitExcpt(smtp, "Expected " & reply & " reply, got: " & line.string)
@@ -88,25 +78,21 @@ proc connect*(address: string, port = 25,
ssl = false, debug = false): TSMTP =
## Establishes a connection with a SMTP server.
## May fail with EInvalidReply or with a socket error.
-
- if not ssl:
- result.sock = socket()
- result.sock.connect(address, TPort(port))
- else:
- when not defined(noSSL):
- result.ssl = True
- discard result.sslSock.connect(address, port)
+ result.sock = socket()
+ if ssl:
+ when defined(ssl):
+ result.sock.wrapSocket(verifyMode = CVerifyNone)
else:
- raise newException(EInvalidReply,
+ raise newException(ESystem,
"SMTP module compiled without SSL support")
-
+ result.sock.connect(address, TPort(port))
result.debug = debug
result.checkReply("220")
result.debugSend("HELO " & address & "\c\L")
result.checkReply("250")
-proc auth*(smtp: TSMTP, username, password: string) =
+proc auth*(smtp: var TSMTP, username, password: string) =
## Sends an AUTH command to the server to login as the `username`
## using `password`.
## May fail with EInvalidReply.
@@ -120,7 +106,7 @@ proc auth*(smtp: TSMTP, username, password: string) =
smtp.debugSend(encode(password) & "\c\L")
smtp.checkReply("235") # Check whether the authentification was successful.
-proc sendmail*(smtp: TSMTP, fromaddr: string,
+proc sendmail*(smtp: var TSMTP, fromaddr: string,
toaddrs: seq[string], msg: string) =
## Sends `msg` from `fromaddr` to `toaddr`.
## Messages may be formed using ``createMessage`` by converting the
@@ -142,10 +128,7 @@ proc sendmail*(smtp: TSMTP, fromaddr: string,
proc close*(smtp: TSMTP) =
## Disconnects from the SMTP server and closes the socket.
smtp.debugSend("QUIT\c\L")
- if not smtp.ssl:
- smtp.sock.close()
- else:
- smtp.sslSock.close()
+ smtp.sock.close()
proc createMessage*(mSubject, mBody: string, mTo, mCc: seq[string],
otherHeaders: openarray[tuple[name, value: string]]): TMessage =
diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim
index eeec628434..8c15c6adb9 100755
--- a/lib/pure/sockets.nim
+++ b/lib/pure/sockets.nim
@@ -10,11 +10,16 @@
## This module implements a simple portable type-safe sockets layer.
##
## Most procedures raise EOS on error.
-
+##
+## For OpenSSL support compile with ``-d:ssl``. When using SSL be aware that
+## most functions will then raise ``ESSL`` on SSL errors.
import os, parseutils
from times import epochTime
+when defined(ssl):
+ import openssl
+
when defined(Windows):
import winlean
else:
@@ -22,8 +27,40 @@ else:
# Note: The enumerations are mapped to Window's constants.
+when defined(ssl):
+ type
+ ESSL* = object of ESynch
+
+ TSSLCVerifyMode* = enum
+ CVerifyNone, CVerifyPeer
+
+ TSSLProtVersion* = enum
+ protSSLv2, protSSLv3, protTLSv1, protSSLv23
+
+ TSSLOptions* = object
+ verifyMode*: TSSLCVerifyMode
+ certFile*, keyFile*: string
+ protVer*: TSSLprotVersion
+
type
- TSocket* = distinct cint ## socket type
+ TSocketImpl = object ## socket type
+ fd: cint
+ case isBuffered: bool # determines whether this socket is buffered.
+ of true:
+ buffer: array[0..4000, char]
+ currPos: int # current index in buffer
+ bufLen: int # current length of buffer
+ of false: nil
+ when defined(ssl):
+ case isSsl: bool
+ of true:
+ sslHandle: PSSL
+ sslContext: PSSLCTX
+ wrapOptions: TSSLOptions
+ of false: nil
+
+ TSocket* = ref TSocketImpl
+
TPort* = distinct int16 ## port type
TDomain* = enum ## domain, which specifies the protocol family of the
@@ -65,11 +102,15 @@ type
ETimeout* = object of ESynch
-const
- InvalidSocket* = TSocket(-1'i32) ## invalid socket number
+proc newTSocket(fd: int32, isBuff: bool): TSocket =
+ new(result)
+ result.fd = fd
+ result.isBuffered = isBuff
+ if isBuff:
+ result.currPos = 0
-proc `==`*(a, b: TSocket): bool {.borrow.}
- ## ``==`` for sockets.
+let
+ InvalidSocket*: TSocket = nil ## invalid socket
proc `==`*(a, b: TPort): bool {.borrow.}
## ``==`` for ports.
@@ -144,18 +185,111 @@ else:
result = cint(ord(p))
proc socket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM,
- protocol: TProtocol = IPPROTO_TCP): TSocket =
+ protocol: TProtocol = IPPROTO_TCP, buffered = true): TSocket =
## creates a new socket; returns `InvalidSocket` if an error occurs.
when defined(Windows):
- result = TSocket(winlean.socket(ord(domain), ord(typ), ord(protocol)))
+ result = newTSocket(winlean.socket(ord(domain), ord(typ), ord(protocol)), buffered)
else:
- result = TSocket(posix.socket(ToInt(domain), ToInt(typ), ToInt(protocol)))
+ result = newTSocket(posix.socket(ToInt(domain), ToInt(typ), ToInt(protocol)), buffered)
+
+when defined(ssl):
+ CRYPTO_malloc_init()
+ SslLibraryInit()
+ SslLoadErrorStrings()
+ ErrLoadBioStrings()
+ OpenSSL_add_all_algorithms()
+
+ proc SSLError(s = "") =
+ if s != "":
+ raise newException(ESSL, s)
+ let err = ErrGetError()
+ if err == 0:
+ raise newException(ESSL, "An EOF was observed that violates the protocol.")
+ if err == -1:
+ OSError()
+ var errStr = ErrErrorString(err, nil)
+ raise newException(ESSL, $errStr)
+
+ # http://simplestcodings.blogspot.co.uk/2010/08/secure-server-client-using-openssl-in-c.html
+ proc loadCertificates(socket: var TSocket, certFile, keyFile: string) =
+ if certFile != "":
+ if SSLCTXUseCertificateFile(socket.sslContext, certFile,
+ SSL_FILETYPE_PEM) != 1:
+ SSLError()
+ if keyFile != "":
+ if SSL_CTX_use_PrivateKey_file(socket.sslContext, keyFile,
+ SSL_FILETYPE_PEM) != 1:
+ SSLError()
+
+ if SSL_CTX_check_private_key(socket.sslContext) != 1:
+ SSLError("Verification of private key file failed.")
+
+ proc wrapSocket*(socket: var TSocket, protVersion = ProtSSLv23,
+ verifyMode = CVerifyPeer,
+ certFile = "", keyFile = "") =
+ ## Creates a SSL context for ``socket`` and wraps the socket in it.
+ ##
+ ## Protocol version specifies the protocol to use. SSLv2, SSLv3, TLSv1 are
+ ## are available with the addition of ``ProtSSLv23`` which allows for
+ ## compatibility with all of them.
+ ##
+ ## There are currently only two options for verify mode; one is ``CVerifyNone``
+ ## and with it certificates will not be verified the other is ``CVerifyPeer``
+ ## and certificates will be verified for it, ``CVerifyPeer`` is the safest choice.
+ ##
+ ## The last two parameters specify the certificate file path and the key file
+ ## path, a server socket will most likely not work without these.
+ ## Certificates can be generated using the following command:
+ ## ``openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout mycert.pem -out mycert.pem``.
+ ##
+ ## **Warning:** Because SSL is meant to be secure I feel the need to warn you
+ ## that this "wrapper" has not been thorougly tested and is therefore
+ ## most likely very prone to security vulnerabilities.
+
+ socket.isSSL = true
+ socket.wrapOptions.verifyMode = verifyMode
+ socket.wrapOptions.certFile = certFile
+ socket.wrapOptions.keyFile = keyFile
+ socket.wrapOptions.protVer = protVersion
+
+ case protVersion
+ of protSSLv23:
+ socket.sslContext = SSL_CTX_new(SSLv23_method()) # SSlv2,3 and TLS1 support.
+ of protSSLv2:
+ socket.sslContext = SSL_CTX_new(SSLv2_method())
+ of protSSLv3:
+ socket.sslContext = SSL_CTX_new(SSLv3_method())
+ of protTLSv1:
+ socket.sslContext = SSL_CTX_new(TLSv1_method())
+
+ if socket.sslContext.SSLCTXSetCipherList("ALL") != 1:
+ SSLError()
+ case verifyMode
+ of CVerifyPeer:
+ socket.sslContext.SSLCTXSetVerify(SSLVerifyPeer, nil)
+ of CVerifyNone:
+ socket.sslContext.SSLCTXSetVerify(SSLVerifyNone, nil)
+ if socket.sslContext == nil:
+ SSLError()
+
+ socket.loadCertificates(certFile, keyFile)
+
+ socket.sslHandle = SSLNew(socket.sslContext)
+ if socket.sslHandle == nil:
+ SSLError()
+
+ if SSLSetFd(socket.sslHandle, socket.fd) != 1:
+ SSLError()
+
+ proc wrapSocket*(socket: var TSocket, wo: TSSLOptions) =
+ ## A variant of the above with a options object.
+ wrapSocket(socket, wo.protVer, wo.verifyMode, wo.certFile, wo.keyFile)
proc listen*(socket: TSocket, backlog = SOMAXCONN) =
## Marks ``socket`` as accepting connections.
## ``Backlog`` specifies the maximum length of the
## queue of pending connections.
- if listen(cint(socket), cint(backlog)) < 0'i32: OSError()
+ if listen(socket.fd, cint(backlog)) < 0'i32: OSError()
proc invalidIp4(s: string) {.noreturn, noinline.} =
raise newException(EInvalidValue, "invalid ip4 address: " & s)
@@ -208,7 +342,7 @@ proc bindAddr*(socket: TSocket, port = TPort(0), address = "") =
name.sin_family = posix.AF_INET
name.sin_port = sockets.htons(int16(port))
name.sin_addr.s_addr = sockets.htonl(INADDR_ANY)
- if bindSocket(cint(socket), cast[ptr TSockAddr](addr(name)),
+ if bindSocket(socket.fd, cast[ptr TSockAddr](addr(name)),
sizeof(name)) < 0'i32:
OSError()
else:
@@ -218,7 +352,7 @@ proc bindAddr*(socket: TSocket, port = TPort(0), address = "") =
hints.ai_socktype = toInt(SOCK_STREAM)
hints.ai_protocol = toInt(IPPROTO_TCP)
gaiNim(address, port, hints, aiList)
- if bindSocket(cint(socket), aiList.ai_addr, aiList.ai_addrLen) < 0'i32:
+ if bindSocket(socket.fd, aiList.ai_addr, aiList.ai_addrLen) < 0'i32:
OSError()
when false:
@@ -245,22 +379,29 @@ proc getSockName*(socket: TSocket): TPort =
#name.sin_port = htons(cint16(port))
#name.sin_addr.s_addr = htonl(INADDR_ANY)
var namelen: cint = sizeof(name)
- if getsockname(cint(socket), cast[ptr TSockAddr](addr(name)),
+ if getsockname(socket.fd, cast[ptr TSockAddr](addr(name)),
addr(namelen)) == -1'i32:
OSError()
result = TPort(sockets.ntohs(name.sin_port))
-proc acceptAddr*(server: TSocket): tuple[sock: TSocket, address: string] =
+proc selectWrite*(writefds: var seq[TSocket], timeout = 500): int
+
+proc acceptAddr*(server: TSocket): tuple[client: TSocket, address: string] =
## Blocks until a connection is being made from a client. When a connection
- ## is made returns the client socket and address of the connecting client.
+ ## is made sets ``client`` to the client socket and ``address`` to the address
+ ## of the connecting client.
## If ``server`` is non-blocking then this function returns immediately, and
## if there are no connections queued the returned socket will be
## ``InvalidSocket``.
## This function will raise EOS if an error occurs.
- var address: Tsockaddr_in
- var addrLen: cint = sizeof(address)
- var sock = accept(cint(server), cast[ptr TSockAddr](addr(address)),
+ ##
+ ## **Warning:** This function might block even if socket is non-blocking
+ ## when using SSL.
+ var sockAddress: Tsockaddr_in
+ var addrLen: cint = sizeof(sockAddress)
+ var sock = accept(server.fd, cast[ptr TSockAddr](addr(sockAddress)),
addr(addrLen))
+
if sock < 0:
# TODO: Test on Windows.
when defined(windows):
@@ -272,20 +413,54 @@ proc acceptAddr*(server: TSocket): tuple[sock: TSocket, address: string] =
if errno == EAGAIN or errno == EWOULDBLOCK:
return (InvalidSocket, "")
else: OSError()
- else: return (TSocket(sock), $inet_ntoa(address.sin_addr))
+ else:
+ when defined(ssl):
+ if server.isSSL:
+ # We must wrap the client sock in a ssl context.
+ var client = newTSocket(sock, server.isBuffered)
+ let wo = server.wrapOptions
+ wrapSocket(client, wo.protVer, wo.verifyMode,
+ wo.certFile, wo.keyFile)
+ let ret = SSLAccept(client.sslHandle)
+ while ret <= 0:
+ let err = SSLGetError(client.sslHandle, ret)
+ if err != SSL_ERROR_WANT_ACCEPT:
+ case err
+ of SSL_ERROR_ZERO_RETURN:
+ SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.")
+ of SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_CONNECT:
+ SSLError("The operation did not complete. Perhaps you should use connectAsync?")
+ of SSL_ERROR_WANT_ACCEPT:
+ var sss: seq[TSocket] = @[client]
+ discard selectWrite(sss, 1500)
+ continue
+ of SSL_ERROR_WANT_X509_LOOKUP:
+ SSLError("Function for x509 lookup has been called.")
+ of SSL_ERROR_SYSCALL, SSL_ERROR_SSL:
+ SSLError()
+ else:
+ SSLError("Unknown error")
+ return (client, $inet_ntoa(sockAddress.sin_addr))
+ return (newTSocket(sock, server.isBuffered), $inet_ntoa(sockAddress.sin_addr))
proc accept*(server: TSocket): TSocket =
## Equivalent to ``acceptAddr`` but doesn't return the address, only the
## socket.
- var (client, a) = acceptAddr(server)
+ let (client, a) = acceptAddr(server)
return client
proc close*(socket: TSocket) =
## closes a socket.
when defined(windows):
- discard winlean.closeSocket(cint(socket))
+ discard winlean.closeSocket(socket.fd)
else:
- discard posix.close(cint(socket))
+ discard posix.close(socket.fd)
+
+ when defined(ssl):
+ if socket.isSSL:
+ discard SSLShutdown(socket.sslHandle)
+
+ SSLCTXFree(socket.sslContext)
proc getServByName*(name, proto: string): TServent =
## well-known getservbyname proc.
@@ -365,7 +540,7 @@ proc getSockOptInt*(socket: TSocket, level, optname: int): int =
## getsockopt for integer options.
var res: cint
var size: cint = sizeof(res)
- if getsockopt(cint(socket), cint(level), cint(optname),
+ if getsockopt(socket.fd, cint(level), cint(optname),
addr(res), addr(size)) < 0'i32:
OSError()
result = int(res)
@@ -373,7 +548,7 @@ proc getSockOptInt*(socket: TSocket, level, optname: int): int =
proc setSockOptInt*(socket: TSocket, level, optname, optval: int) =
## setsockopt for integer options.
var value = cint(optval)
- if setsockopt(cint(socket), cint(level), cint(optname), addr(value),
+ if setsockopt(socket.fd, cint(level), cint(optname), addr(value),
sizeof(value)) < 0'i32:
OSError()
@@ -395,7 +570,7 @@ proc connect*(socket: TSocket, name: string, port = TPort(0),
var success = false
var it = aiList
while it != nil:
- if connect(cint(socket), it.ai_addr, it.ai_addrlen) == 0'i32:
+ if connect(socket.fd, it.ai_addr, it.ai_addrlen) == 0'i32:
success = true
break
it = it.ai_next
@@ -403,6 +578,24 @@ proc connect*(socket: TSocket, name: string, port = TPort(0),
freeaddrinfo(aiList)
if not success: OSError()
+ when defined(ssl):
+ if socket.isSSL:
+ let ret = SSLConnect(socket.sslHandle)
+ if ret <= 0:
+ let err = SSLGetError(socket.sslHandle, ret)
+ case err
+ of SSL_ERROR_ZERO_RETURN:
+ SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.")
+ of SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_CONNECT,
+ SSL_ERROR_WANT_ACCEPT:
+ SSLError("The operation did not complete. Perhaps you should use connectAsync?")
+ of SSL_ERROR_WANT_X509_LOOKUP:
+ SSLError("Function for x509 lookup has been called.")
+ of SSL_ERROR_SYSCALL, SSL_ERROR_SSL:
+ SSLError()
+ else:
+ SSLError("Unknown error")
+
when false:
var s: TSockAddrIn
s.sin_addr.s_addr = inet_addr(name)
@@ -415,7 +608,7 @@ proc connect*(socket: TSocket, name: string, port = TPort(0),
of AF_INET: s.sin_family = posix.AF_INET
of AF_INET6: s.sin_family = posix.AF_INET6
else: nil
- if connect(cint(socket), cast[ptr TSockAddr](addr(s)), sizeof(s)) < 0'i32:
+ if connect(socket.fd, cast[ptr TSockAddr](addr(s)), sizeof(s)) < 0'i32:
OSError()
proc connectAsync*(socket: TSocket, name: string, port = TPort(0),
@@ -431,7 +624,7 @@ proc connectAsync*(socket: TSocket, name: string, port = TPort(0),
var success = false
var it = aiList
while it != nil:
- var ret = connect(cint(socket), it.ai_addr, it.ai_addrlen)
+ var ret = connect(socket.fd, it.ai_addr, it.ai_addrlen)
if ret == 0'i32:
success = true
break
@@ -453,6 +646,26 @@ proc connectAsync*(socket: TSocket, name: string, port = TPort(0),
freeaddrinfo(aiList)
if not success: OSError()
+ when defined(ssl):
+ if socket.isSSL:
+ var ret = SSLConnect(socket.sslHandle)
+ if ret <= 0:
+ var errret = SSLGetError(socket.sslHandle, ret)
+ case errret
+ of SSL_ERROR_ZERO_RETURN:
+ SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.")
+ of SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE,
+ SSL_ERROR_WANT_ACCEPT:
+ SSLError("Unexpected error occured.") # This should just not happen.
+ of SSL_ERROR_WANT_CONNECT:
+ return
+ of SSL_ERROR_WANT_X509_LOOKUP:
+ SSLError("Function for x509 lookup has been called.")
+ of SSL_ERROR_SYSCALL, SSL_ERROR_SSL:
+ SSLError()
+ else:
+ SSLError("Unknown Error")
+
proc timeValFromMilliseconds(timeout = 500): TTimeVal =
if timeout != -1:
var seconds = timeout div 1000
@@ -467,14 +680,14 @@ proc timeValFromMilliseconds(timeout = 500): TTimeVal =
proc createFdSet(fd: var TFdSet, s: seq[TSocket], m: var int) =
FD_ZERO(fd)
for i in items(s):
- m = max(m, int(i))
- FD_SET(cint(i), fd)
+ m = max(m, int(i.fd))
+ FD_SET(i.fd, fd)
proc pruneSocketSet(s: var seq[TSocket], fd: var TFdSet) =
var i = 0
var L = s.len
while i < L:
- if FD_ISSET(cint(s[i]), fd) != 0'i32:
+ if FD_ISSET(s[i].fd, fd) != 0'i32:
s[i] = s[L-1]
dec(L)
else:
@@ -552,34 +765,117 @@ proc select*(readfds: var seq[TSocket], timeout = 500): int =
result = int(select(cint(m+1), addr(rd), nil, nil, nil))
pruneSocketSet(readfds, (rd))
-
+
+proc readIntoBuf(socket: TSocket, flags: int32): int =
+ result = 0
+ when defined(ssl):
+ if socket.isSSL:
+ result = SSLRead(socket.sslHandle, addr(socket.buffer), int(socket.buffer.high))
+ else:
+ result = recv(socket.fd, addr(socket.buffer), int(socket.buffer.high), flags)
+ else:
+ result = recv(socket.fd, addr(socket.buffer), int(socket.buffer.high), flags)
+ if result <= 0:
+ socket.buflen = 0
+ socket.currPos = 0
+ return result
+ socket.bufLen = result
+ socket.currPos = 0
+
+template retRead(flags, readBytes: int) =
+ let res = socket.readIntoBuf(flags)
+ if res <= 0:
+ if readBytes > 0:
+ return readBytes
+ else:
+ return res
+
proc recv*(socket: TSocket, data: pointer, size: int): int =
## receives data from a socket
- result = recv(cint(socket), data, size, 0'i32)
+ if socket.isBuffered:
+ if socket.bufLen == 0:
+ retRead(0'i32, 0)
+
+ when true:
+ var read = 0
+ while read < size:
+ if socket.currPos >= socket.bufLen:
+ retRead(0'i32, read)
+
+ let chunk = min(socket.bufLen-socket.currPos, size-read)
+ var d = cast[cstring](data)
+ copyMem(addr(d[read]), addr(socket.buffer[socket.currPos]), chunk)
+ read.inc(chunk)
+ socket.currPos.inc(chunk)
+ else:
+ var read = 0
+ while read < size:
+ if socket.currPos >= socket.bufLen:
+ retRead(0'i32, read)
+
+ var d = cast[cstring](data)
+ d[read] = socket.buffer[socket.currPos]
+ read.inc(1)
+ socket.currPos.inc(1)
+
+ result = read
+ else:
+ when defined(ssl):
+ if socket.isSSL:
+ result = SSLRead(socket.sslHandle, data, size)
+ else:
+ result = recv(socket.fd, data, size, 0'i32)
+ else:
+ result = recv(socket.fd, data, size, 0'i32)
-template waitFor(): stmt =
- if timeout - int(waited * 1000.0) < 1:
- raise newException(ETimeout, "Call to recv() timed out.")
- var s = @[socket]
- var startTime = epochTime()
- if select(s, timeout - int(waited * 1000.0)) != 1:
- raise newException(ETimeout, "Call to recv() timed out.")
- waited += (epochTime() - startTime)
+proc waitFor(socket: TSocket, waited: var float, timeout: int): int =
+ ## returns the number of characters available to be read. In unbuffered
+ ## sockets this is always 1, otherwise this may as big as the buffer, currently
+ ## 4000.
+ result = 1
+ if socket.isBuffered and socket.bufLen != 0 and socket.bufLen != socket.currPos:
+ result = socket.bufLen - socket.currPos
+ else:
+ if timeout - int(waited * 1000.0) < 1:
+ raise newException(ETimeout, "Call to recv() timed out.")
+ var s = @[socket]
+ var startTime = epochTime()
+ if select(s, timeout - int(waited * 1000.0)) != 1:
+ raise newException(ETimeout, "Call to recv() timed out.")
+ waited += (epochTime() - startTime)
-proc recv*(socket: TSocket, data: var string, size: int, timeout: int): int =
+proc recv*(socket: TSocket, data: pointer, size: int, timeout: int): int =
## overload with a ``timeout`` parameter in miliseconds.
var waited = 0.0 # number of seconds already waited
var read = 0
while read < size:
- waitFor()
- result = recv(cint(socket), addr(data[read]), 1, 0'i32)
+ let avail = waitFor(socket, waited, timeout)
+ var d = cast[cstring](data)
+ result = recv(socket, addr(d[read]), avail)
+ if result == 0: break
if result < 0:
- return
- inc(read)
+ return result
+ inc(read, result)
result = read
+proc peekChar(socket: TSocket, c: var char): int =
+ if socket.isBuffered:
+ result = 1
+ if socket.bufLen == 0 or socket.currPos > socket.bufLen-1:
+ var res = socket.readIntoBuf(0'i32)
+ if res <= 0:
+ result = res
+
+ c = socket.buffer[socket.currPos]
+ else:
+ when defined(ssl):
+ if socket.isSSL:
+ raise newException(ESSL, "Sorry, you cannot use recvLine on an unbuffered SSL socket.")
+
+ result = recv(socket.fd, addr(c), 1, MSG_PEEK)
+
proc recvLine*(socket: TSocket, line: var TaintedString): bool =
## retrieves a line from ``socket``. If a full line is received ``\r\L`` is not
## added to ``line``, however if solely ``\r\L`` is received then ``data``
@@ -590,6 +886,9 @@ proc recvLine*(socket: TSocket, line: var TaintedString): bool =
##
## If the socket is disconnected, ``line`` will be set to ``""`` and ``True``
## will be returned.
+ ##
+ ## **Warning:** Using this function on a unbuffered ssl socket will result
+ ## in an error.
template addNLIfEmpty(): stmt =
if line.len == 0:
line.add("\c\L")
@@ -597,13 +896,13 @@ proc recvLine*(socket: TSocket, line: var TaintedString): bool =
setLen(line.string, 0)
while true:
var c: char
- var n = recv(cint(socket), addr(c), 1, 0'i32)
+ var n = recv(socket, addr(c), 1)
if n < 0: return
elif n == 0: return true
if c == '\r':
- n = recv(cint(socket), addr(c), 1, MSG_PEEK)
+ n = peekChar(socket, c)
if n > 0 and c == '\L':
- discard recv(cint(socket), addr(c), 1, 0'i32)
+ discard recv(socket, addr(c), 1)
elif n <= 0: return false
addNlIfEmpty()
return true
@@ -624,15 +923,15 @@ proc recvLine*(socket: TSocket, line: var TaintedString, timeout: int): bool =
setLen(line.string, 0)
while true:
var c: char
- waitFor()
- var n = recv(cint(socket), addr(c), 1, 0'i32)
+ discard waitFor(socket, waited, timeout)
+ var n = recv(socket, addr(c), 1)
if n < 0: return
elif n == 0: return true
if c == '\r':
- waitFor()
- n = recv(cint(socket), addr(c), 1, MSG_PEEK)
+ discard waitFor(socket, waited, timeout)
+ n = peekChar(socket, c)
if n > 0 and c == '\L':
- discard recv(cint(socket), addr(c), 1, 0'i32)
+ discard recv(socket, addr(c), 1)
elif n <= 0: return false
addNlIfEmpty()
return true
@@ -651,15 +950,15 @@ proc recvLineAsync*(socket: TSocket, line: var TaintedString): TRecvLineResult =
setLen(line.string, 0)
while true:
var c: char
- var n = recv(cint(socket), addr(c), 1, 0'i32)
+ var n = recv(socket, addr(c), 1)
if n < 0:
return (if line.len == 0: RecvFail else: RecvPartialLine)
elif n == 0:
return (if line.len == 0: RecvDisconnected else: RecvPartialLine)
if c == '\r':
- n = recv(cint(socket), addr(c), 1, MSG_PEEK)
+ n = peekChar(socket, c)
if n > 0 and c == '\L':
- discard recv(cint(socket), addr(c), 1, 0'i32)
+ discard recv(socket, addr(c), 1)
elif n <= 0:
return (if line.len == 0: RecvFail else: RecvPartialLine)
return RecvFullLine
@@ -671,7 +970,7 @@ proc recv*(socket: TSocket): TaintedString =
## Socket errors will result in an ``EOS`` error.
## If socket is not a connectionless socket and socket is not connected
## ``""`` will be returned.
- const bufSize = 1000
+ const bufSize = 4000
result = newStringOfCap(bufSize).TaintedString
var pos = 0
while true:
@@ -699,9 +998,10 @@ proc recvTimeout*(socket: TSocket, timeout: int): TaintedString =
## overloaded variant to support a ``timeout`` parameter, the ``timeout``
## parameter specifies the amount of miliseconds to wait for data on the
## socket.
- var s = @[socket]
- if s.select(timeout) != 1:
- raise newException(ETimeout, "Call to recv() timed out.")
+ if socket.bufLen == 0:
+ var s = @[socket]
+ if s.select(timeout) != 1:
+ raise newException(ETimeout, "Call to recv() timed out.")
return socket.recv
@@ -718,7 +1018,24 @@ proc recvAsync*(socket: TSocket, s: var TaintedString): bool =
var pos = 0
while true:
var bytesRead = recv(socket, addr(string(s)[pos]), bufSize-1)
- if bytesRead == -1:
+ when defined(ssl):
+ if socket.isSSL:
+ if bytesRead <= 0:
+ var ret = SSLGetError(socket.sslHandle, bytesRead)
+ case ret
+ of SSL_ERROR_ZERO_RETURN:
+ SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.")
+ of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT:
+ SSLError("Unexpected error occured.") # This should just not happen.
+ of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ:
+ return false
+ of SSL_ERROR_WANT_X509_LOOKUP:
+ SSLError("Function for x509 lookup has been called.")
+ of SSL_ERROR_SYSCALL, SSL_ERROR_SSL:
+ SSLError()
+ else: SSLError("Unknown Error")
+
+ if bytesRead == -1 and not (when defined(ssl): socket.isSSL else: false):
when defined(windows):
# TODO: Test on Windows
var err = WSAGetLastError()
@@ -746,19 +1063,46 @@ proc skip*(socket: TSocket) =
proc send*(socket: TSocket, data: pointer, size: int): int =
## sends data to a socket.
+ when defined(ssl):
+ if socket.isSSL:
+ return SSLWrite(socket.sslHandle, cast[cstring](data), size)
+
when defined(windows) or defined(macosx):
- result = send(cint(socket), data, size, 0'i32)
+ result = send(socket.fd, data, size, 0'i32)
else:
- result = send(cint(socket), data, size, int32(MSG_NOSIGNAL))
+ result = send(socket.fd, data, size, int32(MSG_NOSIGNAL))
proc send*(socket: TSocket, data: string) =
## sends data to a socket.
- if send(socket, cstring(data), data.len) != data.len: OSError()
+ if send(socket, cstring(data), data.len) != data.len:
+ when defined(ssl):
+ if socket.isSSL:
+ SSLError()
+
+ OSError()
proc sendAsync*(socket: TSocket, data: string): bool =
## sends data to a non-blocking socket. Returns whether ``data`` was sent.
result = true
var bytesSent = send(socket, cstring(data), data.len)
+ when defined(ssl):
+ if socket.isSSL:
+ if bytesSent <= 0:
+ let ret = SSLGetError(socket.sslHandle, bytesSent)
+ case ret
+ of SSL_ERROR_ZERO_RETURN:
+ SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.")
+ of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT:
+ SSLError("Unexpected error occured.") # This should just not happen.
+ of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ:
+ return false
+ of SSL_ERROR_WANT_X509_LOOKUP:
+ SSLError("Function for x509 lookup has been called.")
+ of SSL_ERROR_SYSCALL, SSL_ERROR_SSL:
+ SSLError()
+ else: SSLError("Unknown Error")
+ else:
+ return
if bytesSent == -1:
when defined(windows):
var err = WSAGetLastError()
@@ -792,15 +1136,15 @@ proc setBlocking*(s: TSocket, blocking: bool) =
## sets blocking mode on socket
when defined(Windows):
var mode = clong(ord(not blocking)) # 1 for non-blocking, 0 for blocking
- if SOCKET_ERROR == ioctlsocket(TWinSocket(s), FIONBIO, addr(mode)):
+ if SOCKET_ERROR == ioctlsocket(TWinSocket(s.fd), FIONBIO, addr(mode)):
OSError()
else: # BSD sockets
- var x: int = fcntl(cint(s), F_GETFL, 0)
+ var x: int = fcntl(s.fd, F_GETFL, 0)
if x == -1:
OSError()
else:
var mode = if blocking: x and not O_NONBLOCK else: x or O_NONBLOCK
- if fcntl(cint(s), F_SETFL, mode) == -1:
+ if fcntl(s.fd, F_SETFL, mode) == -1:
OSError()
proc connect*(socket: TSocket, timeout: int, name: string, port = TPort(0),
diff --git a/lib/pure/times.nim b/lib/pure/times.nim
index 4cb873b1ca..eded16d21d 100755
--- a/lib/pure/times.nim
+++ b/lib/pure/times.nim
@@ -557,9 +557,9 @@ proc format*(info: TTimeInfo, f: string): string =
result.add("0")
result.add($info.monthday)
of "ddd":
- result.add(($info.monthday)[0 .. 2])
+ result.add(($info.weekday)[0 .. 2])
of "dddd":
- result.add($info.monthday)
+ result.add($info.weekday)
of "h":
result.add($(info.hour - 12))
of "hh":
diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim
index e11cd5fe34..f76573788b 100644
--- a/lib/pure/unicode.nim
+++ b/lib/pure/unicode.nim
@@ -18,9 +18,9 @@ type
TRune* = distinct irune ## type that can hold any Unicode character
TRune16* = distinct int16 ## 16 bit Unicode character
-proc `<=%`*(a, b: TRune): bool {.borrow.}
-proc `<%`*(a, b: TRune): bool {.borrow.}
-proc `==`*(a, b: TRune): bool {.borrow.}
+proc `<=%`*(a, b: TRune): bool = return int(a) <=% int(b)
+proc `<%`*(a, b: TRune): bool = return int(a) <% int(b)
+proc `==`*(a, b: TRune): bool = return int(a) == int(b)
template ones(n: expr): expr = ((1 shl n)-1)
diff --git a/lib/system.nim b/lib/system.nim
index c8166bc10b..fe8f7a5172 100755
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -21,9 +21,15 @@ type
int16* {.magic: Int16.} ## signed 16 bit integer type
int32* {.magic: Int32.} ## signed 32 bit integer type
int64* {.magic: Int64.} ## signed 64 bit integer type
+ uint* {.magic: UInt.} ## unsigned default integer type
+ uint8* {.magic: UInt8.} ## unsigned 8 bit integer type
+ uint16* {.magic: UInt16.} ## unsigned 16 bit integer type
+ uint32* {.magic: UInt32.} ## unsigned 32 bit integer type
+ uint64* {.magic: UInt64.} ## unsigned 64 bit integer type
float* {.magic: Float.} ## default floating point type
float32* {.magic: Float32.} ## 32 bit floating point type
float64* {.magic: Float64.} ## 64 bit floating point type
+
type # we need to start a new type section here, so that ``0`` can have a type
bool* {.magic: Bool.} = enum ## built-in boolean type
false = 0, true = 1
@@ -49,14 +55,23 @@ type
## a type description (for templates)
void* {.magic: "VoidType".} ## meta type to denote the absense of any type
- TInteger* = int|int8|int16|int32|int64
+ TSignedInt* = distinct int|int8|int16|int32|int64
+ ## type class matching all signed integer types
+
+ TUnsignedInt* = distinct uint|uint8|uint16|uint32|uint64
+ ## type class matching all unsigned integer types
+
+ TInteger* = distinct TSignedInt|TUnsignedInt
## type class matching all integer types
- TOrdinal* = TInteger|bool|enum
+ TOrdinal* = distinct TInteger|bool|enum
## type class matching all ordinal types; however this includes enums with
## holes.
+
+ TReal* = distinct float|float32|float64
+ ## type class matching all floating point number types
- TNumber* = TInteger|float|float32|float64
+ TNumber* = distinct TInteger|TReal
## type class matching all number types
proc defined*(x: expr): bool {.magic: "Defined", noSideEffect.}
@@ -517,65 +532,88 @@ proc abs*(x: int64): int64 {.magic: "AbsI64", noSideEffect.}
## is -MININT for its type), an overflow exception is thrown (if overflow
## checking is turned on).
-proc `+%` *(x, y: int): int {.magic: "AddU", noSideEffect.}
-proc `+%` *(x, y: int8): int8 {.magic: "AddU", noSideEffect.}
-proc `+%` *(x, y: int16): int16 {.magic: "AddU", noSideEffect.}
-proc `+%` *(x, y: int32): int32 {.magic: "AddU", noSideEffect.}
-proc `+%` *(x, y: int64): int64 {.magic: "AddU64", noSideEffect.}
+type
+ UIntMax32 = distinct uint|uint8|uint16|uint32
+ IntMax32 = distinct int|int8|int16|int32
+
+proc `+` *(x, y: UIntMax32): UIntMax32 {.magic: "AddU", noSideEffect.}
+proc `+` *(x, y: UInt64): uint64 {.magic: "AddU64", noSideEffect.}
+ ## Binary `+` operator for unsigned integers.
+
+proc `+%` *(x, y: IntMax32): IntMax32 {.magic: "AddU", noSideEffect.}
+proc `+%` *(x, y: Int64): Int64 {.magic: "AddU64", 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: int): int {.magic: "SubU", noSideEffect.}
-proc `-%` *(x, y: int8): int8 {.magic: "SubU", noSideEffect.}
-proc `-%` *(x, y: int16): int16 {.magic: "SubU", noSideEffect.}
-proc `-%` *(x, y: int32): int32 {.magic: "SubU", noSideEffect.}
-proc `-%` *(x, y: int64): int64 {.magic: "SubU64", noSideEffect.}
+proc `-` *(x, y: UIntMax32): UIntMax32 {.magic: "SubU", noSideEffect.}
+proc `-` *(x, y: UInt64): UInt64 {.magic: "SubU64", noSideEffect.}
+ ## Binary `-` operator for unsigned integers.
+
+proc `-%` *(x, y: IntMax32): IntMax32 {.magic: "SubU", noSideEffect.}
+proc `-%` *(x, y: Int64): Int64 {.magic: "SubU64", 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: int): int {.magic: "MulU", noSideEffect.}
-proc `*%` *(x, y: int8): int8 {.magic: "MulU", noSideEffect.}
-proc `*%` *(x, y: int16): int16 {.magic: "MulU", noSideEffect.}
-proc `*%` *(x, y: int32): int32 {.magic: "MulU", noSideEffect.}
-proc `*%` *(x, y: int64): int64 {.magic: "MulU64", noSideEffect.}
+proc `*` *(x, y: UIntMax32): UIntMax32 {.magic: "MulU", noSideEffect.}
+proc `*` *(x, y: UInt64): UInt64 {.magic: "MulU64", noSideEffect.}
+ ## Binary `*` operator for unsigned integers.
+
+proc `*%` *(x, y: IntMax32): IntMax32 {.magic: "MulU", noSideEffect.}
+proc `*%` *(x, y: Int64): Int64 {.magic: "MulU64", 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: int): int {.magic: "DivU", noSideEffect.}
-proc `/%` *(x, y: int8): int8 {.magic: "DivU", noSideEffect.}
-proc `/%` *(x, y: int16): int16 {.magic: "DivU", noSideEffect.}
-proc `/%` *(x, y: int32): int32 {.magic: "DivU", noSideEffect.}
-proc `/%` *(x, y: int64): int64 {.magic: "DivU64", noSideEffect.}
+proc `div` *(x, y: UIntMax32): UIntMax32 {.magic: "DivU", noSideEffect.}
+proc `div` *(x, y: UInt64): UInt64 {.magic: "DivU64", noSideEffect.}
+ ## computes the integer division. This is roughly the same as
+ ## ``floor(x/y)``.
+
+proc `/` *(x, y: UIntMax32): UIntMax32 {.magic: "DivU", noSideEffect.}
+proc `/` *(x, y: UInt64): UInt64 {.magic: "DivU64", noSideEffect.}
+ ## computes the integer division. This is roughly the same as
+ ## ``floor(x/y)``.
+
+proc `/%` *(x, y: IntMax32): IntMax32 {.magic: "DivU", noSideEffect.}
+proc `/%` *(x, y: Int64): Int64 {.magic: "DivU64", 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: int): int {.magic: "ModU", noSideEffect.}
-proc `%%` *(x, y: int8): int8 {.magic: "ModU", noSideEffect.}
-proc `%%` *(x, y: int16): int16 {.magic: "ModU", noSideEffect.}
-proc `%%` *(x, y: int32): int32 {.magic: "ModU", noSideEffect.}
-proc `%%` *(x, y: int64): int64 {.magic: "ModU64", noSideEffect.}
+proc `%` *(x, y: UIntMax32): UIntMax32 {.magic: "DivU", noSideEffect.}
+proc `%` *(x, y: UInt64): UInt64 {.magic: "DivU64", noSideEffect.}
+ ## computes the integer modulo operation. This is the same as
+ ## ``x - (x div y) * y``.
+
+proc `mod` *(x, y: UIntMax32): UIntMax32 {.magic: "DivU", noSideEffect.}
+proc `mod` *(x, y: UInt64): UInt64 {.magic: "DivU64", noSideEffect.}
+ ## computes the integer modulo operation. This is the same as
+ ## ``x - (x div y) * y``.
+
+proc `%%` *(x, y: IntMax32): IntMax32 {.magic: "ModU", noSideEffect.}
+proc `%%` *(x, y: Int64): Int64 {.magic: "ModU64", 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: int): bool {.magic: "LeU", noSideEffect.}
-proc `<=%` *(x, y: int8): bool {.magic: "LeU", noSideEffect.}
-proc `<=%` *(x, y: int16): bool {.magic: "LeU", noSideEffect.}
-proc `<=%` *(x, y: int32): bool {.magic: "LeU", noSideEffect.}
-proc `<=%` *(x, y: int64): bool {.magic: "LeU64", noSideEffect.}
+proc `<=` *(x, y: UIntMax32): bool {.magic: "LeU", noSideEffect.}
+proc `<=` *(x, y: UInt64): bool {.magic: "LeU64", noSideEffect.}
+ ## Returns true iff ``x <= y``.
+
+proc `<=%` *(x, y: IntMax32): bool {.magic: "LeU", 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: int): bool {.magic: "LtU", noSideEffect.}
-proc `<%` *(x, y: int8): bool {.magic: "LtU", noSideEffect.}
-proc `<%` *(x, y: int16): bool {.magic: "LtU", noSideEffect.}
-proc `<%` *(x, y: int32): bool {.magic: "LtU", noSideEffect.}
-proc `<%` *(x, y: int64): bool {.magic: "LtU64", noSideEffect.}
+proc `<` *(x, y: UIntMax32): bool {.magic: "LtU", noSideEffect.}
+proc `<` *(x, y: UInt64): bool {.magic: "LtU64", noSideEffect.}
+ ## Returns true iff ``unsigned(x) < unsigned(y)``.
+
+proc `<%` *(x, y: IntMax32): bool {.magic: "LtU", 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)``.
@@ -935,6 +973,8 @@ type # these work for most platforms:
## This is the same as the type ``short`` in *C*.
cint* {.importc: "int", nodecl.} = int32
## This is the same as the type ``int`` in *C*.
+ csize* {.importc: "size_t", nodecl.} = int
+ ## This is the same as the type ``size_t`` in *C*.
clong* {.importc: "long", nodecl.} = int
## This is the same as the type ``long`` in *C*.
clonglong* {.importc: "long long", nodecl.} = int64
@@ -951,7 +991,7 @@ type # these work for most platforms:
## This is binary compatible to the type ``char**`` in *C*. The array's
## high value is large enough to disable bounds checking in practice.
## Use `cstringArrayToSeq` to convert it into a ``seq[string]``.
-
+
PFloat32* = ptr Float32 ## an alias for ``ptr float32``
PFloat64* = ptr Float64 ## an alias for ``ptr float64``
PInt64* = ptr Int64 ## an alias for ``ptr int64``
diff --git a/lib/system/assign.nim b/lib/system/assign.nim
index 59c44a6cce..f29dc547c7 100755
--- a/lib/system/assign.nim
+++ b/lib/system/assign.nim
@@ -139,6 +139,10 @@ proc objectInit(dest: Pointer, typ: PNimType) =
# ---------------------- assign zero -----------------------------------------
+proc nimDestroyRange*[T](r: T) =
+ # internal proc used for destroying sequences and arrays
+ 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) =
var d = cast[TAddress](dest)
diff --git a/lib/system/hti.nim b/lib/system/hti.nim
index 1d62b910a4..d79679107f 100755
--- a/lib/system/hti.nim
+++ b/lib/system/hti.nim
@@ -37,7 +37,9 @@ type # This should be he same as ast.TTypeKind
tyPointer, tyOpenArray,
tyString, tyCString, tyForward,
tyInt, tyInt8, tyInt16, tyInt32, tyInt64,
- tyFloat, tyFloat32, tyFloat64, tyFloat128
+ tyFloat, tyFloat32, tyFloat64, tyFloat128,
+ tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64,
+ tyBigNum,
TNimNodeKind = enum nkNone, nkSlot, nkList, nkCase
TNimNode {.codegenType, final.} = object
diff --git a/lib/windows/windows.nim b/lib/windows/windows.nim
index d96c2bbed9..9f7fd2d85b 100755
--- a/lib/windows/windows.nim
+++ b/lib/windows/windows.nim
@@ -41,10 +41,6 @@ type # WinNT.h -- Defines the 32-Bit Windows types and constants
type # BaseTsd.h -- Type definitions for the basic sized types
# Give here only the bare minimum, to be expanded as needs arise
- UINT8* = int8
- UINT16* = int16
- UINT32* = int32
- UINT64* = int64
LONG32* = int32
ULONG32* = int32
DWORD32* = int32
@@ -95,7 +91,6 @@ type # WinDef.h -- Basic Windows Type Definitions
LPCVOID* = pointer
# INT* = int # Cannot work and not necessary anyway
- UINT* = int
PUINT* = ptr int
WPARAM* = LONG_PTR
@@ -18518,9 +18513,9 @@ proc DisableThreadLibraryCalls*(hLibModule: HMODULE): WINBOOL{.stdcall,
proc GetProcAddress*(hModule: HINST, lpProcName: LPCSTR): FARPROC{.stdcall,
dynlib: "kernel32", importc: "GetProcAddress".}
proc GetVersion*(): DWORD{.stdcall, dynlib: "kernel32", importc: "GetVersion".}
-proc GlobalAlloc*(uFlags: UINT, dwBytes: DWORD): HGLOBAL{.stdcall,
+proc GlobalAlloc*(uFlags: INT, dwBytes: DWORD): HGLOBAL{.stdcall,
dynlib: "kernel32", importc: "GlobalAlloc".}
-proc GlobalReAlloc*(hMem: HGLOBAL, dwBytes: DWORD, uFlags: UINT): HGLOBAL{.
+proc GlobalReAlloc*(hMem: HGLOBAL, dwBytes: DWORD, uFlags: INT): HGLOBAL{.
stdcall, dynlib: "kernel32", importc: "GlobalReAlloc".}
proc GlobalSize*(hMem: HGLOBAL): DWORD{.stdcall, dynlib: "kernel32",
importc: "GlobalSize".}
@@ -23620,8 +23615,8 @@ proc ListView_SetItemPosition32(hwndLV: HWND, i, x, y: int32): LRESULT =
proc ListView_SetItemState(hwndLV: HWND, i, data, mask: int32): LRESULT =
var gnu_lvi: LV_ITEM
- gnu_lvi.stateMask = mask
- gnu_lvi.state = data
+ gnu_lvi.stateMask = uint(mask)
+ gnu_lvi.state = uint(data)
result = SendMessage(hwndLV, LVM_SETITEMSTATE, WPARAM(i),
cast[LPARAM](addr(gnu_lvi)))
diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim
index 5fc6ddd020..b5eed38f3f 100755
--- a/lib/wrappers/openssl.nim
+++ b/lib/wrappers/openssl.nim
@@ -192,19 +192,44 @@ const
BIO_C_DO_STATE_MACHINE = 101
BIO_C_GET_SSL = 110
-proc SSL_library_init*(): cInt{.cdecl, dynlib: DLLSSLName, importc.}
+proc SSL_library_init*(): cInt{.cdecl, dynlib: DLLSSLName, importc, discardable.}
proc SSL_load_error_strings*(){.cdecl, dynlib: DLLSSLName, importc.}
proc ERR_load_BIO_strings*(){.cdecl, dynlib: DLLSSLName, importc.}
proc SSLv23_client_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.}
+proc SSLv23_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.}
+proc SSLv2_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.}
+proc SSLv3_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.}
+proc TLSv1_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.}
+proc SSL_new*(context: PSSL_CTX): PSSL{.cdecl, dynlib: DLLSSLName, importc.}
+proc SSL_free*(ssl: PSSL){.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_CTX_new*(meth: PSSL_METHOD): PSSL_CTX{.cdecl,
dynlib: DLLSSLName, importc.}
proc SSL_CTX_load_verify_locations*(ctx: PSSL_CTX, CAfile: cstring,
CApath: cstring): cInt{.cdecl, dynlib: DLLSSLName, importc.}
+proc SSL_CTX_free*(arg0: PSSL_CTX){.cdecl, dynlib: DLLSSLName, importc.}
+proc SSL_CTX_set_verify*(s: PSSL_CTX, mode: int, cb: proc (a: int, b: pointer): int){.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_get_verify_result*(ssl: PSSL): int{.cdecl,
dynlib: DLLSSLName, importc.}
+proc SSL_CTX_set_cipher_list*(s: PSSLCTX, ciphers: cstring): cint{.cdecl, dynlib: DLLSSLName, importc.}
+proc SSL_CTX_use_certificate_file*(ctx: PSSL_CTX, filename: cstring, typ: cInt): cInt{.
+ cdecl, dynlib: DLLSSLName, importc.}
+proc SSL_CTX_use_PrivateKey_file*(ctx: PSSL_CTX,
+ filename: cstring, typ: cInt): cInt{.cdecl, dynlib: DLLSSLName, importc.}
+proc SSL_CTX_check_private_key*(ctx: PSSL_CTX): cInt{.cdecl, dynlib: DLLSSLName,
+ importc.}
+
+proc SSL_set_fd*(ssl: PSSL, fd: cint): cint{.cdecl, dynlib: DLLSSLName, importc.}
+
+proc SSL_shutdown*(ssl: PSSL): cInt{.cdecl, dynlib: DLLSSLName, importc.}
+proc SSL_connect*(ssl: PSSL): cint{.cdecl, dynlib: DLLSSLName, importc.}
+proc SSL_read*(ssl: PSSL, buf: pointer, num: int): cint{.cdecl, dynlib: DLLSSLName, importc.}
+proc SSL_write*(ssl: PSSL, buf: cstring, num: int): cint{.cdecl, dynlib: DLLSSLName, importc.}
+proc SSL_get_error*(s: PSSL, ret_code: cInt): cInt{.cdecl, dynlib: DLLSSLName, importc.}
+proc SSL_accept*(ssl: PSSL): cInt{.cdecl, dynlib: DLLSSLName, importc.}
+
proc BIO_new_ssl_connect*(ctx: PSSL_CTX): PBIO{.cdecl,
dynlib: DLLSSLName, importc.}
proc BIO_ctrl*(bio: PBIO, cmd: cint, larg: int, arg: cstring): int{.cdecl,
@@ -227,16 +252,27 @@ proc BIO_free*(b: PBIO): cInt{.cdecl, dynlib: DLLUtilName, importc.}
proc ERR_print_errors_fp*(fp: TFile){.cdecl, dynlib: DLLSSLName, importc.}
+proc ERR_error_string*(e: cInt, buf: cstring): cstring{.cdecl,
+ dynlib: DLLUtilName, importc.}
+proc ERR_get_error*(): cInt{.cdecl, dynlib: DLLUtilName, importc.}
+
+proc OpenSSL_add_all_algorithms*(){.cdecl, dynlib: DLLSSLName, importc: "OPENSSL_add_all_algorithms_conf".}
+
+proc OPENSSL_config*(configName: cstring){.cdecl, dynlib: DLLSSLName, importc.}
+
+proc CRYPTO_set_mem_functions(a,b,c: pointer){.cdecl, dynlib: DLLSSLName, importc.}
+
+proc CRYPTO_malloc_init*() =
+ CRYPTO_set_mem_functions(alloc, realloc, dealloc)
+
when True:
nil
else:
- proc SslGetError*(s: PSSL, ret_code: cInt): cInt{.cdecl, dynlib: DLLSSLName,
- importc.}
proc SslCtxSetCipherList*(arg0: PSSL_CTX, str: cstring): cInt{.cdecl,
dynlib: DLLSSLName, importc.}
proc SslCtxNew*(meth: PSSL_METHOD): PSSL_CTX{.cdecl,
dynlib: DLLSSLName, importc.}
- proc SslCtxFree*(arg0: PSSL_CTX){.cdecl, dynlib: DLLSSLName, importc.}
+
proc SslSetFd*(s: PSSL, fd: cInt): cInt{.cdecl, dynlib: DLLSSLName, importc.}
proc SslCtrl*(ssl: PSSL, cmd: cInt, larg: int, parg: Pointer): int{.cdecl,
dynlib: DLLSSLName, importc.}
@@ -255,19 +291,15 @@ else:
dynlib: DLLSSLName, importc.}
proc SslCtxUsePrivateKeyASN1*(pk: cInt, ctx: PSSL_CTX,
d: cstring, length: int): cInt{.cdecl, dynlib: DLLSSLName, importc.}
- proc SslCtxUsePrivateKeyFile*(ctx: PSSL_CTX,
- filename: cstring, typ: cInt): cInt{.cdecl, dynlib: DLLSSLName, importc.}
+
proc SslCtxUseCertificate*(ctx: PSSL_CTX, x: SslPtr): cInt{.cdecl,
dynlib: DLLSSLName, importc.}
proc SslCtxUseCertificateASN1*(ctx: PSSL_CTX, length: int, d: cstring): cInt{.
cdecl, dynlib: DLLSSLName, importc.}
- proc SslCtxUseCertificateFile*(ctx: PSSL_CTX, filename: cstring, typ: cInt): cInt{.
- cdecl, dynlib: DLLSSLName, importc.}
+
# function SslCtxUseCertificateChainFile(ctx: PSSL_CTX; const filename: PChar):cInt;
proc SslCtxUseCertificateChainFile*(ctx: PSSL_CTX, filename: cstring): cInt{.
cdecl, dynlib: DLLSSLName, importc.}
- proc SslCtxCheckPrivateKeyFile*(ctx: PSSL_CTX): cInt{.cdecl, dynlib: DLLSSLName,
- importc.}
proc SslCtxSetDefaultPasswdCb*(ctx: PSSL_CTX, cb: PPasswdCb){.cdecl,
dynlib: DLLSSLName, importc.}
proc SslCtxSetDefaultPasswdCbUserdata*(ctx: PSSL_CTX, u: SslPtr){.cdecl,
@@ -276,10 +308,10 @@ else:
proc SslCtxLoadVerifyLocations*(ctx: PSSL_CTX, CAfile: cstring, CApath: cstring): cInt{.
cdecl, dynlib: DLLSSLName, importc.}
proc SslNew*(ctx: PSSL_CTX): PSSL{.cdecl, dynlib: DLLSSLName, importc.}
- proc SslFree*(ssl: PSSL){.cdecl, dynlib: DLLSSLName, importc.}
- proc SslAccept*(ssl: PSSL): cInt{.cdecl, dynlib: DLLSSLName, importc.}
+
+
proc SslConnect*(ssl: PSSL): cInt{.cdecl, dynlib: DLLSSLName, importc.}
- proc SslShutdown*(ssl: PSSL): cInt{.cdecl, dynlib: DLLSSLName, importc.}
+
proc SslRead*(ssl: PSSL, buf: SslPtr, num: cInt): cInt{.cdecl,
dynlib: DLLSSLName, importc.}
proc SslPeek*(ssl: PSSL, buf: SslPtr, num: cInt): cInt{.cdecl,
@@ -339,9 +371,7 @@ else:
proc EVPcleanup*(){.cdecl, dynlib: DLLUtilName, importc.}
# function ErrErrorString(e: cInt; buf: PChar): PChar;
proc SSLeayversion*(t: cInt): cstring{.cdecl, dynlib: DLLUtilName, importc.}
- proc ErrErrorString*(e: cInt, buf: cstring, length: cInt){.cdecl,
- dynlib: DLLUtilName, importc.}
- proc ErrGetError*(): cInt{.cdecl, dynlib: DLLUtilName, importc.}
+
proc ErrClearError*(){.cdecl, dynlib: DLLUtilName, importc.}
proc ErrFreeStrings*(){.cdecl, dynlib: DLLUtilName, importc.}
proc ErrRemoveState*(pid: cInt){.cdecl, dynlib: DLLUtilName, importc.}
diff --git a/lib/wrappers/sdl/sdl.nim b/lib/wrappers/sdl/sdl.nim
index cf4eb452d7..a48cb59efa 100755
--- a/lib/wrappers/sdl/sdl.nim
+++ b/lib/wrappers/sdl/sdl.nim
@@ -756,9 +756,7 @@ type
PUInt8Array* = ptr TUInt8Array
TUInt8Array* = array[0..high(int) shr 1, byte]
PUInt16* = ptr UInt16
- UInt16* = int16
- PUInt32* = ptr int32
- UInt32* = int32
+ PUInt32* = ptr UInt32
PUInt64* = ptr UInt64
UInt64*{.final.} = object
hi*: int32
diff --git a/tests/reject/tenummix.nim b/tests/reject/tenummix.nim
index f32eb82a77..8965ab3c3b 100644
--- a/tests/reject/tenummix.nim
+++ b/tests/reject/tenummix.nim
@@ -1,6 +1,6 @@
discard """
file: "system.nim"
- line: 640
+ line: 678
errormsg: "type mismatch"
"""
diff --git a/tests/run/texceptions.nim b/tests/run/texceptions.nim
new file mode 100644
index 0000000000..69b2d0f6a4
--- /dev/null
+++ b/tests/run/texceptions.nim
@@ -0,0 +1,66 @@
+discard """
+ output: '''
+BEFORE
+FINALLY
+
+BEFORE
+EXCEPT
+FINALLY
+RECOVER
+
+BEFORE
+EXCEPT
+FINALLY
+'''
+"""
+
+echo ""
+
+proc no_expcetion =
+ try:
+ echo "BEFORE"
+
+ except:
+ echo "EXCEPT"
+ raise
+
+ finally:
+ echo "FINALLY"
+
+try: no_expcetion()
+except: echo "RECOVER"
+
+echo ""
+
+proc reraise_in_except =
+ try:
+ echo "BEFORE"
+ raise newException(EIO, "")
+
+ except EIO:
+ echo "EXCEPT"
+ raise
+
+ finally:
+ echo "FINALLY"
+
+try: reraise_in_except()
+except: echo "RECOVER"
+
+echo ""
+
+proc return_in_except =
+ try:
+ echo "BEFORE"
+ raise newException(EIO, "")
+
+ except:
+ echo "EXCEPT"
+ return
+
+ finally:
+ echo "FINALLY"
+
+try: return_in_except()
+except: echo "RECOVER"
+
diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim
index 9927d5bcd6..f66bad1f4e 100755
--- a/tools/niminst/niminst.nim
+++ b/tools/niminst/niminst.nim
@@ -391,7 +391,7 @@ proc srcdist(c: var TConfigData) =
if existsDir(dir): removeDir(dir)
createDir(dir)
var cmd = ("nimrod compile -f --symbolfiles:off --compileonly " &
- "--gen_mapping --cc:gcc" &
+ "--gen_mapping --cc:gcc --skipUserCfg" &
" --os:$# --cpu:$# $# $#") %
[c.oses[osA-1], c.cpus[cpuA-1], c.nimrodArgs,
changeFileExt(c.infile, "nim")]
diff --git a/web/news.txt b/web/news.txt
index 847c36561b..eeff4bf8a7 100755
--- a/web/news.txt
+++ b/web/news.txt
@@ -51,7 +51,11 @@ Library Additions
- Added ``system.||`` for parallel for loop support.
- The GC supports (soft) realtime systems via ``GC_setMaxPause``
and ``GC_step`` procs.
-
+- The sockets module now supports ssl through the OpenSSL library, ``recvLine``
+ is now much more efficient thanks to the newly implemented sockets buffering.
+- The httpclient module now supports ssl/tls.
+- Added ``times.format`` as well as many other utility functions
+ for managing time.
Changes affecting backwards compatibility
-----------------------------------------
@@ -77,7 +81,7 @@ Changes affecting backwards compatibility
- RTTI and thus the ``marshall`` module don't contain the proper field names
of tuples anymore. This had to be changed as the old behaviour never
produced consistent results.
-
+- Deprecated the ``ssl`` module.
Compiler Additions
------------------