Merge branch 'master' of github.com:Araq/Nimrod

This commit is contained in:
Araq 2013-05-14 00:59:07 +02:00
commit 635ad3b336
31 changed files with 460 additions and 331 deletions

View file

@ -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 %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 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 %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 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\lexbase.c -o build\1_1\lexbase.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 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 %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 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 %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 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 %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 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 %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 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 %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 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 %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 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\ecmasgen.c -o build\1_1\ecmasgen.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 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 %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 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 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 %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 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\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\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 ECHO SUCCESS

View file

@ -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 %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 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 %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 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\lexbase.c -o build\1_2\lexbase.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 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 %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 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 %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 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 %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 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 %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 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 %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 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 %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 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\ecmasgen.c -o build\1_2\ecmasgen.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 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 %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 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 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 %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 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\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\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 ECHO SUCCESS

View file

@ -13,10 +13,6 @@ import
msgs, hashes, nversion, options, strutils, crc, ropes, idents, lists, msgs, hashes, nversion, options, strutils, crc, ropes, idents, lists,
intsets, idgen intsets, idgen
const
ImportTablePos* = 0 # imported symbols are at level 0
ModuleTablePos* = 1 # module's top level symbols are at level 1
type type
TCallingConvention* = enum TCallingConvention* = enum
ccDefault, # proc has no explicit calling convention ccDefault, # proc has no explicit calling convention
@ -284,6 +280,9 @@ const
sfHoist* = sfVolatile ## proc return value can be hoisted sfHoist* = sfVolatile ## proc return value can be hoisted
sfNoForward* = sfRegister
# forward declarations are not required (per module)
const const
# getting ready for the future expr/stmt merge # getting ready for the future expr/stmt merge
nkWhen* = nkWhenStmt nkWhen* = nkWhenStmt
@ -609,6 +608,13 @@ type
PInstantiation* = ref TInstantiation PInstantiation* = ref TInstantiation
TScope* = object
depthLevel*: int
symbols*: TStrTable
parent*: PScope
PScope* = ref TScope
PLib* = ref TLib PLib* = ref TLib
TSym* {.acyclic.} = object of TIdObj TSym* {.acyclic.} = object of TIdObj
# proc and type instantiations are cached in the generic symbol # proc and type instantiations are cached in the generic symbol
@ -617,12 +623,14 @@ type
typeInstCache*: seq[PType] typeInstCache*: seq[PType]
of routineKinds: of routineKinds:
procInstCache*: seq[PInstantiation] procInstCache*: seq[PInstantiation]
scope*: PScope # the scope where the proc was defined
of skModule: of skModule:
# modules keep track of the generic symbols they use from other modules. # modules keep track of the generic symbols they use from other modules.
# this is because in incremental compilation, when a module is about to # this is because in incremental compilation, when a module is about to
# be replaced with a newer version, we must decrement the usage count # be replaced with a newer version, we must decrement the usage count
# of all previously used generics. # of all previously used generics.
usedGenerics*: seq[PInstantiation] usedGenerics*: seq[PInstantiation]
tab*: TStrTable # interface table for modules
else: nil else: nil
magic*: TMagic magic*: TMagic
@ -631,7 +639,6 @@ type
info*: TLineInfo info*: TLineInfo
owner*: PSym owner*: PSym
flags*: TSymFlags flags*: TSymFlags
tab*: TStrTable # interface table for modules
ast*: PNode # syntax tree of proc, iterator, etc.: ast*: PNode # syntax tree of proc, iterator, etc.:
# the whole proc including header; this is used # the whole proc including header; this is used
# for easy generation of proper error messages # for easy generation of proper error messages
@ -1053,6 +1060,7 @@ proc copySym(s: PSym, keepId: bool = false): PSym =
when debugIds: RegisterId(result) when debugIds: RegisterId(result)
result.flags = s.flags result.flags = s.flags
result.magic = s.magic result.magic = s.magic
if s.kind == skModule:
copyStrTable(result.tab, s.tab) copyStrTable(result.tab, s.tab)
result.options = s.options result.options = s.options
result.position = s.position result.position = s.position
@ -1080,6 +1088,9 @@ proc initStrTable(x: var TStrTable) =
x.counter = 0 x.counter = 0
newSeq(x.data, startSize) newSeq(x.data, startSize)
proc newStrTable*: TStrTable =
initStrTable(result)
proc initTable(x: var TTable) = proc initTable(x: var TTable) =
x.counter = 0 x.counter = 0
newSeq(x.data, startSize) newSeq(x.data, startSize)

View file

