diff --git a/build.bat b/build.bat index 952b128b2a..9e182d0ff8 100644 --- a/build.bat +++ b/build.bat @@ -73,8 +73,8 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\babelcmd.c -o build\1_1\babelcmd.o %CC% %COMP_FLAGS% -Ibuild -c build\1_1\babelcmd.c -o build\1_1\babelcmd.o ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\lexer.c -o build\1_1\lexer.o %CC% %COMP_FLAGS% -Ibuild -c build\1_1\lexer.c -o build\1_1\lexer.o -ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\lexbase.c -o build\1_1\lexbase.o -%CC% %COMP_FLAGS% -Ibuild -c build\1_1\lexbase.c -o build\1_1\lexbase.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\nimlexbase.c -o build\1_1\nimlexbase.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_1\nimlexbase.c -o build\1_1\nimlexbase.o ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\llstream.c -o build\1_1\llstream.o %CC% %COMP_FLAGS% -Ibuild -c build\1_1\llstream.c -o build\1_1\llstream.o ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\nimconf.c -o build\1_1\nimconf.o @@ -159,6 +159,8 @@ 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\algorithm.c -o build\1_1\algorithm.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_1\algorithm.c -o build\1_1\algorithm.o 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\patterns.c -o build\1_1\patterns.o @@ -171,8 +173,14 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\cgendata.c -o build\1_1\cgendata.o %CC% %COMP_FLAGS% -Ibuild -c build\1_1\cgendata.c -o build\1_1\cgendata.o ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\ccgmerge.c -o build\1_1\ccgmerge.o %CC% %COMP_FLAGS% -Ibuild -c build\1_1\ccgmerge.c -o build\1_1\ccgmerge.o -ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\ecmasgen.c -o build\1_1\ecmasgen.o -%CC% %COMP_FLAGS% -Ibuild -c build\1_1\ecmasgen.c -o build\1_1\ecmasgen.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\jsgen.c -o build\1_1\jsgen.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_1\jsgen.c -o build\1_1\jsgen.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\json.c -o build\1_1\json.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_1\json.c -o build\1_1\json.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\lexbase.c -o build\1_1\lexbase.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_1\lexbase.c -o build\1_1\lexbase.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\unicode.c -o build\1_1\unicode.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_1\unicode.c -o build\1_1\unicode.o ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\passaux.c -o build\1_1\passaux.o %CC% %COMP_FLAGS% -Ibuild -c build\1_1\passaux.c -o build\1_1\passaux.o ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\depends.c -o build\1_1\depends.o @@ -184,8 +192,8 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_1\service.c -o build\1_1\service.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\nimrod.o build\1_1\system.o build\1_1\commands.o build\1_1\os.o build\1_1\strutils.o build\1_1\parseutils.o build\1_1\times.o build\1_1\winlean.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\sockets.o build\1_1\ropes.o build\1_1\platform.o build\1_1\crc.o build\1_1\nversion.o build\1_1\condsyms.o build\1_1\ast.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\babelcmd.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\types.o build\1_1\trees.o build\1_1\memfiles.o build\1_1\rodwrite.o build\1_1\passes.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\saturate.o build\1_1\transf.o build\1_1\cgmeth.o build\1_1\sempass2.o build\1_1\lambdalifting.o build\1_1\evaltempl.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\parampatterns.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\aliases.o build\1_1\patterns.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\docgen2.o build\1_1\service.o build\1_1\parseopt.o -%LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_1\nimrod.o build\1_1\system.o build\1_1\commands.o build\1_1\os.o build\1_1\strutils.o build\1_1\parseutils.o build\1_1\times.o build\1_1\winlean.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\sockets.o build\1_1\ropes.o build\1_1\platform.o build\1_1\crc.o build\1_1\nversion.o build\1_1\condsyms.o build\1_1\ast.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\babelcmd.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\types.o build\1_1\trees.o build\1_1\memfiles.o build\1_1\rodwrite.o build\1_1\passes.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\saturate.o build\1_1\transf.o build\1_1\cgmeth.o build\1_1\sempass2.o build\1_1\lambdalifting.o build\1_1\evaltempl.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\parampatterns.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\aliases.o build\1_1\patterns.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\docgen2.o build\1_1\service.o build\1_1\parseopt.o +ECHO %LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_1\nimrod.o build\1_1\system.o build\1_1\commands.o build\1_1\os.o build\1_1\strutils.o build\1_1\parseutils.o build\1_1\times.o build\1_1\winlean.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\sockets.o build\1_1\ropes.o build\1_1\platform.o build\1_1\crc.o build\1_1\nversion.o build\1_1\condsyms.o build\1_1\ast.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\babelcmd.o build\1_1\lexer.o build\1_1\nimlexbase.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\types.o build\1_1\trees.o build\1_1\memfiles.o build\1_1\rodwrite.o build\1_1\passes.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\saturate.o build\1_1\transf.o build\1_1\cgmeth.o build\1_1\sempass2.o build\1_1\lambdalifting.o build\1_1\evaltempl.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\parampatterns.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\algorithm.o build\1_1\aliases.o build\1_1\patterns.o build\1_1\cgen.o build\1_1\ccgutils.o build\1_1\cgendata.o build\1_1\ccgmerge.o build\1_1\jsgen.o build\1_1\json.o build\1_1\lexbase.o build\1_1\unicode.o build\1_1\passaux.o build\1_1\depends.o build\1_1\docgen2.o build\1_1\service.o build\1_1\parseopt.o +%LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_1\nimrod.o build\1_1\system.o build\1_1\commands.o build\1_1\os.o build\1_1\strutils.o build\1_1\parseutils.o build\1_1\times.o build\1_1\winlean.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\sockets.o build\1_1\ropes.o build\1_1\platform.o build\1_1\crc.o build\1_1\nversion.o build\1_1\condsyms.o build\1_1\ast.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\babelcmd.o build\1_1\lexer.o build\1_1\nimlexbase.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\types.o build\1_1\trees.o build\1_1\memfiles.o build\1_1\rodwrite.o build\1_1\passes.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\saturate.o build\1_1\transf.o build\1_1\cgmeth.o build\1_1\sempass2.o build\1_1\lambdalifting.o build\1_1\evaltempl.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\parampatterns.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\algorithm.o build\1_1\aliases.o build\1_1\patterns.o build\1_1\cgen.o build\1_1\ccgutils.o build\1_1\cgendata.o build\1_1\ccgmerge.o build\1_1\jsgen.o build\1_1\json.o build\1_1\lexbase.o build\1_1\unicode.o build\1_1\passaux.o build\1_1\depends.o build\1_1\docgen2.o build\1_1\service.o build\1_1\parseopt.o ECHO SUCCESS diff --git a/build64.bat b/build64.bat index 1a40657d54..3238b7c229 100644 --- a/build64.bat +++ b/build64.bat @@ -73,8 +73,8 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\babelcmd.c -o build\1_2\babelcmd.o %CC% %COMP_FLAGS% -Ibuild -c build\1_2\babelcmd.c -o build\1_2\babelcmd.o ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\lexer.c -o build\1_2\lexer.o %CC% %COMP_FLAGS% -Ibuild -c build\1_2\lexer.c -o build\1_2\lexer.o -ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\lexbase.c -o build\1_2\lexbase.o -%CC% %COMP_FLAGS% -Ibuild -c build\1_2\lexbase.c -o build\1_2\lexbase.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\nimlexbase.c -o build\1_2\nimlexbase.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\nimlexbase.c -o build\1_2\nimlexbase.o ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\llstream.c -o build\1_2\llstream.o %CC% %COMP_FLAGS% -Ibuild -c build\1_2\llstream.c -o build\1_2\llstream.o ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\nimconf.c -o build\1_2\nimconf.o @@ -159,6 +159,8 @@ 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\algorithm.c -o build\1_2\algorithm.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\algorithm.c -o build\1_2\algorithm.o 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\patterns.c -o build\1_2\patterns.o @@ -171,8 +173,14 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\cgendata.c -o build\1_2\cgendata.o %CC% %COMP_FLAGS% -Ibuild -c build\1_2\cgendata.c -o build\1_2\cgendata.o ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\ccgmerge.c -o build\1_2\ccgmerge.o %CC% %COMP_FLAGS% -Ibuild -c build\1_2\ccgmerge.c -o build\1_2\ccgmerge.o -ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\ecmasgen.c -o build\1_2\ecmasgen.o -%CC% %COMP_FLAGS% -Ibuild -c build\1_2\ecmasgen.c -o build\1_2\ecmasgen.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\jsgen.c -o build\1_2\jsgen.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\jsgen.c -o build\1_2\jsgen.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\json.c -o build\1_2\json.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\json.c -o build\1_2\json.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\lexbase.c -o build\1_2\lexbase.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\lexbase.c -o build\1_2\lexbase.o +ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\unicode.c -o build\1_2\unicode.o +%CC% %COMP_FLAGS% -Ibuild -c build\1_2\unicode.c -o build\1_2\unicode.o ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\passaux.c -o build\1_2\passaux.o %CC% %COMP_FLAGS% -Ibuild -c build\1_2\passaux.c -o build\1_2\passaux.o ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\depends.c -o build\1_2\depends.o @@ -184,8 +192,8 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build\1_2\service.c -o build\1_2\service.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\nimrod.o build\1_2\system.o build\1_2\commands.o build\1_2\os.o build\1_2\strutils.o build\1_2\parseutils.o build\1_2\times.o build\1_2\winlean.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\sockets.o build\1_2\ropes.o build\1_2\platform.o build\1_2\crc.o build\1_2\nversion.o build\1_2\condsyms.o build\1_2\ast.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\babelcmd.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\types.o build\1_2\trees.o build\1_2\memfiles.o build\1_2\rodwrite.o build\1_2\passes.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\saturate.o build\1_2\transf.o build\1_2\cgmeth.o build\1_2\sempass2.o build\1_2\lambdalifting.o build\1_2\evaltempl.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\parampatterns.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\aliases.o build\1_2\patterns.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\docgen2.o build\1_2\service.o build\1_2\parseopt.o -%LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_2\nimrod.o build\1_2\system.o build\1_2\commands.o build\1_2\os.o build\1_2\strutils.o build\1_2\parseutils.o build\1_2\times.o build\1_2\winlean.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\sockets.o build\1_2\ropes.o build\1_2\platform.o build\1_2\crc.o build\1_2\nversion.o build\1_2\condsyms.o build\1_2\ast.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\babelcmd.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\types.o build\1_2\trees.o build\1_2\memfiles.o build\1_2\rodwrite.o build\1_2\passes.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\saturate.o build\1_2\transf.o build\1_2\cgmeth.o build\1_2\sempass2.o build\1_2\lambdalifting.o build\1_2\evaltempl.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\parampatterns.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\aliases.o build\1_2\patterns.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\docgen2.o build\1_2\service.o build\1_2\parseopt.o +ECHO %LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_2\nimrod.o build\1_2\system.o build\1_2\commands.o build\1_2\os.o build\1_2\strutils.o build\1_2\parseutils.o build\1_2\times.o build\1_2\winlean.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\sockets.o build\1_2\ropes.o build\1_2\platform.o build\1_2\crc.o build\1_2\nversion.o build\1_2\condsyms.o build\1_2\ast.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\babelcmd.o build\1_2\lexer.o build\1_2\nimlexbase.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\types.o build\1_2\trees.o build\1_2\memfiles.o build\1_2\rodwrite.o build\1_2\passes.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\saturate.o build\1_2\transf.o build\1_2\cgmeth.o build\1_2\sempass2.o build\1_2\lambdalifting.o build\1_2\evaltempl.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\parampatterns.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\algorithm.o build\1_2\aliases.o build\1_2\patterns.o build\1_2\cgen.o build\1_2\ccgutils.o build\1_2\cgendata.o build\1_2\ccgmerge.o build\1_2\jsgen.o build\1_2\json.o build\1_2\lexbase.o build\1_2\unicode.o build\1_2\passaux.o build\1_2\depends.o build\1_2\docgen2.o build\1_2\service.o build\1_2\parseopt.o +%LINKER% %LINK_FLAGS% -o bin\nimrod.exe build\1_2\nimrod.o build\1_2\system.o build\1_2\commands.o build\1_2\os.o build\1_2\strutils.o build\1_2\parseutils.o build\1_2\times.o build\1_2\winlean.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\sockets.o build\1_2\ropes.o build\1_2\platform.o build\1_2\crc.o build\1_2\nversion.o build\1_2\condsyms.o build\1_2\ast.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\babelcmd.o build\1_2\lexer.o build\1_2\nimlexbase.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\types.o build\1_2\trees.o build\1_2\memfiles.o build\1_2\rodwrite.o build\1_2\passes.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\saturate.o build\1_2\transf.o build\1_2\cgmeth.o build\1_2\sempass2.o build\1_2\lambdalifting.o build\1_2\evaltempl.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\parampatterns.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\algorithm.o build\1_2\aliases.o build\1_2\patterns.o build\1_2\cgen.o build\1_2\ccgutils.o build\1_2\cgendata.o build\1_2\ccgmerge.o build\1_2\jsgen.o build\1_2\json.o build\1_2\lexbase.o build\1_2\unicode.o build\1_2\passaux.o build\1_2\depends.o build\1_2\docgen2.o build\1_2\service.o build\1_2\parseopt.o ECHO SUCCESS diff --git a/compiler/ast.nim b/compiler/ast.nim index eb12c977fa..d4d5bce9cc 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -13,10 +13,6 @@ import msgs, hashes, nversion, options, strutils, crc, ropes, idents, lists, intsets, idgen -const - ImportTablePos* = 0 # imported symbols are at level 0 - ModuleTablePos* = 1 # module's top level symbols are at level 1 - type TCallingConvention* = enum ccDefault, # proc has no explicit calling convention @@ -284,6 +280,9 @@ const sfHoist* = sfVolatile ## proc return value can be hoisted + sfNoForward* = sfRegister + # forward declarations are not required (per module) + const # getting ready for the future expr/stmt merge nkWhen* = nkWhenStmt @@ -608,7 +607,14 @@ type # simple ref count here PInstantiation* = ref TInstantiation - + + TScope* = object + depthLevel*: int + symbols*: TStrTable + parent*: PScope + + PScope* = ref TScope + PLib* = ref TLib TSym* {.acyclic.} = object of TIdObj # proc and type instantiations are cached in the generic symbol @@ -617,12 +623,14 @@ type typeInstCache*: seq[PType] of routineKinds: procInstCache*: seq[PInstantiation] + scope*: PScope # the scope where the proc was defined of skModule: # modules keep track of the generic symbols they use from other modules. # this is because in incremental compilation, when a module is about to # be replaced with a newer version, we must decrement the usage count # of all previously used generics. usedGenerics*: seq[PInstantiation] + tab*: TStrTable # interface table for modules else: nil magic*: TMagic @@ -631,7 +639,6 @@ type info*: TLineInfo owner*: PSym flags*: TSymFlags - tab*: TStrTable # interface table for modules ast*: PNode # syntax tree of proc, iterator, etc.: # the whole proc including header; this is used # for easy generation of proper error messages @@ -1053,7 +1060,8 @@ proc copySym(s: PSym, keepId: bool = false): PSym = when debugIds: RegisterId(result) result.flags = s.flags result.magic = s.magic - copyStrTable(result.tab, s.tab) + if s.kind == skModule: + copyStrTable(result.tab, s.tab) result.options = s.options result.position = s.position result.loc = s.loc @@ -1080,6 +1088,9 @@ proc initStrTable(x: var TStrTable) = x.counter = 0 newSeq(x.data, startSize) +proc newStrTable*: TStrTable = + initStrTable(result) + proc initTable(x: var TTable) = x.counter = 0 newSeq(x.data, startSize) diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index 364e164bbc..fd6774e7a5 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -72,37 +72,6 @@ type proc InitIdentIter*(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym proc NextIdentIter*(ti: var TIdentIter, tab: TStrTable): PSym -# -------------- symbol table ---------------------------------------------- -# Each TParser object (which represents a module being compiled) has its own -# symbol table. A symbol table is organized as a stack of str tables. The -# stack represents the different scopes. -# Stack pointer: -# 0 imported symbols from other modules -# 1 module level -# 2 proc level -# 3 nested statements -# ... -# -type - TSymTab*{.final.} = object - tos*: Natural # top of stack - stack*: seq[TStrTable] - - -proc InitSymTab*(tab: var TSymTab) -proc DeinitSymTab*(tab: var TSymTab) -proc SymTabGet*(tab: TSymTab, s: PIdent): PSym -proc SymTabGet*(tab: TSymTab, s: PIdent, filter: TSymKinds): PSym -proc SymTabLocalGet*(tab: TSymTab, s: PIdent): PSym -proc SymTabAdd*(tab: var TSymTab, e: PSym) -proc SymTabAddAt*(tab: var TSymTab, e: PSym, at: Natural) -proc SymTabAddUnique*(tab: var TSymTab, e: PSym): TResult -proc SymTabAddUniqueAt*(tab: var TSymTab, e: PSym, at: Natural): TResult -proc OpenScope*(tab: var TSymTab) -proc RawCloseScope*(tab: var TSymTab) - # the real "closeScope" adds some - # checks in parsobj - # these are for debugging only: They are not really deprecated, but I want # the warning so that release versions do not contain debugging statements: proc debug*(n: PSym) {.deprecated.} @@ -708,52 +677,7 @@ proc NextIter(ti: var TTabIter, tab: TStrTable): PSym = result = tab.data[ti.h] Inc(ti.h) # ... and increment by one always if result != nil: break - -proc InitSymTab(tab: var TSymTab) = - tab.tos = 0 - tab.stack = EmptySeq -proc DeinitSymTab(tab: var TSymTab) = - tab.stack = nil - -proc SymTabLocalGet(tab: TSymTab, s: PIdent): PSym = - result = StrTableGet(tab.stack[tab.tos - 1], s) - -proc SymTabGet(tab: TSymTab, s: PIdent): PSym = - for i in countdown(tab.tos - 1, 0): - result = StrTableGet(tab.stack[i], s) - if result != nil: return - result = nil - -proc SymTabGet*(tab: TSymTab, s: PIdent, filter: TSymKinds): PSym = - for i in countdown(tab.tos - 1, 0): - result = StrTableGet(tab.stack[i], s) - if result != nil and result.kind in filter: return - result = nil - -proc SymTabAddAt(tab: var TSymTab, e: PSym, at: Natural) = - StrTableAdd(tab.stack[at], e) - -proc SymTabAdd(tab: var TSymTab, e: PSym) = - StrTableAdd(tab.stack[tab.tos - 1], e) - -proc SymTabAddUniqueAt(tab: var TSymTab, e: PSym, at: Natural): TResult = - if StrTableIncl(tab.stack[at], e): - result = Failure - else: - result = Success - -proc SymTabAddUnique(tab: var TSymTab, e: PSym): TResult = - result = SymTabAddUniqueAt(tab, e, tab.tos - 1) - -proc OpenScope(tab: var TSymTab) = - if tab.tos >= len(tab.stack): setlen(tab.stack, tab.tos + 1) - initStrTable(tab.stack[tab.tos]) - Inc(tab.tos) - -proc RawCloseScope(tab: var TSymTab) = - Dec(tab.tos) - iterator items*(tab: TStrTable): PSym = var it: TTabIter var s = InitTabIter(it, tab) @@ -761,10 +685,6 @@ iterator items*(tab: TStrTable): PSym = yield s s = NextIter(it, tab) -iterator items*(tab: TSymTab): PSym = - for i in countdown(tab.tos-1, 0): - for it in items(tab.stack[i]): yield it - proc hasEmptySlot(data: TIdPairSeq): bool = for h in countup(0, high(data)): if data[h].key == nil: diff --git a/compiler/cgen.nim b/compiler/cgen.nim index f034f6675b..ddb9ec0adc 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -842,8 +842,10 @@ proc requestConstImpl(p: BProc, sym: PSym) = if sfExportc in sym.flags and generatedHeader != nil: app(generatedHeader.s[cfsData], headerDecl) +proc isActivated(prc: PSym): bool = prc.typ != nil + proc genProc(m: BModule, prc: PSym) = - if sfBorrow in prc.flags: return + if sfBorrow in prc.flags or not isActivated(prc): return fillProcLoc(prc) if {sfForward, sfFromGeneric} * prc.flags != {}: addForwardedProc(m, prc) else: diff --git a/compiler/importer.nim b/compiler/importer.nim index d274b4693a..ebb848ea78 100644 --- a/compiler/importer.nim +++ b/compiler/importer.nim @@ -48,7 +48,7 @@ proc rawImportSymbol(c: PContext, s: PSym) = # This does not handle stubs, because otherwise loading on demand would be # pointless in practice. So importing stubs is fine here! # check if we have already a symbol of the same name: - var check = StrTableGet(c.tab.stack[importTablePos], s.name) + var check = StrTableGet(c.importTable.symbols, s.name) if check != nil and check.id != s.id: if s.kind notin OverloadableSyms: # s and check need to be qualified: @@ -56,7 +56,7 @@ proc rawImportSymbol(c: PContext, s: PSym) = Incl(c.AmbiguousSymbols, check.id) # thanks to 'export' feature, it could be we import the same symbol from # multiple sources, so we need to call 'StrTableAdd' here: - StrTableAdd(c.tab.stack[importTablePos], s) + StrTableAdd(c.importTable.symbols, s) if s.kind == skType: var etyp = s.typ if etyp.kind in {tyBool, tyEnum} and sfPure notin s.flags: @@ -68,12 +68,12 @@ proc rawImportSymbol(c: PContext, s: PSym) = # have been put into the symbol table # BUGFIX: but only iff they are the same symbols! var it: TIdentIter - check = InitIdentIter(it, c.tab.stack[importTablePos], e.name) + check = InitIdentIter(it, c.importTable.symbols, e.name) while check != nil: if check.id == e.id: e = nil break - check = NextIdentIter(it, c.tab.stack[importTablePos]) + check = NextIdentIter(it, c.importTable.symbols) if e != nil: rawImportSymbol(c, e) else: diff --git a/compiler/lookups.nim b/compiler/lookups.nim index c0e3ea880c..05470f54f6 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -13,6 +13,8 @@ import intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread, renderer, wordrecg, idgen +proc ensureNoMissingOrUnusedSymbols(scope: PScope) + proc considerAcc*(n: PNode): PIdent = case n.kind of nkIdent: result = n.ident @@ -33,6 +35,49 @@ proc considerAcc*(n: PNode): PIdent = else: GlobalError(n.info, errIdentifierExpected, renderTree(n)) +template addSym*(scope: PScope, s: PSym) = + StrTableAdd(scope.symbols, s) + +proc addUniqueSym*(scope: PScope, s: PSym): TResult = + if StrTableIncl(scope.symbols, s): + result = Failure + else: + result = Success + +proc openScope*(c: PContext): PScope {.discardable.} = + result = PScope(parent: c.currentScope, + symbols: newStrTable(), + depthLevel: c.scopeDepth + 1) + c.currentScope = result + +proc rawCloseScope*(c: PContext) = + c.currentScope = c.currentScope.parent + +proc closeScope*(c: PContext) = + ensureNoMissingOrUnusedSymbols(c.currentScope) + rawCloseScope(c) + +iterator walkScopes*(scope: PScope): PScope = + var current = scope + while current != nil: + yield current + current = current.parent + +proc localSearchInScope*(c: PContext, s: PIdent): PSym = + result = StrTableGet(c.currentScope.symbols, s) + +proc searchInScopes*(c: PContext, s: PIdent): PSym = + for scope in walkScopes(c.currentScope): + result = StrTableGet(scope.symbols, s) + if result != nil: return + result = nil + +proc searchInScopes*(c: PContext, s: PIdent, filter: TSymKinds): PSym = + for scope in walkScopes(c.currentScope): + result = StrTableGet(scope.symbols, s) + if result != nil and result.kind in filter: return + result = nil + proc errorSym*(c: PContext, n: PNode): PSym = ## creates an error symbol to avoid cascading errors (for IDE support) var m = n @@ -46,31 +91,29 @@ proc errorSym*(c: PContext, n: PNode): PSym = result.typ = errorType(c) incl(result.flags, sfDiscardable) # pretend it's imported from some unknown module to prevent cascading errors: - SymTabAddAt(c.tab, result, ast.ImportTablePos) + c.importTable.addSym(result) type TOverloadIterMode* = enum oimDone, oimNoQualifier, oimSelfModule, oimOtherModule, oimSymChoice, oimSymChoiceLocalLookup TOverloadIter*{.final.} = object - stackPtr*: int it*: TIdentIter m*: PSym mode*: TOverloadIterMode + symChoiceIndex*: int + scope*: PScope inSymChoice: TIntSet proc getSymRepr*(s: PSym): string = case s.kind of skProc, skMethod, skConverter, skIterator: result = getProcHeader(s) else: result = s.name.s - -proc CloseScope*(tab: var TSymTab) = + +proc ensureNoMissingOrUnusedSymbols(scope: PScope) = # check if all symbols have been used and defined: - if tab.tos > len(tab.stack): - InternalError("CloseScope") - return var it: TTabIter - var s = InitTabIter(it, tab.stack[tab.tos-1]) + var s = InitTabIter(it, scope.symbols) var missingImpls = 0 while s != nil: if sfForward in s.flags: @@ -83,25 +126,21 @@ proc CloseScope*(tab: var TSymTab) = # BUGFIX: check options in s! if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam}: Message(s.info, hintXDeclaredButNotUsed, getSymRepr(s)) - s = NextIter(it, tab.stack[tab.tos-1]) - astalgo.rawCloseScope(tab) - + s = NextIter(it, scope.symbols) + proc WrongRedefinition*(info: TLineInfo, s: string) = if gCmd != cmdInteractive: localError(info, errAttemptToRedefine, s) - -proc AddSym*(t: var TStrTable, n: PSym) = - if StrTableIncl(t, n): WrongRedefinition(n.info, n.name.s) -proc addDecl*(c: PContext, sym: PSym) = - if SymTabAddUnique(c.tab, sym) == Failure: +proc addDecl*(c: PContext, sym: PSym) = + if c.currentScope.addUniqueSym(sym) == Failure: WrongRedefinition(sym.info, sym.Name.s) proc addPrelimDecl*(c: PContext, sym: PSym) = - discard SymTabAddUnique(c.tab, sym) + discard c.currentScope.addUniqueSym(sym) -proc addDeclAt*(c: PContext, sym: PSym, at: Natural) = - if SymTabAddUniqueAt(c.tab, sym, at) == Failure: +proc addDeclAt*(scope: PScope, sym: PSym) = + if scope.addUniqueSym(sym) == Failure: WrongRedefinition(sym.info, sym.Name.s) proc AddInterfaceDeclAux(c: PContext, sym: PSym) = @@ -110,35 +149,35 @@ proc AddInterfaceDeclAux(c: PContext, sym: PSym) = if c.module != nil: StrTableAdd(c.module.tab, sym) else: InternalError(sym.info, "AddInterfaceDeclAux") -proc addInterfaceDeclAt*(c: PContext, sym: PSym, at: Natural) = - addDeclAt(c, sym, at) +proc addInterfaceDeclAt*(c: PContext, scope: PScope, sym: PSym) = + addDeclAt(scope, sym) AddInterfaceDeclAux(c, sym) - -proc addOverloadableSymAt*(c: PContext, fn: PSym, at: Natural) = + +proc addOverloadableSymAt*(scope: PScope, fn: PSym) = if fn.kind notin OverloadableSyms: InternalError(fn.info, "addOverloadableSymAt") return - var check = StrTableGet(c.tab.stack[at], fn.name) + var check = StrTableGet(scope.symbols, fn.name) if check != nil and check.Kind notin OverloadableSyms: WrongRedefinition(fn.info, fn.Name.s) else: - SymTabAddAt(c.tab, fn, at) + scope.addSym(fn) proc addInterfaceDecl*(c: PContext, sym: PSym) = # it adds the symbol to the interface if appropriate addDecl(c, sym) AddInterfaceDeclAux(c, sym) -proc addInterfaceOverloadableSymAt*(c: PContext, sym: PSym, at: int) = +proc addInterfaceOverloadableSymAt*(c: PContext, scope: PScope, sym: PSym) = # it adds the symbol to the interface if appropriate - addOverloadableSymAt(c, sym, at) + addOverloadableSymAt(scope, sym) AddInterfaceDeclAux(c, sym) proc lookUp*(c: PContext, n: PNode): PSym = # Looks up a symbol. Generates an error in case of nil. case n.kind of nkIdent: - result = SymtabGet(c.Tab, n.ident) + result = searchInScopes(c, n.ident) if result == nil: LocalError(n.info, errUndeclaredIdentifier, n.ident.s) result = errorSym(c, n) @@ -146,7 +185,7 @@ proc lookUp*(c: PContext, n: PNode): PSym = result = n.sym of nkAccQuoted: var ident = considerAcc(n) - result = SymtabGet(c.Tab, ident) + result = searchInScopes(c, ident) if result == nil: LocalError(n.info, errUndeclaredIdentifier, ident.s) result = errorSym(c, n) @@ -165,7 +204,7 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = case n.kind of nkIdent, nkAccQuoted: var ident = considerAcc(n) - result = SymtabGet(c.Tab, ident) + result = searchInScopes(c, ident) if result == nil and checkUndeclared in flags: LocalError(n.info, errUndeclaredIdentifier, ident.s) result = errorSym(c, n) @@ -187,7 +226,7 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = ident = considerAcc(n.sons[1]) if ident != nil: if m == c.module: - result = StrTableGet(c.tab.stack[ModuleTablePos], ident) + result = StrTableGet(c.topLevelScope.symbols, ident) else: result = StrTableGet(m.tab, ident) if result == nil and checkUndeclared in flags: @@ -205,12 +244,15 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = case n.kind of nkIdent, nkAccQuoted: var ident = considerAcc(n) - o.stackPtr = c.tab.tos + o.scope = c.currentScope o.mode = oimNoQualifier - while result == nil: - dec(o.stackPtr) - if o.stackPtr < 0: break - result = InitIdentIter(o.it, c.tab.stack[o.stackPtr], ident) + while true: + result = InitIdentIter(o.it, o.scope.symbols, ident) + if result != nil: + break + else: + o.scope = o.scope.parent + if o.scope == nil: break of nkSym: result = n.sym o.mode = oimDone @@ -226,7 +268,7 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = if ident != nil: if o.m == c.module: # a module may access its private members: - result = InitIdentIter(o.it, c.tab.stack[ModuleTablePos], ident) + result = InitIdentIter(o.it, c.topLevelScope.symbols, ident) o.mode = oimSelfModule else: result = InitIdentIter(o.it, o.m.tab, ident) @@ -237,7 +279,7 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = of nkClosedSymChoice, nkOpenSymChoice: o.mode = oimSymChoice result = n.sons[0].sym - o.stackPtr = 1 + o.symChoiceIndex = 1 o.inSymChoice = initIntSet() Incl(o.inSymChoice, result.id) else: nil @@ -245,9 +287,9 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = proc lastOverloadScope*(o: TOverloadIter): int = case o.mode - of oimNoQualifier: result = o.stackPtr - of oimSelfModule: result = ModuleTablePos - of oimOtherModule: result = ImportTablePos + of oimNoQualifier: result = o.scope.depthLevel + of oimSelfModule: result = 1 + of oimOtherModule: result = 0 else: result = -1 proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = @@ -255,41 +297,41 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = of oimDone: result = nil of oimNoQualifier: - if o.stackPtr >= 0: - result = nextIdentIter(o.it, c.tab.stack[o.stackPtr]) - while result == nil: - dec(o.stackPtr) - if o.stackPtr < 0: break - result = InitIdentIter(o.it, c.tab.stack[o.stackPtr], o.it.name) + if o.scope != nil: + result = nextIdentIter(o.it, o.scope.symbols) + while result == nil: + o.scope = o.scope.parent + if o.scope == nil: break + result = InitIdentIter(o.it, o.scope.symbols, o.it.name) # BUGFIX: o.it.name <-> n.ident else: result = nil of oimSelfModule: - result = nextIdentIter(o.it, c.tab.stack[ModuleTablePos]) + result = nextIdentIter(o.it, c.topLevelScope.symbols) of oimOtherModule: result = nextIdentIter(o.it, o.m.tab) of oimSymChoice: - if o.stackPtr < sonsLen(n): - result = n.sons[o.stackPtr].sym + if o.symChoiceIndex < sonsLen(n): + result = n.sons[o.symChoiceIndex].sym Incl(o.inSymChoice, result.id) - inc(o.stackPtr) + inc o.symChoiceIndex elif n.kind == nkOpenSymChoice: # try 'local' symbols too for Koenig's lookup: o.mode = oimSymChoiceLocalLookup - o.stackPtr = c.tab.tos-1 - result = FirstIdentExcluding(o.it, c.tab.stack[o.stackPtr], + o.scope = c.currentScope + result = FirstIdentExcluding(o.it, o.scope.symbols, n.sons[0].sym.name, o.inSymChoice) while result == nil: - dec(o.stackPtr) - if o.stackPtr < 0: break - result = FirstIdentExcluding(o.it, c.tab.stack[o.stackPtr], + o.scope = o.scope.parent + if o.scope == nil: break + result = FirstIdentExcluding(o.it, o.scope.symbols, n.sons[0].sym.name, o.inSymChoice) of oimSymChoiceLocalLookup: - result = nextIdentExcluding(o.it, c.tab.stack[o.stackPtr], o.inSymChoice) + result = nextIdentExcluding(o.it, o.scope.symbols, o.inSymChoice) while result == nil: - dec(o.stackPtr) - if o.stackPtr < 0: break - result = FirstIdentExcluding(o.it, c.tab.stack[o.stackPtr], + o.scope = o.scope.parent + if o.scope == nil: break + result = FirstIdentExcluding(o.it, o.scope.symbols, n.sons[0].sym.name, o.inSymChoice) if result != nil and result.kind == skStub: loadStub(result) diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim index 005ee3ae3e..352b6ca043 100644 --- a/compiler/magicsys.nim +++ b/compiler/magicsys.nim @@ -19,7 +19,6 @@ proc registerSysType*(t: PType) proc getSysType*(kind: TTypeKind): PType proc getCompilerProc*(name: string): PSym proc registerCompilerProc*(s: PSym) -proc InitSystem*(tab: var TSymTab) proc FinishSystem*(tab: TStrTable) proc getSysSym*(name: string): PSym # implementation @@ -154,7 +153,6 @@ proc getCompilerProc(name: string): PSym = proc registerCompilerProc(s: PSym) = strTableAdd(compilerprocs, s) -proc InitSystem(tab: var TSymTab) = nil proc FinishSystem(tab: TStrTable) = nil initStrTable(compilerprocs) diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index ba761739af..4e2a4e5367 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -12,7 +12,7 @@ import os, platform, condsyms, ast, astalgo, idents, semdata, msgs, renderer, wordrecg, ropes, options, strutils, lists, extccomp, math, magicsys, trees, - rodread, types + rodread, types, lookups const FirstCallConv* = wNimcall @@ -42,7 +42,7 @@ const wFatal, wDefine, wUndef, wCompile, wLink, wLinkSys, wPure, wPush, wPop, wBreakpoint, wWatchpoint, wPassL, wPassC, wDeadCodeElim, wDeprecated, wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll, - wLinearScanEnd, wPatterns, wEffects} + wLinearScanEnd, wPatterns, wEffects, wNoForward} lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wDeprecated, wExtern, wThread, wImportcpp, wImportobjc, wNoStackFrame, @@ -182,7 +182,11 @@ proc onOff(c: PContext, n: PNode, op: TOptions) = proc pragmaDeadCodeElim(c: PContext, n: PNode) = if IsTurnedOn(c, n): incl(c.module.flags, sfDeadCodeElim) else: excl(c.module.flags, sfDeadCodeElim) - + +proc pragmaNoForward(c: PContext, n: PNode) = + if IsTurnedOn(c, n): incl(c.module.flags, sfNoForward) + else: excl(c.module.flags, sfNoForward) + proc processCallConv(c: PContext, n: PNode) = if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent): var sw = whichKeyword(n.sons[1].ident) @@ -409,7 +413,7 @@ proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode = if c < 0: sub = substr(str, b + 1) else: sub = substr(str, b + 1, c - 1) if sub != "": - var e = SymtabGet(con.tab, getIdent(sub)) + var e = searchInScopes(con, getIdent(sub)) if e != nil: if e.kind == skStub: loadStub(e) addSon(result, newSymNode(e)) @@ -552,6 +556,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, noVal(it) incl(sym.flags, sfThread) of wDeadCodeElim: pragmaDeadCodeElim(c, it) + of wNoForward: pragmaNoForward(c, it) of wMagic: processMagic(c, it, sym) of wCompileTime: noVal(it) diff --git a/compiler/procfind.nim b/compiler/procfind.nim index 2db6247e11..aefccd140f 100644 --- a/compiler/procfind.nim +++ b/compiler/procfind.nim @@ -30,11 +30,12 @@ proc equalGenericParams(procA, procB: PNode): bool = if not ExprStructuralEquivalent(a.ast, b.ast): return result = true -proc SearchForProc*(c: PContext, fn: PSym, tos: int): PSym = - # Searchs for the fn in the symbol table. If the parameter lists are exactly +proc SearchForProc*(c: PContext, scope: PScope, fn: PSym): PSym = + # Searchs for a forward declaration or a "twin" symbol of fn + # in the symbol table. If the parameter lists are exactly # the same the sym in the symbol table is returned, else nil. var it: TIdentIter - result = initIdentIter(it, c.tab.stack[tos], fn.Name) + result = initIdentIter(it, scope.symbols, fn.Name) if isGenericRoutine(fn): # we simply check the AST; this is imprecise but nearly the best what # can be done; this doesn't work either though as type constraints are @@ -48,7 +49,7 @@ proc SearchForProc*(c: PContext, fn: PSym, tos: int): PSym = fn.ast.sons[paramsPos]) and equalGenericParams(genR, genF): return - result = NextIdentIter(it, c.tab.stack[tos]) + result = NextIdentIter(it, scope.symbols) else: while result != nil: if result.Kind == fn.kind and not isGenericRoutine(result): @@ -60,7 +61,7 @@ proc SearchForProc*(c: PContext, fn: PSym, tos: int): PSym = return of paramsNotEqual: nil - result = NextIdentIter(it, c.tab.stack[tos]) + result = NextIdentIter(it, scope.symbols) when false: proc paramsFitBorrow(child, parent: PNode): bool = @@ -76,16 +77,16 @@ when false: dcEqOrDistinctOf): return result = true - proc SearchForBorrowProc*(c: PContext, fn: PSym, tos: int): PSym = + proc SearchForBorrowProc*(c: PContext, startScope: PScope, fn: PSym): PSym = # Searchs for the fn in the symbol table. If the parameter lists are suitable # for borrowing the sym in the symbol table is returned, else nil. var it: TIdentIter - for scope in countdown(tos, 0): - result = initIdentIter(it, c.tab.stack[scope], fn.Name) + for scope in walkScopes(startScope): + result = initIdentIter(it, scope.symbols, fn.Name) while result != nil: # watchout! result must not be the same as fn! if (result.Kind == fn.kind) and (result.id != fn.id): if equalGenericParams(result.ast.sons[genericParamsPos], fn.ast.sons[genericParamsPos]): if paramsFitBorrow(fn.typ.n, result.typ.n): return - result = NextIdentIter(it, c.tab.stack[scope]) + result = NextIdentIter(it, scope.symbols) diff --git a/compiler/sem.nim b/compiler/sem.nim index 92b25b1baf..671bd00434 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -99,7 +99,7 @@ proc commonType*(x, y: PType): PType = result.addSonSkipIntLit(r) proc isTopLevel(c: PContext): bool {.inline.} = - result = c.tab.tos <= 2 + result = c.currentScope.depthLevel <= 2 proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym = result = newSym(kind, considerAcc(n), getCurrOwner(), n.info) @@ -247,15 +247,14 @@ proc myOpen(module: PSym): PPassContext = c.semTypeNode = semTypeNode pushProcCon(c, module) pushOwner(c.module) - openScope(c.tab) # scope for imported symbols - SymTabAdd(c.tab, module) # a module knows itself + c.importTable = openScope(c) + c.importTable.addSym(module) # a module knows itself if sfSystemModule in module.flags: magicsys.SystemModule = module # set global variable! - InitSystem(c.tab) # currently does nothing else: - SymTabAdd(c.tab, magicsys.SystemModule) # import the "System" identifier + c.importTable.addSym magicsys.SystemModule # import the "System" identifier importAllSymbols(c, magicsys.SystemModule) - openScope(c.tab) # scope for the module's symbols + c.topLevelScope = openScope(c) result = c proc myOpenCached(module: PSym, rd: PRodReader): PPassContext = @@ -281,7 +280,7 @@ proc RecoverContext(c: PContext) = # clean up in case of a semantic error: We clean up the stacks, etc. This is # faster than wrapping every stack operation in a 'try finally' block and # requires far less code. - while c.tab.tos-1 > ModuleTablePos: rawCloseScope(c.tab) + c.currentScope = c.topLevelScope while getCurrOwner().kind != skModule: popOwner() while c.p != nil and c.p.owner.kind != skModule: c.p = c.p.next @@ -310,8 +309,8 @@ proc checkThreads(c: PContext) = proc myClose(context: PPassContext, n: PNode): PNode = var c = PContext(context) - closeScope(c.tab) # close module's scope - rawCloseScope(c.tab) # imported symbols; don't check for unused ones! + closeScope(c) # close module's scope + rawCloseScope(c) # imported symbols; don't check for unused ones! result = newNode(nkStmtList) if n != nil: InternalError(n.info, "n is not nil") #result := n; diff --git a/compiler/semcall.nim b/compiler/semcall.nim index be41299ad7..735e6fac8e 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -32,6 +32,8 @@ proc sameMethodDispatcher(a, b: PSym): bool = # be disambiguated by the programmer; this way the right generic is # instantiated. +proc determineType(c: PContext, s: PSym) + proc resolveOverloads(c: PContext, n, orig: PNode, filter: TSymKinds): TCandidate = var initialBinding: PNode @@ -58,6 +60,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode, while sym != nil: if sym.kind in filter: + determineType(c, sym) initCandidate(z, sym, initialBinding, o.lastOverloadScope) z.calleeSym = sym matches(c, n, orig, z) @@ -198,7 +201,7 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = else: result = explicitGenericInstError(n) -proc SearchForBorrowProc(c: PContext, fn: PSym, tos: int): PSym = +proc SearchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym = # Searchs for the fn in the symbol table. If the parameter lists are suitable # for borrowing the sym in the symbol table is returned, else nil. # New approach: generate fn(x, y, z) where x, y, z have the proper types diff --git a/compiler/semdata.nim b/compiler/semdata.nim index afce365f96..4c94d08129 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -44,10 +44,13 @@ type efLValue, efWantIterator, efInTypeof, efWantStmt, efDetermineType, efAllowDestructor TExprFlags* = set[TExprFlag] - + PContext* = ref TContext TContext* = object of TPassContext # a context represents a module module*: PSym # the module sym belonging to the context + currentScope*: PScope # current scope + importTable*: PScope # scope for all imported symbols + topLevelScope*: PScope # scope for all top-level symbols p*: PProcCon # procedure context friendModule*: PSym # current friend module; may access private data; # this is used so that generic instantiations @@ -55,7 +58,6 @@ type InstCounter*: int # to prevent endless instantiations threadEntries*: TSymSeq # list of thread entries to check - tab*: TSymTab # each module has its own symbol table AmbiguousSymbols*: TIntSet # ids of all ambiguous symbols (cannot # store this info in the syms themselves!) InGenericContext*: int # > 0 if we are in a generic type @@ -82,8 +84,7 @@ type # naming it multiple times generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile lastGenericIdx*: int # used for the generics stack - - + proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair = result.genericSym = s result.inst = inst @@ -103,6 +104,10 @@ proc makeVarType*(c: PContext, baseType: PType): PType proc newTypeS*(kind: TTypeKind, c: PContext): PType proc fillTypeS*(dest: PType, kind: TTypeKind, c: PContext) +proc scopeDepth*(c: PContext): int {.inline.} = + result = if c.currentScope != nil: c.currentScope.depthLevel + else: 0 + # owner handling: proc getCurrOwner*(): PSym proc PushOwner*(owner: PSym) @@ -151,7 +156,6 @@ proc newOptionEntry(): POptionEntry = proc newContext(module: PSym): PContext = new(result) - InitSymTab(result.tab) result.AmbiguousSymbols = initIntset() initLinkedList(result.optionStack) initLinkedList(result.libs) diff --git a/compiler/semdestruct.nim b/compiler/semdestruct.nim index 2383ac6496..797d8895e6 100644 --- a/compiler/semdestruct.nim +++ b/compiler/semdestruct.nim @@ -120,7 +120,7 @@ proc instantiateDestructor(c: PContext, typ: PType): bool = of tySequence, tyArray, tyArrayConstr, tyOpenArray, tyVarargs: if instantiateDestructor(c, t.sons[0]): if rangeDestructorProc == nil: - rangeDestructorProc = SymtabGet(c.tab, getIdent"nimDestroyRange") + rangeDestructorProc = searchInScopes(c, getIdent"nimDestroyRange") t.destructor = rangeDestructorProc return true else: diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 93dfc2f374..4f5c4fce52 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -328,9 +328,9 @@ proc semOpAux(c: PContext, n: PNode) = proc overloadedCallOpr(c: PContext, n: PNode): PNode = # quick check if there is *any* () operator overloaded: var par = getIdent("()") - if SymtabGet(c.Tab, par) == nil: + if searchInScopes(c, par) == nil: result = nil - else: + else: result = newNodeI(nkCall, n.info) addSon(result, newIdentNode(par, n.info)) for i in countup(0, sonsLen(n) - 1): addSon(result, n.sons[i]) @@ -937,7 +937,7 @@ proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = addSon(result, copyTree(n[0])) else: var i = considerAcc(n.sons[1]) - var f = SymTabGet(c.tab, i) + var f = searchInScopes(c, i) # if f != nil and f.kind == skStub: loadStub(f) # ``loadStub`` is not correct here as we don't care for ``f`` really if f != nil: @@ -1139,7 +1139,7 @@ proc SemReturn(c: PContext, n: PNode): PNode = LocalError(n.info, errXNotAllowedHere, "\'return\'") proc semProcBody(c: PContext, n: PNode): PNode = - openScope(c.tab) + openScope(c) result = semExpr(c, n) if c.p.resultSym != nil and not isEmptyType(result.typ): # transform ``expr`` to ``result = expr``, but not if the expr is already @@ -1163,7 +1163,7 @@ proc semProcBody(c: PContext, n: PNode): PNode = result = semAsgn(c, a) else: discardCheck(result) - closeScope(c.tab) + closeScope(c) proc SemYieldVarResult(c: PContext, n: PNode, restype: PType) = var t = skipTypes(restype, {tyGenericInst}) @@ -1205,9 +1205,9 @@ proc SemYield(c: PContext, n: PNode): PNode = proc lookUpForDefined(c: PContext, i: PIdent, onlyCurrentScope: bool): PSym = if onlyCurrentScope: - result = SymtabLocalGet(c.tab, i) + result = localSearchInScope(c, i) else: - result = SymtabGet(c.Tab, i) # no need for stub loading + result = searchInScopes(c, i) # no need for stub loading proc LookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym = case n.kind @@ -1222,7 +1222,7 @@ proc LookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym = if (n.sons[1].kind == nkIdent): var ident = n.sons[1].ident if m == c.module: - result = StrTableGet(c.tab.stack[ModuleTablePos], ident) + result = StrTableGet(c.topLevelScope.symbols, ident) else: result = StrTableGet(m.tab, ident) else: @@ -1374,8 +1374,8 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = msgs.gErrorMax = high(int) # open a scope for temporary symbol inclusions: - let oldTos = c.tab.tos - openScope(c.tab) + let oldScope = c.currentScope + openScope(c) let oldOwnerLen = len(gOwners) let oldGenerics = c.generics let oldContextLen = msgs.getInfoContextLen() @@ -1398,7 +1398,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = c.p = oldProcCon msgs.setInfoContextLen(oldContextLen) setlen(gOwners, oldOwnerLen) - while c.tab.tos > oldTos: rawCloseScope(c.tab) + c.currentScope = oldScope dec c.InCompilesContext dec msgs.gSilence msgs.gErrorCounter = oldErrorCount @@ -1641,7 +1641,7 @@ proc semBlock(c: PContext, n: PNode): PNode = result = n Inc(c.p.nestedBlockCounter) checkSonsLen(n, 2) - openScope(c.tab) # BUGFIX: label is in the scope of block! + openScope(c) # BUGFIX: label is in the scope of block! if n.sons[0].kind != nkEmpty: var labl = newSymG(skLabel, n.sons[0], c) if sfGenSym notin labl.flags: @@ -1652,7 +1652,7 @@ proc semBlock(c: PContext, n: PNode): PNode = n.typ = n.sons[1].typ if isEmptyType(n.typ): n.kind = nkBlockStmt else: n.kind = nkBlockExpr - closeScope(c.tab) + closeScope(c) Dec(c.p.nestedBlockCounter) proc buildCall(n: PNode): PNode = @@ -1671,11 +1671,17 @@ proc buildCall(n: PNode): PNode = else: result = n +proc doBlockIsStmtList(n: PNode): bool = + result = n.kind == nkDo and + n[paramsPos].sonsLen == 1 and + n[paramsPos][0].kind == nkEmpty + proc fixImmediateParams(n: PNode): PNode = # XXX: Temporary work-around until we carry out # the planned overload resolution reforms for i in 1 .. ModuleTablePos, section)) + SuggestWriteln(SymToStr(it, isLocal = isLocal, section)) inc outputs proc suggestSymList(c: PContext, list: PNode, outputs: var int) = @@ -123,11 +125,14 @@ proc suggestOperations(c: PContext, n: PNode, typ: PType, outputs: var int) = proc suggestEverything(c: PContext, n: PNode, outputs: var int) = # do not produce too many symbols: - for i in countdown(c.tab.tos-1, 1): - for it in items(c.tab.stack[i]): + var isLocal = true + for scope in walkScopes(c.currentScope): + if scope == c.topLevelScope: isLocal = false + for it in items(scope.symbols): if filterSym(it): - SuggestWriteln(SymToStr(it, isLocal = i > ModuleTablePos, sectionSuggest)) + SuggestWriteln(SymToStr(it, isLocal = isLocal, sectionSuggest)) inc outputs + if scope == c.topLevelScope: break proc suggestFieldAccess(c: PContext, n: PNode, outputs: var int) = # special code that deals with ``myObj.``. `n` is NOT the nkDotExpr-node, but @@ -138,7 +143,7 @@ proc suggestFieldAccess(c: PContext, n: PNode, outputs: var int) = if n.kind == nkSym and n.sym.kind == skModule: if n.sym == c.module: # all symbols accessible, because we are in the current module: - for it in items(c.tab.stack[ModuleTablePos]): + for it in items(c.topLevelScope.symbols): if filterSym(it): SuggestWriteln(SymToStr(it, isLocal=false, sectionSuggest)) inc outputs diff --git a/compiler/types.nim b/compiler/types.nim index 6f47a7f2dc..3096b73c8e 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1016,8 +1016,9 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool = of tyExpr, tyStmt, tyTypeDesc: result = true # XXX er ... no? these should not be allowed! - of tyGenericBody, tyGenericParam, tyForward, tyNone, tyGenericInvokation, - tyTypeClass: + of tyTypeClass: + result = true + of tyGenericBody, tyGenericParam, tyForward, tyNone, tyGenericInvokation: result = false of tyEmpty, tyNil: result = kind == skConst diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index 3ad2f45cae..36d08c7182 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -53,7 +53,7 @@ type wFloatchecks, wNanChecks, wInfChecks, wAssertions, wPatterns, wWarnings, wHints, wOptimization, wRaises, wWrites, wReads, wSize, wEffects, wTags, - wDeadCodeElim, wSafecode, + wDeadCodeElim, wSafecode, wNoForward, wPragma, wCompileTime, wNoInit, wPassc, wPassl, wBorrow, wDiscardable, @@ -135,7 +135,7 @@ const "assertions", "patterns", "warnings", "hints", "optimization", "raises", "writes", "reads", "size", "effects", "tags", - "deadcodeelim", "safecode", + "deadcodeelim", "safecode", "noforward", "pragma", "compiletime", "noinit", "passc", "passl", "borrow", "discardable", "fieldchecks", diff --git a/doc/manual.txt b/doc/manual.txt index e6fe5fbdb6..f7b2314c19 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -4649,6 +4649,51 @@ Example: .. code-block:: nimrod {.deadCodeElim: on.} +NoForward pragma +---------------- +The `noforward`:idx pragma can be used to turn on and off a special compilation +mode that to large extent eliminates the need for forward declarations. In this +mode, the proc definitions may appear out of order and the compiler will postpone +their semantic analysis and compilation until it actually needs to generate code +using the definitions. In this regard, this mode is similar to the modus operandi +of dynamic scripting languages, where the function calls are not resolved until +the code is executed. Here is the detailed algorithm taken by the compiler: + +1. When a callable symbol is first encountered, the compiler will only note the +symbol callable name and it will add it to the appropriate overload set in the +current scope. At this step, it won't try to resolve any of the type expressions +used in the signature of the symbol (so they can refer to other not yet defined +symbols). + +2. When a top level call is encountered (usually at the very end of the module), +the compiler will try to determine the actual types of all of the symbols in the +matching overload set. This is a potentially recursive process as the signatures +of the symbols may include other call expressions, whoose types will be resolved +at this point too. + +3. Finally, after the best overload is picked, the compiler will start compiling +the body of the respective symbol. This in turn will lead the compiler to discover +more call expresions that need to be resolved and steps 2 and 3 will be repeated +as necessary. + +Please note that if a callable symbol is never used in this scenario, its body +will never be compiled. This is the default behavior leading to best compilation +times, but if exhaustive compilation of all definitions is required, using +``nimrod check`` provides this option as well. + +Example: + +.. code-block: nimrod + + {. noforward: on .} + + proc foo(x: int) = + bar x + + proc bar(x: int) = + echo x + + foo(10) Pragma pragma ------------- diff --git a/lib/pure/xmltree.nim b/lib/pure/xmltree.nim index 8cf484bfc7..e3fc272379 100644 --- a/lib/pure/xmltree.nim +++ b/lib/pure/xmltree.nim @@ -78,7 +78,7 @@ proc innerText*(n: PXmlNode): string = result = "" assert n.k == xnElement for i in 0 .. n.s.len-1: - if n.s[i].k in {xnText, xnEntity}: result.add(n.fText) + if n.s[i].k in {xnText, xnEntity}: result.add(n.s[i].fText) proc tag*(n: PXmlNode): string {.inline.} = ## gets the tag name of `n`. `n` has to be an ``xnElement`` node. diff --git a/tests/compile/tnoforward.nim b/tests/compile/tnoforward.nim new file mode 100644 index 0000000000..0359ff3487 --- /dev/null +++ b/tests/compile/tnoforward.nim @@ -0,0 +1,10 @@ +{. noforward: on .} + +proc foo(x: int) = + bar x + +proc bar(x: int) = + echo x + +foo(10) + diff --git a/tests/reject/tbindtypedesc.nim b/tests/reject/tbindtypedesc.nim new file mode 100644 index 0000000000..d6fbae5374 --- /dev/null +++ b/tests/reject/tbindtypedesc.nim @@ -0,0 +1,12 @@ +discard """ + line: 11 + file: "tbindtypedesc.nim" + errormsg: "type mismatch: got (typedesc[float], string)" +""" + +proc foo(T: typedesc; some: T) = + echo($some) + +foo int, 4 +foo float, "bad" + diff --git a/tests/reject/tstmtexp.nim b/tests/reject/tstmtexp.nim index 50248ad329..7cbf2eb3dd 100644 --- a/tests/reject/tstmtexp.nim +++ b/tests/reject/tstmtexp.nim @@ -3,8 +3,7 @@ discard """ line: 8 errormsg: "value returned by statement has to be discarded" """ -# Test 3 - -1+4 #ERROR_MSG value returned by statement has to be discarded +# Test 3 +1+4 #ERROR_MSG value returned by statement has to be discarded diff --git a/web/news.txt b/web/news.txt index ef42554025..7c46e550a1 100644 --- a/web/news.txt +++ b/web/news.txt @@ -56,6 +56,8 @@ Compiler Additions to be turned on explicitly via ``--warning[ShadowIdent]:on``. - The compiler now supports almost every pragma in a ``push`` pragma. - Generic converters have been implemented. +- Added a ``noforward`` pragma enabling a special compilation mode that largely + eliminates the need for forward declarations. Language Additions