@ -72,37 +72,6 @@ type
proc InitIdentIter*(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym proc InitIdentIter*(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym
proc NextIdentIter*(ti: var TIdentIter, tab: TStrTable): 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 # these are for debugging only: They are not really deprecated, but I want
# the warning so that release versions do not contain debugging statements: # the warning so that release versions do not contain debugging statements:
proc debug*(n: PSym) {.deprecated.} proc debug*(n: PSym) {.deprecated.}
@ -709,51 +678,6 @@ proc NextIter(ti: var TTabIter, tab: TStrTable): PSym =
Inc(ti.h) # ... and increment by one always Inc(ti.h) # ... and increment by one always
if result != nil: break 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 = iterator items*(tab: TStrTable): PSym =
var it: TTabIter var it: TTabIter
var s = InitTabIter(it, tab) var s = InitTabIter(it, tab)
@ -761,10 +685,6 @@ iterator items*(tab: TStrTable): PSym =
yield s yield s
s = NextIter(it, tab) 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 = proc hasEmptySlot(data: TIdPairSeq): bool =
for h in countup(0, high(data)): for h in countup(0, high(data)):
if data[h].key == nil: if data[h].key == nil:

View file

@ -842,8 +842,10 @@ proc requestConstImpl(p: BProc, sym: PSym) =
if sfExportc in sym.flags and generatedHeader != nil: if sfExportc in sym.flags and generatedHeader != nil:
app(generatedHeader.s[cfsData], headerDecl) app(generatedHeader.s[cfsData], headerDecl)
proc isActivated(prc: PSym): bool = prc.typ != nil
proc genProc(m: BModule, prc: PSym) = proc genProc(m: BModule, prc: PSym) =
if sfBorrow in prc.flags: return if sfBorrow in prc.flags or not isActivated(prc): return
fillProcLoc(prc) fillProcLoc(prc)
if {sfForward, sfFromGeneric} * prc.flags != {}: addForwardedProc(m, prc) if {sfForward, sfFromGeneric} * prc.flags != {}: addForwardedProc(m, prc)
else: else:

View file

@ -48,7 +48,7 @@ proc rawImportSymbol(c: PContext, s: PSym) =
# This does not handle stubs, because otherwise loading on demand would be # This does not handle stubs, because otherwise loading on demand would be
# pointless in practice. So importing stubs is fine here! # pointless in practice. So importing stubs is fine here!
# check if we have already a symbol of the same name: # 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 check != nil and check.id != s.id:
if s.kind notin OverloadableSyms: if s.kind notin OverloadableSyms:
# s and check need to be qualified: # s and check need to be qualified:
@ -56,7 +56,7 @@ proc rawImportSymbol(c: PContext, s: PSym) =
Incl(c.AmbiguousSymbols, check.id) Incl(c.AmbiguousSymbols, check.id)
# thanks to 'export' feature, it could be we import the same symbol from # thanks to 'export' feature, it could be we import the same symbol from
# multiple sources, so we need to call 'StrTableAdd' here: # multiple sources, so we need to call 'StrTableAdd' here:
StrTableAdd(c.tab.stack[importTablePos], s) StrTableAdd(c.importTable.symbols, s)
if s.kind == skType: if s.kind == skType:
var etyp = s.typ var etyp = s.typ
if etyp.kind in {tyBool, tyEnum} and sfPure notin s.flags: 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 # have been put into the symbol table
# BUGFIX: but only iff they are the same symbols! # BUGFIX: but only iff they are the same symbols!
var it: TIdentIter var it: TIdentIter
check = InitIdentIter(it, c.tab.stack[importTablePos], e.name) check = InitIdentIter(it, c.importTable.symbols, e.name)
while check != nil: while check != nil:
if check.id == e.id: if check.id == e.id:
e = nil e = nil
break break
check = NextIdentIter(it, c.tab.stack[importTablePos]) check = NextIdentIter(it, c.importTable.symbols)
if e != nil: if e != nil:
rawImportSymbol(c, e) rawImportSymbol(c, e)
else: else:

View file

@ -13,6 +13,8 @@ import
intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread, intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread,
renderer, wordrecg, idgen renderer, wordrecg, idgen
proc ensureNoMissingOrUnusedSymbols(scope: PScope)
proc considerAcc*(n: PNode): PIdent = proc considerAcc*(n: PNode): PIdent =
case n.kind case n.kind
of nkIdent: result = n.ident of nkIdent: result = n.ident
@ -33,6 +35,49 @@ proc considerAcc*(n: PNode): PIdent =
else: else:
GlobalError(n.info, errIdentifierExpected, renderTree(n)) 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 = proc errorSym*(c: PContext, n: PNode): PSym =
## creates an error symbol to avoid cascading errors (for IDE support) ## creates an error symbol to avoid cascading errors (for IDE support)
var m = n var m = n
@ -46,17 +91,18 @@ proc errorSym*(c: PContext, n: PNode): PSym =
result.typ = errorType(c) result.typ = errorType(c)
incl(result.flags, sfDiscardable) incl(result.flags, sfDiscardable)
# pretend it's imported from some unknown module to prevent cascading errors: # pretend it's imported from some unknown module to prevent cascading errors:
SymTabAddAt(c.tab, result, ast.ImportTablePos) c.importTable.addSym(result)
type type
TOverloadIterMode* = enum TOverloadIterMode* = enum
oimDone, oimNoQualifier, oimSelfModule, oimOtherModule, oimSymChoice, oimDone, oimNoQualifier, oimSelfModule, oimOtherModule, oimSymChoice,
oimSymChoiceLocalLookup oimSymChoiceLocalLookup
TOverloadIter*{.final.} = object TOverloadIter*{.final.} = object
stackPtr*: int
it*: TIdentIter it*: TIdentIter
m*: PSym m*: PSym
mode*: TOverloadIterMode mode*: TOverloadIterMode
symChoiceIndex*: int
scope*: PScope
inSymChoice: TIntSet inSymChoice: TIntSet
proc getSymRepr*(s: PSym): string = proc getSymRepr*(s: PSym): string =
@ -64,13 +110,10 @@ proc getSymRepr*(s: PSym): string =
of skProc, skMethod, skConverter, skIterator: result = getProcHeader(s) of skProc, skMethod, skConverter, skIterator: result = getProcHeader(s)
else: result = s.name.s else: result = s.name.s
proc CloseScope*(tab: var TSymTab) = proc ensureNoMissingOrUnusedSymbols(scope: PScope) =
# check if all symbols have been used and defined: # check if all symbols have been used and defined:
if tab.tos > len(tab.stack):
InternalError("CloseScope")
return
var it: TTabIter var it: TTabIter
var s = InitTabIter(it, tab.stack[tab.tos-1]) var s = InitTabIter(it, scope.symbols)
var missingImpls = 0 var missingImpls = 0
while s != nil: while s != nil:
if sfForward in s.flags: if sfForward in s.flags:
@ -83,25 +126,21 @@ proc CloseScope*(tab: var TSymTab) =
# BUGFIX: check options in s! # BUGFIX: check options in s!
if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam}: if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam}:
Message(s.info, hintXDeclaredButNotUsed, getSymRepr(s)) Message(s.info, hintXDeclaredButNotUsed, getSymRepr(s))
s = NextIter(it, tab.stack[tab.tos-1]) s = NextIter(it, scope.symbols)
astalgo.rawCloseScope(tab)
proc WrongRedefinition*(info: TLineInfo, s: string) = proc WrongRedefinition*(info: TLineInfo, s: string) =
if gCmd != cmdInteractive: if gCmd != cmdInteractive:
localError(info, errAttemptToRedefine, s) 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) = proc addDecl*(c: PContext, sym: PSym) =
if SymTabAddUnique(c.tab, sym) == Failure: if c.currentScope.addUniqueSym(sym) == Failure:
WrongRedefinition(sym.info, sym.Name.s) WrongRedefinition(sym.info, sym.Name.s)
proc addPrelimDecl*(c: PContext, sym: PSym) = proc addPrelimDecl*(c: PContext, sym: PSym) =
discard SymTabAddUnique(c.tab, sym) discard c.currentScope.addUniqueSym(sym)
proc addDeclAt*(c: PContext, sym: PSym, at: Natural) = proc addDeclAt*(scope: PScope, sym: PSym) =
if SymTabAddUniqueAt(c.tab, sym, at) == Failure: if scope.addUniqueSym(sym) == Failure:
WrongRedefinition(sym.info, sym.Name.s) WrongRedefinition(sym.info, sym.Name.s)
proc AddInterfaceDeclAux(c: PContext, sym: PSym) = proc AddInterfaceDeclAux(c: PContext, sym: PSym) =
@ -110,35 +149,35 @@ proc AddInterfaceDeclAux(c: PContext, sym: PSym) =
if c.module != nil: StrTableAdd(c.module.tab, sym) if c.module != nil: StrTableAdd(c.module.tab, sym)
else: InternalError(sym.info, "AddInterfaceDeclAux") else: InternalError(sym.info, "AddInterfaceDeclAux")
proc addInterfaceDeclAt*(c: PContext, sym: PSym, at: Natural) = proc addInterfaceDeclAt*(c: PContext, scope: PScope, sym: PSym) =
addDeclAt(c, sym, at) addDeclAt(scope, sym)
AddInterfaceDeclAux(c, sym) AddInterfaceDeclAux(c, sym)
proc addOverloadableSymAt*(c: PContext, fn: PSym, at: Natural) = proc addOverloadableSymAt*(scope: PScope, fn: PSym) =
if fn.kind notin OverloadableSyms: if fn.kind notin OverloadableSyms:
InternalError(fn.info, "addOverloadableSymAt") InternalError(fn.info, "addOverloadableSymAt")
return 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: if check != nil and check.Kind notin OverloadableSyms:
WrongRedefinition(fn.info, fn.Name.s) WrongRedefinition(fn.info, fn.Name.s)
else: else:
SymTabAddAt(c.tab, fn, at) scope.addSym(fn)
proc addInterfaceDecl*(c: PContext, sym: PSym) = proc addInterfaceDecl*(c: PContext, sym: PSym) =
# it adds the symbol to the interface if appropriate # it adds the symbol to the interface if appropriate
addDecl(c, sym) addDecl(c, sym)
AddInterfaceDeclAux(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 # it adds the symbol to the interface if appropriate
addOverloadableSymAt(c, sym, at) addOverloadableSymAt(scope, sym)
AddInterfaceDeclAux(c, sym) AddInterfaceDeclAux(c, sym)
proc lookUp*(c: PContext, n: PNode): PSym = proc lookUp*(c: PContext, n: PNode): PSym =
# Looks up a symbol. Generates an error in case of nil. # Looks up a symbol. Generates an error in case of nil.
case n.kind case n.kind
of nkIdent: of nkIdent:
result = SymtabGet(c.Tab, n.ident) result = searchInScopes(c, n.ident)
if result == nil: if result == nil:
LocalError(n.info, errUndeclaredIdentifier, n.ident.s) LocalError(n.info, errUndeclaredIdentifier, n.ident.s)
result = errorSym(c, n) result = errorSym(c, n)
@ -146,7 +185,7 @@ proc lookUp*(c: PContext, n: PNode): PSym =
result = n.sym result = n.sym
of nkAccQuoted: of nkAccQuoted:
var ident = considerAcc(n) var ident = considerAcc(n)
result = SymtabGet(c.Tab, ident) result = searchInScopes(c, ident)
if result == nil: if result == nil:
LocalError(n.info, errUndeclaredIdentifier, ident.s) LocalError(n.info, errUndeclaredIdentifier, ident.s)
result = errorSym(c, n) result = errorSym(c, n)
@ -165,7 +204,7 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
case n.kind case n.kind
of nkIdent, nkAccQuoted: of nkIdent, nkAccQuoted:
var ident = considerAcc(n) var ident = considerAcc(n)
result = SymtabGet(c.Tab, ident) result = searchInScopes(c, ident)
if result == nil and checkUndeclared in flags: if result == nil and checkUndeclared in flags:
LocalError(n.info, errUndeclaredIdentifier, ident.s) LocalError(n.info, errUndeclaredIdentifier, ident.s)
result = errorSym(c, n) result = errorSym(c, n)
@ -187,7 +226,7 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
ident = considerAcc(n.sons[1]) ident = considerAcc(n.sons[1])
if ident != nil: if ident != nil:
if m == c.module: if m == c.module:
result = StrTableGet(c.tab.stack[ModuleTablePos], ident) result = StrTableGet(c.topLevelScope.symbols, ident)
else: else:
result = StrTableGet(m.tab, ident) result = StrTableGet(m.tab, ident)
if result == nil and checkUndeclared in flags: if result == nil and checkUndeclared in flags:
@ -205,12 +244,15 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
case n.kind case n.kind
of nkIdent, nkAccQuoted: of nkIdent, nkAccQuoted:
var ident = considerAcc(n) var ident = considerAcc(n)
o.stackPtr = c.tab.tos o.scope = c.currentScope
o.mode = oimNoQualifier o.mode = oimNoQualifier
while result == nil: while true:
dec(o.stackPtr) result = InitIdentIter(o.it, o.scope.symbols, ident)
if o.stackPtr < 0: break if result != nil:
result = InitIdentIter(o.it, c.tab.stack[o.stackPtr], ident) break
else:
o.scope = o.scope.parent
if o.scope == nil: break
of nkSym: of nkSym:
result = n.sym result = n.sym
o.mode = oimDone o.mode = oimDone
@ -226,7 +268,7 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
if ident != nil: if ident != nil:
if o.m == c.module: if o.m == c.module:
# a module may access its private members: # 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 o.mode = oimSelfModule
else: else:
result = InitIdentIter(o.it, o.m.tab, ident) 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: of nkClosedSymChoice, nkOpenSymChoice:
o.mode = oimSymChoice o.mode = oimSymChoice
result = n.sons[0].sym result = n.sons[0].sym
o.stackPtr = 1 o.symChoiceIndex = 1
o.inSymChoice = initIntSet() o.inSymChoice = initIntSet()
Incl(o.inSymChoice, result.id) Incl(o.inSymChoice, result.id)
else: nil else: nil
@ -245,9 +287,9 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
proc lastOverloadScope*(o: TOverloadIter): int = proc lastOverloadScope*(o: TOverloadIter): int =
case o.mode case o.mode
of oimNoQualifier: result = o.stackPtr of oimNoQualifier: result = o.scope.depthLevel
of oimSelfModule: result = ModuleTablePos of oimSelfModule: result = 1
of oimOtherModule: result = ImportTablePos of oimOtherModule: result = 0
else: result = -1 else: result = -1
proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = 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: of oimDone:
result = nil result = nil
of oimNoQualifier: of oimNoQualifier:
if o.stackPtr >= 0: if o.scope != nil:
result = nextIdentIter(o.it, c.tab.stack[o.stackPtr]) result = nextIdentIter(o.it, o.scope.symbols)
while result == nil: while result == nil:
dec(o.stackPtr) o.scope = o.scope.parent
if o.stackPtr < 0: break if o.scope == nil: break
result = InitIdentIter(o.it, c.tab.stack[o.stackPtr], o.it.name) result = InitIdentIter(o.it, o.scope.symbols, o.it.name)
# BUGFIX: o.it.name <-> n.ident # BUGFIX: o.it.name <-> n.ident
else: else:
result = nil result = nil
of oimSelfModule: of oimSelfModule:
result = nextIdentIter(o.it, c.tab.stack[ModuleTablePos]) result = nextIdentIter(o.it, c.topLevelScope.symbols)
of oimOtherModule: of oimOtherModule:
result = nextIdentIter(o.it, o.m.tab) result = nextIdentIter(o.it, o.m.tab)
of oimSymChoice: of oimSymChoice:
if o.stackPtr < sonsLen(n): if o.symChoiceIndex < sonsLen(n):
result = n.sons[o.stackPtr].sym result = n.sons[o.symChoiceIndex].sym
Incl(o.inSymChoice, result.id) Incl(o.inSymChoice, result.id)
inc(o.stackPtr) inc o.symChoiceIndex
elif n.kind == nkOpenSymChoice: elif n.kind == nkOpenSymChoice:
# try 'local' symbols too for Koenig's lookup: # try 'local' symbols too for Koenig's lookup:
o.mode = oimSymChoiceLocalLookup o.mode = oimSymChoiceLocalLookup
o.stackPtr = c.tab.tos-1 o.scope = c.currentScope
result = FirstIdentExcluding(o.it, c.tab.stack[o.stackPtr], result = FirstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice) n.sons[0].sym.name, o.inSymChoice)
while result == nil: while result == nil:
dec(o.stackPtr) o.scope = o.scope.parent
if o.stackPtr < 0: break if o.scope == nil: break
result = FirstIdentExcluding(o.it, c.tab.stack[o.stackPtr], result = FirstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice) n.sons[0].sym.name, o.inSymChoice)
of oimSymChoiceLocalLookup: 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: while result == nil:
dec(o.stackPtr) o.scope = o.scope.parent
if o.stackPtr < 0: break if o.scope == nil: break
result = FirstIdentExcluding(o.it, c.tab.stack[o.stackPtr], result = FirstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice) n.sons[0].sym.name, o.inSymChoice)
if result != nil and result.kind == skStub: loadStub(result) if result != nil and result.kind == skStub: loadStub(result)

View file

@ -19,7 +19,6 @@ proc registerSysType*(t: PType)
proc getSysType*(kind: TTypeKind): PType proc getSysType*(kind: TTypeKind): PType
proc getCompilerProc*(name: string): PSym proc getCompilerProc*(name: string): PSym
proc registerCompilerProc*(s: PSym) proc registerCompilerProc*(s: PSym)
proc InitSystem*(tab: var TSymTab)
proc FinishSystem*(tab: TStrTable) proc FinishSystem*(tab: TStrTable)
proc getSysSym*(name: string): PSym proc getSysSym*(name: string): PSym
# implementation # implementation
@ -154,7 +153,6 @@ proc getCompilerProc(name: string): PSym =
proc registerCompilerProc(s: PSym) = proc registerCompilerProc(s: PSym) =
strTableAdd(compilerprocs, s) strTableAdd(compilerprocs, s)
proc InitSystem(tab: var TSymTab) = nil
proc FinishSystem(tab: TStrTable) = nil proc FinishSystem(tab: TStrTable) = nil
initStrTable(compilerprocs) initStrTable(compilerprocs)

View file

@ -12,7 +12,7 @@
import import
os, platform, condsyms, ast, astalgo, idents, semdata, msgs, renderer, os, platform, condsyms, ast, astalgo, idents, semdata, msgs, renderer,
wordrecg, ropes, options, strutils, lists, extccomp, math, magicsys, trees, wordrecg, ropes, options, strutils, lists, extccomp, math, magicsys, trees,
rodread, types rodread, types, lookups
const const
FirstCallConv* = wNimcall FirstCallConv* = wNimcall
@ -42,7 +42,7 @@ const
wFatal, wDefine, wUndef, wCompile, wLink, wLinkSys, wPure, wPush, wPop, wFatal, wDefine, wUndef, wCompile, wLink, wLinkSys, wPure, wPush, wPop,
wBreakpoint, wWatchpoint, wPassL, wPassC, wDeadCodeElim, wDeprecated, wBreakpoint, wWatchpoint, wPassL, wPassC, wDeadCodeElim, wDeprecated,
wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll, wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
wLinearScanEnd, wPatterns, wEffects} wLinearScanEnd, wPatterns, wEffects, wNoForward}
lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader,
wDeprecated, wExtern, wThread, wImportcpp, wImportobjc, wNoStackFrame, wDeprecated, wExtern, wThread, wImportcpp, wImportobjc, wNoStackFrame,
@ -183,6 +183,10 @@ proc pragmaDeadCodeElim(c: PContext, n: PNode) =
if IsTurnedOn(c, n): incl(c.module.flags, sfDeadCodeElim) if IsTurnedOn(c, n): incl(c.module.flags, sfDeadCodeElim)
else: excl(c.module.flags, sfDeadCodeElim) 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) = proc processCallConv(c: PContext, n: PNode) =
if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent): if (n.kind == nkExprColonExpr) and (n.sons[1].kind == nkIdent):
var sw = whichKeyword(n.sons[1].ident) 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) if c < 0: sub = substr(str, b + 1)
else: sub = substr(str, b + 1, c - 1) else: sub = substr(str, b + 1, c - 1)
if sub != "": if sub != "":
var e = SymtabGet(con.tab, getIdent(sub)) var e = searchInScopes(con, getIdent(sub))
if e != nil: if e != nil:
if e.kind == skStub: loadStub(e) if e.kind == skStub: loadStub(e)
addSon(result, newSymNode(e)) addSon(result, newSymNode(e))
@ -552,6 +556,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
noVal(it) noVal(it)
incl(sym.flags, sfThread) incl(sym.flags, sfThread)
of wDeadCodeElim: pragmaDeadCodeElim(c, it) of wDeadCodeElim: pragmaDeadCodeElim(c, it)
of wNoForward: pragmaNoForward(c, it)
of wMagic: processMagic(c, it, sym) of wMagic: processMagic(c, it, sym)
of wCompileTime: of wCompileTime:
noVal(it) noVal(it)

View file

@ -30,11 +30,12 @@ proc equalGenericParams(procA, procB: PNode): bool =
if not ExprStructuralEquivalent(a.ast, b.ast): return if not ExprStructuralEquivalent(a.ast, b.ast): return
result = true result = true
proc SearchForProc*(c: PContext, fn: PSym, tos: int): PSym = proc SearchForProc*(c: PContext, scope: PScope, fn: PSym): PSym =
# Searchs for the fn in the symbol table. If the parameter lists are exactly # 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. # the same the sym in the symbol table is returned, else nil.
var it: TIdentIter var it: TIdentIter
result = initIdentIter(it, c.tab.stack[tos], fn.Name) result = initIdentIter(it, scope.symbols, fn.Name)
if isGenericRoutine(fn): if isGenericRoutine(fn):
# we simply check the AST; this is imprecise but nearly the best what # 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 # 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 fn.ast.sons[paramsPos]) and
equalGenericParams(genR, genF): equalGenericParams(genR, genF):
return return
result = NextIdentIter(it, c.tab.stack[tos]) result = NextIdentIter(it, scope.symbols)
else: else:
while result != nil: while result != nil:
if result.Kind == fn.kind and not isGenericRoutine(result): if result.Kind == fn.kind and not isGenericRoutine(result):
@ -60,7 +61,7 @@ proc SearchForProc*(c: PContext, fn: PSym, tos: int): PSym =
return return
of paramsNotEqual: of paramsNotEqual:
nil nil
result = NextIdentIter(it, c.tab.stack[tos]) result = NextIdentIter(it, scope.symbols)
when false: when false:
proc paramsFitBorrow(child, parent: PNode): bool = proc paramsFitBorrow(child, parent: PNode): bool =
@ -76,16 +77,16 @@ when false:
dcEqOrDistinctOf): return dcEqOrDistinctOf): return
result = true 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 # 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. # for borrowing the sym in the symbol table is returned, else nil.
var it: TIdentIter var it: TIdentIter
for scope in countdown(tos, 0): for scope in walkScopes(startScope):
result = initIdentIter(it, c.tab.stack[scope], fn.Name) result = initIdentIter(it, scope.symbols, fn.Name)
while result != nil: while result != nil:
# watchout! result must not be the same as fn! # watchout! result must not be the same as fn!
if (result.Kind == fn.kind) and (result.id != fn.id): if (result.Kind == fn.kind) and (result.id != fn.id):
if equalGenericParams(result.ast.sons[genericParamsPos], if equalGenericParams(result.ast.sons[genericParamsPos],
fn.ast.sons[genericParamsPos]): fn.ast.sons[genericParamsPos]):
if paramsFitBorrow(fn.typ.n, result.typ.n): return if paramsFitBorrow(fn.typ.n, result.typ.n): return
result = NextIdentIter(it, c.tab.stack[scope]) result = NextIdentIter(it, scope.symbols)

View file

@ -99,7 +99,7 @@ proc commonType*(x, y: PType): PType =
result.addSonSkipIntLit(r) result.addSonSkipIntLit(r)
proc isTopLevel(c: PContext): bool {.inline.} = 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 = proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym =
result = newSym(kind, considerAcc(n), getCurrOwner(), n.info) result = newSym(kind, considerAcc(n), getCurrOwner(), n.info)
@ -247,15 +247,14 @@ proc myOpen(module: PSym): PPassContext =
c.semTypeNode = semTypeNode c.semTypeNode = semTypeNode
pushProcCon(c, module) pushProcCon(c, module)
pushOwner(c.module) pushOwner(c.module)
openScope(c.tab) # scope for imported symbols c.importTable = openScope(c)
SymTabAdd(c.tab, module) # a module knows itself c.importTable.addSym(module) # a module knows itself
if sfSystemModule in module.flags: if sfSystemModule in module.flags:
magicsys.SystemModule = module # set global variable! magicsys.SystemModule = module # set global variable!
InitSystem(c.tab) # currently does nothing
else: else:
SymTabAdd(c.tab, magicsys.SystemModule) # import the "System" identifier c.importTable.addSym magicsys.SystemModule # import the "System" identifier
importAllSymbols(c, magicsys.SystemModule) importAllSymbols(c, magicsys.SystemModule)
openScope(c.tab) # scope for the module's symbols c.topLevelScope = openScope(c)
result = c result = c
proc myOpenCached(module: PSym, rd: PRodReader): PPassContext = 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 # 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 # faster than wrapping every stack operation in a 'try finally' block and
# requires far less code. # requires far less code.
while c.tab.tos-1 > ModuleTablePos: rawCloseScope(c.tab) c.currentScope = c.topLevelScope
while getCurrOwner().kind != skModule: popOwner() while getCurrOwner().kind != skModule: popOwner()
while c.p != nil and c.p.owner.kind != skModule: c.p = c.p.next 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 = proc myClose(context: PPassContext, n: PNode): PNode =
var c = PContext(context) var c = PContext(context)
closeScope(c.tab) # close module's scope closeScope(c) # close module's scope
rawCloseScope(c.tab) # imported symbols; don't check for unused ones! rawCloseScope(c) # imported symbols; don't check for unused ones!
result = newNode(nkStmtList) result = newNode(nkStmtList)
if n != nil: if n != nil:
InternalError(n.info, "n is not nil") #result := n; InternalError(n.info, "n is not nil") #result := n;

View file

@ -32,6 +32,8 @@ proc sameMethodDispatcher(a, b: PSym): bool =
# be disambiguated by the programmer; this way the right generic is # be disambiguated by the programmer; this way the right generic is
# instantiated. # instantiated.
proc determineType(c: PContext, s: PSym)
proc resolveOverloads(c: PContext, n, orig: PNode, proc resolveOverloads(c: PContext, n, orig: PNode,
filter: TSymKinds): TCandidate = filter: TSymKinds): TCandidate =
var initialBinding: PNode var initialBinding: PNode
@ -58,6 +60,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
while sym != nil: while sym != nil:
if sym.kind in filter: if sym.kind in filter:
determineType(c, sym)
initCandidate(z, sym, initialBinding, o.lastOverloadScope) initCandidate(z, sym, initialBinding, o.lastOverloadScope)
z.calleeSym = sym z.calleeSym = sym
matches(c, n, orig, z) matches(c, n, orig, z)
@ -198,7 +201,7 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
else: else:
result = explicitGenericInstError(n) 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 # 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. # 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 # New approach: generate fn(x, y, z) where x, y, z have the proper types

View file

@ -48,6 +48,9 @@ type
PContext* = ref TContext PContext* = ref TContext
TContext* = object of TPassContext # a context represents a module TContext* = object of TPassContext # a context represents a module
module*: PSym # the module sym belonging to the context 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 p*: PProcCon # procedure context
friendModule*: PSym # current friend module; may access private data; friendModule*: PSym # current friend module; may access private data;
# this is used so that generic instantiations # this is used so that generic instantiations
@ -55,7 +58,6 @@ type
InstCounter*: int # to prevent endless instantiations InstCounter*: int # to prevent endless instantiations
threadEntries*: TSymSeq # list of thread entries to check 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 AmbiguousSymbols*: TIntSet # ids of all ambiguous symbols (cannot
# store this info in the syms themselves!) # store this info in the syms themselves!)
InGenericContext*: int # > 0 if we are in a generic type InGenericContext*: int # > 0 if we are in a generic type
@ -83,7 +85,6 @@ type
generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile
lastGenericIdx*: int # used for the generics stack lastGenericIdx*: int # used for the generics stack
proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair = proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
result.genericSym = s result.genericSym = s
result.inst = inst result.inst = inst
@ -103,6 +104,10 @@ proc makeVarType*(c: PContext, baseType: PType): PType
proc newTypeS*(kind: TTypeKind, c: PContext): PType proc newTypeS*(kind: TTypeKind, c: PContext): PType
proc fillTypeS*(dest: PType, kind: TTypeKind, c: PContext) 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: # owner handling:
proc getCurrOwner*(): PSym proc getCurrOwner*(): PSym
proc PushOwner*(owner: PSym) proc PushOwner*(owner: PSym)
@ -151,7 +156,6 @@ proc newOptionEntry(): POptionEntry =
proc newContext(module: PSym): PContext = proc newContext(module: PSym): PContext =
new(result) new(result)
InitSymTab(result.tab)
result.AmbiguousSymbols = initIntset() result.AmbiguousSymbols = initIntset()
initLinkedList(result.optionStack) initLinkedList(result.optionStack)
initLinkedList(result.libs) initLinkedList(result.libs)

View file

@ -120,7 +120,7 @@ proc instantiateDestructor(c: PContext, typ: PType): bool =
of tySequence, tyArray, tyArrayConstr, tyOpenArray, tyVarargs: of tySequence, tyArray, tyArrayConstr, tyOpenArray, tyVarargs:
if instantiateDestructor(c, t.sons[0]): if instantiateDestructor(c, t.sons[0]):
if rangeDestructorProc == nil: if rangeDestructorProc == nil:
rangeDestructorProc = SymtabGet(c.tab, getIdent"nimDestroyRange") rangeDestructorProc = searchInScopes(c, getIdent"nimDestroyRange")
t.destructor = rangeDestructorProc t.destructor = rangeDestructorProc
return true return true
else: else:

View file

@ -328,7 +328,7 @@ proc semOpAux(c: PContext, n: PNode) =
proc overloadedCallOpr(c: PContext, n: PNode): PNode = proc overloadedCallOpr(c: PContext, n: PNode): PNode =
# quick check if there is *any* () operator overloaded: # quick check if there is *any* () operator overloaded:
var par = getIdent("()") var par = getIdent("()")
if SymtabGet(c.Tab, par) == nil: if searchInScopes(c, par) == nil:
result = nil result = nil
else: else:
result = newNodeI(nkCall, n.info) result = newNodeI(nkCall, n.info)
@ -937,7 +937,7 @@ proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
addSon(result, copyTree(n[0])) addSon(result, copyTree(n[0]))
else: else:
var i = considerAcc(n.sons[1]) 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) # if f != nil and f.kind == skStub: loadStub(f)
# ``loadStub`` is not correct here as we don't care for ``f`` really # ``loadStub`` is not correct here as we don't care for ``f`` really
if f != nil: if f != nil:
@ -1139,7 +1139,7 @@ proc SemReturn(c: PContext, n: PNode): PNode =
LocalError(n.info, errXNotAllowedHere, "\'return\'") LocalError(n.info, errXNotAllowedHere, "\'return\'")
proc semProcBody(c: PContext, n: PNode): PNode = proc semProcBody(c: PContext, n: PNode): PNode =
openScope(c.tab) openScope(c)
result = semExpr(c, n) result = semExpr(c, n)
if c.p.resultSym != nil and not isEmptyType(result.typ): if c.p.resultSym != nil and not isEmptyType(result.typ):
# transform ``expr`` to ``result = expr``, but not if the expr is already # 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) result = semAsgn(c, a)
else: else:
discardCheck(result) discardCheck(result)
closeScope(c.tab) closeScope(c)
proc SemYieldVarResult(c: PContext, n: PNode, restype: PType) = proc SemYieldVarResult(c: PContext, n: PNode, restype: PType) =
var t = skipTypes(restype, {tyGenericInst}) 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 = proc lookUpForDefined(c: PContext, i: PIdent, onlyCurrentScope: bool): PSym =
if onlyCurrentScope: if onlyCurrentScope:
result = SymtabLocalGet(c.tab, i) result = localSearchInScope(c, i)
else: 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 = proc LookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym =
case n.kind case n.kind
@ -1222,7 +1222,7 @@ proc LookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym =
if (n.sons[1].kind == nkIdent): if (n.sons[1].kind == nkIdent):
var ident = n.sons[1].ident var ident = n.sons[1].ident
if m == c.module: if m == c.module:
result = StrTableGet(c.tab.stack[ModuleTablePos], ident) result = StrTableGet(c.topLevelScope.symbols, ident)
else: else:
result = StrTableGet(m.tab, ident) result = StrTableGet(m.tab, ident)
else: else:
@ -1374,8 +1374,8 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
msgs.gErrorMax = high(int) msgs.gErrorMax = high(int)
# open a scope for temporary symbol inclusions: # open a scope for temporary symbol inclusions:
let oldTos = c.tab.tos let oldScope = c.currentScope
openScope(c.tab) openScope(c)
let oldOwnerLen = len(gOwners) let oldOwnerLen = len(gOwners)
let oldGenerics = c.generics let oldGenerics = c.generics
let oldContextLen = msgs.getInfoContextLen() let oldContextLen = msgs.getInfoContextLen()
@ -1398,7 +1398,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
c.p = oldProcCon c.p = oldProcCon
msgs.setInfoContextLen(oldContextLen) msgs.setInfoContextLen(oldContextLen)
setlen(gOwners, oldOwnerLen) setlen(gOwners, oldOwnerLen)
while c.tab.tos > oldTos: rawCloseScope(c.tab) c.currentScope = oldScope
dec c.InCompilesContext dec c.InCompilesContext
dec msgs.gSilence dec msgs.gSilence
msgs.gErrorCounter = oldErrorCount msgs.gErrorCounter = oldErrorCount
@ -1641,7 +1641,7 @@ proc semBlock(c: PContext, n: PNode): PNode =
result = n result = n
Inc(c.p.nestedBlockCounter) Inc(c.p.nestedBlockCounter)
checkSonsLen(n, 2) 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: if n.sons[0].kind != nkEmpty:
var labl = newSymG(skLabel, n.sons[0], c) var labl = newSymG(skLabel, n.sons[0], c)
if sfGenSym notin labl.flags: if sfGenSym notin labl.flags:
@ -1652,7 +1652,7 @@ proc semBlock(c: PContext, n: PNode): PNode =
n.typ = n.sons[1].typ n.typ = n.sons[1].typ
if isEmptyType(n.typ): n.kind = nkBlockStmt if isEmptyType(n.typ): n.kind = nkBlockStmt
else: n.kind = nkBlockExpr else: n.kind = nkBlockExpr
closeScope(c.tab) closeScope(c)
Dec(c.p.nestedBlockCounter) Dec(c.p.nestedBlockCounter)
proc buildCall(n: PNode): PNode = proc buildCall(n: PNode): PNode =
@ -1671,11 +1671,17 @@ proc buildCall(n: PNode): PNode =
else: else:
result = n 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 = proc fixImmediateParams(n: PNode): PNode =
# XXX: Temporary work-around until we carry out # XXX: Temporary work-around until we carry out
# the planned overload resolution reforms # the planned overload resolution reforms
for i in 1 .. <safeLen(n): for i in 1 .. <safeLen(n):
if n[i].kind == nkDo: n.sons[i] = n[i][bodyPos] if doBlockIsStmtList(n[i]):
n.sons[i] = n[i][bodyPos]
result = n result = n
proc semExport(c: PContext, n: PNode): PNode = proc semExport(c: PContext, n: PNode): PNode =

View file

@ -36,9 +36,9 @@ proc semGenericStmt(c: PContext, n: PNode, flags: TSemGenericFlags,
proc semGenericStmtScope(c: PContext, n: PNode, proc semGenericStmtScope(c: PContext, n: PNode,
flags: TSemGenericFlags, flags: TSemGenericFlags,
ctx: var TIntSet): PNode = ctx: var TIntSet): PNode =
openScope(c.tab) openScope(c)
result = semGenericStmt(c, n, flags, ctx) result = semGenericStmt(c, n, flags, ctx)
closeScope(c.tab) closeScope(c)
template macroToExpand(s: expr): expr = template macroToExpand(s: expr): expr =
s.kind in {skMacro, skTemplate} and (s.typ.len == 1 or sfImmediate in s.flags) s.kind in {skMacro, skTemplate} and (s.typ.len == 1 or sfImmediate in s.flags)
@ -77,7 +77,7 @@ proc Lookup(c: PContext, n: PNode, flags: TSemGenericFlags,
ctx: var TIntSet): PNode = ctx: var TIntSet): PNode =
result = n result = n
let ident = considerAcc(n) let ident = considerAcc(n)
var s = SymtabGet(c.Tab, ident) var s = searchInScopes(c, ident)
if s == nil: if s == nil:
if ident.id notin ctx and withinMixin notin flags: if ident.id notin ctx and withinMixin notin flags:
localError(n.info, errUndeclaredIdentifier, ident.s) localError(n.info, errUndeclaredIdentifier, ident.s)
@ -175,12 +175,12 @@ proc semGenericStmt(c: PContext, n: PNode,
for i in countup(0, sonsLen(n)-1): for i in countup(0, sonsLen(n)-1):
n.sons[i] = semGenericStmt(c, n.sons[i], flags+{withinMixin}, ctx) n.sons[i] = semGenericStmt(c, n.sons[i], flags+{withinMixin}, ctx)
of nkWhileStmt: of nkWhileStmt:
openScope(c.tab) openScope(c)
for i in countup(0, sonsLen(n)-1): for i in countup(0, sonsLen(n)-1):
n.sons[i] = semGenericStmt(c, n.sons[i], flags, ctx) n.sons[i] = semGenericStmt(c, n.sons[i], flags, ctx)
closeScope(c.tab) closeScope(c)
of nkCaseStmt: of nkCaseStmt:
openScope(c.tab) openScope(c)
n.sons[0] = semGenericStmt(c, n.sons[0], flags, ctx) n.sons[0] = semGenericStmt(c, n.sons[0], flags, ctx)
for i in countup(1, sonsLen(n)-1): for i in countup(1, sonsLen(n)-1):
var a = n.sons[i] var a = n.sons[i]
@ -189,22 +189,22 @@ proc semGenericStmt(c: PContext, n: PNode,
for j in countup(0, L-2): for j in countup(0, L-2):
a.sons[j] = semGenericStmt(c, a.sons[j], flags, ctx) a.sons[j] = semGenericStmt(c, a.sons[j], flags, ctx)
a.sons[L - 1] = semGenericStmtScope(c, a.sons[L-1], flags, ctx) a.sons[L - 1] = semGenericStmtScope(c, a.sons[L-1], flags, ctx)
closeScope(c.tab) closeScope(c)
of nkForStmt, nkParForStmt: of nkForStmt, nkParForStmt:
var L = sonsLen(n) var L = sonsLen(n)
openScope(c.tab) openScope(c)
n.sons[L - 2] = semGenericStmt(c, n.sons[L-2], flags, ctx) n.sons[L - 2] = semGenericStmt(c, n.sons[L-2], flags, ctx)
for i in countup(0, L - 3): for i in countup(0, L - 3):
addPrelimDecl(c, newSymS(skUnknown, n.sons[i], c)) addPrelimDecl(c, newSymS(skUnknown, n.sons[i], c))
n.sons[L - 1] = semGenericStmt(c, n.sons[L-1], flags, ctx) n.sons[L - 1] = semGenericStmt(c, n.sons[L-1], flags, ctx)
closeScope(c.tab) closeScope(c)
of nkBlockStmt, nkBlockExpr, nkBlockType: of nkBlockStmt, nkBlockExpr, nkBlockType:
checkSonsLen(n, 2) checkSonsLen(n, 2)
openScope(c.tab) openScope(c)
if n.sons[0].kind != nkEmpty: if n.sons[0].kind != nkEmpty:
addPrelimDecl(c, newSymS(skUnknown, n.sons[0], c)) addPrelimDecl(c, newSymS(skUnknown, n.sons[0], c))
n.sons[1] = semGenericStmt(c, n.sons[1], flags, ctx) n.sons[1] = semGenericStmt(c, n.sons[1], flags, ctx)
closeScope(c.tab) closeScope(c)
of nkTryStmt: of nkTryStmt:
checkMinSonsLen(n, 2) checkMinSonsLen(n, 2)
n.sons[0] = semGenericStmtScope(c, n.sons[0], flags, ctx) n.sons[0] = semGenericStmtScope(c, n.sons[0], flags, ctx)
@ -260,10 +260,10 @@ proc semGenericStmt(c: PContext, n: PNode,
if (a.kind != nkTypeDef): IllFormedAst(a) if (a.kind != nkTypeDef): IllFormedAst(a)
checkSonsLen(a, 3) checkSonsLen(a, 3)
if a.sons[1].kind != nkEmpty: if a.sons[1].kind != nkEmpty:
openScope(c.tab) openScope(c)
a.sons[1] = semGenericStmt(c, a.sons[1], flags, ctx) a.sons[1] = semGenericStmt(c, a.sons[1], flags, ctx)
a.sons[2] = semGenericStmt(c, a.sons[2], flags+{withinTypeDesc}, ctx) a.sons[2] = semGenericStmt(c, a.sons[2], flags+{withinTypeDesc}, ctx)
closeScope(c.tab) closeScope(c)
else: else:
a.sons[2] = semGenericStmt(c, a.sons[2], flags+{withinTypeDesc}, ctx) a.sons[2] = semGenericStmt(c, a.sons[2], flags+{withinTypeDesc}, ctx)
of nkEnumTy: of nkEnumTy:
@ -276,7 +276,7 @@ proc semGenericStmt(c: PContext, n: PNode,
of nkEnumFieldDef: a = n.sons[i].sons[0] of nkEnumFieldDef: a = n.sons[i].sons[0]
of nkIdent: a = n.sons[i] of nkIdent: a = n.sons[i]
else: illFormedAst(n) else: illFormedAst(n)
addDeclAt(c, newSymS(skUnknown, getIdentNode(a.sons[i]), c), c.tab.tos-1) addDecl(c, newSymS(skUnknown, getIdentNode(a.sons[i]), c))
of nkObjectTy, nkTupleTy: of nkObjectTy, nkTupleTy:
nil nil
of nkFormalParams: of nkFormalParams:
@ -298,7 +298,7 @@ proc semGenericStmt(c: PContext, n: PNode,
checkSonsLen(n, bodyPos + 1) checkSonsLen(n, bodyPos + 1)
if n.kind notin nkLambdaKinds: if n.kind notin nkLambdaKinds:
addPrelimDecl(c, newSymS(skUnknown, getIdentNode(n.sons[0]), c)) addPrelimDecl(c, newSymS(skUnknown, getIdentNode(n.sons[0]), c))
openScope(c.tab) openScope(c)
n.sons[genericParamsPos] = semGenericStmt(c, n.sons[genericParamsPos], n.sons[genericParamsPos] = semGenericStmt(c, n.sons[genericParamsPos],
flags, ctx) flags, ctx)
if n.sons[paramsPos].kind != nkEmpty: if n.sons[paramsPos].kind != nkEmpty:
@ -310,7 +310,7 @@ proc semGenericStmt(c: PContext, n: PNode,
if n.sons[namePos].kind == nkSym: body = n.sons[namePos].sym.getBody if n.sons[namePos].kind == nkSym: body = n.sons[namePos].sym.getBody
else: body = n.sons[bodyPos] else: body = n.sons[bodyPos]
n.sons[bodyPos] = semGenericStmtScope(c, body, flags, ctx) n.sons[bodyPos] = semGenericStmtScope(c, body, flags, ctx)
closeScope(c.tab) closeScope(c)
of nkPragma, nkPragmaExpr: nil of nkPragma, nkPragmaExpr: nil
of nkExprColonExpr: of nkExprColonExpr:
checkMinSonsLen(n, 2) checkMinSonsLen(n, 2)

View file

@ -106,13 +106,13 @@ proc fixupInstantiatedSymbols(c: PContext, s: PSym) =
if c.generics[i].genericSym.id == s.id: if c.generics[i].genericSym.id == s.id:
var oldPrc = c.generics[i].inst.sym var oldPrc = c.generics[i].inst.sym
pushInfoContext(oldPrc.info) pushInfoContext(oldPrc.info)
openScope(c.tab) openScope(c)
var n = oldPrc.ast var n = oldPrc.ast
n.sons[bodyPos] = copyTree(s.getBody) n.sons[bodyPos] = copyTree(s.getBody)
if n.sons[paramsPos].kind != nkEmpty: if n.sons[paramsPos].kind != nkEmpty:
addParams(c, oldPrc.typ.n, oldPrc.kind) addParams(c, oldPrc.typ.n, oldPrc.kind)
instantiateBody(c, n, oldPrc) instantiateBody(c, n, oldPrc)
closeScope(c.tab) closeScope(c)
popInfoContext() popInfoContext()
proc sideEffectsCheck(c: PContext, s: PSym) = proc sideEffectsCheck(c: PContext, s: PSym) =
@ -144,7 +144,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
result.owner = getCurrOwner().owner result.owner = getCurrOwner().owner
result.ast = n result.ast = n
pushOwner(result) pushOwner(result)
openScope(c.tab) openScope(c)
if n.sons[genericParamsPos].kind == nkEmpty: if n.sons[genericParamsPos].kind == nkEmpty:
InternalError(n.info, "generateInstance") InternalError(n.info, "generateInstance")
n.sons[namePos] = newSymNode(result) n.sons[namePos] = newSymNode(result)
@ -177,7 +177,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
else: else:
result = oldPrc result = oldPrc
popInfoContext() popInfoContext()
closeScope(c.tab) # close scope for parameters closeScope(c) # close scope for parameters
popOwner() popOwner()
c.friendModule = oldFriend c.friendModule = oldFriend
dec(c.InstCounter) dec(c.InstCounter)

View file

@ -80,8 +80,9 @@ proc semLocals(c: PContext, n: PNode): PNode =
result = newNodeIT(nkPar, n.info, tupleType) result = newNodeIT(nkPar, n.info, tupleType)
tupleType.n = newNodeI(nkRecList, n.info) tupleType.n = newNodeI(nkRecList, n.info)
# for now we skip openarrays ... # for now we skip openarrays ...
for i in countdown(c.tab.tos-1, ModuleTablePos+1): for scope in walkScopes(c.currentScope):
for it in items(c.tab.stack[i]): if scope == c.topLevelScope: break
for it in items(scope.symbols):
# XXX parameters' owners are wrong for generics; this caused some pain # XXX parameters' owners are wrong for generics; this caused some pain
# for closures too; we should finally fix it. # for closures too; we should finally fix it.
#if it.owner != c.p.owner: return result #if it.owner != c.p.owner: return result

View file

@ -52,12 +52,12 @@ proc semAsm(con: PContext, n: PNode): PNode =
proc semWhile(c: PContext, n: PNode): PNode = proc semWhile(c: PContext, n: PNode): PNode =
result = n result = n
checkSonsLen(n, 2) checkSonsLen(n, 2)
openScope(c.tab) openScope(c)
n.sons[0] = forceBool(c, semExprWithType(c, n.sons[0])) n.sons[0] = forceBool(c, semExprWithType(c, n.sons[0]))
inc(c.p.nestedLoopCounter) inc(c.p.nestedLoopCounter)
n.sons[1] = semStmt(c, n.sons[1]) n.sons[1] = semStmt(c, n.sons[1])
dec(c.p.nestedLoopCounter) dec(c.p.nestedLoopCounter)
closeScope(c.tab) closeScope(c)
if n.sons[1].typ == EnforceVoidContext: if n.sons[1].typ == EnforceVoidContext:
result.typ = EnforceVoidContext result.typ = EnforceVoidContext
@ -103,9 +103,9 @@ proc semExprBranch(c: PContext, n: PNode): PNode =
semDestructorCheck(c, result, {}) semDestructorCheck(c, result, {})
proc semExprBranchScope(c: PContext, n: PNode): PNode = proc semExprBranchScope(c: PContext, n: PNode): PNode =
openScope(c.tab) openScope(c)
result = semExprBranch(c, n) result = semExprBranch(c, n)
closeScope(c.tab) closeScope(c)
const const
skipForDiscardable = {nkIfStmt, nkIfExpr, nkCaseStmt, nkOfBranch, skipForDiscardable = {nkIfStmt, nkIfExpr, nkCaseStmt, nkOfBranch,
@ -150,12 +150,12 @@ proc semIf(c: PContext, n: PNode): PNode =
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
var it = n.sons[i] var it = n.sons[i]
if it.len == 2: if it.len == 2:
when newScopeForIf: openScope(c.tab) when newScopeForIf: openScope(c)
it.sons[0] = forceBool(c, semExprWithType(c, it.sons[0])) it.sons[0] = forceBool(c, semExprWithType(c, it.sons[0]))
when not newScopeForIf: openScope(c.tab) when not newScopeForIf: openScope(c)
it.sons[1] = semExprBranch(c, it.sons[1]) it.sons[1] = semExprBranch(c, it.sons[1])
typ = commonType(typ, it.sons[1].typ) typ = commonType(typ, it.sons[1].typ)
closeScope(c.tab) closeScope(c)
elif it.len == 1: elif it.len == 1:
hasElse = true hasElse = true
it.sons[0] = semExprBranchScope(c, it.sons[0]) it.sons[0] = semExprBranchScope(c, it.sons[0])
@ -176,7 +176,7 @@ proc semIf(c: PContext, n: PNode): PNode =
proc semCase(c: PContext, n: PNode): PNode = proc semCase(c: PContext, n: PNode): PNode =
result = n result = n
checkMinSonsLen(n, 2) checkMinSonsLen(n, 2)
openScope(c.tab) openScope(c)
n.sons[0] = semExprWithType(c, n.sons[0]) n.sons[0] = semExprWithType(c, n.sons[0])
var chckCovered = false var chckCovered = false
var covered: biggestint = 0 var covered: biggestint = 0
@ -202,12 +202,12 @@ proc semCase(c: PContext, n: PNode): PNode =
of nkElifBranch: of nkElifBranch:
chckCovered = false chckCovered = false
checkSonsLen(x, 2) checkSonsLen(x, 2)
when newScopeForIf: openScope(c.tab) when newScopeForIf: openScope(c)
x.sons[0] = forceBool(c, semExprWithType(c, x.sons[0])) x.sons[0] = forceBool(c, semExprWithType(c, x.sons[0]))
when not newScopeForIf: openScope(c.tab) when not newScopeForIf: openScope(c)
x.sons[1] = semExprBranch(c, x.sons[1]) x.sons[1] = semExprBranch(c, x.sons[1])
typ = commonType(typ, x.sons[1].typ) typ = commonType(typ, x.sons[1].typ)
closeScope(c.tab) closeScope(c)
of nkElse: of nkElse:
chckCovered = false chckCovered = false
checkSonsLen(x, 1) checkSonsLen(x, 1)
@ -221,7 +221,7 @@ proc semCase(c: PContext, n: PNode): PNode =
hasElse = true hasElse = true
else: else:
localError(n.info, errNotAllCasesCovered) localError(n.info, errNotAllCasesCovered)
closeScope(c.tab) closeScope(c)
if isEmptyType(typ) or typ.kind == tyNil or not hasElse: if isEmptyType(typ) or typ.kind == tyNil or not hasElse:
for i in 1..n.len-1: discardCheck(n.sons[i].lastSon) for i in 1..n.len-1: discardCheck(n.sons[i].lastSon)
# propagate any enforced VoidContext: # propagate any enforced VoidContext:
@ -289,8 +289,9 @@ proc fitRemoveHiddenConv(c: PContext, typ: Ptype, n: PNode): PNode =
changeType(result, typ, check=false) changeType(result, typ, check=false)
proc findShadowedVar(c: PContext, v: PSym): PSym = proc findShadowedVar(c: PContext, v: PSym): PSym =
for i in countdown(c.tab.tos - 2, ModuleTablePos+1): for scope in walkScopes(c.currentScope.parent):
let shadowed = StrTableGet(c.tab.stack[i], v.name) if scope == c.topLevelScope: break
let shadowed = StrTableGet(scope.symbols, v.name)
if shadowed != nil and shadowed.kind in skLocalVars: if shadowed != nil and shadowed.kind in skLocalVars:
return shadowed return shadowed
@ -472,12 +473,12 @@ proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) =
var fc: TFieldInstCtx # either 'tup[i]' or 'field' is valid var fc: TFieldInstCtx # either 'tup[i]' or 'field' is valid
fc.field = typ.sym fc.field = typ.sym
fc.replaceByFieldName = c.m == mFieldPairs fc.replaceByFieldName = c.m == mFieldPairs
openScope(c.c.tab) openScope(c.c)
inc c.c.InUnrolledContext inc c.c.InUnrolledContext
let body = instFieldLoopBody(fc, lastSon(forLoop), forLoop) let body = instFieldLoopBody(fc, lastSon(forLoop), forLoop)
father.add(SemStmt(c.c, body)) father.add(SemStmt(c.c, body))
dec c.c.InUnrolledContext dec c.c.InUnrolledContext
closeScope(c.c.tab) closeScope(c.c)
of nkNilLit: nil of nkNilLit: nil
of nkRecCase: of nkRecCase:
let L = forLoop.len let L = forLoop.len
@ -541,7 +542,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
if tupleTypeA.kind == tyTuple: if tupleTypeA.kind == tyTuple:
var loopBody = n.sons[length-1] var loopBody = n.sons[length-1]
for i in 0..sonsLen(tupleTypeA)-1: for i in 0..sonsLen(tupleTypeA)-1:
openScope(c.tab) openScope(c)
var fc: TFieldInstCtx var fc: TFieldInstCtx
fc.tupleType = tupleTypeA fc.tupleType = tupleTypeA
fc.tupleIndex = i fc.tupleIndex = i
@ -550,7 +551,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
inc c.InUnrolledContext inc c.InUnrolledContext
stmts.add(SemStmt(c, body)) stmts.add(SemStmt(c, body))
dec c.InUnrolledContext dec c.InUnrolledContext
closeScope(c.tab) closeScope(c)
else: else:
var fc: TFieldsCtx var fc: TFieldsCtx
fc.m = m fc.m = m
@ -618,7 +619,7 @@ proc semFor(c: PContext, n: PNode): PNode =
result = n result = n
checkMinSonsLen(n, 3) checkMinSonsLen(n, 3)
var length = sonsLen(n) var length = sonsLen(n)
openScope(c.tab) openScope(c)
n.sons[length-2] = semExprNoDeref(c, n.sons[length-2], {efWantIterator}) n.sons[length-2] = semExprNoDeref(c, n.sons[length-2], {efWantIterator})
var call = n.sons[length-2] var call = n.sons[length-2]
if call.kind in nkCallKinds and call.sons[0].typ.callConv == ccClosure: if call.kind in nkCallKinds and call.sons[0].typ.callConv == ccClosure:
@ -644,7 +645,7 @@ proc semFor(c: PContext, n: PNode): PNode =
# propagate any enforced VoidContext: # propagate any enforced VoidContext:
if n.sons[length-1].typ == EnforceVoidContext: if n.sons[length-1].typ == EnforceVoidContext:
result.typ = EnforceVoidContext result.typ = EnforceVoidContext
closeScope(c.tab) closeScope(c)
proc semRaise(c: PContext, n: PNode): PNode = proc semRaise(c: PContext, n: PNode): PNode =
result = n result = n
@ -694,7 +695,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
if a.sons[1].kind != nkEmpty: if a.sons[1].kind != nkEmpty:
# We have a generic type declaration here. In generic types, # We have a generic type declaration here. In generic types,
# symbol lookup needs to be done here. # symbol lookup needs to be done here.
openScope(c.tab) openScope(c)
pushOwner(s) pushOwner(s)
if s.magic == mNone: s.typ.kind = tyGenericBody if s.magic == mNone: s.typ.kind = tyGenericBody
# XXX for generic type aliases this is not correct! We need the # XXX for generic type aliases this is not correct! We need the
@ -719,7 +720,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
body.size = -1 # could not be computed properly body.size = -1 # could not be computed properly
s.typ.sons[sonsLen(s.typ) - 1] = body s.typ.sons[sonsLen(s.typ) - 1] = body
popOwner() popOwner()
closeScope(c.tab) closeScope(c)
elif a.sons[2].kind != nkEmpty: elif a.sons[2].kind != nkEmpty:
# process the type's body: # process the type's body:
pushOwner(s) pushOwner(s)
@ -776,7 +777,7 @@ proc addParams(c: PContext, n: PNode, kind: TSymKind) =
proc semBorrow(c: PContext, n: PNode, s: PSym) = proc semBorrow(c: PContext, n: PNode, s: PSym) =
# search for the correct alias: # search for the correct alias:
var b = SearchForBorrowProc(c, s, c.tab.tos - 2) var b = SearchForBorrowProc(c, c.currentScope.parent, s)
if b != nil: if b != nil:
# store the alias: # store the alias:
n.sons[bodyPos] = newSymNode(b) n.sons[bodyPos] = newSymNode(b)
@ -804,7 +805,7 @@ proc lookupMacro(c: PContext, n: PNode): PSym =
result = n.sym result = n.sym
if result.kind notin {skMacro, skTemplate}: result = nil if result.kind notin {skMacro, skTemplate}: result = nil
else: else:
result = SymtabGet(c.Tab, considerAcc(n), {skMacro, skTemplate}) result = searchInScopes(c, considerAcc(n), {skMacro, skTemplate})
proc semProcAnnotation(c: PContext, prc: PNode): PNode = proc semProcAnnotation(c: PContext, prc: PNode): PNode =
var n = prc.sons[pragmasPos] var n = prc.sons[pragmasPos]
@ -839,7 +840,7 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
else: else:
s = n[namePos].sym s = n[namePos].sym
pushOwner(s) pushOwner(s)
openScope(c.tab) openScope(c)
if n.sons[genericParamsPos].kind != nkEmpty: if n.sons[genericParamsPos].kind != nkEmpty:
illFormedAst(n) # process parameters: illFormedAst(n) # process parameters:
if n.sons[paramsPos].kind != nkEmpty: if n.sons[paramsPos].kind != nkEmpty:
@ -865,7 +866,7 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
sideEffectsCheck(c, s) sideEffectsCheck(c, s)
else: else:
LocalError(n.info, errImplOfXexpected, s.name.s) LocalError(n.info, errImplOfXexpected, s.name.s)
closeScope(c.tab) # close scope for parameters closeScope(c) # close scope for parameters
popOwner() popOwner()
result.typ = s.typ result.typ = s.typ
@ -888,17 +889,48 @@ proc maybeAddResult(c: PContext, s: PSym, n: PNode) =
addResult(c, s.typ.sons[0], n.info, s.kind) addResult(c, s.typ.sons[0], n.info, s.kind)
addResultNode(c, n) addResultNode(c, n)
type
TProcCompilationSteps = enum
stepRegisterSymbol,
stepDetermineType,
stepCompileBody
proc isForwardDecl(s: PSym): bool =
InternalAssert s.kind == skProc
result = s.ast[bodyPos].kind != nkEmpty
proc semProcAux(c: PContext, n: PNode, kind: TSymKind, proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
validPragmas: TSpecialWords): PNode = validPragmas: TSpecialWords,
phase = stepRegisterSymbol): PNode =
result = semProcAnnotation(c, n) result = semProcAnnotation(c, n)
if result != nil: return result if result != nil: return result
result = n result = n
checkSonsLen(n, bodyPos + 1) checkSonsLen(n, bodyPos + 1)
var s = semIdentDef(c, n.sons[0], kind) var s: PSym
var typeIsDetermined = false
if n[namePos].kind != nkSym:
assert phase == stepRegisterSymbol
s = semIdentDef(c, n.sons[0], kind)
n.sons[namePos] = newSymNode(s) n.sons[namePos] = newSymNode(s)
s.ast = n s.ast = n
s.scope = c.currentScope
if sfNoForward in c.module.flags and
sfSystemModule notin c.module.flags:
addInterfaceOverloadableSymAt(c, c.currentScope, s)
s.flags.incl sfForward
return
else:
s = n[namePos].sym
typeIsDetermined = s.typ == nil
# if typeIsDetermined: assert phase == stepCompileBody
# else: assert phase == stepDetermineType
# before compiling the proc body, set as current the scope
# where the proc was declared
let oldScope = c.currentScope
c.currentScope = s.scope
pushOwner(s) pushOwner(s)
openScope(c.tab) openScope(c)
var gp: PNode var gp: PNode
if n.sons[genericParamsPos].kind != nkEmpty: if n.sons[genericParamsPos].kind != nkEmpty:
n.sons[genericParamsPos] = semGenericParamList(c, n.sons[genericParamsPos]) n.sons[genericParamsPos] = semGenericParamList(c, n.sons[genericParamsPos])
@ -921,17 +953,17 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
n.sons[patternPos] = semPattern(c, n.sons[patternPos]) n.sons[patternPos] = semPattern(c, n.sons[patternPos])
if s.kind == skIterator: s.typ.flags.incl(tfIterator) if s.kind == skIterator: s.typ.flags.incl(tfIterator)
var proto = SearchForProc(c, s, c.tab.tos-2) # -2 because we have a scope var proto = SearchForProc(c, s.scope, s)
# open for parameters
if proto == nil: if proto == nil:
s.typ.callConv = lastOptionEntry(c).defaultCC s.typ.callConv = lastOptionEntry(c).defaultCC
# add it here, so that recursive procs are possible: # add it here, so that recursive procs are possible:
# -2 because we have a scope open for parameters
if sfGenSym in s.flags: nil if sfGenSym in s.flags: nil
elif kind in OverloadableSyms: elif kind in OverloadableSyms:
addInterfaceOverloadableSymAt(c, s, c.tab.tos - 2) if not typeIsDetermined:
addInterfaceOverloadableSymAt(c, s.scope, s)
else: else:
addInterfaceDeclAt(c, s, c.tab.tos - 2) if not typeIsDetermined:
addInterfaceDeclAt(c, s.scope, s)
if n.sons[pragmasPos].kind != nkEmpty: if n.sons[pragmasPos].kind != nkEmpty:
pragma(c, s, n.sons[pragmasPos], validPragmas) pragma(c, s, n.sons[pragmasPos], validPragmas)
else: else:
@ -942,8 +974,8 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
if sfForward notin proto.flags: if sfForward notin proto.flags:
WrongRedefinition(n.info, proto.name.s) WrongRedefinition(n.info, proto.name.s)
excl(proto.flags, sfForward) excl(proto.flags, sfForward)
closeScope(c.tab) # close scope with wrong parameter symbols closeScope(c) # close scope with wrong parameter symbols
openScope(c.tab) # open scope for old (correct) parameter symbols openScope(c) # open scope for old (correct) parameter symbols
if proto.ast.sons[genericParamsPos].kind != nkEmpty: if proto.ast.sons[genericParamsPos].kind != nkEmpty:
addGenericParamListToScope(c, proto.ast.sons[genericParamsPos]) addGenericParamListToScope(c, proto.ast.sons[genericParamsPos])
addParams(c, proto.typ.n, proto.kind) addParams(c, proto.typ.n, proto.kind)
@ -992,11 +1024,17 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
incl(s.flags, sfForward) incl(s.flags, sfForward)
elif sfBorrow in s.flags: semBorrow(c, n, s) elif sfBorrow in s.flags: semBorrow(c, n, s)
sideEffectsCheck(c, s) sideEffectsCheck(c, s)
closeScope(c.tab) # close scope for parameters closeScope(c) # close scope for parameters
c.currentScope = oldScope
popOwner() popOwner()
if n.sons[patternPos].kind != nkEmpty: if n.sons[patternPos].kind != nkEmpty:
c.patterns.add(s) c.patterns.add(s)
proc determineType(c: PContext, s: PSym) =
if s.typ != nil: return
#if s.magic != mNone: return
discard semProcAux(c, s.ast, s.kind, {}, stepDetermineType)
proc semIterator(c: PContext, n: PNode): PNode = proc semIterator(c: PContext, n: PNode): PNode =
result = semProcAux(c, n, skIterator, iteratorPragmas) result = semProcAux(c, n, skIterator, iteratorPragmas)
var s = result.sons[namePos].sym var s = result.sons[namePos].sym
@ -1183,6 +1221,6 @@ proc SemStmt(c: PContext, n: PNode): PNode =
result = semExprNoType(c, n) result = semExprNoType(c, n)
proc semStmtScope(c: PContext, n: PNode): PNode = proc semStmtScope(c: PContext, n: PNode): PNode =
openScope(c.tab) openScope(c)
result = semStmt(c, n) result = semStmt(c, n)
closeScope(c.tab) closeScope(c)

View file

@ -130,8 +130,8 @@ proc isTemplParam(c: TemplCtx, n: PNode): bool {.inline.} =
proc semTemplBody(c: var TemplCtx, n: PNode): PNode proc semTemplBody(c: var TemplCtx, n: PNode): PNode
proc openScope(c: var TemplCtx) = openScope(c.c.tab) proc openScope(c: var TemplCtx) = openScope(c.c)
proc closeScope(c: var TemplCtx) = closeScope(c.c.tab) proc closeScope(c: var TemplCtx) = closeScope(c.c)
proc semTemplBodyScope(c: var TemplCtx, n: PNode): PNode = proc semTemplBodyScope(c: var TemplCtx, n: PNode): PNode =
openScope(c) openScope(c)
@ -379,7 +379,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
s = semIdentVis(c, skTemplate, n.sons[0], {}) s = semIdentVis(c, skTemplate, n.sons[0], {})
# check parameter list: # check parameter list:
pushOwner(s) pushOwner(s)
openScope(c.tab) openScope(c)
n.sons[namePos] = newSymNode(s, n.sons[namePos].info) n.sons[namePos] = newSymNode(s, n.sons[namePos].info)
if n.sons[pragmasPos].kind != nkEmpty: if n.sons[pragmasPos].kind != nkEmpty:
pragma(c, s, n.sons[pragmasPos], templatePragmas) pragma(c, s, n.sons[pragmasPos], templatePragmas)
@ -422,18 +422,17 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
if s.typ.sons[0].kind notin {tyStmt, tyTypeDesc}: if s.typ.sons[0].kind notin {tyStmt, tyTypeDesc}:
n.sons[bodyPos] = transformToExpr(n.sons[bodyPos]) n.sons[bodyPos] = transformToExpr(n.sons[bodyPos])
# only parameters are resolved, no type checking is performed # only parameters are resolved, no type checking is performed
closeScope(c.tab) closeScope(c)
popOwner() popOwner()
s.ast = n s.ast = n
result = n result = n
if n.sons[bodyPos].kind == nkEmpty: if n.sons[bodyPos].kind == nkEmpty:
LocalError(n.info, errImplOfXexpected, s.name.s) LocalError(n.info, errImplOfXexpected, s.name.s)
let curScope = c.tab.tos - 1 var proto = SearchForProc(c, c.currentScope, s)
var proto = SearchForProc(c, s, curScope)
if proto == nil: if proto == nil:
addInterfaceOverloadableSymAt(c, s, curScope) addInterfaceOverloadableSymAt(c, c.currentScope, s)
else: else:
SymTabReplace(c.tab.stack[curScope], proto, s) SymTabReplace(c.currentScope.symbols, proto, s)
if n.sons[patternPos].kind != nkEmpty: if n.sons[patternPos].kind != nkEmpty:
c.patterns.add(s) c.patterns.add(s)
@ -551,7 +550,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
result.sons[i] = semPatternBody(c, n.sons[i]) result.sons[i] = semPatternBody(c, n.sons[i])
proc semPattern(c: PContext, n: PNode): PNode = proc semPattern(c: PContext, n: PNode): PNode =
openScope(c.tab) openScope(c)
var ctx: TemplCtx var ctx: TemplCtx
ctx.toBind = initIntSet() ctx.toBind = initIntSet()
ctx.toMixin = initIntSet() ctx.toMixin = initIntSet()
@ -563,4 +562,4 @@ proc semPattern(c: PContext, n: PNode): PNode =
result = result.sons[0] result = result.sons[0]
elif result.len == 0: elif result.len == 0:
LocalError(n.info, errInvalidExpression) LocalError(n.info, errInvalidExpression)
closeScope(c.tab) closeScope(c)

View file

@ -79,7 +79,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
incl(e.flags, sfExported) incl(e.flags, sfExported)
if not isPure: StrTableAdd(c.module.tab, e) if not isPure: StrTableAdd(c.module.tab, e)
addSon(result.n, newSymNode(e)) addSon(result.n, newSymNode(e))
if sfGenSym notin e.flags and not isPure: addDeclAt(c, e, c.tab.tos - 1) if sfGenSym notin e.flags and not isPure: addDecl(c, e)
inc(counter) inc(counter)
proc semSet(c: PContext, n: PNode, prev: PType): PType = proc semSet(c: PContext, n: PNode, prev: PType): PType =
@ -570,7 +570,6 @@ proc paramTypeClass(c: PContext, paramType: PType, procKind: TSymKind):
# if id is not nil, the generic param will bind just once (see below) # if id is not nil, the generic param will bind just once (see below)
case paramType.kind: case paramType.kind:
of tyExpr: of tyExpr:
if procKind notin {skTemplate, skMacro}:
if paramType.sonsLen == 0: if paramType.sonsLen == 0:
# proc(a, b: expr) # proc(a, b: expr)
# no constraints, treat like generic param # no constraints, treat like generic param
@ -581,8 +580,7 @@ proc paramTypeClass(c: PContext, paramType: PType, procKind: TSymKind):
result.typ = newTypeS(tyExpr, c) result.typ = newTypeS(tyExpr, c)
result.typ.sons = paramType.sons result.typ.sons = paramType.sons
of tyTypeDesc: of tyTypeDesc:
if procKind notin {skTemplate, skMacro} and if tfInstantiated notin paramType.flags:
tfInstantiated notin paramType.flags:
result.typ = newTypeS(tyTypeDesc, c) result.typ = newTypeS(tyTypeDesc, c)
result.typ.sons = paramType.sons result.typ.sons = paramType.sons
of tyDistinct: of tyDistinct:
@ -604,11 +602,16 @@ proc paramTypeClass(c: PContext, paramType: PType, procKind: TSymKind):
proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
paramType: PType, paramName: string, paramType: PType, paramName: string,
info: TLineInfo): PType = info: TLineInfo): PType =
result = paramType
if procKind in {skMacro, skTemplate}:
# generic param types in macros and templates affect overload
# resolution, but don't work as generic params when it comes
# to proc instantiation. We don't need to lift such params here.
return
## Params having implicit generic types or pseudo types such as 'expr' ## Params having implicit generic types or pseudo types such as 'expr'
## need to be added to the generic params lists. ## need to be added to the generic params lists.
## 'expr' is different from 'expr{string}' so we must first call ## 'expr' is different from 'expr{string}' so we must first call
## paramTypeClass to get the actual type we are going to use. ## paramTypeClass to get the actual type we are going to use.
result = paramType
var (typeClass, paramTypId) = paramTypeClass(c, paramType, procKind) var (typeClass, paramTypId) = paramTypeClass(c, paramType, procKind)
let isAnon = paramTypId == nil let isAnon = paramTypId == nil
if typeClass != nil: if typeClass != nil:
@ -616,7 +619,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
if genericParams == nil: if genericParams == nil:
# genericParams is nil when the proc is being instantiated # genericParams is nil when the proc is being instantiated
# the resolved type will be in scope then # the resolved type will be in scope then
let s = SymtabGet(c.tab, paramTypId) let s = searchInScopes(c, paramTypId)
# tests/run/tinterf triggers this: # tests/run/tinterf triggers this:
if s != nil: result = s.typ if s != nil: result = s.typ
else: else:
@ -734,13 +737,13 @@ proc semStmtListType(c: PContext, n: PNode, prev: PType): PType =
proc semBlockType(c: PContext, n: PNode, prev: PType): PType = proc semBlockType(c: PContext, n: PNode, prev: PType): PType =
Inc(c.p.nestedBlockCounter) Inc(c.p.nestedBlockCounter)
checkSonsLen(n, 2) checkSonsLen(n, 2)
openScope(c.tab) openScope(c)
if n.sons[0].kind notin {nkEmpty, nkSym}: if n.sons[0].kind notin {nkEmpty, nkSym}:
addDecl(c, newSymS(skLabel, n.sons[0], c)) addDecl(c, newSymS(skLabel, n.sons[0], c))
result = semStmtListType(c, n.sons[1], prev) result = semStmtListType(c, n.sons[1], prev)
n.sons[1].typ = result n.sons[1].typ = result
n.typ = result n.typ = result
closeScope(c.tab) closeScope(c)
Dec(c.p.nestedBlockCounter) Dec(c.p.nestedBlockCounter)
proc semGenericParamInInvokation(c: PContext, n: PNode): PType = proc semGenericParamInInvokation(c: PContext, n: PNode): PType =
@ -749,7 +752,7 @@ proc semGenericParamInInvokation(c: PContext, n: PNode): PType =
when false: when false:
if n.kind == nkSym: if n.kind == nkSym:
# for generics we need to lookup the type var again: # for generics we need to lookup the type var again:
var s = SymtabGet(c.Tab, n.sym.name) var s = searchInScopes(c, n.sym.name)
if s != nil: if s != nil:
if s.kind == skType and s.typ != nil: if s.kind == skType and s.typ != nil:
var t = n.sym.typ var t = n.sym.typ
@ -910,7 +913,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
result = newConstraint(c, tyProc) result = newConstraint(c, tyProc)
else: else:
checkSonsLen(n, 2) checkSonsLen(n, 2)
openScope(c.tab) openScope(c)
result = semProcTypeNode(c, n.sons[0], nil, prev, skProc) result = semProcTypeNode(c, n.sons[0], nil, prev, skProc)
# dummy symbol for `pragma`: # dummy symbol for `pragma`:
var s = newSymS(skProc, newIdentNode(getIdent("dummy"), n.info), c) var s = newSymS(skProc, newIdentNode(getIdent("dummy"), n.info), c)
@ -922,7 +925,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
else: else:
pragma(c, s, n.sons[1], procTypePragmas) pragma(c, s, n.sons[1], procTypePragmas)
when useEffectSystem: SetEffectsForProcType(result, n.sons[1]) when useEffectSystem: SetEffectsForProcType(result, n.sons[1])
closeScope(c.tab) closeScope(c)
if n.kind == nkIteratorTy: if n.kind == nkIteratorTy:
result.flags.incl(tfIterator) result.flags.incl(tfIterator)
result.callConv = ccClosure result.callConv = ccClosure

View file

@ -592,14 +592,20 @@ proc typeRel(c: var TCandidate, f, a: PType): TTypeRelation =
else: else:
result = typeRel(c, x, a) # check if it fits result = typeRel(c, x, a) # check if it fits
of tyTypeDesc: of tyTypeDesc:
var prev = PType(idTableGet(c.bindings, f))
if prev == nil:
if a.kind == tyTypeDesc: if a.kind == tyTypeDesc:
if f.sonsLen == 0: if f.sonsLen == 0:
result = isGeneric result = isGeneric
else: else:
result = matchTypeClass(c, f, a.sons[0]) result = matchTypeClass(c, f, a.sons[0])
if result == isGeneric: put(c.bindings, f, a) if result == isGeneric:
put(c.bindings, f, a)
else: else:
result = isNone result = isNone
else:
InternalAssert prev.sonsLen == 1
result = typeRel(c, prev.sons[0], a)
of tyExpr, tyStmt: of tyExpr, tyStmt:
result = isGeneric result = isGeneric
of tyProxy: of tyProxy:
@ -683,11 +689,12 @@ proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType,
proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType, proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
arg, argOrig: PNode): PNode = arg, argOrig: PNode): PNode =
var r: TTypeRelation var r: TTypeRelation
if f.kind == tyExpr: let fMaybeExpr = f.skipTypes({tyDistinct})
if f.sonsLen == 0: if fMaybeExpr.kind == tyExpr:
if fMaybeExpr.sonsLen == 0:
r = isGeneric r = isGeneric
else: else:
let match = matchTypeClass(m, f, a) let match = matchTypeClass(m, fMaybeExpr, a)
if match != isGeneric: r = isNone if match != isGeneric: r = isNone
else: else:
# XXX: Ideally, this should happen much earlier somewhere near # XXX: Ideally, this should happen much earlier somewhere near

View file

@ -64,11 +64,13 @@ when not defined(nimhygiene):
{.pragma: inject.} {.pragma: inject.}
template wholeSymTab(cond, section: expr) {.immediate.} = template wholeSymTab(cond, section: expr) {.immediate.} =
for i in countdown(c.tab.tos-1, 0): var isLocal = true
for item in items(c.tab.stack[i]): for scope in walkScopes(c.currentScope):
if scope == c.topLevelScope: isLocal = false
for item in items(scope.symbols):
let it {.inject.} = item let it {.inject.} = item
if cond: if cond:
SuggestWriteln(SymToStr(it, isLocal = i > ModuleTablePos, section)) SuggestWriteln(SymToStr(it, isLocal = isLocal, section))
inc outputs inc outputs
proc suggestSymList(c: PContext, list: PNode, outputs: var int) = 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) = proc suggestEverything(c: PContext, n: PNode, outputs: var int) =
# do not produce too many symbols: # do not produce too many symbols:
for i in countdown(c.tab.tos-1, 1): var isLocal = true
for it in items(c.tab.stack[i]): for scope in walkScopes(c.currentScope):
if scope == c.topLevelScope: isLocal = false
for it in items(scope.symbols):
if filterSym(it): if filterSym(it):
SuggestWriteln(SymToStr(it, isLocal = i > ModuleTablePos, sectionSuggest)) SuggestWriteln(SymToStr(it, isLocal = isLocal, sectionSuggest))
inc outputs inc outputs
if scope == c.topLevelScope: break
proc suggestFieldAccess(c: PContext, n: PNode, outputs: var int) = proc suggestFieldAccess(c: PContext, n: PNode, outputs: var int) =
# special code that deals with ``myObj.``. `n` is NOT the nkDotExpr-node, but # 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.kind == nkSym and n.sym.kind == skModule:
if n.sym == c.module: if n.sym == c.module:
# all symbols accessible, because we are in the current 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): if filterSym(it):
SuggestWriteln(SymToStr(it, isLocal=false, sectionSuggest)) SuggestWriteln(SymToStr(it, isLocal=false, sectionSuggest))
inc outputs inc outputs

View file

@ -1016,8 +1016,9 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
of tyExpr, tyStmt, tyTypeDesc: of tyExpr, tyStmt, tyTypeDesc:
result = true result = true
# XXX er ... no? these should not be allowed! # XXX er ... no? these should not be allowed!
of tyGenericBody, tyGenericParam, tyForward, tyNone, tyGenericInvokation, of tyTypeClass:
tyTypeClass: result = true
of tyGenericBody, tyGenericParam, tyForward, tyNone, tyGenericInvokation:
result = false result = false
of tyEmpty, tyNil: of tyEmpty, tyNil:
result = kind == skConst result = kind == skConst

View file

@ -53,7 +53,7 @@ type
wFloatchecks, wNanChecks, wInfChecks, wFloatchecks, wNanChecks, wInfChecks,
wAssertions, wPatterns, wWarnings, wAssertions, wPatterns, wWarnings,
wHints, wOptimization, wRaises, wWrites, wReads, wSize, wEffects, wTags, wHints, wOptimization, wRaises, wWrites, wReads, wSize, wEffects, wTags,
wDeadCodeElim, wSafecode, wDeadCodeElim, wSafecode, wNoForward,
wPragma, wPragma,
wCompileTime, wNoInit, wCompileTime, wNoInit,
wPassc, wPassl, wBorrow, wDiscardable, wPassc, wPassl, wBorrow, wDiscardable,
@ -135,7 +135,7 @@ const
"assertions", "patterns", "warnings", "hints", "assertions", "patterns", "warnings", "hints",
"optimization", "raises", "writes", "reads", "size", "effects", "tags", "optimization", "raises", "writes", "reads", "size", "effects", "tags",
"deadcodeelim", "safecode", "deadcodeelim", "safecode", "noforward",
"pragma", "pragma",
"compiletime", "noinit", "compiletime", "noinit",
"passc", "passl", "borrow", "discardable", "fieldchecks", "passc", "passl", "borrow", "discardable", "fieldchecks",

View file

@ -4649,6 +4649,51 @@ Example:
.. code-block:: nimrod .. code-block:: nimrod
{.deadCodeElim: on.} {.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 Pragma pragma
------------- -------------

View file

@ -78,7 +78,7 @@ proc innerText*(n: PXmlNode): string =
result = "" result = ""
assert n.k == xnElement assert n.k == xnElement
for i in 0 .. n.s.len-1: 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.} = proc tag*(n: PXmlNode): string {.inline.} =
## gets the tag name of `n`. `n` has to be an ``xnElement`` node. ## gets the tag name of `n`. `n` has to be an ``xnElement`` node.

View file

@ -0,0 +1,10 @@
{. noforward: on .}
proc foo(x: int) =
bar x
proc bar(x: int) =
echo x
foo(10)

View file

@ -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"

View file

@ -7,4 +7,3 @@ discard """
1+4 #ERROR_MSG value returned by statement has to be discarded 1+4 #ERROR_MSG value returned by statement has to be discarded

View file

@ -56,6 +56,8 @@ Compiler Additions
to be turned on explicitly via ``--warning[ShadowIdent]:on``. to be turned on explicitly via ``--warning[ShadowIdent]:on``.
- The compiler now supports almost every pragma in a ``push`` pragma. - The compiler now supports almost every pragma in a ``push`` pragma.
- Generic converters have been implemented. - Generic converters have been implemented.
- Added a ``noforward`` pragma enabling a special compilation mode that largely
eliminates the need for forward declarations.
Language Additions Language Additions