[svn:parrot] r39884 - in branches/tt761_keys_revamp: . compilers/imcc compilers/nqp/src/Grammar compilers/pct/src/PAST compilers/pct/src/PCT compilers/pge compilers/pge/PGE config/auto config/gen config/gen/config_h config/gen/makefiles config/init/hints config/inter docs docs/book docs/book/draft docs/book/pir docs/pdds docs/project docs/user/pir editor examples/opengl examples/pge examples/tutorial include/parrot lib/Parrot lib/Parrot/Docs/Section lib/Parrot/OpTrans lib/Parrot/Pmc2c lib/Parrot/Pmc2c/PMC runtime/parrot/library runtime/parrot/library/CGI runtime/parrot/library/Getopt runtime/parrot/library/MIME runtime/parrot/library/OpenGL runtime/parrot/library/PGE runtime/parrot/library/Test runtime/parrot/library/Test/Builder src src/gc src/interp src/io src/jit/i386 src/ops src/pmc src/runcore src/string src/string/charset t/codingstd t/compilers/imcc/syn t/compilers/pge/perl6regex t/examples t/library t/oo t/op t/pmc t/steps tools/build tools/dev tools/util

bacek at svn.parrot.org bacek at svn.parrot.org
Sat Jul 4 21:38:39 UTC 2009


Author: bacek
Date: Sat Jul  4 21:38:28 2009
New Revision: 39884
URL: https://trac.parrot.org/parrot/changeset/39884

Log:
Bring brach up-to-date with trunk.

Added:
   branches/tt761_keys_revamp/docs/book/draft/README
      - copied, changed from r39858, branches/tt761_keys_revamp/docs/book/README
   branches/tt761_keys_revamp/docs/book/draft/appa_glossary.pod
      - copied, changed from r39858, branches/tt761_keys_revamp/docs/book/appa_glossary.pod
   branches/tt761_keys_revamp/docs/book/draft/appb_patch_submission.pod
      - copied, changed from r39858, branches/tt761_keys_revamp/docs/book/appb_patch_submission.pod
   branches/tt761_keys_revamp/docs/book/draft/appc_command_line_options.pod
      - copied, changed from r39858, branches/tt761_keys_revamp/docs/book/appc_command_line_options.pod
   branches/tt761_keys_revamp/docs/book/draft/appd_build_options.pod
      - copied, changed from r39858, branches/tt761_keys_revamp/docs/book/appd_build_options.pod
   branches/tt761_keys_revamp/docs/book/draft/appe_source_code.pod
      - copied, changed from r39858, branches/tt761_keys_revamp/docs/book/appe_source_code.pod
   branches/tt761_keys_revamp/docs/book/draft/ch01_introduction.pod
      - copied, changed from r39858, branches/tt761_keys_revamp/docs/book/ch01_introduction.pod
   branches/tt761_keys_revamp/docs/book/draft/ch02_getting_started.pod
      - copied, changed from r39858, branches/tt761_keys_revamp/docs/book/ch02_getting_started.pod
   branches/tt761_keys_revamp/docs/book/draft/ch04_compiler_tools.pod
      - copied, changed from r39858, branches/tt761_keys_revamp/docs/book/ch04_compiler_tools.pod
   branches/tt761_keys_revamp/docs/book/draft/ch05_pge.pod
      - copied, changed from r39858, branches/tt761_keys_revamp/docs/book/ch05_pge.pod
   branches/tt761_keys_revamp/docs/book/draft/ch06_nqp.pod
      - copied, changed from r39858, branches/tt761_keys_revamp/docs/book/ch06_nqp.pod
   branches/tt761_keys_revamp/docs/book/draft/ch07_dynpmcs.pod
      - copied, changed from r39858, branches/tt761_keys_revamp/docs/book/ch07_dynpmcs.pod
   branches/tt761_keys_revamp/docs/book/draft/ch08_dynops.pod
      - copied, changed from r39858, branches/tt761_keys_revamp/docs/book/ch08_dynops.pod
   branches/tt761_keys_revamp/docs/book/draft/ch10_opcode_reference.pod
      - copied, changed from r39858, branches/tt761_keys_revamp/docs/book/ch10_opcode_reference.pod
   branches/tt761_keys_revamp/docs/book/draft/ch11_directive_reference.pod
      - copied, changed from r39858, branches/tt761_keys_revamp/docs/book/ch11_directive_reference.pod
   branches/tt761_keys_revamp/docs/book/draft/ch12_operator_reference.pod
      - copied, changed from r39858, branches/tt761_keys_revamp/docs/book/ch12_operator_reference.pod
   branches/tt761_keys_revamp/docs/book/pir/
   branches/tt761_keys_revamp/docs/book/pir/ch01_introduction.pod
   branches/tt761_keys_revamp/docs/book/pir/ch02_getting_started.pod
   branches/tt761_keys_revamp/docs/book/pir/ch03_basic_syntax.pod
   branches/tt761_keys_revamp/docs/book/pir/ch04_variables.pod
   branches/tt761_keys_revamp/docs/book/pir/ch05_control_structures.pod
   branches/tt761_keys_revamp/docs/book/pir/ch06_subroutines.pod
   branches/tt761_keys_revamp/docs/book/pir/ch07_objects.pod
   branches/tt761_keys_revamp/docs/book/pir/ch08_io.pod
   branches/tt761_keys_revamp/docs/book/pir/ch09_exceptions.pod
   branches/tt761_keys_revamp/examples/opengl/math.pir
   branches/tt761_keys_revamp/examples/pge/
   branches/tt761_keys_revamp/examples/pge/demo.pir
      - copied, changed from r39858, branches/tt761_keys_revamp/compilers/pge/demo.pir
   branches/tt761_keys_revamp/runtime/parrot/library/OpenGL/
   branches/tt761_keys_revamp/runtime/parrot/library/OpenGL/Math.pir
Deleted:
   branches/tt761_keys_revamp/compilers/pge/demo.pir
   branches/tt761_keys_revamp/docs/book/README
   branches/tt761_keys_revamp/docs/book/appa_glossary.pod
   branches/tt761_keys_revamp/docs/book/appb_patch_submission.pod
   branches/tt761_keys_revamp/docs/book/appc_command_line_options.pod
   branches/tt761_keys_revamp/docs/book/appd_build_options.pod
   branches/tt761_keys_revamp/docs/book/appe_source_code.pod
   branches/tt761_keys_revamp/docs/book/ch01_introduction.pod
   branches/tt761_keys_revamp/docs/book/ch02_getting_started.pod
   branches/tt761_keys_revamp/docs/book/ch03_pir.pod
   branches/tt761_keys_revamp/docs/book/ch04_compiler_tools.pod
   branches/tt761_keys_revamp/docs/book/ch05_pge.pod
   branches/tt761_keys_revamp/docs/book/ch06_nqp.pod
   branches/tt761_keys_revamp/docs/book/ch07_dynpmcs.pod
   branches/tt761_keys_revamp/docs/book/ch08_dynops.pod
   branches/tt761_keys_revamp/docs/book/ch10_opcode_reference.pod
   branches/tt761_keys_revamp/docs/book/ch11_directive_reference.pod
   branches/tt761_keys_revamp/docs/book/ch12_operator_reference.pod
   branches/tt761_keys_revamp/lib/Parrot/OpTrans/Compiled.pm
Modified:
   branches/tt761_keys_revamp/CREDITS
   branches/tt761_keys_revamp/ChangeLog
   branches/tt761_keys_revamp/DEPRECATED.pod
   branches/tt761_keys_revamp/MANIFEST
   branches/tt761_keys_revamp/MANIFEST.SKIP
   branches/tt761_keys_revamp/MANIFEST.generated
   branches/tt761_keys_revamp/META.yml
   branches/tt761_keys_revamp/NEWS
   branches/tt761_keys_revamp/PLATFORMS
   branches/tt761_keys_revamp/README
   branches/tt761_keys_revamp/VERSION
   branches/tt761_keys_revamp/compilers/imcc/cfg.c
   branches/tt761_keys_revamp/compilers/imcc/imc.c
   branches/tt761_keys_revamp/compilers/imcc/imc.h
   branches/tt761_keys_revamp/compilers/imcc/imcc.l
   branches/tt761_keys_revamp/compilers/imcc/imcc.y
   branches/tt761_keys_revamp/compilers/imcc/imclexer.c
   branches/tt761_keys_revamp/compilers/imcc/imcparser.c
   branches/tt761_keys_revamp/compilers/imcc/imcparser.h
   branches/tt761_keys_revamp/compilers/imcc/instructions.c
   branches/tt761_keys_revamp/compilers/imcc/instructions.h
   branches/tt761_keys_revamp/compilers/imcc/main.c
   branches/tt761_keys_revamp/compilers/imcc/optimizer.c
   branches/tt761_keys_revamp/compilers/imcc/parser_util.c
   branches/tt761_keys_revamp/compilers/imcc/pbc.c
   branches/tt761_keys_revamp/compilers/imcc/pbc.h
   branches/tt761_keys_revamp/compilers/imcc/pcc.c
   branches/tt761_keys_revamp/compilers/imcc/reg_alloc.c
   branches/tt761_keys_revamp/compilers/imcc/symreg.c
   branches/tt761_keys_revamp/compilers/nqp/src/Grammar/Actions.pir
   branches/tt761_keys_revamp/compilers/pct/src/PAST/Compiler.pir
   branches/tt761_keys_revamp/compilers/pct/src/PCT/Dumper.pir
   branches/tt761_keys_revamp/compilers/pge/PGE/Match.pir
   branches/tt761_keys_revamp/compilers/pge/PGE/OPTable.pir
   branches/tt761_keys_revamp/compilers/pge/PGE/Perl6Regex.pir
   branches/tt761_keys_revamp/config/auto/gcc.pm
   branches/tt761_keys_revamp/config/auto/icu.pm
   branches/tt761_keys_revamp/config/gen/config_h/config_h.in
   branches/tt761_keys_revamp/config/gen/crypto.pm
   branches/tt761_keys_revamp/config/gen/makefiles/root.in
   branches/tt761_keys_revamp/config/gen/opengl.pm
   branches/tt761_keys_revamp/config/init/hints/darwin.pm
   branches/tt761_keys_revamp/config/init/hints/dragonfly.pm
   branches/tt761_keys_revamp/config/init/hints/freebsd.pm
   branches/tt761_keys_revamp/config/init/hints/linux.pm
   branches/tt761_keys_revamp/config/init/hints/mswin32.pm
   branches/tt761_keys_revamp/config/init/hints/openbsd.pm
   branches/tt761_keys_revamp/config/inter/libparrot.pm
   branches/tt761_keys_revamp/docs/parrothist.pod
   branches/tt761_keys_revamp/docs/pdds/pdd19_pir.pod
   branches/tt761_keys_revamp/docs/pdds/pdd27_multiple_dispatch.pod
   branches/tt761_keys_revamp/docs/project/release_manager_guide.pod
   branches/tt761_keys_revamp/docs/user/pir/objects.pod
   branches/tt761_keys_revamp/docs/user/pir/pmcs.pod
   branches/tt761_keys_revamp/editor/pir_vim.in
   branches/tt761_keys_revamp/examples/opengl/shapes.p6
   branches/tt761_keys_revamp/examples/tutorial/01_temp_var.pir
   branches/tt761_keys_revamp/examples/tutorial/02_local_var.pir
   branches/tt761_keys_revamp/examples/tutorial/03_temp_var_basic_pmcs.pir
   branches/tt761_keys_revamp/examples/tutorial/24_string_ops_clone.pir
   branches/tt761_keys_revamp/examples/tutorial/30_arrays_basic.pir
   branches/tt761_keys_revamp/examples/tutorial/32_array_ops_sprintf.pir
   branches/tt761_keys_revamp/examples/tutorial/33_hashes.pir
   branches/tt761_keys_revamp/examples/tutorial/34_multikey.pir
   branches/tt761_keys_revamp/examples/tutorial/40_file_ops.pir
   branches/tt761_keys_revamp/examples/tutorial/55_iterator.pir
   branches/tt761_keys_revamp/examples/tutorial/56_defined.pir
   branches/tt761_keys_revamp/examples/tutorial/57_exists.pir
   branches/tt761_keys_revamp/examples/tutorial/61_namespaces.pir
   branches/tt761_keys_revamp/examples/tutorial/70_class_object.pir
   branches/tt761_keys_revamp/examples/tutorial/81_continuation.pir
   branches/tt761_keys_revamp/include/parrot/compiler.h
   branches/tt761_keys_revamp/include/parrot/key.h
   branches/tt761_keys_revamp/include/parrot/memory.h
   branches/tt761_keys_revamp/include/parrot/pmc.h
   branches/tt761_keys_revamp/include/parrot/stacks.h
   branches/tt761_keys_revamp/include/parrot/sub.h
   branches/tt761_keys_revamp/include/parrot/thr_windows.h
   branches/tt761_keys_revamp/lib/Parrot/Distribution.pm
   branches/tt761_keys_revamp/lib/Parrot/Docs/Section/Parrot.pm
   branches/tt761_keys_revamp/lib/Parrot/Install.pm
   branches/tt761_keys_revamp/lib/Parrot/OpTrans.pm
   branches/tt761_keys_revamp/lib/Parrot/OpTrans/C.pm
   branches/tt761_keys_revamp/lib/Parrot/OpTrans/CGP.pm
   branches/tt761_keys_revamp/lib/Parrot/OpTrans/CGoto.pm
   branches/tt761_keys_revamp/lib/Parrot/OpTrans/CPrederef.pm
   branches/tt761_keys_revamp/lib/Parrot/OpTrans/CSwitch.pm
   branches/tt761_keys_revamp/lib/Parrot/OpsFile.pm
   branches/tt761_keys_revamp/lib/Parrot/OpsRenumber.pm
   branches/tt761_keys_revamp/lib/Parrot/Pmc2c/Attribute.pm
   branches/tt761_keys_revamp/lib/Parrot/Pmc2c/PMC.pm
   branches/tt761_keys_revamp/lib/Parrot/Pmc2c/PMC/RO.pm
   branches/tt761_keys_revamp/lib/Parrot/Pmc2c/PMCEmitter.pm
   branches/tt761_keys_revamp/runtime/parrot/library/CGI/QueryHash.pir
   branches/tt761_keys_revamp/runtime/parrot/library/Getopt/Obj.pir
   branches/tt761_keys_revamp/runtime/parrot/library/MIME/Base64.pir
   branches/tt761_keys_revamp/runtime/parrot/library/OpenGL.pir
   branches/tt761_keys_revamp/runtime/parrot/library/P6object.pir
   branches/tt761_keys_revamp/runtime/parrot/library/PGE/Util.pir
   branches/tt761_keys_revamp/runtime/parrot/library/Range.pir
   branches/tt761_keys_revamp/runtime/parrot/library/Test/Builder/Output.pir
   branches/tt761_keys_revamp/runtime/parrot/library/Test/More.pir
   branches/tt761_keys_revamp/src/debug.c
   branches/tt761_keys_revamp/src/embed.c
   branches/tt761_keys_revamp/src/gc/alloc_memory.c
   branches/tt761_keys_revamp/src/gc/api.c
   branches/tt761_keys_revamp/src/hash.c
   branches/tt761_keys_revamp/src/interp/inter_create.c
   branches/tt761_keys_revamp/src/io/unix.c
   branches/tt761_keys_revamp/src/jit/i386/jit_defs.c
   branches/tt761_keys_revamp/src/key.c
   branches/tt761_keys_revamp/src/library.c
   branches/tt761_keys_revamp/src/main.c
   branches/tt761_keys_revamp/src/oo.c
   branches/tt761_keys_revamp/src/ops/cmp.ops
   branches/tt761_keys_revamp/src/ops/ops.num
   branches/tt761_keys_revamp/src/packdump.c
   branches/tt761_keys_revamp/src/packfile.c
   branches/tt761_keys_revamp/src/parrot_debugger.c
   branches/tt761_keys_revamp/src/pbc_merge.c
   branches/tt761_keys_revamp/src/pmc.c
   branches/tt761_keys_revamp/src/pmc/bignum.pmc
   branches/tt761_keys_revamp/src/pmc/filehandle.pmc
   branches/tt761_keys_revamp/src/pmc/multisub.pmc
   branches/tt761_keys_revamp/src/pmc/parrotinterpreter.pmc
   branches/tt761_keys_revamp/src/pmc/parrotrunningthread.pmc
   branches/tt761_keys_revamp/src/pmc/parrotthread.pmc
   branches/tt761_keys_revamp/src/pmc/stringhandle.pmc
   branches/tt761_keys_revamp/src/pmc/sub.pmc
   branches/tt761_keys_revamp/src/runcore/cores.c
   branches/tt761_keys_revamp/src/runcore/trace.c
   branches/tt761_keys_revamp/src/stacks.c
   branches/tt761_keys_revamp/src/string/api.c
   branches/tt761_keys_revamp/src/string/charset/unicode.c
   branches/tt761_keys_revamp/t/codingstd/c_indent.t
   branches/tt761_keys_revamp/t/compilers/imcc/syn/errors.t
   branches/tt761_keys_revamp/t/compilers/imcc/syn/regressions.t
   branches/tt761_keys_revamp/t/compilers/pge/perl6regex/context.t
   branches/tt761_keys_revamp/t/examples/pod.t
   branches/tt761_keys_revamp/t/library/p6object.t
   branches/tt761_keys_revamp/t/library/test_more.t
   branches/tt761_keys_revamp/t/oo/metamodel.t
   branches/tt761_keys_revamp/t/op/arithmetics.t
   branches/tt761_keys_revamp/t/op/cmp-nonbranch.t
   branches/tt761_keys_revamp/t/op/debuginfo.t
   branches/tt761_keys_revamp/t/op/globals.t
   branches/tt761_keys_revamp/t/op/ifunless.t
   branches/tt761_keys_revamp/t/op/integer.t
   branches/tt761_keys_revamp/t/op/io.t
   branches/tt761_keys_revamp/t/op/lexicals.t
   branches/tt761_keys_revamp/t/op/string.t
   branches/tt761_keys_revamp/t/op/stringu.t
   branches/tt761_keys_revamp/t/pmc/bignum.t
   branches/tt761_keys_revamp/t/pmc/capture.t
   branches/tt761_keys_revamp/t/pmc/exceptionhandler.t
   branches/tt761_keys_revamp/t/pmc/namespace.t
   branches/tt761_keys_revamp/t/pmc/nci.t
   branches/tt761_keys_revamp/t/steps/auto_icu-01.t
   branches/tt761_keys_revamp/tools/build/nativecall.pl
   branches/tt761_keys_revamp/tools/build/ops2c.pl
   branches/tt761_keys_revamp/tools/dev/branch_status.pl
   branches/tt761_keys_revamp/tools/dev/fetch_languages.pl
   branches/tt761_keys_revamp/tools/dev/parrot.supp
   branches/tt761_keys_revamp/tools/dev/pbc_to_exe.pir
   branches/tt761_keys_revamp/tools/util/release.json

Modified: branches/tt761_keys_revamp/CREDITS
==============================================================================
--- branches/tt761_keys_revamp/CREDITS	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/CREDITS	Sat Jul  4 21:38:28 2009	(r39884)
@@ -92,7 +92,7 @@
 N: Andrew Whitworth
 D: Internals development
 D: Documentation
-D: Release manager for 0.8.2
+D: Release manager for 0.8.2 and 1.3.0
 E: wknight8111 at gmail.com
 U: Whiteknight
 
@@ -134,6 +134,13 @@
 E: audreyt at audreyt.org
 D: Pugs, a Perl6->Parrot implementation.
 
+N: Austin Hastings
+U: Austin
+A: austin_hastings at yahoo.com
+A: austin_h... at yahoo.com
+E: austin_hastings at yahoo.com
+D: Close
+
 N: Benjamin Goldberg
 D: Numerous improvements and proposals.
 

Modified: branches/tt761_keys_revamp/ChangeLog
==============================================================================
--- branches/tt761_keys_revamp/ChangeLog	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/ChangeLog	Sat Jul  4 21:38:28 2009	(r39884)
@@ -1,5 +1,9 @@
 #1 $Id$
 
+2009.06.16    Whiteknight
+        * Released 1.3.0
+        Ses NEWS for more.
+
 2009.05.19    Infinoid
         * Released 1.2.0
         See NEWS for more.

Modified: branches/tt761_keys_revamp/DEPRECATED.pod
==============================================================================
--- branches/tt761_keys_revamp/DEPRECATED.pod	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/DEPRECATED.pod	Sat Jul  4 21:38:28 2009	(r39884)
@@ -75,6 +75,10 @@
 
 L<https://trac.parrot.org/parrot/ticket/679>
 
+=item Method stdhandle in ParrotInterpreter [experimental]
+
+L<https://trac.parrot.org/parrot/ticket/264>
+
 =back
 
 =head1 Opcodes

Modified: branches/tt761_keys_revamp/MANIFEST
==============================================================================
--- branches/tt761_keys_revamp/MANIFEST	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/MANIFEST	Sat Jul  4 21:38:28 2009	(r39884)
@@ -1,7 +1,7 @@
 # ex: set ro:
 # $Id$
 #
-# generated by tools/dev/mk_manifest_and_skip.pl Sat Jun 13 06:12:21 2009 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Thu Jul  2 17:10:26 2009 UT
 #
 # See below for documentation on the format of this file.
 #
@@ -138,7 +138,6 @@
 compilers/pge/PGE/builtins.pg                               [pge]
 compilers/pge/README.pod                                    []doc
 compilers/pge/STATUS                                        [pge]
-compilers/pge/demo.pir                                      [pge]
 compilers/pirc/README.pod                                   []doc
 compilers/pirc/TODO                                         [pirc]
 compilers/pirc/heredoc/heredocmain.c                        [pirc]
@@ -411,26 +410,34 @@
 config/inter/shlibs.pm                                      []
 config/inter/types.pm                                       []
 config/inter/yacc.pm                                        []
-docs/book/README                                            []doc
-docs/book/appa_glossary.pod                                 []
-docs/book/appb_patch_submission.pod                         []
-docs/book/appc_command_line_options.pod                     []
-docs/book/appd_build_options.pod                            []
-docs/book/appe_source_code.pod                              []
-docs/book/ch01_introduction.pod                             []
-docs/book/ch02_getting_started.pod                          []
-docs/book/ch03_pir.pod                                      []
-docs/book/ch04_compiler_tools.pod                           []
-docs/book/ch05_pge.pod                                      []
-docs/book/ch06_nqp.pod                                      []
-docs/book/ch07_dynpmcs.pod                                  []
-docs/book/ch08_dynops.pod                                   []
-docs/book/ch10_opcode_reference.pod                         []
-docs/book/ch11_directive_reference.pod                      []
-docs/book/ch12_operator_reference.pod                       []
+docs/book/draft/README                                      []doc
+docs/book/draft/appa_glossary.pod                           []
+docs/book/draft/appb_patch_submission.pod                   []
+docs/book/draft/appc_command_line_options.pod               []
+docs/book/draft/appd_build_options.pod                      []
+docs/book/draft/appe_source_code.pod                        []
+docs/book/draft/ch01_introduction.pod                       []
+docs/book/draft/ch02_getting_started.pod                    []
+docs/book/draft/ch04_compiler_tools.pod                     []
+docs/book/draft/ch05_pge.pod                                []
+docs/book/draft/ch06_nqp.pod                                []
+docs/book/draft/ch07_dynpmcs.pod                            []
+docs/book/draft/ch08_dynops.pod                             []
+docs/book/draft/ch10_opcode_reference.pod                   []
+docs/book/draft/ch11_directive_reference.pod                []
+docs/book/draft/ch12_operator_reference.pod                 []
 docs/book/draft/chXX_hlls.pod                               []
 docs/book/draft/chXX_library.pod                            []
 docs/book/draft/chXX_testing_and_debugging.pod              []
+docs/book/pir/ch01_introduction.pod                         []
+docs/book/pir/ch02_getting_started.pod                      []
+docs/book/pir/ch03_basic_syntax.pod                         []
+docs/book/pir/ch04_variables.pod                            []
+docs/book/pir/ch05_control_structures.pod                   []
+docs/book/pir/ch06_subroutines.pod                          []
+docs/book/pir/ch07_objects.pod                              []
+docs/book/pir/ch08_io.pod                                   []
+docs/book/pir/ch09_exceptions.pod                           []
 docs/compiler_faq.pod                                       [devel]doc
 docs/configuration.pod                                      []
 docs/debug.pod                                              [devel]doc
@@ -716,6 +723,7 @@
 examples/nci/xlibtest.p6                                    [examples]
 examples/nci/xlibtest.pir                                   [examples]
 examples/nci/xlibtest.rb                                    [examples]
+examples/opengl/math.pir                                    [examples]
 examples/opengl/shapes.p6                                   [examples]
 examples/opengl/shapes.pir                                  [examples]
 examples/opengl/static-triangle.p6                          [examples]
@@ -729,6 +737,7 @@
 examples/past/01-sub.pir                                    [examples]
 examples/past/blocktype_immediate.pir                       [examples]
 examples/past/four_plus_one.pir                             [examples]
+examples/pge/demo.pir                                       [examples]
 examples/pir/befunge/Changes                                [examples]
 examples/pir/befunge/Configure.pl                           [examples]
 examples/pir/befunge/MAINTAINER                             [examples]
@@ -1059,7 +1068,6 @@
 lib/Parrot/OpTrans/CGoto.pm                                 [devel]lib
 lib/Parrot/OpTrans/CPrederef.pm                             [devel]lib
 lib/Parrot/OpTrans/CSwitch.pm                               [devel]lib
-lib/Parrot/OpTrans/Compiled.pm                              [devel]lib
 lib/Parrot/Ops2c/Auxiliary.pm                               [devel]lib
 lib/Parrot/Ops2c/Utils.pm                                   [devel]lib
 lib/Parrot/Ops2pm.pm                                        [devel]lib
@@ -1163,6 +1171,7 @@
 runtime/parrot/library/NCI/Utils.pir                        [library]
 runtime/parrot/library/NCI/call_toolkit_init.pir            [library]
 runtime/parrot/library/OpenGL.pir                           [library]
+runtime/parrot/library/OpenGL/Math.pir                      [library]
 runtime/parrot/library/P6object.pir                         [library]
 runtime/parrot/library/PCT/README                           []doc
 runtime/parrot/library/PGE/Dumper.pir                       [library]

Modified: branches/tt761_keys_revamp/MANIFEST.SKIP
==============================================================================
--- branches/tt761_keys_revamp/MANIFEST.SKIP	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/MANIFEST.SKIP	Sat Jul  4 21:38:28 2009	(r39884)
@@ -1,6 +1,6 @@
 # ex: set ro:
 # $Id$
-# generated by tools/dev/mk_manifest_and_skip.pl Fri May 15 17:05:40 2009 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Thu Jun 25 20:34:12 2009 UT
 #
 # This file should contain a transcript of the svn:ignore properties
 # of the directories in the Parrot subversion repository. (Needed for
@@ -578,6 +578,9 @@
 # generated from svn:ignore of 'runtime/parrot/library/NCI/'
 ^runtime/parrot/library/NCI/.*\.pbc$
 ^runtime/parrot/library/NCI/.*\.pbc/
+# generated from svn:ignore of 'runtime/parrot/library/OpenGL/'
+^runtime/parrot/library/OpenGL/.*\.pbc$
+^runtime/parrot/library/OpenGL/.*\.pbc/
 # generated from svn:ignore of 'runtime/parrot/library/PCT/'
 ^runtime/parrot/library/PCT/.*\.pbc$
 ^runtime/parrot/library/PCT/.*\.pbc/
@@ -825,6 +828,8 @@
 ^src/string/.*\.o/
 ^src/string/.*\.obj$
 ^src/string/.*\.obj/
+^src/string/.*\.str$
+^src/string/.*\.str/
 ^src/string/private_cstring\.h$
 ^src/string/private_cstring\.h/
 # generated from svn:ignore of 'src/string/charset/'

Modified: branches/tt761_keys_revamp/MANIFEST.generated
==============================================================================
--- branches/tt761_keys_revamp/MANIFEST.generated	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/MANIFEST.generated	Sat Jul  4 21:38:28 2009	(r39884)
@@ -2,10 +2,10 @@
 # See tools/dev/install_files.pl for documentation on the
 # format of this file.
 # Please re-sort this file after *EVERY* modification
-blib/lib/libparrot.1.2.0.dylib                    [main]lib
+blib/lib/libparrot.1.3.0.dylib                    [main]lib
 blib/lib/libparrot.a                              [main]lib
 blib/lib/libparrot.dylib                          [main]lib
-blib/lib/libparrot.so.1.2.0                       [main]lib
+blib/lib/libparrot.so.1.3.0                       [main]lib
 blib/lib/libparrot.so                             [main]lib
 compilers/json/JSON/grammar.pbc                   [json]
 compilers/json/JSON.pbc                           [json]

Modified: branches/tt761_keys_revamp/META.yml
==============================================================================
--- branches/tt761_keys_revamp/META.yml	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/META.yml	Sat Jul  4 21:38:28 2009	(r39884)
@@ -4,7 +4,7 @@
 # See http://module-build.sourceforge.net/META-spec-current.html for details.
 ---
 name: parrot
-version: 1.2.0
+version: 1.3.0
 author: parrot-dev at lists.parrot.org
 abstract: a virtual machine designed for dynamic languages
 license: artistic2
@@ -30,7 +30,6 @@
         - Parrot::Docs::HTMLPage
         - Parrot::OpTrans::CGP
         - Parrot::OpTrans::CSwitch
-        - Parrot::OpTrans::Compiled
         - Parrot::OpsFile
 requires:
   Storable: 2.12

Modified: branches/tt761_keys_revamp/NEWS
==============================================================================
--- branches/tt761_keys_revamp/NEWS	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/NEWS	Sat Jul  4 21:38:28 2009	(r39884)
@@ -2,8 +2,32 @@
 
 New in 1.3.0
 - Core
-  + Optimization for parts of the IO system
-  + Fix inheritance heirarchy of FileHandle and Socket PMC types
+  + Optimized parts of the IO system
+  + Fixed inheritance hierarchy of FileHandle and Socket PMC types
+  + Fixed leaks involving subroutines and Parrot_Context
+  + Cleaned up and refactored GC internals, including fixes and optimizations
+  + Optimized PMC class manipulations to use type numbers instead of string names
+  + Fixed problems involving hashval calculations in strings
+  + Removed unnecessary MULTI dispatches in built-in PMCs
+  + Fixed memory leaks involving PMCs that were not properly destroyed
+  + Fixed creation of PMCProxy PMCs in correct namespaces
+  + Added preliminary Pipe support
+  + Fixed cloning of Object PMCs
+  + Added root_new opcode
+  + Added initial versions of Packfile PMCs with read/write capabilities
+- Compilers
+  + Fixed several memory leaks in IMCC
+  + Updated PCT to use root_new opcode
+  + Added support for keyword "self" in NQP
+- Documentation
+  + Improved and expanded /docs/book
+  + Updated project documentation
+  + Defined 'experimental' status and procedures in DEPRECATED.pod
+- Miscellaneous
+  + Cleaned code and improved code-level documentation
+  + Various bugfixes, code cleanups, and coding standard fixes
+  + Added an experimental compiler library to help use PIR libraries from HLLs
+  + Updated OpenGL library and examples to support experimental HLL import
 
 New in 1.2.0
 - Core

Modified: branches/tt761_keys_revamp/PLATFORMS
==============================================================================
--- branches/tt761_keys_revamp/PLATFORMS	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/PLATFORMS	Sat Jul  4 21:38:28 2009	(r39884)
@@ -39,6 +39,7 @@
 dragonfly2.2.0-i386-gcc-4.1.2 4   Y    Y    -     Y   Y   Y    Y     ?  20090427
 freebsd-x86-gcc-4.2.1         4   Y    Y    Y     ?   ?   Y    Y     Y  20090415
 freebsd-amd64-gcc-4.2.1       8   Y    -    -     ?   ?   Y    Y     Y  20090419
+linux-amd64-clang-r73854      8   ?    ?    =     Y   Y   Y/4  Y/1   ?  20090622
 linux-ppc-gcc3.4.5                Y    Y    Y     ?   ?   Y    Y     ?  20080519
 linux-s390x-gcc4.1.2         B4   ?    -    -     Y   Y   Y    Y/2   ?  20080908
 linux-x86_64-gcc4.1.2         8   Y    -    -     Y   Y   Y    Y     ?  20080220
@@ -93,6 +94,8 @@
    --ccflags='-m64' --ldflags='-m64' --linkflags='-m64'
 *2 http://rt.perl.org/rt3/Ticket/Display.html?id=60926
 *3 failures in 'make examples_tests' (part of 'make fulltest')
+*4 compiles with --ccflags=-U__APPLE_CC__ --without-gmp
+   See http://lists.parrot.org/pipermail/parrot-dev/2009-June/002407.html
 
 The following configurations are also working on x86/linux (and possibly
 other platforms):

Modified: branches/tt761_keys_revamp/README
==============================================================================
--- branches/tt761_keys_revamp/README	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/README	Sat Jul  4 21:38:28 2009	(r39884)
@@ -1,4 +1,4 @@
-This is Parrot, version 1.2.0
+This is Parrot, version 1.3.0
 ------------------------------
 
 Parrot is Copyright (C) 2001-2009, Parrot Foundation.

Modified: branches/tt761_keys_revamp/VERSION
==============================================================================
--- branches/tt761_keys_revamp/VERSION	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/VERSION	Sat Jul  4 21:38:28 2009	(r39884)
@@ -1 +1 @@
-1.2.0
+1.3.0

Modified: branches/tt761_keys_revamp/compilers/imcc/cfg.c
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/cfg.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/cfg.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -644,7 +644,7 @@
     /* memory housekeeping */
     e->next = NULL;
 
-    if (unit->edge_list == 0)
+    if (unit->edge_list == NULL)
         unit->edge_list = e;
     else {
         e->next         = unit->edge_list;
@@ -1555,7 +1555,7 @@
     mem_sys_free(unit->loop_info);
 
     unit->n_loops   = 0;
-    unit->loop_info = 0;
+    unit->loop_info = NULL;
 }
 
 

Modified: branches/tt761_keys_revamp/compilers/imcc/imc.c
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/imc.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/imc.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -143,6 +143,11 @@
     clear_globals(interp);
     mem_sys_free(IMCC_INFO(interp)->ghash.data);
     IMCC_INFO(interp)->ghash.data = NULL;
+
+    if (IMCC_INFO(interp)->state) {
+        free(IMCC_INFO(interp)->state->file);
+        IMCC_INFO(interp)->state->file = NULL;
+    }
 }
 
 

Modified: branches/tt761_keys_revamp/compilers/imcc/imc.h
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/imc.h	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/imc.h	Sat Jul  4 21:38:28 2009	(r39884)
@@ -64,6 +64,7 @@
 /* HEADERIZER BEGIN: compilers/imcc/imcc.y */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 Instruction * IMCC_create_itcall_label(PARROT_INTERP)
         __attribute__nonnull__(1);
@@ -72,6 +73,7 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 Instruction * INS_LABEL(PARROT_INTERP,
     ARGMOD_NULLOK(IMC_Unit *unit),
@@ -148,6 +150,7 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*unit);
 
+PARROT_WARN_UNUSED_RESULT
 unsigned int ig_test(int i, int j, int N, ARGIN(unsigned int *graph))
         __attribute__nonnull__(4);
 
@@ -293,13 +296,16 @@
         __attribute__nonnull__(3)
         FUNC_MODIFIES(*error_message);
 
-int imcc_vfprintf(PARROT_INTERP,
-    ARGIN(PMC *io),
+PARROT_IGNORABLE_RESULT
+int /*@alt void@*/
+imcc_vfprintf(PARROT_INTERP,
+    ARGMOD(PMC *io),
     ARGIN(const char *format),
     va_list ap)
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
-        __attribute__nonnull__(3);
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*io);
 
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
@@ -527,7 +533,6 @@
     Interp                *interp;
     char                  *file;
     FILE                  *handle;
-    int                    file_needs_free; /* is *file malloced? */
     int                    line;
     int                    pasm_file;       /* pasm_file mode of this frame */
 };

Modified: branches/tt761_keys_revamp/compilers/imcc/imcc.l
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/imcc.l	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/imcc.l	Sat Jul  4 21:38:28 2009	(r39884)
@@ -96,7 +96,7 @@
 
 #define DUP_AND_RET(valp, token)             \
   do {                                       \
-      if (valp) (valp)->s = str_dup(yytext); \
+      if (valp) (valp)->s = mem_sys_strdup(yytext); \
       return (token);                        \
   } while (0)
 
@@ -104,7 +104,7 @@
   do {                                       \
       if (valp) {                            \
           mem_sys_free((valp)->s);           \
-          (valp)->s = str_dup(yytext);       \
+          (valp)->s = mem_sys_strdup(yytext);       \
           return (token);                    \
       }                                      \
   } while (0)
@@ -171,7 +171,7 @@
         }
 
 <heredoc1>.*{EOL} {
-            IMCC_INFO(interp)->frames->heredoc_rest = str_dup(yytext);
+            IMCC_INFO(interp)->frames->heredoc_rest = mem_sys_strdup(yytext);
             BEGIN(heredoc2);
     }
 
@@ -231,9 +231,8 @@
         yy_pop_state(yyscanner);
         yy_push_state(cmt3, yyscanner);
 
-        IMCC_INFO(interp)->frames->s.file = str_dup(yytext);
-        IMCC_INFO(interp)->frames->s.file_needs_free = 1;
-        IMCC_INFO(interp)->cur_unit->file = str_dup(yytext);
+        IMCC_INFO(interp)->frames->s.file = mem_sys_strdup(yytext);
+        IMCC_INFO(interp)->cur_unit->file = mem_sys_strdup(yytext);
 
         return FILECOMMENT;
     }
@@ -460,7 +459,7 @@
         if (c != STRINGC)
             return c;
 
-        /* STRINGCs have a str_dup()ed valp->s */
+        /* STRINGCs have a mem_sys_strdup()ed valp->s */
         mem_sys_free(valp->s);
         YYCHOP();
         include_file(interp, yytext + 1, yyscanner);
@@ -517,7 +516,7 @@
         YYCHOP();
 
         if (valp)
-            valp->s = str_dup(yytext);
+            valp->s = mem_sys_strdup(yytext);
 
         return LABEL;
     }
@@ -540,7 +539,7 @@
 <*>{OCT}              DUP_AND_RET(valp, INTC);
 
 <*>{BIGINT} {
-        valp->s = str_dup(yytext);
+        valp->s = mem_sys_strdup(yytext);
 
         /* trailing 'L' */
         valp->s[strlen(valp->s) - 1] = '\0';
@@ -550,7 +549,7 @@
     }
 
 <*>{STRINGCONSTANT} {
-        valp->s = str_dup(yytext);
+        valp->s = mem_sys_strdup(yytext);
 
         /* RT #42382 delete quotes, -> emit, pbc */
         return STRINGC;
@@ -563,7 +562,7 @@
            off newline and quote. */
         if (IMCC_INFO(interp)->frames->heredoc_rest)
             IMCC_fataly(interp, EXCEPTION_SYNTAX_ERROR, "nested heredoc not supported");
-        IMCC_INFO(interp)->heredoc_end = str_dup(yytext + 3);
+        IMCC_INFO(interp)->heredoc_end = mem_sys_strdup(yytext + 3);
         IMCC_INFO(interp)->heredoc_end[strlen(IMCC_INFO(interp)->heredoc_end) - 1] = 0;
 
         if (!strlen(IMCC_INFO(interp)->heredoc_end))
@@ -586,7 +585,7 @@
 
 <*>{UNICODE} {
         /* charset:"..." */
-        valp->s = str_dup(yytext);
+        valp->s = mem_sys_strdup(yytext);
 
         /* this is actually not unicode but a string with a charset */
         return USTRINGC;
@@ -635,7 +634,7 @@
             "'%s' is only a valid register name in PASM mode", yytext);
 
         if (valp)
-            valp->s = str_dup(yytext);
+            valp->s = mem_sys_strdup(yytext);
 
         return REG;
     }
@@ -664,7 +663,7 @@
             }
         }
 
-        valp->s = str_dup(yytext);
+        valp->s = mem_sys_strdup(yytext);
         return (!pesky_global__is_def && is_op(interp, valp->s) ? PARROT_OP : IDENTIFIER);
     }
 
@@ -788,13 +787,8 @@
 
     if (IMCC_INFO(interp)->frames) {
         tmp->s.pasm_file = IMCC_INFO(interp)->frames->s.pasm_file;
-
-        if (IMCC_INFO(interp)->frames->s.file_needs_free)
-            tmp->s.file            = str_dup(IMCC_INFO(interp)->frames->s.file);
-        else
-            tmp->s.file            = IMCC_INFO(interp)->frames->s.file;
-
-        tmp->s.file_needs_free = IMCC_INFO(interp)->frames->s.file_needs_free;
+        if (IMCC_INFO(interp)->frames->s.file)
+            tmp->s.file = mem_sys_strdup(IMCC_INFO(interp)->frames->s.file);
     }
 
     tmp->s.interp = interp;
@@ -833,13 +827,7 @@
     } else
         ret = frame->s.line;
 
-    /* RT #42383 if frame->s.file was allocated free it */
-    /* Update: This should do it! */
-    if (frame->s.file_needs_free) {
-        DECL_CONST_CAST;
-        mem_sys_free(PARROT_const_cast(char *,frame->s.file));
-        frame->s.file_needs_free = 0;
-    }
+    mem_sys_free(frame->s.file);
     mem_sys_free(frame);
 
     if (buffer != NULL)
@@ -866,7 +854,7 @@
         if (*p == '\0')
             break;
 
-        /* free any str_dup()ed strings */
+        /* free any mem_sys_strdup()ed strings */
         if (yytext)
             mem_sys_free(valp->s);
     } while (*p != '\0');
@@ -924,7 +912,7 @@
 {
     YYSTYPE  val;
     size_t   len      = 0;
-    char    *current  = str_dup("");
+    char    *current  = mem_sys_strdup("");
     yyguts_t *yyg     = (yyguts_t *)yyscanner;
     int      c        = yylex_skip(&val, interp, " \n", yyscanner);
 
@@ -946,7 +934,7 @@
                             MAX_PARAM, macro_name);
 
             params->name[params->num_param++] = current;
-            current                           = str_dup("");
+            current                           = mem_sys_strdup("");
             len                               = 0;
 
             if (val.s)
@@ -1121,7 +1109,7 @@
     else
         memset(&m->params, 0, sizeof (params_t));
 
-    m->expansion = str_dup(expansion);
+    m->expansion = mem_sys_strdup(expansion);
     m->line      = start_line;
 }
 
@@ -1162,12 +1150,10 @@
 
         /* remember macro name for error reporting
          * first free any filename allocated in new_frame() */
-        if (frame->s.file && frame->s.file_needs_free)
+        if (frame->s.file)
             mem_sys_free(frame->s.file);
 
-        /* RT #42384 check that all the .file text is malloced / freed */
-        frame->s.file            = str_dup(name);
-        frame->s.file_needs_free = 1;
+        frame->s.file            = mem_sys_strdup(name);
 
         /* whitespace can be safely ignored */
         do {
@@ -1196,7 +1182,7 @@
         BEGIN(start_cond);
 
         if (frame->expansion.num_param == 0 && m->params.num_param == 1) {
-            frame->expansion.name[0] = str_dup("");
+            frame->expansion.name[0] = mem_sys_strdup("");
             frame->expansion.num_param = 1;
         }
 
@@ -1215,7 +1201,7 @@
                 const char * const s = find_macro_param(interp, current + 1);
 
                 if (s) {
-                    frame->expansion.name[i] = str_dup(s);
+                    frame->expansion.name[i] = mem_sys_strdup(s);
                     mem_sys_free(current);
                 }
 
@@ -1238,6 +1224,7 @@
 
         IMCC_INFO(interp)->line = m->line;
         scan_string(frame, m->expansion, yyscanner);
+
         return 1;
     }
 
@@ -1254,12 +1241,16 @@
     char *ext;
     FILE *file;
 
-    if (!s || !(file = fopen(s, "r")))
+    if (!s || !(file = fopen(s, "r"))) {
+        if (frame->s.file)
+            mem_sys_free(frame->s.file);
         IMCC_fataly(interp, EXCEPTION_EXTERNAL_ERROR, strerror(errno));
+    }
 
+    if (frame->s.file)
+        mem_sys_free(frame->s.file);
     mem_sys_free(s);
-    frame->s.file            = file_name;
-    frame->s.file_needs_free = 0;
+    frame->s.file            = mem_sys_strdup(file_name);
     frame->s.handle          = file;
     ext                      = strrchr(file_name, '.');
 
@@ -1432,17 +1423,16 @@
 set_filename(PARROT_INTERP, char * const filename)
 {
     IMCC_INFO(interp)->frames->s.file = filename;
-    IMCC_INFO(interp)->frames->s.file_needs_free = 1;
 
     /* in case .line is used outside a .sub, then this
      * can't be done; hence the check.
-     * The str_dup() is done, as the original #line implementation
+     * The mem_sys_strdup() is done, as the original #line implementation
      * duplicated the string twice as well; one for the
      * frames->s.file and one for cur_unit->file.
-     * During the parse, the STRINGC is already str_dup()ed once.
+     * During the parse, the STRINGC is already mem_sys_strdup()ed once.
      */
     if (IMCC_INFO(interp)->cur_unit)
-        IMCC_INFO(interp)->cur_unit->file = str_dup(filename);
+        IMCC_INFO(interp)->cur_unit->file = mem_sys_strdup(filename);
 }
 
 /* Functions to set and get yyin, as we can't decorate it for export

Modified: branches/tt761_keys_revamp/compilers/imcc/imcc.y
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/imcc.y	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/imcc.y	Sat Jul  4 21:38:28 2009	(r39884)
@@ -42,55 +42,60 @@
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-static void add_pcc_named_arg(PARROT_INTERP,
+static void add_pcc_named_arg(
     ARGMOD(SymReg *cur_call),
-    ARGIN(SymReg *name),
-    ARGIN(SymReg *value))
+    ARGMOD(SymReg *name),
+    ARGMOD(SymReg *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*cur_call);
+        FUNC_MODIFIES(*cur_call)
+        FUNC_MODIFIES(*name)
+        FUNC_MODIFIES(*value);
 
-static void add_pcc_named_arg_var(PARROT_INTERP,
+static void add_pcc_named_arg_var(
     ARGMOD(SymReg *cur_call),
-    ARGIN(SymReg *name),
-    ARGIN(SymReg *value))
+    ARGMOD(SymReg *name),
+    ARGMOD(SymReg *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*cur_call);
+        FUNC_MODIFIES(*cur_call)
+        FUNC_MODIFIES(*name)
+        FUNC_MODIFIES(*value);
 
-static void add_pcc_named_param(PARROT_INTERP,
+static void add_pcc_named_param(
     ARGMOD(SymReg *cur_call),
-    ARGIN(SymReg *name),
-    ARGIN(SymReg *value))
+    ARGMOD(SymReg *name),
+    ARGMOD(SymReg *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*cur_call);
+        FUNC_MODIFIES(*cur_call)
+        FUNC_MODIFIES(*name)
+        FUNC_MODIFIES(*value);
 
-static void add_pcc_named_result(PARROT_INTERP,
+static void add_pcc_named_result(
     ARGMOD(SymReg *cur_call),
-    ARGIN(SymReg *name),
-    ARGIN(SymReg *value))
+    ARGMOD(SymReg *name),
+    ARGMOD(SymReg *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*cur_call);
+        FUNC_MODIFIES(*cur_call)
+        FUNC_MODIFIES(*name)
+        FUNC_MODIFIES(*value);
 
-static void add_pcc_named_return(PARROT_INTERP,
+static void add_pcc_named_return(
     ARGMOD(SymReg *cur_call),
-    ARGIN(SymReg *name),
-    ARGIN(SymReg *value))
+    ARGMOD(SymReg *name),
+    ARGMOD(SymReg *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*cur_call);
+        FUNC_MODIFIES(*cur_call)
+        FUNC_MODIFIES(*name)
+        FUNC_MODIFIES(*value);
 
 static void adv_named_set(PARROT_INTERP, ARGIN(const char *name))
         __attribute__nonnull__(1)
@@ -128,6 +133,7 @@
         FUNC_MODIFIES(*unit)
         FUNC_MODIFIES(*r);
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
 static Instruction * iINDEXFETCH(PARROT_INTERP,
     ARGMOD(IMC_Unit *unit),
@@ -141,6 +147,7 @@
         __attribute__nonnull__(5)
         FUNC_MODIFIES(*unit);
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
 static Instruction * iINDEXSET(PARROT_INTERP,
     ARGMOD(IMC_Unit *unit),
@@ -154,6 +161,7 @@
         __attribute__nonnull__(5)
         FUNC_MODIFIES(*unit);
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static Instruction * iLABEL(PARROT_INTERP,
     ARGMOD_NULLOK(IMC_Unit *unit),
@@ -168,6 +176,7 @@
 static const char * inv_op(ARGIN(const char *op))
         __attribute__nonnull__(1);
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static Instruction * iSUBROUTINE(PARROT_INTERP,
     ARGMOD_NULLOK(IMC_Unit *unit),
@@ -219,11 +228,13 @@
         FUNC_MODIFIES(*unit)
         FUNC_MODIFIES(*left);
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static SymReg * mk_sub_address_fromc(PARROT_INTERP, ARGIN(const char *name))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static SymReg * mk_sub_address_u(PARROT_INTERP, ARGIN(const char *name))
         __attribute__nonnull__(1)
@@ -239,28 +250,23 @@
         FUNC_MODIFIES(*name);
 
 #define ASSERT_ARGS_add_pcc_named_arg __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(cur_call) \
+       PARROT_ASSERT_ARG(cur_call) \
     || PARROT_ASSERT_ARG(name) \
     || PARROT_ASSERT_ARG(value)
 #define ASSERT_ARGS_add_pcc_named_arg_var __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(cur_call) \
+       PARROT_ASSERT_ARG(cur_call) \
     || PARROT_ASSERT_ARG(name) \
     || PARROT_ASSERT_ARG(value)
 #define ASSERT_ARGS_add_pcc_named_param __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(cur_call) \
+       PARROT_ASSERT_ARG(cur_call) \
     || PARROT_ASSERT_ARG(name) \
     || PARROT_ASSERT_ARG(value)
 #define ASSERT_ARGS_add_pcc_named_result __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(cur_call) \
+       PARROT_ASSERT_ARG(cur_call) \
     || PARROT_ASSERT_ARG(name) \
     || PARROT_ASSERT_ARG(value)
 #define ASSERT_ARGS_add_pcc_named_return __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(cur_call) \
+       PARROT_ASSERT_ARG(cur_call) \
     || PARROT_ASSERT_ARG(name) \
     || PARROT_ASSERT_ARG(value)
 #define ASSERT_ARGS_adv_named_set __attribute__unused__ int _ASSERT_ARGS_CHECK = \
@@ -385,7 +391,7 @@
 
     for (p = opname, q = fmt; *q && *q != ' ';)
         *p++ = *q++;
-    *p = 0;
+    *p = '\0';
     if (!*q)
         fmt = NULL;
     else
@@ -437,11 +443,11 @@
     r[0] = left;
     if (ascii) {
         /* strip delimiters */
-        name                   = str_dup(constant + 1);
+        name                   = mem_sys_strdup(constant + 1);
         name[strlen(name) - 1] = 0;
     }
     else {
-        name = str_dup(constant);
+        name = mem_sys_strdup(constant);
     }
 
     switch (type_enum) {
@@ -487,7 +493,7 @@
     SymReg *r[3];
     char   *const_name;
     const int ascii       = (*constant == '\'' || *constant == '"');
-    char   *unquoted_name = str_dup(name + 1);
+    char   *unquoted_name = mem_sys_strdup(name + 1);
     size_t  name_length   = strlen(unquoted_name) - 1;
 
     unquoted_name[name_length] = 0;
@@ -504,11 +510,11 @@
     r[0] = left;
     if (ascii) {
         /* strip delimiters */
-        const_name                         = str_dup(constant + 1);
+        const_name                         = mem_sys_strdup(constant + 1);
         const_name[strlen(const_name) - 1] = 0;
     }
     else {
-        const_name = str_dup(constant);
+        const_name = mem_sys_strdup(constant);
     }
 
     if ((strncmp(unquoted_name, "Sub",       name_length) == 0)
@@ -585,6 +591,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 Instruction *
 INS_LABEL(PARROT_INTERP, ARGMOD_NULLOK(IMC_Unit *unit), ARGMOD(SymReg *r0), int emit)
@@ -609,6 +616,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static Instruction *
 iLABEL(PARROT_INTERP, ARGMOD_NULLOK(IMC_Unit *unit), ARGMOD(SymReg *r0))
@@ -630,7 +638,7 @@
 
 */
 
-
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static Instruction *
 iSUBROUTINE(PARROT_INTERP, ARGMOD_NULLOK(IMC_Unit *unit), ARGMOD(SymReg *r))
@@ -659,6 +667,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
 static Instruction *
 iINDEXFETCH(PARROT_INTERP, ARGMOD(IMC_Unit *unit), ARGIN(SymReg *r0), ARGIN(SymReg *r1),
@@ -680,6 +689,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
 static Instruction *
 iINDEXSET(PARROT_INTERP, ARGMOD(IMC_Unit *unit), ARGIN(SymReg *r0), ARGIN(SymReg *r1),
@@ -723,6 +733,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 Instruction *
 IMCC_create_itcall_label(PARROT_INTERP)
@@ -752,6 +763,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static SymReg *
 mk_sub_address_fromc(PARROT_INTERP, ARGIN(const char *name))
@@ -759,7 +771,7 @@
     ASSERT_ARGS(mk_sub_address_fromc)
     /* name is a quoted sub name */
     SymReg *r;
-    char *name_copy                  = str_dup(name + 1);
+    char *name_copy                  = mem_sys_strdup(name + 1);
     name_copy[strlen(name_copy) - 1] = 0;
 
     r = mk_sub_address(interp, name_copy);
@@ -776,6 +788,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static SymReg *
 mk_sub_address_u(PARROT_INTERP, ARGIN(const char *name))
@@ -875,17 +888,17 @@
 
 /*
 
-=item C<static void add_pcc_named_arg(PARROT_INTERP, SymReg *cur_call, SymReg
-*name, SymReg *value)>
+=item C<static void add_pcc_named_arg(SymReg *cur_call, SymReg *name, SymReg
+*value)>
 
 =cut
 
 */
 
 static void
-add_pcc_named_arg(PARROT_INTERP, ARGMOD(SymReg *cur_call),
-        ARGIN(SymReg *name),
-        ARGIN(SymReg *value))
+add_pcc_named_arg(ARGMOD(SymReg *cur_call),
+        ARGMOD(SymReg *name),
+        ARGMOD(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_arg)
     name->type  |= VT_NAMED;
@@ -896,16 +909,16 @@
 
 /*
 
-=item C<static void add_pcc_named_arg_var(PARROT_INTERP, SymReg *cur_call,
-SymReg *name, SymReg *value)>
+=item C<static void add_pcc_named_arg_var(SymReg *cur_call, SymReg *name, SymReg
+*value)>
 
 =cut
 
 */
 
 static void
-add_pcc_named_arg_var(PARROT_INTERP, ARGMOD(SymReg *cur_call),
-    ARGIN(SymReg *name), ARGIN(SymReg *value))
+add_pcc_named_arg_var(ARGMOD(SymReg *cur_call),
+    ARGMOD(SymReg *name), ARGMOD(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_arg_var)
     name->type |= VT_NAMED;
@@ -915,17 +928,17 @@
 
 /*
 
-=item C<static void add_pcc_named_result(PARROT_INTERP, SymReg *cur_call, SymReg
-*name, SymReg *value)>
+=item C<static void add_pcc_named_result(SymReg *cur_call, SymReg *name, SymReg
+*value)>
 
 =cut
 
 */
 
 static void
-add_pcc_named_result(PARROT_INTERP, ARGMOD(SymReg *cur_call),
-        ARGIN(SymReg *name),
-        ARGIN(SymReg *value))
+add_pcc_named_result(ARGMOD(SymReg *cur_call),
+        ARGMOD(SymReg *name),
+        ARGMOD(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_result)
     name->type         |= VT_NAMED;
@@ -936,17 +949,17 @@
 
 /*
 
-=item C<static void add_pcc_named_param(PARROT_INTERP, SymReg *cur_call, SymReg
-*name, SymReg *value)>
+=item C<static void add_pcc_named_param(SymReg *cur_call, SymReg *name, SymReg
+*value)>
 
 =cut
 
 */
 
 static void
-add_pcc_named_param(PARROT_INTERP, ARGMOD(SymReg *cur_call),
-        ARGIN(SymReg *name),
-        ARGIN(SymReg *value))
+add_pcc_named_param(ARGMOD(SymReg *cur_call),
+        ARGMOD(SymReg *name),
+        ARGMOD(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_param)
     name->type         |= VT_NAMED;
@@ -957,17 +970,17 @@
 
 /*
 
-=item C<static void add_pcc_named_return(PARROT_INTERP, SymReg *cur_call, SymReg
-*name, SymReg *value)>
+=item C<static void add_pcc_named_return(SymReg *cur_call, SymReg *name, SymReg
+*value)>
 
 =cut
 
 */
 
 static void
-add_pcc_named_return(PARROT_INTERP, ARGMOD(SymReg *cur_call),
-        ARGIN(SymReg *name),
-        ARGIN(SymReg *value))
+add_pcc_named_return(ARGMOD(SymReg *cur_call),
+        ARGMOD(SymReg *name),
+        ARGMOD(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_return)
     name->type         |= VT_NAMED;
@@ -1269,6 +1282,7 @@
                     IMCC_INFO(interp)->cur_unit,
                     mk_sub_label(interp, $4));
            IMCC_INFO(interp)->cur_call->pcc_sub->pragma = $3;
+           mem_sys_free($4);
          }
    | PNULL var
          {
@@ -1348,7 +1362,7 @@
         {
           IMCC_INFO(interp)->cur_call->pcc_sub->pragma = $5;
           if (!IMCC_INFO(interp)->cur_unit->instructions->symregs[0]->subid) {
-            IMCC_INFO(interp)->cur_unit->instructions->symregs[0]->subid = str_dup(
+            IMCC_INFO(interp)->cur_unit->instructions->symregs[0]->subid = mem_sys_strdup(
             IMCC_INFO(interp)->cur_unit->instructions->symregs[0]->name);
           }
         }
@@ -1362,7 +1376,7 @@
    | sub_params sub_param '\n'
          {
            if (IMCC_INFO(interp)->adv_named_id) {
-                 add_pcc_named_param(interp, IMCC_INFO(interp)->cur_call,
+                 add_pcc_named_param(IMCC_INFO(interp)->cur_call,
                                      IMCC_INFO(interp)->adv_named_id, $2);
                  IMCC_INFO(interp)->adv_named_id = NULL;
            }
@@ -1657,7 +1671,7 @@
      RESULT target paramtype_list { $$ = $2; $$->type |= $3; }
    | LOCAL { pesky_global__is_def=1; } type id_list_id
          {
-           IdList *l = $4;
+           IdList * const l = $4;
            SymReg *ignored;
            if (l->unique_reg)
                ignored = mk_ident_ur(interp, l->id, $3);
@@ -1761,7 +1775,7 @@
    | arg
          {
            if (IMCC_INFO(interp)->adv_named_id) {
-               add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return,
+               add_pcc_named_return(IMCC_INFO(interp)->sr_return,
                                     IMCC_INFO(interp)->adv_named_id, $1);
                IMCC_INFO(interp)->adv_named_id = NULL;
            }
@@ -1770,13 +1784,13 @@
          }
    | STRINGC ADV_ARROW var
          {
-            SymReg *name = mk_const(interp, $1, 'S');
-            add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return, name, $3);
+            SymReg * const name = mk_const(interp, $1, 'S');
+            add_pcc_named_return(IMCC_INFO(interp)->sr_return, name, $3);
          }
    | var_returns COMMA arg
          {
            if (IMCC_INFO(interp)->adv_named_id) {
-               add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return,
+               add_pcc_named_return(IMCC_INFO(interp)->sr_return,
                                     IMCC_INFO(interp)->adv_named_id, $3);
                IMCC_INFO(interp)->adv_named_id = NULL;
              }
@@ -1785,8 +1799,8 @@
          }
    | var_returns COMMA STRINGC ADV_ARROW var
          {
-           SymReg *name = mk_const(interp, $3, 'S');
-           add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return, name, $5);
+           SymReg * const name = mk_const(interp, $3, 'S');
+           add_pcc_named_return(IMCC_INFO(interp)->sr_return, name, $5);
          }
    ;
 
@@ -1831,7 +1845,7 @@
 label:
      LABEL
          {
-             Instruction *i = iLABEL(interp, IMCC_INFO(interp)->cur_unit, mk_local_label(interp, $1));
+             Instruction * const i = iLABEL(interp, IMCC_INFO(interp)->cur_unit, mk_local_label(interp, $1));
              mem_sys_free($1);
              $$ = i;
          }
@@ -1854,14 +1868,14 @@
 id_list :
      id_list_id
          {
-           IdList* l = $1;
+           IdList* const l = $1;
            l->next = NULL;
            $$ = l;
          }
 
    | id_list COMMA id_list_id
          {
-           IdList* l = $3;
+           IdList* const l = $3;
            l->next = $1;
            $$ = l;
          }
@@ -1904,13 +1918,13 @@
          }
    | LEXICAL STRINGC COMMA target
          {
-           SymReg *n = mk_const(interp, $2, 'S');
+           SymReg * const n = mk_const(interp, $2, 'S');
            set_lexical(interp, $4, n); $$ = 0;
            mem_sys_free($2);
          }
    | LEXICAL USTRINGC COMMA target
          {
-           SymReg *n = mk_const(interp, $2, 'U');
+           SymReg * const n = mk_const(interp, $2, 'U');
            set_lexical(interp, $4, n); $$ = 0;
            mem_sys_free($2);
          }
@@ -1968,7 +1982,7 @@
 classname:
      IDENTIFIER
          {
-           /* there'd normally be a str_dup() here, but the lexer already
+           /* there'd normally be a mem_sys_strdup() here, but the lexer already
             * copied the string, so it's safe to use directly */
            if ((IMCC_INFO(interp)->cur_pmc_type = pmc_type(interp,
                Parrot_str_new(interp, $1, 0))) <= 0) {
@@ -2113,7 +2127,7 @@
    | target DOT sub_label_op
         {
             /* disallow bareword method names; SREG name constants are fine */
-            char *name = $3->name;
+            const char * const name = $3->name;
             if (!($3->type & VTREG)) {
                 if (*name != '\'' || *name != '\"')
                     IMCC_fataly(interp, EXCEPTION_SYNTAX_ERROR,
@@ -2155,7 +2169,7 @@
          {
            $$ = 0;
            if (IMCC_INFO(interp)->adv_named_id) {
-               add_pcc_named_arg(interp, IMCC_INFO(interp)->cur_call, IMCC_INFO(interp)->adv_named_id, $3);
+               add_pcc_named_arg(IMCC_INFO(interp)->cur_call, IMCC_INFO(interp)->adv_named_id, $3);
                IMCC_INFO(interp)->adv_named_id = NULL;
            }
            else
@@ -2165,7 +2179,7 @@
          {
            $$ = 0;
            if (IMCC_INFO(interp)->adv_named_id) {
-               add_pcc_named_arg(interp, IMCC_INFO(interp)->cur_call, IMCC_INFO(interp)->adv_named_id, $1);
+               add_pcc_named_arg(IMCC_INFO(interp)->cur_call, IMCC_INFO(interp)->adv_named_id, $1);
                IMCC_INFO(interp)->adv_named_id = NULL;
            }
            else
@@ -2174,19 +2188,19 @@
    | arglist COMMA STRINGC ADV_ARROW var
          {
            $$ = 0;
-           add_pcc_named_arg(interp, IMCC_INFO(interp)->cur_call,
+           add_pcc_named_arg(IMCC_INFO(interp)->cur_call,
                 mk_const(interp, $3, 'S'), $5);
            mem_sys_free($3);
          }
    | var ADV_ARROW var
          {
            $$ = 0;
-           add_pcc_named_arg_var(interp, IMCC_INFO(interp)->cur_call, $1, $3);
+           add_pcc_named_arg_var(IMCC_INFO(interp)->cur_call, $1, $3);
          }
    | STRINGC ADV_ARROW var
          {
            $$ = 0;
-           add_pcc_named_arg(interp, IMCC_INFO(interp)->cur_call,
+           add_pcc_named_arg(IMCC_INFO(interp)->cur_call,
                 mk_const(interp, $1, 'S'), $3);
            mem_sys_free($1);
          }
@@ -2219,7 +2233,7 @@
          {
            $$ = 0;
            if (IMCC_INFO(interp)->adv_named_id) {
-               add_pcc_named_result(interp, IMCC_INFO(interp)->cur_call, IMCC_INFO(interp)->adv_named_id, $3);
+               add_pcc_named_result(IMCC_INFO(interp)->cur_call, IMCC_INFO(interp)->adv_named_id, $3);
                IMCC_INFO(interp)->adv_named_id = NULL;
            }
            else
@@ -2227,7 +2241,7 @@
          }
    | targetlist COMMA STRINGC ADV_ARROW target
          {
-            add_pcc_named_result(interp, IMCC_INFO(interp)->cur_call,
+            add_pcc_named_result(IMCC_INFO(interp)->cur_call,
             mk_const(interp, $3, 'S'), $5);
             mem_sys_free($3);
          }
@@ -2235,7 +2249,7 @@
          {
            $$ = 0;
            if (IMCC_INFO(interp)->adv_named_id) {
-               add_pcc_named_result(interp, IMCC_INFO(interp)->cur_call, IMCC_INFO(interp)->adv_named_id, $1);
+               add_pcc_named_result(IMCC_INFO(interp)->cur_call, IMCC_INFO(interp)->adv_named_id, $1);
                IMCC_INFO(interp)->adv_named_id = NULL;
            }
            else
@@ -2243,7 +2257,7 @@
          }
    | STRINGC ADV_ARROW target
          {
-           add_pcc_named_result(interp, IMCC_INFO(interp)->cur_call, mk_const(interp, $1, 'S'), $3);
+           add_pcc_named_result(IMCC_INFO(interp)->cur_call, mk_const(interp, $1, 'S'), $3);
            mem_sys_free($1);
          }
    | /* empty */                { $$ = 0; }

Modified: branches/tt761_keys_revamp/compilers/imcc/imclexer.c
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/imclexer.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/imclexer.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -2464,7 +2464,7 @@
 
 #define DUP_AND_RET(valp, token)             \
   do {                                       \
-      if (valp) (valp)->s = str_dup(yytext); \
+      if (valp) (valp)->s = mem_sys_strdup(yytext); \
       return (token);                        \
   } while (0)
 
@@ -2472,7 +2472,7 @@
   do {                                       \
       if (valp) {                            \
           mem_sys_free((valp)->s);           \
-          (valp)->s = str_dup(yytext);       \
+          (valp)->s = mem_sys_strdup(yytext);       \
           return (token);                    \
       }                                      \
   } while (0)
@@ -2836,7 +2836,7 @@
 YY_RULE_SETUP
 #line 173 "compilers/imcc/imcc.l"
 {
-            IMCC_INFO(interp)->frames->heredoc_rest = str_dup(yytext);
+            IMCC_INFO(interp)->frames->heredoc_rest = mem_sys_strdup(yytext);
             BEGIN(heredoc2);
     }
 	YY_BREAK
@@ -2907,16 +2907,15 @@
         yy_pop_state(yyscanner);
         yy_push_state(cmt3, yyscanner);
 
-        IMCC_INFO(interp)->frames->s.file = str_dup(yytext);
-        IMCC_INFO(interp)->frames->s.file_needs_free = 1;
-        IMCC_INFO(interp)->cur_unit->file = str_dup(yytext);
+        IMCC_INFO(interp)->frames->s.file = mem_sys_strdup(yytext);
+        IMCC_INFO(interp)->cur_unit->file = mem_sys_strdup(yytext);
 
         return FILECOMMENT;
     }
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 241 "compilers/imcc/imcc.l"
+#line 240 "compilers/imcc/imcc.l"
 {
         yy_pop_state(yyscanner);
         yy_push_state(cmt4, yyscanner);
@@ -2924,17 +2923,17 @@
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 246 "compilers/imcc/imcc.l"
+#line 245 "compilers/imcc/imcc.l"
 { yy_push_state(cmt2, yyscanner); }
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 248 "compilers/imcc/imcc.l"
+#line 247 "compilers/imcc/imcc.l"
 { yy_push_state(cmt1, yyscanner);  }
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 250 "compilers/imcc/imcc.l"
+#line 249 "compilers/imcc/imcc.l"
 {
         IMCC_INFO(interp)->line = atoi(yytext);
         yy_pop_state(yyscanner);
@@ -2945,7 +2944,7 @@
 case 9:
 /* rule 9 can match eol */
 YY_RULE_SETUP
-#line 257 "compilers/imcc/imcc.l"
+#line 256 "compilers/imcc/imcc.l"
 {
         yy_pop_state(yyscanner);
         IMCC_INFO(interp)->line++;
@@ -2954,7 +2953,7 @@
 case 10:
 /* rule 10 can match eol */
 YY_RULE_SETUP
-#line 262 "compilers/imcc/imcc.l"
+#line 261 "compilers/imcc/imcc.l"
 {
         if (IMCC_INFO(interp)->expect_pasm == 2)
             BEGIN(INITIAL);
@@ -2967,7 +2966,7 @@
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 272 "compilers/imcc/imcc.l"
+#line 271 "compilers/imcc/imcc.l"
 {
         yy_push_state(cmt5, yyscanner);
     }
@@ -2975,7 +2974,7 @@
 case 12:
 /* rule 12 can match eol */
 YY_RULE_SETUP
-#line 276 "compilers/imcc/imcc.l"
+#line 275 "compilers/imcc/imcc.l"
 {
         if (IMCC_INFO(interp)->expect_pasm == 2)
             BEGIN(INITIAL);
@@ -2991,7 +2990,7 @@
 case 13:
 /* rule 13 can match eol */
 YY_RULE_SETUP
-#line 289 "compilers/imcc/imcc.l"
+#line 288 "compilers/imcc/imcc.l"
 {
     /* this is a stand-alone =cut, but we're
      * not in POD mode, so just ignore.
@@ -3000,7 +2999,7 @@
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 295 "compilers/imcc/imcc.l"
+#line 294 "compilers/imcc/imcc.l"
 {
         IMCC_INFO(interp)->in_pod = 1;
         yy_push_state(pod, yyscanner);
@@ -3009,7 +3008,7 @@
 case 15:
 /* rule 15 can match eol */
 YY_RULE_SETUP
-#line 300 "compilers/imcc/imcc.l"
+#line 299 "compilers/imcc/imcc.l"
 {
         IMCC_INFO(interp)->in_pod = 0;
         yy_pop_state(yyscanner);
@@ -3018,473 +3017,473 @@
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 306 "compilers/imcc/imcc.l"
+#line 305 "compilers/imcc/imcc.l"
 { /*ignore*/ }
 	YY_BREAK
 case 17:
 /* rule 17 can match eol */
 YY_RULE_SETUP
-#line 308 "compilers/imcc/imcc.l"
+#line 307 "compilers/imcc/imcc.l"
 { IMCC_INFO(interp)->line++; }
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 310 "compilers/imcc/imcc.l"
+#line 309 "compilers/imcc/imcc.l"
 return TK_LINE;
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 311 "compilers/imcc/imcc.l"
+#line 310 "compilers/imcc/imcc.l"
 return TK_FILE;
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 312 "compilers/imcc/imcc.l"
+#line 311 "compilers/imcc/imcc.l"
 return ANNOTATE;
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 313 "compilers/imcc/imcc.l"
+#line 312 "compilers/imcc/imcc.l"
 return LEXICAL;
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 314 "compilers/imcc/imcc.l"
+#line 313 "compilers/imcc/imcc.l"
 return ARG;
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 315 "compilers/imcc/imcc.l"
+#line 314 "compilers/imcc/imcc.l"
 return SUB;
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 316 "compilers/imcc/imcc.l"
+#line 315 "compilers/imcc/imcc.l"
 return ESUB;
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 317 "compilers/imcc/imcc.l"
+#line 316 "compilers/imcc/imcc.l"
 return PCC_BEGIN;
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 318 "compilers/imcc/imcc.l"
+#line 317 "compilers/imcc/imcc.l"
 return PCC_END;
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 319 "compilers/imcc/imcc.l"
+#line 318 "compilers/imcc/imcc.l"
 return PCC_CALL;
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 320 "compilers/imcc/imcc.l"
+#line 319 "compilers/imcc/imcc.l"
 return NCI_CALL;
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 321 "compilers/imcc/imcc.l"
+#line 320 "compilers/imcc/imcc.l"
 return METH_CALL;
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 322 "compilers/imcc/imcc.l"
+#line 321 "compilers/imcc/imcc.l"
 return INVOCANT;
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 323 "compilers/imcc/imcc.l"
+#line 322 "compilers/imcc/imcc.l"
 return PCC_SUB;
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 324 "compilers/imcc/imcc.l"
+#line 323 "compilers/imcc/imcc.l"
 return PCC_BEGIN_RETURN;
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 325 "compilers/imcc/imcc.l"
+#line 324 "compilers/imcc/imcc.l"
 return PCC_END_RETURN;
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 326 "compilers/imcc/imcc.l"
+#line 325 "compilers/imcc/imcc.l"
 return PCC_BEGIN_YIELD;
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 327 "compilers/imcc/imcc.l"
+#line 326 "compilers/imcc/imcc.l"
 return PCC_END_YIELD;
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 329 "compilers/imcc/imcc.l"
+#line 328 "compilers/imcc/imcc.l"
 return METHOD;
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 330 "compilers/imcc/imcc.l"
+#line 329 "compilers/imcc/imcc.l"
 return MULTI;
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 331 "compilers/imcc/imcc.l"
+#line 330 "compilers/imcc/imcc.l"
 return MAIN;
 	YY_BREAK
 case 39:
 YY_RULE_SETUP
-#line 332 "compilers/imcc/imcc.l"
+#line 331 "compilers/imcc/imcc.l"
 return LOAD;
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 333 "compilers/imcc/imcc.l"
+#line 332 "compilers/imcc/imcc.l"
 return INIT;
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 334 "compilers/imcc/imcc.l"
+#line 333 "compilers/imcc/imcc.l"
 return IMMEDIATE;
 	YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 335 "compilers/imcc/imcc.l"
+#line 334 "compilers/imcc/imcc.l"
 return POSTCOMP;
 	YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 336 "compilers/imcc/imcc.l"
+#line 335 "compilers/imcc/imcc.l"
 return ANON;
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 337 "compilers/imcc/imcc.l"
+#line 336 "compilers/imcc/imcc.l"
 return OUTER;
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 338 "compilers/imcc/imcc.l"
+#line 337 "compilers/imcc/imcc.l"
 return NEED_LEX;
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 339 "compilers/imcc/imcc.l"
+#line 338 "compilers/imcc/imcc.l"
 return VTABLE_METHOD;
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 340 "compilers/imcc/imcc.l"
+#line 339 "compilers/imcc/imcc.l"
 return NS_ENTRY;
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
-#line 341 "compilers/imcc/imcc.l"
+#line 340 "compilers/imcc/imcc.l"
 return UNIQUE_REG;
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
-#line 342 "compilers/imcc/imcc.l"
+#line 341 "compilers/imcc/imcc.l"
 return SUB_INSTANCE_OF;
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
-#line 343 "compilers/imcc/imcc.l"
+#line 342 "compilers/imcc/imcc.l"
 return SUBID;
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
-#line 345 "compilers/imcc/imcc.l"
+#line 344 "compilers/imcc/imcc.l"
 return RESULT;
 	YY_BREAK
 case 52:
 YY_RULE_SETUP
-#line 346 "compilers/imcc/imcc.l"
+#line 345 "compilers/imcc/imcc.l"
 return GET_RESULTS;
 	YY_BREAK
 case 53:
 YY_RULE_SETUP
-#line 347 "compilers/imcc/imcc.l"
+#line 346 "compilers/imcc/imcc.l"
 return YIELDT;
 	YY_BREAK
 case 54:
 YY_RULE_SETUP
-#line 348 "compilers/imcc/imcc.l"
+#line 347 "compilers/imcc/imcc.l"
 return SET_YIELD;
 	YY_BREAK
 case 55:
 YY_RULE_SETUP
-#line 349 "compilers/imcc/imcc.l"
+#line 348 "compilers/imcc/imcc.l"
 return RETURN;
 	YY_BREAK
 case 56:
 YY_RULE_SETUP
-#line 350 "compilers/imcc/imcc.l"
+#line 349 "compilers/imcc/imcc.l"
 return SET_RETURN;
 	YY_BREAK
 case 57:
 YY_RULE_SETUP
-#line 351 "compilers/imcc/imcc.l"
+#line 350 "compilers/imcc/imcc.l"
 return TAILCALL;
 	YY_BREAK
 case 58:
 YY_RULE_SETUP
-#line 352 "compilers/imcc/imcc.l"
+#line 351 "compilers/imcc/imcc.l"
 return LOADLIB;
 	YY_BREAK
 case 59:
 YY_RULE_SETUP
-#line 354 "compilers/imcc/imcc.l"
+#line 353 "compilers/imcc/imcc.l"
 return ADV_FLAT;
 	YY_BREAK
 case 60:
 YY_RULE_SETUP
-#line 355 "compilers/imcc/imcc.l"
+#line 354 "compilers/imcc/imcc.l"
 return ADV_SLURPY;
 	YY_BREAK
 case 61:
 YY_RULE_SETUP
-#line 356 "compilers/imcc/imcc.l"
+#line 355 "compilers/imcc/imcc.l"
 return ADV_OPTIONAL;
 	YY_BREAK
 case 62:
 YY_RULE_SETUP
-#line 357 "compilers/imcc/imcc.l"
+#line 356 "compilers/imcc/imcc.l"
 return ADV_OPT_FLAG;
 	YY_BREAK
 case 63:
 YY_RULE_SETUP
-#line 358 "compilers/imcc/imcc.l"
+#line 357 "compilers/imcc/imcc.l"
 return ADV_NAMED;
 	YY_BREAK
 case 64:
 YY_RULE_SETUP
-#line 359 "compilers/imcc/imcc.l"
+#line 358 "compilers/imcc/imcc.l"
 return ADV_ARROW;
 	YY_BREAK
 case 65:
 YY_RULE_SETUP
-#line 360 "compilers/imcc/imcc.l"
+#line 359 "compilers/imcc/imcc.l"
 return ADV_INVOCANT;
 	YY_BREAK
 case 66:
 YY_RULE_SETUP
-#line 362 "compilers/imcc/imcc.l"
+#line 361 "compilers/imcc/imcc.l"
 return NAMESPACE;
 	YY_BREAK
 case 67:
 YY_RULE_SETUP
-#line 363 "compilers/imcc/imcc.l"
+#line 362 "compilers/imcc/imcc.l"
 return HLL;
 	YY_BREAK
 case 68:
 YY_RULE_SETUP
-#line 365 "compilers/imcc/imcc.l"
+#line 364 "compilers/imcc/imcc.l"
 return LOCAL;
 	YY_BREAK
 case 69:
 YY_RULE_SETUP
-#line 366 "compilers/imcc/imcc.l"
+#line 365 "compilers/imcc/imcc.l"
 return CONST;
 	YY_BREAK
 case 70:
 YY_RULE_SETUP
-#line 367 "compilers/imcc/imcc.l"
+#line 366 "compilers/imcc/imcc.l"
 return GLOBAL_CONST;
 	YY_BREAK
 case 71:
 YY_RULE_SETUP
-#line 368 "compilers/imcc/imcc.l"
+#line 367 "compilers/imcc/imcc.l"
 return PARAM;
 	YY_BREAK
 case 72:
 YY_RULE_SETUP
-#line 369 "compilers/imcc/imcc.l"
+#line 368 "compilers/imcc/imcc.l"
 return GOTO;
 	YY_BREAK
 case 73:
 YY_RULE_SETUP
-#line 370 "compilers/imcc/imcc.l"
+#line 369 "compilers/imcc/imcc.l"
 return IF;
 	YY_BREAK
 case 74:
 YY_RULE_SETUP
-#line 371 "compilers/imcc/imcc.l"
+#line 370 "compilers/imcc/imcc.l"
 return UNLESS;
 	YY_BREAK
 case 75:
 YY_RULE_SETUP
-#line 372 "compilers/imcc/imcc.l"
+#line 371 "compilers/imcc/imcc.l"
 return PNULL;
 	YY_BREAK
 case 76:
 YY_RULE_SETUP
-#line 373 "compilers/imcc/imcc.l"
+#line 372 "compilers/imcc/imcc.l"
 return INTV;
 	YY_BREAK
 case 77:
 YY_RULE_SETUP
-#line 374 "compilers/imcc/imcc.l"
+#line 373 "compilers/imcc/imcc.l"
 return FLOATV;
 	YY_BREAK
 case 78:
 YY_RULE_SETUP
-#line 376 "compilers/imcc/imcc.l"
+#line 375 "compilers/imcc/imcc.l"
 return PMCV;
 	YY_BREAK
 case 79:
 YY_RULE_SETUP
-#line 377 "compilers/imcc/imcc.l"
+#line 376 "compilers/imcc/imcc.l"
 return STRINGV;
 	YY_BREAK
 case 80:
 YY_RULE_SETUP
-#line 378 "compilers/imcc/imcc.l"
+#line 377 "compilers/imcc/imcc.l"
 return SHIFT_LEFT;
 	YY_BREAK
 case 81:
 YY_RULE_SETUP
-#line 379 "compilers/imcc/imcc.l"
+#line 378 "compilers/imcc/imcc.l"
 return SHIFT_RIGHT;
 	YY_BREAK
 case 82:
 YY_RULE_SETUP
-#line 380 "compilers/imcc/imcc.l"
+#line 379 "compilers/imcc/imcc.l"
 return SHIFT_RIGHT_U;
 	YY_BREAK
 case 83:
 YY_RULE_SETUP
-#line 381 "compilers/imcc/imcc.l"
+#line 380 "compilers/imcc/imcc.l"
 return LOG_AND;
 	YY_BREAK
 case 84:
 YY_RULE_SETUP
-#line 382 "compilers/imcc/imcc.l"
+#line 381 "compilers/imcc/imcc.l"
 return LOG_OR;
 	YY_BREAK
 case 85:
 YY_RULE_SETUP
-#line 383 "compilers/imcc/imcc.l"
+#line 382 "compilers/imcc/imcc.l"
 return LOG_XOR;
 	YY_BREAK
 case 86:
 YY_RULE_SETUP
-#line 384 "compilers/imcc/imcc.l"
+#line 383 "compilers/imcc/imcc.l"
 return RELOP_LT;
 	YY_BREAK
 case 87:
 YY_RULE_SETUP
-#line 385 "compilers/imcc/imcc.l"
+#line 384 "compilers/imcc/imcc.l"
 return RELOP_LTE;
 	YY_BREAK
 case 88:
 YY_RULE_SETUP
-#line 386 "compilers/imcc/imcc.l"
+#line 385 "compilers/imcc/imcc.l"
 return RELOP_GT;
 	YY_BREAK
 case 89:
 YY_RULE_SETUP
-#line 387 "compilers/imcc/imcc.l"
+#line 386 "compilers/imcc/imcc.l"
 return RELOP_GTE;
 	YY_BREAK
 case 90:
 YY_RULE_SETUP
-#line 388 "compilers/imcc/imcc.l"
+#line 387 "compilers/imcc/imcc.l"
 return RELOP_EQ;
 	YY_BREAK
 case 91:
 YY_RULE_SETUP
-#line 389 "compilers/imcc/imcc.l"
+#line 388 "compilers/imcc/imcc.l"
 return RELOP_NE;
 	YY_BREAK
 case 92:
 YY_RULE_SETUP
-#line 390 "compilers/imcc/imcc.l"
+#line 389 "compilers/imcc/imcc.l"
 return POW;
 	YY_BREAK
 case 93:
 YY_RULE_SETUP
-#line 392 "compilers/imcc/imcc.l"
+#line 391 "compilers/imcc/imcc.l"
 return CONCAT;
 	YY_BREAK
 case 94:
 YY_RULE_SETUP
-#line 393 "compilers/imcc/imcc.l"
+#line 392 "compilers/imcc/imcc.l"
 return DOT;
 	YY_BREAK
 case 95:
 YY_RULE_SETUP
-#line 395 "compilers/imcc/imcc.l"
+#line 394 "compilers/imcc/imcc.l"
 return PLUS_ASSIGN;
 	YY_BREAK
 case 96:
 YY_RULE_SETUP
-#line 396 "compilers/imcc/imcc.l"
+#line 395 "compilers/imcc/imcc.l"
 return MINUS_ASSIGN;
 	YY_BREAK
 case 97:
 YY_RULE_SETUP
-#line 397 "compilers/imcc/imcc.l"
+#line 396 "compilers/imcc/imcc.l"
 return MUL_ASSIGN;
 	YY_BREAK
 case 98:
 YY_RULE_SETUP
-#line 398 "compilers/imcc/imcc.l"
+#line 397 "compilers/imcc/imcc.l"
 return DIV_ASSIGN;
 	YY_BREAK
 case 99:
 YY_RULE_SETUP
-#line 399 "compilers/imcc/imcc.l"
+#line 398 "compilers/imcc/imcc.l"
 return MOD_ASSIGN;
 	YY_BREAK
 case 100:
 YY_RULE_SETUP
-#line 400 "compilers/imcc/imcc.l"
+#line 399 "compilers/imcc/imcc.l"
 return FDIV;
 	YY_BREAK
 case 101:
 YY_RULE_SETUP
-#line 401 "compilers/imcc/imcc.l"
+#line 400 "compilers/imcc/imcc.l"
 return FDIV_ASSIGN;
 	YY_BREAK
 case 102:
 YY_RULE_SETUP
-#line 402 "compilers/imcc/imcc.l"
+#line 401 "compilers/imcc/imcc.l"
 return BAND_ASSIGN;
 	YY_BREAK
 case 103:
 YY_RULE_SETUP
-#line 403 "compilers/imcc/imcc.l"
+#line 402 "compilers/imcc/imcc.l"
 return BOR_ASSIGN;
 	YY_BREAK
 case 104:
 YY_RULE_SETUP
-#line 404 "compilers/imcc/imcc.l"
+#line 403 "compilers/imcc/imcc.l"
 return BXOR_ASSIGN;
 	YY_BREAK
 case 105:
 YY_RULE_SETUP
-#line 405 "compilers/imcc/imcc.l"
+#line 404 "compilers/imcc/imcc.l"
 return SHR_ASSIGN;
 	YY_BREAK
 case 106:
 YY_RULE_SETUP
-#line 406 "compilers/imcc/imcc.l"
+#line 405 "compilers/imcc/imcc.l"
 return SHL_ASSIGN;
 	YY_BREAK
 case 107:
 YY_RULE_SETUP
-#line 407 "compilers/imcc/imcc.l"
+#line 406 "compilers/imcc/imcc.l"
 return SHR_U_ASSIGN;
 	YY_BREAK
 case 108:
 YY_RULE_SETUP
-#line 408 "compilers/imcc/imcc.l"
+#line 407 "compilers/imcc/imcc.l"
 return CONCAT_ASSIGN;
 	YY_BREAK
 case 109:
 YY_RULE_SETUP
-#line 410 "compilers/imcc/imcc.l"
+#line 409 "compilers/imcc/imcc.l"
 {
         char *macro_name   = NULL;
         int   start_cond   = YY_START;
@@ -3530,21 +3529,21 @@
 	YY_BREAK
 case 110:
 YY_RULE_SETUP
-#line 453 "compilers/imcc/imcc.l"
+#line 452 "compilers/imcc/imcc.l"
 {
         return read_macro(valp, interp, yyscanner);
     }
 	YY_BREAK
 case 111:
 YY_RULE_SETUP
-#line 457 "compilers/imcc/imcc.l"
+#line 456 "compilers/imcc/imcc.l"
 {
         const int c = yylex(valp,yyscanner,interp);
 
         if (c != STRINGC)
             return c;
 
-        /* STRINGCs have a str_dup()ed valp->s */
+        /* STRINGCs have a mem_sys_strdup()ed valp->s */
         mem_sys_free(valp->s);
         YYCHOP();
         include_file(interp, yytext + 1, yyscanner);
@@ -3552,7 +3551,7 @@
 	YY_BREAK
 case 112:
 YY_RULE_SETUP
-#line 469 "compilers/imcc/imcc.l"
+#line 468 "compilers/imcc/imcc.l"
 {
         if (valp) {
             char *label;
@@ -3577,7 +3576,7 @@
 	YY_BREAK
 case 113:
 YY_RULE_SETUP
-#line 491 "compilers/imcc/imcc.l"
+#line 490 "compilers/imcc/imcc.l"
 {
 
         if (valp) {
@@ -3602,25 +3601,25 @@
 	YY_BREAK
 case 114:
 YY_RULE_SETUP
-#line 513 "compilers/imcc/imcc.l"
+#line 512 "compilers/imcc/imcc.l"
 return COMMA;
 	YY_BREAK
 case 115:
 YY_RULE_SETUP
-#line 515 "compilers/imcc/imcc.l"
+#line 514 "compilers/imcc/imcc.l"
 {
         /* trim last ':' */
         YYCHOP();
 
         if (valp)
-            valp->s = str_dup(yytext);
+            valp->s = mem_sys_strdup(yytext);
 
         return LABEL;
     }
 	YY_BREAK
 case 116:
 YY_RULE_SETUP
-#line 525 "compilers/imcc/imcc.l"
+#line 524 "compilers/imcc/imcc.l"
 {
         char   * const macro_name = yytext + 1;
 
@@ -3632,34 +3631,34 @@
 	YY_BREAK
 case 117:
 YY_RULE_SETUP
-#line 536 "compilers/imcc/imcc.l"
+#line 535 "compilers/imcc/imcc.l"
 DUP_AND_RET(valp, FLOATC);
 	YY_BREAK
 case 118:
 YY_RULE_SETUP
-#line 537 "compilers/imcc/imcc.l"
+#line 536 "compilers/imcc/imcc.l"
 DUP_AND_RET(valp, INTC);
 	YY_BREAK
 case 119:
 YY_RULE_SETUP
-#line 538 "compilers/imcc/imcc.l"
+#line 537 "compilers/imcc/imcc.l"
 DUP_AND_RET(valp, INTC);
 	YY_BREAK
 case 120:
 YY_RULE_SETUP
-#line 539 "compilers/imcc/imcc.l"
+#line 538 "compilers/imcc/imcc.l"
 DUP_AND_RET(valp, INTC);
 	YY_BREAK
 case 121:
 YY_RULE_SETUP
-#line 540 "compilers/imcc/imcc.l"
+#line 539 "compilers/imcc/imcc.l"
 DUP_AND_RET(valp, INTC);
 	YY_BREAK
 case 122:
 YY_RULE_SETUP
-#line 542 "compilers/imcc/imcc.l"
+#line 541 "compilers/imcc/imcc.l"
 {
-        valp->s = str_dup(yytext);
+        valp->s = mem_sys_strdup(yytext);
 
         /* trailing 'L' */
         valp->s[strlen(valp->s) - 1] = '\0';
@@ -3670,9 +3669,9 @@
 	YY_BREAK
 case 123:
 YY_RULE_SETUP
-#line 552 "compilers/imcc/imcc.l"
+#line 551 "compilers/imcc/imcc.l"
 {
-        valp->s = str_dup(yytext);
+        valp->s = mem_sys_strdup(yytext);
 
         /* RT #42382 delete quotes, -> emit, pbc */
         return STRINGC;
@@ -3680,7 +3679,7 @@
 	YY_BREAK
 case 124:
 YY_RULE_SETUP
-#line 559 "compilers/imcc/imcc.l"
+#line 558 "compilers/imcc/imcc.l"
 {
         macro_frame_t *frame;
 
@@ -3688,7 +3687,7 @@
            off newline and quote. */
         if (IMCC_INFO(interp)->frames->heredoc_rest)
             IMCC_fataly(interp, EXCEPTION_SYNTAX_ERROR, "nested heredoc not supported");
-        IMCC_INFO(interp)->heredoc_end = str_dup(yytext + 3);
+        IMCC_INFO(interp)->heredoc_end = mem_sys_strdup(yytext + 3);
         IMCC_INFO(interp)->heredoc_end[strlen(IMCC_INFO(interp)->heredoc_end) - 1] = 0;
 
         if (!strlen(IMCC_INFO(interp)->heredoc_end))
@@ -3711,10 +3710,10 @@
 	YY_BREAK
 case 125:
 YY_RULE_SETUP
-#line 587 "compilers/imcc/imcc.l"
+#line 586 "compilers/imcc/imcc.l"
 {
         /* charset:"..." */
-        valp->s = str_dup(yytext);
+        valp->s = mem_sys_strdup(yytext);
 
         /* this is actually not unicode but a string with a charset */
         return USTRINGC;
@@ -3722,7 +3721,7 @@
 	YY_BREAK
 case 126:
 YY_RULE_SETUP
-#line 595 "compilers/imcc/imcc.l"
+#line 594 "compilers/imcc/imcc.l"
 {
         if (valp) (valp)->s = yytext;
         if (IMCC_INFO(interp)->state->pasm_file)
@@ -3733,7 +3732,7 @@
 	YY_BREAK
 case 127:
 YY_RULE_SETUP
-#line 603 "compilers/imcc/imcc.l"
+#line 602 "compilers/imcc/imcc.l"
 {
         if (valp) (valp)->s = yytext;
         if (IMCC_INFO(interp)->state->pasm_file)
@@ -3744,7 +3743,7 @@
 	YY_BREAK
 case 128:
 YY_RULE_SETUP
-#line 611 "compilers/imcc/imcc.l"
+#line 610 "compilers/imcc/imcc.l"
 {
         if (valp) (valp)->s = yytext;
         if (IMCC_INFO(interp)->state->pasm_file)
@@ -3755,7 +3754,7 @@
 	YY_BREAK
 case 129:
 YY_RULE_SETUP
-#line 619 "compilers/imcc/imcc.l"
+#line 618 "compilers/imcc/imcc.l"
 {
         if (valp) (valp)->s = yytext;
         if (IMCC_INFO(interp)->state->pasm_file)
@@ -3766,7 +3765,7 @@
 	YY_BREAK
 case 130:
 YY_RULE_SETUP
-#line 627 "compilers/imcc/imcc.l"
+#line 626 "compilers/imcc/imcc.l"
 {
         IMCC_fataly(interp, EXCEPTION_SYNTAX_ERROR,
             "'%s' is not a valid register name", yytext);
@@ -3774,21 +3773,21 @@
 	YY_BREAK
 case 131:
 YY_RULE_SETUP
-#line 632 "compilers/imcc/imcc.l"
+#line 631 "compilers/imcc/imcc.l"
 {
         if (IMCC_INFO(interp)->state->pasm_file == 0)
             IMCC_fataly(interp, EXCEPTION_SYNTAX_ERROR,
             "'%s' is only a valid register name in PASM mode", yytext);
 
         if (valp)
-            valp->s = str_dup(yytext);
+            valp->s = mem_sys_strdup(yytext);
 
         return REG;
     }
 	YY_BREAK
 case 132:
 YY_RULE_SETUP
-#line 643 "compilers/imcc/imcc.l"
+#line 642 "compilers/imcc/imcc.l"
 {
         if (!pesky_global__is_def) {
             SymReg *r = find_sym(interp, yytext);
@@ -3813,25 +3812,25 @@
             }
         }
 
-        valp->s = str_dup(yytext);
+        valp->s = mem_sys_strdup(yytext);
         return (!pesky_global__is_def && is_op(interp, valp->s) ? PARROT_OP : IDENTIFIER);
     }
 	YY_BREAK
 case 133:
 YY_RULE_SETUP
-#line 672 "compilers/imcc/imcc.l"
+#line 671 "compilers/imcc/imcc.l"
 /* skip */;
 	YY_BREAK
 case 134:
 YY_RULE_SETUP
-#line 674 "compilers/imcc/imcc.l"
+#line 673 "compilers/imcc/imcc.l"
 {
         /* catch all except for state macro */
         return yytext[0];
     }
 	YY_BREAK
 case YY_STATE_EOF(emit):
-#line 679 "compilers/imcc/imcc.l"
+#line 678 "compilers/imcc/imcc.l"
 {
         BEGIN(INITIAL);
 
@@ -3844,18 +3843,18 @@
     }
 	YY_BREAK
 case YY_STATE_EOF(INITIAL):
-#line 690 "compilers/imcc/imcc.l"
+#line 689 "compilers/imcc/imcc.l"
 yyterminate();
 	YY_BREAK
 case 135:
 YY_RULE_SETUP
-#line 692 "compilers/imcc/imcc.l"
+#line 691 "compilers/imcc/imcc.l"
 DUP_AND_RET(valp, ENDM);
 	YY_BREAK
 case 136:
 /* rule 136 can match eol */
 YY_RULE_SETUP
-#line 694 "compilers/imcc/imcc.l"
+#line 693 "compilers/imcc/imcc.l"
 {
         IMCC_INFO(interp)->line++;
         DUP_AND_RET(valp, '\n');
@@ -3863,12 +3862,12 @@
 	YY_BREAK
 case 137:
 YY_RULE_SETUP
-#line 699 "compilers/imcc/imcc.l"
+#line 698 "compilers/imcc/imcc.l"
 return LABEL;
 	YY_BREAK
 case 138:
 YY_RULE_SETUP
-#line 701 "compilers/imcc/imcc.l"
+#line 700 "compilers/imcc/imcc.l"
 {
 
         if (yylex(valp,yyscanner,interp) != LABEL)
@@ -3895,7 +3894,7 @@
 	YY_BREAK
 case 139:
 YY_RULE_SETUP
-#line 725 "compilers/imcc/imcc.l"
+#line 724 "compilers/imcc/imcc.l"
 {
         if (valp) {
             const size_t len = strlen(IMCC_INFO(interp)->cur_macro_name) + yyleng + 12;
@@ -3914,49 +3913,49 @@
 	YY_BREAK
 case 140:
 YY_RULE_SETUP
-#line 741 "compilers/imcc/imcc.l"
+#line 740 "compilers/imcc/imcc.l"
 /* skip leading ws */;
 	YY_BREAK
 case 141:
 YY_RULE_SETUP
-#line 742 "compilers/imcc/imcc.l"
+#line 741 "compilers/imcc/imcc.l"
 DUP_AND_RET(valp, ' ');
 	YY_BREAK
 case 142:
 YY_RULE_SETUP
-#line 743 "compilers/imcc/imcc.l"
+#line 742 "compilers/imcc/imcc.l"
 DUP_AND_RET(valp, REG);
 	YY_BREAK
 case 143:
 YY_RULE_SETUP
-#line 744 "compilers/imcc/imcc.l"
+#line 743 "compilers/imcc/imcc.l"
 DUP_AND_RET(valp, REG);
 	YY_BREAK
 case 144:
 YY_RULE_SETUP
-#line 745 "compilers/imcc/imcc.l"
+#line 744 "compilers/imcc/imcc.l"
 DUP_AND_RET(valp, IDENTIFIER);
 	YY_BREAK
 case 145:
 YY_RULE_SETUP
-#line 746 "compilers/imcc/imcc.l"
+#line 745 "compilers/imcc/imcc.l"
 DUP_AND_RET(valp, MACRO);
 	YY_BREAK
 case 146:
 YY_RULE_SETUP
-#line 747 "compilers/imcc/imcc.l"
+#line 746 "compilers/imcc/imcc.l"
 DUP_AND_RET(valp, yytext[0]);
 	YY_BREAK
 case YY_STATE_EOF(macro):
-#line 748 "compilers/imcc/imcc.l"
+#line 747 "compilers/imcc/imcc.l"
 yyterminate();
 	YY_BREAK
 case 147:
 YY_RULE_SETUP
-#line 750 "compilers/imcc/imcc.l"
+#line 749 "compilers/imcc/imcc.l"
 ECHO;
 	YY_BREAK
-#line 3960 "compilers/imcc/imclexer.c"
+#line 3959 "compilers/imcc/imclexer.c"
 case YY_STATE_EOF(pod):
 case YY_STATE_EOF(cmt1):
 case YY_STATE_EOF(cmt2):
@@ -5158,7 +5157,7 @@
 
 #define YYTABLES_NAME "yytables"
 
-#line 750 "compilers/imcc/imcc.l"
+#line 749 "compilers/imcc/imcc.l"
 
 
 
@@ -5201,13 +5200,8 @@
 
     if (IMCC_INFO(interp)->frames) {
         tmp->s.pasm_file = IMCC_INFO(interp)->frames->s.pasm_file;
-
-        if (IMCC_INFO(interp)->frames->s.file_needs_free)
-            tmp->s.file            = str_dup(IMCC_INFO(interp)->frames->s.file);
-        else
-            tmp->s.file            = IMCC_INFO(interp)->frames->s.file;
-
-        tmp->s.file_needs_free = IMCC_INFO(interp)->frames->s.file_needs_free;
+        if (IMCC_INFO(interp)->frames->s.file)
+            tmp->s.file = mem_sys_strdup(IMCC_INFO(interp)->frames->s.file);
     }
 
     tmp->s.interp = interp;
@@ -5246,13 +5240,7 @@
     } else
         ret = frame->s.line;
 
-    /* RT #42383 if frame->s.file was allocated free it */
-    /* Update: This should do it! */
-    if (frame->s.file_needs_free) {
-        DECL_CONST_CAST;
-        mem_sys_free(PARROT_const_cast(char *,frame->s.file));
-        frame->s.file_needs_free = 0;
-    }
+    mem_sys_free(frame->s.file);
     mem_sys_free(frame);
 
     if (buffer != NULL)
@@ -5279,7 +5267,7 @@
         if (*p == '\0')
             break;
 
-        /* free any str_dup()ed strings */
+        /* free any mem_sys_strdup()ed strings */
         if (yytext)
             mem_sys_free(valp->s);
     } while (*p != '\0');
@@ -5337,7 +5325,7 @@
 {
     YYSTYPE  val;
     size_t   len      = 0;
-    char    *current  = str_dup("");
+    char    *current  = mem_sys_strdup("");
     yyguts_t *yyg     = (yyguts_t *)yyscanner;
     int      c        = yylex_skip(&val, interp, " \n", yyscanner);
 
@@ -5359,7 +5347,7 @@
                             MAX_PARAM, macro_name);
 
             params->name[params->num_param++] = current;
-            current                           = str_dup("");
+            current                           = mem_sys_strdup("");
             len                               = 0;
 
             if (val.s)
@@ -5534,7 +5522,7 @@
     else
         memset(&m->params, 0, sizeof (params_t));
 
-    m->expansion = str_dup(expansion);
+    m->expansion = mem_sys_strdup(expansion);
     m->line      = start_line;
 }
 
@@ -5575,12 +5563,10 @@
 
         /* remember macro name for error reporting
          * first free any filename allocated in new_frame() */
-        if (frame->s.file && frame->s.file_needs_free)
+        if (frame->s.file)
             mem_sys_free(frame->s.file);
 
-        /* RT #42384 check that all the .file text is malloced / freed */
-        frame->s.file            = str_dup(name);
-        frame->s.file_needs_free = 1;
+        frame->s.file            = mem_sys_strdup(name);
 
         /* whitespace can be safely ignored */
         do {
@@ -5609,7 +5595,7 @@
         BEGIN(start_cond);
 
         if (frame->expansion.num_param == 0 && m->params.num_param == 1) {
-            frame->expansion.name[0] = str_dup("");
+            frame->expansion.name[0] = mem_sys_strdup("");
             frame->expansion.num_param = 1;
         }
 
@@ -5628,7 +5614,7 @@
                 const char * const s = find_macro_param(interp, current + 1);
 
                 if (s) {
-                    frame->expansion.name[i] = str_dup(s);
+                    frame->expansion.name[i] = mem_sys_strdup(s);
                     mem_sys_free(current);
                 }
 
@@ -5651,6 +5637,7 @@
 
         IMCC_INFO(interp)->line = m->line;
         scan_string(frame, m->expansion, yyscanner);
+
         return 1;
     }
 
@@ -5667,12 +5654,16 @@
     char *ext;
     FILE *file;
 
-    if (!s || !(file = fopen(s, "r")))
+    if (!s || !(file = fopen(s, "r"))) {
+        if (frame->s.file)
+            mem_sys_free(frame->s.file);
         IMCC_fataly(interp, EXCEPTION_EXTERNAL_ERROR, strerror(errno));
+    }
 
+    if (frame->s.file)
+        mem_sys_free(frame->s.file);
     mem_sys_free(s);
-    frame->s.file            = file_name;
-    frame->s.file_needs_free = 0;
+    frame->s.file            = mem_sys_strdup(file_name);
     frame->s.handle          = file;
     ext                      = strrchr(file_name, '.');
 
@@ -5843,17 +5834,16 @@
 set_filename(PARROT_INTERP, char * const filename)
 {
     IMCC_INFO(interp)->frames->s.file = filename;
-    IMCC_INFO(interp)->frames->s.file_needs_free = 1;
 
     /* in case .line is used outside a .sub, then this
      * can't be done; hence the check.
-     * The str_dup() is done, as the original #line implementation
+     * The mem_sys_strdup() is done, as the original #line implementation
      * duplicated the string twice as well; one for the
      * frames->s.file and one for cur_unit->file.
-     * During the parse, the STRINGC is already str_dup()ed once.
+     * During the parse, the STRINGC is already mem_sys_strdup()ed once.
      */
     if (IMCC_INFO(interp)->cur_unit)
-        IMCC_INFO(interp)->cur_unit->file = str_dup(filename);
+        IMCC_INFO(interp)->cur_unit->file = mem_sys_strdup(filename);
 }
 
 /* Functions to set and get yyin, as we can't decorate it for export

Modified: branches/tt761_keys_revamp/compilers/imcc/imcparser.c
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/imcparser.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/imcparser.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -366,55 +366,60 @@
 /* HEADERIZER BEGIN: static */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
-static void add_pcc_named_arg(PARROT_INTERP,
+static void add_pcc_named_arg(
     ARGMOD(SymReg *cur_call),
-    ARGIN(SymReg *name),
-    ARGIN(SymReg *value))
+    ARGMOD(SymReg *name),
+    ARGMOD(SymReg *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*cur_call);
+        FUNC_MODIFIES(*cur_call)
+        FUNC_MODIFIES(*name)
+        FUNC_MODIFIES(*value);
 
-static void add_pcc_named_arg_var(PARROT_INTERP,
+static void add_pcc_named_arg_var(
     ARGMOD(SymReg *cur_call),
-    ARGIN(SymReg *name),
-    ARGIN(SymReg *value))
+    ARGMOD(SymReg *name),
+    ARGMOD(SymReg *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*cur_call);
+        FUNC_MODIFIES(*cur_call)
+        FUNC_MODIFIES(*name)
+        FUNC_MODIFIES(*value);
 
-static void add_pcc_named_param(PARROT_INTERP,
+static void add_pcc_named_param(
     ARGMOD(SymReg *cur_call),
-    ARGIN(SymReg *name),
-    ARGIN(SymReg *value))
+    ARGMOD(SymReg *name),
+    ARGMOD(SymReg *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*cur_call);
+        FUNC_MODIFIES(*cur_call)
+        FUNC_MODIFIES(*name)
+        FUNC_MODIFIES(*value);
 
-static void add_pcc_named_result(PARROT_INTERP,
+static void add_pcc_named_result(
     ARGMOD(SymReg *cur_call),
-    ARGIN(SymReg *name),
-    ARGIN(SymReg *value))
+    ARGMOD(SymReg *name),
+    ARGMOD(SymReg *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*cur_call);
+        FUNC_MODIFIES(*cur_call)
+        FUNC_MODIFIES(*name)
+        FUNC_MODIFIES(*value);
 
-static void add_pcc_named_return(PARROT_INTERP,
+static void add_pcc_named_return(
     ARGMOD(SymReg *cur_call),
-    ARGIN(SymReg *name),
-    ARGIN(SymReg *value))
+    ARGMOD(SymReg *name),
+    ARGMOD(SymReg *value))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*cur_call);
+        FUNC_MODIFIES(*cur_call)
+        FUNC_MODIFIES(*name)
+        FUNC_MODIFIES(*value);
 
 static void adv_named_set(PARROT_INTERP, ARGIN(const char *name))
         __attribute__nonnull__(1)
@@ -452,6 +457,7 @@
         FUNC_MODIFIES(*unit)
         FUNC_MODIFIES(*r);
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
 static Instruction * iINDEXFETCH(PARROT_INTERP,
     ARGMOD(IMC_Unit *unit),
@@ -465,6 +471,7 @@
         __attribute__nonnull__(5)
         FUNC_MODIFIES(*unit);
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
 static Instruction * iINDEXSET(PARROT_INTERP,
     ARGMOD(IMC_Unit *unit),
@@ -478,6 +485,7 @@
         __attribute__nonnull__(5)
         FUNC_MODIFIES(*unit);
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static Instruction * iLABEL(PARROT_INTERP,
     ARGMOD_NULLOK(IMC_Unit *unit),
@@ -492,6 +500,7 @@
 static const char * inv_op(ARGIN(const char *op))
         __attribute__nonnull__(1);
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static Instruction * iSUBROUTINE(PARROT_INTERP,
     ARGMOD_NULLOK(IMC_Unit *unit),
@@ -543,11 +552,13 @@
         FUNC_MODIFIES(*unit)
         FUNC_MODIFIES(*left);
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static SymReg * mk_sub_address_fromc(PARROT_INTERP, ARGIN(const char *name))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static SymReg * mk_sub_address_u(PARROT_INTERP, ARGIN(const char *name))
         __attribute__nonnull__(1)
@@ -563,28 +574,23 @@
         FUNC_MODIFIES(*name);
 
 #define ASSERT_ARGS_add_pcc_named_arg __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(cur_call) \
+       PARROT_ASSERT_ARG(cur_call) \
     || PARROT_ASSERT_ARG(name) \
     || PARROT_ASSERT_ARG(value)
 #define ASSERT_ARGS_add_pcc_named_arg_var __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(cur_call) \
+       PARROT_ASSERT_ARG(cur_call) \
     || PARROT_ASSERT_ARG(name) \
     || PARROT_ASSERT_ARG(value)
 #define ASSERT_ARGS_add_pcc_named_param __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(cur_call) \
+       PARROT_ASSERT_ARG(cur_call) \
     || PARROT_ASSERT_ARG(name) \
     || PARROT_ASSERT_ARG(value)
 #define ASSERT_ARGS_add_pcc_named_result __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(cur_call) \
+       PARROT_ASSERT_ARG(cur_call) \
     || PARROT_ASSERT_ARG(name) \
     || PARROT_ASSERT_ARG(value)
 #define ASSERT_ARGS_add_pcc_named_return __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(cur_call) \
+       PARROT_ASSERT_ARG(cur_call) \
     || PARROT_ASSERT_ARG(name) \
     || PARROT_ASSERT_ARG(value)
 #define ASSERT_ARGS_adv_named_set __attribute__unused__ int _ASSERT_ARGS_CHECK = \
@@ -709,7 +715,7 @@
 
     for (p = opname, q = fmt; *q && *q != ' ';)
         *p++ = *q++;
-    *p = 0;
+    *p = '\0';
     if (!*q)
         fmt = NULL;
     else
@@ -761,11 +767,11 @@
     r[0] = left;
     if (ascii) {
         /* strip delimiters */
-        name                   = str_dup(constant + 1);
+        name                   = mem_sys_strdup(constant + 1);
         name[strlen(name) - 1] = 0;
     }
     else {
-        name = str_dup(constant);
+        name = mem_sys_strdup(constant);
     }
 
     switch (type_enum) {
@@ -811,7 +817,7 @@
     SymReg *r[3];
     char   *const_name;
     const int ascii       = (*constant == '\'' || *constant == '"');
-    char   *unquoted_name = str_dup(name + 1);
+    char   *unquoted_name = mem_sys_strdup(name + 1);
     size_t  name_length   = strlen(unquoted_name) - 1;
 
     unquoted_name[name_length] = 0;
@@ -828,11 +834,11 @@
     r[0] = left;
     if (ascii) {
         /* strip delimiters */
-        const_name                         = str_dup(constant + 1);
+        const_name                         = mem_sys_strdup(constant + 1);
         const_name[strlen(const_name) - 1] = 0;
     }
     else {
-        const_name = str_dup(constant);
+        const_name = mem_sys_strdup(constant);
     }
 
     if ((strncmp(unquoted_name, "Sub",       name_length) == 0)
@@ -909,6 +915,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 Instruction *
 INS_LABEL(PARROT_INTERP, ARGMOD_NULLOK(IMC_Unit *unit), ARGMOD(SymReg *r0), int emit)
@@ -933,6 +940,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static Instruction *
 iLABEL(PARROT_INTERP, ARGMOD_NULLOK(IMC_Unit *unit), ARGMOD(SymReg *r0))
@@ -954,7 +962,7 @@
 
 */
 
-
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static Instruction *
 iSUBROUTINE(PARROT_INTERP, ARGMOD_NULLOK(IMC_Unit *unit), ARGMOD(SymReg *r))
@@ -983,6 +991,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
 static Instruction *
 iINDEXFETCH(PARROT_INTERP, ARGMOD(IMC_Unit *unit), ARGIN(SymReg *r0), ARGIN(SymReg *r1),
@@ -1004,6 +1013,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
 static Instruction *
 iINDEXSET(PARROT_INTERP, ARGMOD(IMC_Unit *unit), ARGIN(SymReg *r0), ARGIN(SymReg *r1),
@@ -1047,6 +1057,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 Instruction *
 IMCC_create_itcall_label(PARROT_INTERP)
@@ -1076,6 +1087,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static SymReg *
 mk_sub_address_fromc(PARROT_INTERP, ARGIN(const char *name))
@@ -1083,7 +1095,7 @@
     ASSERT_ARGS(mk_sub_address_fromc)
     /* name is a quoted sub name */
     SymReg *r;
-    char *name_copy                  = str_dup(name + 1);
+    char *name_copy                  = mem_sys_strdup(name + 1);
     name_copy[strlen(name_copy) - 1] = 0;
 
     r = mk_sub_address(interp, name_copy);
@@ -1100,6 +1112,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static SymReg *
 mk_sub_address_u(PARROT_INTERP, ARGIN(const char *name))
@@ -1199,17 +1212,17 @@
 
 /*
 
-=item C<static void add_pcc_named_arg(PARROT_INTERP, SymReg *cur_call, SymReg
-*name, SymReg *value)>
+=item C<static void add_pcc_named_arg(SymReg *cur_call, SymReg *name, SymReg
+*value)>
 
 =cut
 
 */
 
 static void
-add_pcc_named_arg(PARROT_INTERP, ARGMOD(SymReg *cur_call),
-        ARGIN(SymReg *name),
-        ARGIN(SymReg *value))
+add_pcc_named_arg(ARGMOD(SymReg *cur_call),
+        ARGMOD(SymReg *name),
+        ARGMOD(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_arg)
     name->type  |= VT_NAMED;
@@ -1220,16 +1233,16 @@
 
 /*
 
-=item C<static void add_pcc_named_arg_var(PARROT_INTERP, SymReg *cur_call,
-SymReg *name, SymReg *value)>
+=item C<static void add_pcc_named_arg_var(SymReg *cur_call, SymReg *name, SymReg
+*value)>
 
 =cut
 
 */
 
 static void
-add_pcc_named_arg_var(PARROT_INTERP, ARGMOD(SymReg *cur_call),
-    ARGIN(SymReg *name), ARGIN(SymReg *value))
+add_pcc_named_arg_var(ARGMOD(SymReg *cur_call),
+    ARGMOD(SymReg *name), ARGMOD(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_arg_var)
     name->type |= VT_NAMED;
@@ -1239,17 +1252,17 @@
 
 /*
 
-=item C<static void add_pcc_named_result(PARROT_INTERP, SymReg *cur_call, SymReg
-*name, SymReg *value)>
+=item C<static void add_pcc_named_result(SymReg *cur_call, SymReg *name, SymReg
+*value)>
 
 =cut
 
 */
 
 static void
-add_pcc_named_result(PARROT_INTERP, ARGMOD(SymReg *cur_call),
-        ARGIN(SymReg *name),
-        ARGIN(SymReg *value))
+add_pcc_named_result(ARGMOD(SymReg *cur_call),
+        ARGMOD(SymReg *name),
+        ARGMOD(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_result)
     name->type         |= VT_NAMED;
@@ -1260,17 +1273,17 @@
 
 /*
 
-=item C<static void add_pcc_named_param(PARROT_INTERP, SymReg *cur_call, SymReg
-*name, SymReg *value)>
+=item C<static void add_pcc_named_param(SymReg *cur_call, SymReg *name, SymReg
+*value)>
 
 =cut
 
 */
 
 static void
-add_pcc_named_param(PARROT_INTERP, ARGMOD(SymReg *cur_call),
-        ARGIN(SymReg *name),
-        ARGIN(SymReg *value))
+add_pcc_named_param(ARGMOD(SymReg *cur_call),
+        ARGMOD(SymReg *name),
+        ARGMOD(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_param)
     name->type         |= VT_NAMED;
@@ -1281,17 +1294,17 @@
 
 /*
 
-=item C<static void add_pcc_named_return(PARROT_INTERP, SymReg *cur_call, SymReg
-*name, SymReg *value)>
+=item C<static void add_pcc_named_return(SymReg *cur_call, SymReg *name, SymReg
+*value)>
 
 =cut
 
 */
 
 static void
-add_pcc_named_return(PARROT_INTERP, ARGMOD(SymReg *cur_call),
-        ARGIN(SymReg *name),
-        ARGIN(SymReg *value))
+add_pcc_named_return(ARGMOD(SymReg *cur_call),
+        ARGMOD(SymReg *name),
+        ARGMOD(SymReg *value))
 {
     ASSERT_ARGS(add_pcc_named_return)
     name->type         |= VT_NAMED;
@@ -1376,7 +1389,7 @@
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 1035 "compilers/imcc/imcc.y"
+#line 1048 "compilers/imcc/imcc.y"
 {
     IdList * idlist;
     int t;
@@ -1384,8 +1397,8 @@
     SymReg * sr;
     Instruction *i;
 }
-/* Line 187 of yacc.c.  */
-#line 1378 "compilers/imcc/imcparser.c"
+/* Line 193 of yacc.c.  */
+#line 1391 "compilers/imcc/imcparser.c"
 	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
@@ -1398,7 +1411,7 @@
 
 
 /* Line 216 of yacc.c.  */
-#line 1391 "compilers/imcc/imcparser.c"
+#line 1404 "compilers/imcc/imcparser.c"
 
 #ifdef short
 # undef short
@@ -1819,40 +1832,40 @@
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,  1130,  1130,  1134,  1135,  1139,  1140,  1141,  1147,  1153,
-    1154,  1155,  1156,  1160,  1161,  1170,  1176,  1184,  1196,  1209,
-    1209,  1218,  1218,  1225,  1225,  1234,  1235,  1239,  1240,  1244,
-    1245,  1246,  1247,  1248,  1249,  1250,  1253,  1253,  1262,  1261,
-    1273,  1277,  1286,  1290,  1294,  1294,  1306,  1308,  1312,  1327,
-    1335,  1340,  1344,  1348,  1339,  1360,  1361,  1362,  1375,  1375,
-    1379,  1393,  1397,  1403,  1412,  1418,  1427,  1433,  1442,  1448,
-    1457,  1465,  1470,  1481,  1484,  1489,  1497,  1498,  1499,  1500,
-    1501,  1512,  1523,  1526,  1528,  1533,  1532,  1565,  1566,  1570,
-    1571,  1575,  1576,  1580,  1581,  1585,  1586,  1587,  1588,  1589,
-    1590,  1591,  1592,  1593,  1594,  1595,  1596,  1597,  1598,  1602,
-    1607,  1611,  1616,  1620,  1624,  1629,  1638,  1639,  1643,  1648,
-    1649,  1657,  1658,  1658,  1673,  1674,  1678,  1679,  1680,  1681,
-    1682,  1683,  1684,  1689,  1689,  1692,  1700,  1700,  1706,  1707,
-    1712,  1720,  1721,  1726,  1734,  1738,  1743,  1742,  1755,  1756,
-    1760,  1761,  1771,  1776,  1786,  1795,  1796,  1808,  1812,  1814,
-    1815,  1816,  1817,  1818,  1822,  1823,  1827,  1828,  1832,  1843,
-    1844,  1855,  1862,  1871,  1881,  1882,  1887,  1888,  1889,  1889,
-    1905,  1911,  1917,  1917,  1924,  1925,  1925,  1931,  1937,  1941,
-    1953,  1954,  1955,  1956,  1957,  1958,  1962,  1963,  1964,  1965,
-    1969,  1982,  1984,  1986,  1988,  1990,  1995,  1998,  2005,  2004,
-    2013,  2014,  2015,  2016,  2024,  2025,  2026,  2030,  2031,  2032,
-    2033,  2034,  2035,  2036,  2037,  2038,  2039,  2040,  2041,  2042,
-    2043,  2044,  2045,  2046,  2047,  2048,  2049,  2050,  2051,  2052,
-    2058,  2057,  2069,  2076,  2077,  2078,  2079,  2080,  2081,  2082,
-    2083,  2084,  2085,  2086,  2087,  2088,  2093,  2104,  2105,  2106,
-    2107,  2113,  2127,  2133,  2139,  2145,  2144,  2153,  2154,  2164,
-    2174,  2181,  2186,  2196,  2200,  2201,  2205,  2206,  2209,  2210,
-    2214,  2218,  2228,  2234,  2244,  2249,  2253,  2254,  2258,  2262,
-    2266,  2273,  2277,  2281,  2288,  2289,  2293,  2294,  2295,  2296,
-    2297,  2298,  2302,  2303,  2307,  2308,  2312,  2313,  2317,  2318,
-    2325,  2332,  2333,  2334,  2338,  2339,  2343,  2344,  2348,  2349,
-    2353,  2354,  2358,  2358,  2371,  2371,  2384,  2385,  2393,  2402,
-    2403,  2404,  2405,  2406,  2410,  2411,  2412,  2413
+       0,  1143,  1143,  1147,  1148,  1152,  1153,  1154,  1160,  1166,
+    1167,  1168,  1169,  1173,  1174,  1183,  1189,  1197,  1209,  1222,
+    1222,  1231,  1231,  1238,  1238,  1247,  1248,  1252,  1253,  1257,
+    1258,  1259,  1260,  1261,  1262,  1263,  1266,  1266,  1275,  1274,
+    1287,  1291,  1300,  1304,  1308,  1308,  1320,  1322,  1326,  1341,
+    1349,  1354,  1358,  1362,  1353,  1374,  1375,  1376,  1389,  1389,
+    1393,  1407,  1411,  1417,  1426,  1432,  1441,  1447,  1456,  1462,
+    1471,  1479,  1484,  1495,  1498,  1503,  1511,  1512,  1513,  1514,
+    1515,  1526,  1537,  1540,  1542,  1547,  1546,  1579,  1580,  1584,
+    1585,  1589,  1590,  1594,  1595,  1599,  1600,  1601,  1602,  1603,
+    1604,  1605,  1606,  1607,  1608,  1609,  1610,  1611,  1612,  1616,
+    1621,  1625,  1630,  1634,  1638,  1643,  1652,  1653,  1657,  1662,
+    1663,  1671,  1672,  1672,  1687,  1688,  1692,  1693,  1694,  1695,
+    1696,  1697,  1698,  1703,  1703,  1706,  1714,  1714,  1720,  1721,
+    1726,  1734,  1735,  1740,  1748,  1752,  1757,  1756,  1769,  1770,
+    1774,  1775,  1785,  1790,  1800,  1809,  1810,  1822,  1826,  1828,
+    1829,  1830,  1831,  1832,  1836,  1837,  1841,  1842,  1846,  1857,
+    1858,  1869,  1876,  1885,  1895,  1896,  1901,  1902,  1903,  1903,
+    1919,  1925,  1931,  1931,  1938,  1939,  1939,  1945,  1951,  1955,
+    1967,  1968,  1969,  1970,  1971,  1972,  1976,  1977,  1978,  1979,
+    1983,  1996,  1998,  2000,  2002,  2004,  2009,  2012,  2019,  2018,
+    2027,  2028,  2029,  2030,  2038,  2039,  2040,  2044,  2045,  2046,
+    2047,  2048,  2049,  2050,  2051,  2052,  2053,  2054,  2055,  2056,
+    2057,  2058,  2059,  2060,  2061,  2062,  2063,  2064,  2065,  2066,
+    2072,  2071,  2083,  2090,  2091,  2092,  2093,  2094,  2095,  2096,
+    2097,  2098,  2099,  2100,  2101,  2102,  2107,  2118,  2119,  2120,
+    2121,  2127,  2141,  2147,  2153,  2159,  2158,  2167,  2168,  2178,
+    2188,  2195,  2200,  2210,  2214,  2215,  2219,  2220,  2223,  2224,
+    2228,  2232,  2242,  2248,  2258,  2263,  2267,  2268,  2272,  2276,
+    2280,  2287,  2291,  2295,  2302,  2303,  2307,  2308,  2309,  2310,
+    2311,  2312,  2316,  2317,  2321,  2322,  2326,  2327,  2331,  2332,
+    2339,  2346,  2347,  2348,  2352,  2353,  2357,  2358,  2362,  2363,
+    2367,  2368,  2372,  2372,  2385,  2385,  2398,  2399,  2407,  2416,
+    2417,  2418,  2419,  2420,  2424,  2425,  2426,  2427
 };
 #endif
 
@@ -3206,102 +3219,102 @@
   switch (yyn)
     {
         case 2:
-#line 1130 "compilers/imcc/imcc.y"
-    { if (yynerrs) YYABORT; (yyval.i) = 0; }
+#line 1143 "compilers/imcc/imcc.y"
+    { if (yynerrs) YYABORT; (yyval.i) = 0; ;}
     break;
 
   case 5:
-#line 1139 "compilers/imcc/imcc.y"
-    { (yyval.i) = (yyvsp[(1) - (1)].i); }
+#line 1152 "compilers/imcc/imcc.y"
+    { (yyval.i) = (yyvsp[(1) - (1)].i); ;}
     break;
 
   case 6:
-#line 1140 "compilers/imcc/imcc.y"
-    { (yyval.i) = (yyvsp[(1) - (1)].i); }
+#line 1153 "compilers/imcc/imcc.y"
+    { (yyval.i) = (yyvsp[(1) - (1)].i); ;}
     break;
 
   case 7:
-#line 1142 "compilers/imcc/imcc.y"
+#line 1155 "compilers/imcc/imcc.y"
     {
            (yyval.i) = (yyvsp[(1) - (1)].i);
            imc_close_unit(interp, IMCC_INFO(interp)->cur_unit);
            IMCC_INFO(interp)->cur_unit = 0;
-         }
+         ;}
     break;
 
   case 8:
-#line 1148 "compilers/imcc/imcc.y"
+#line 1161 "compilers/imcc/imcc.y"
     {
            (yyval.i) = (yyvsp[(1) - (1)].i);
            imc_close_unit(interp, IMCC_INFO(interp)->cur_unit);
            IMCC_INFO(interp)->cur_unit = 0;
-         }
+         ;}
     break;
 
   case 9:
-#line 1153 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; }
+#line 1166 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; ;}
     break;
 
   case 10:
-#line 1154 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; }
+#line 1167 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; ;}
     break;
 
   case 11:
-#line 1155 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; }
+#line 1168 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; ;}
     break;
 
   case 12:
-#line 1156 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; }
+#line 1169 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; ;}
     break;
 
   case 13:
-#line 1160 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; }
+#line 1173 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; ;}
     break;
 
   case 14:
-#line 1162 "compilers/imcc/imcc.y"
+#line 1175 "compilers/imcc/imcc.y"
     {
            (yyval.i) = 0;
            do_loadlib(interp, (yyvsp[(2) - (3)].s));
            mem_sys_free((yyvsp[(2) - (3)].s));
-         }
+         ;}
     break;
 
   case 15:
-#line 1171 "compilers/imcc/imcc.y"
+#line 1184 "compilers/imcc/imcc.y"
     {
            IMCC_INFO(interp)->line = atoi((yyvsp[(2) - (5)].s));
            /* set_filename() frees the STRINGC */
            set_filename(interp, (yyvsp[(4) - (5)].s));
-         }
+         ;}
     break;
 
   case 16:
-#line 1177 "compilers/imcc/imcc.y"
+#line 1190 "compilers/imcc/imcc.y"
     {
            /* set_filename() frees the STRINGC */
            set_filename(interp, (yyvsp[(2) - (3)].s));
-         }
+         ;}
     break;
 
   case 17:
-#line 1185 "compilers/imcc/imcc.y"
+#line 1198 "compilers/imcc/imcc.y"
     {
           /* We'll want to store an entry while emitting instructions, so just
            * store annotation like it's an instruction. */
           SymReg * const key = mk_const(interp, (yyvsp[(2) - (4)].s), 'S');
           (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, ".annotate", 2, key, (yyvsp[(4) - (4)].sr));
           mem_sys_free((yyvsp[(2) - (4)].s));
-        }
+        ;}
     break;
 
   case 18:
-#line 1197 "compilers/imcc/imcc.y"
+#line 1210 "compilers/imcc/imcc.y"
     {
             STRING * const hll_name = Parrot_str_unescape(interp, (yyvsp[(2) - (2)].s) + 1, '"', NULL);
             CONTEXT(interp)->current_HLL =
@@ -3310,119 +3323,120 @@
             IMCC_INFO(interp)->cur_namespace = NULL;
             mem_sys_free((yyvsp[(2) - (2)].s));
             (yyval.t) = 0;
-         }
+         ;}
     break;
 
   case 19:
-#line 1209 "compilers/imcc/imcc.y"
-    { pesky_global__is_def = 1; }
+#line 1222 "compilers/imcc/imcc.y"
+    { pesky_global__is_def = 1; ;}
     break;
 
   case 20:
-#line 1210 "compilers/imcc/imcc.y"
+#line 1223 "compilers/imcc/imcc.y"
     {
              mk_const_ident(interp, (yyvsp[(4) - (6)].s), (yyvsp[(3) - (6)].t), (yyvsp[(6) - (6)].sr), 1);
              mem_sys_free((yyvsp[(4) - (6)].s));
              pesky_global__is_def = 0;
-         }
+         ;}
     break;
 
   case 21:
-#line 1218 "compilers/imcc/imcc.y"
-    { pesky_global__is_def=1; }
+#line 1231 "compilers/imcc/imcc.y"
+    { pesky_global__is_def=1; ;}
     break;
 
   case 22:
-#line 1219 "compilers/imcc/imcc.y"
+#line 1232 "compilers/imcc/imcc.y"
     {
            (yyval.i) = mk_pmc_const(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(3) - (6)].s), (yyvsp[(4) - (6)].sr), (yyvsp[(6) - (6)].s));
            mem_sys_free((yyvsp[(6) - (6)].s));
            pesky_global__is_def = 0;
-         }
+         ;}
     break;
 
   case 23:
-#line 1225 "compilers/imcc/imcc.y"
-    { pesky_global__is_def=1; }
+#line 1238 "compilers/imcc/imcc.y"
+    { pesky_global__is_def=1; ;}
     break;
 
   case 24:
-#line 1226 "compilers/imcc/imcc.y"
+#line 1239 "compilers/imcc/imcc.y"
     {
            (yyval.i) = mk_pmc_const_named(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(3) - (6)].s), (yyvsp[(4) - (6)].sr), (yyvsp[(6) - (6)].s));
            mem_sys_free((yyvsp[(3) - (6)].s));
            mem_sys_free((yyvsp[(6) - (6)].s));
            pesky_global__is_def = 0;
-         }
+         ;}
     break;
 
   case 29:
-#line 1244 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0;  }
+#line 1257 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0;  ;}
     break;
 
   case 30:
-#line 1245 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0;  }
+#line 1258 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0;  ;}
     break;
 
   case 31:
-#line 1246 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0;  }
+#line 1259 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0;  ;}
     break;
 
   case 32:
-#line 1247 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0;  }
+#line 1260 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0;  ;}
     break;
 
   case 33:
-#line 1248 "compilers/imcc/imcc.y"
-    { (yyval.i) = (yyvsp[(1) - (1)].i); }
+#line 1261 "compilers/imcc/imcc.y"
+    { (yyval.i) = (yyvsp[(1) - (1)].i); ;}
     break;
 
   case 36:
-#line 1253 "compilers/imcc/imcc.y"
-    { clear_state(interp); }
+#line 1266 "compilers/imcc/imcc.y"
+    { clear_state(interp); ;}
     break;
 
   case 37:
-#line 1255 "compilers/imcc/imcc.y"
+#line 1268 "compilers/imcc/imcc.y"
     {
            (yyval.i) = INS(interp, IMCC_INFO(interp)->cur_unit,
                     (yyvsp[(2) - (3)].s), 0, IMCC_INFO(interp)->regs,
                     IMCC_INFO(interp)->nargs, IMCC_INFO(interp) -> keyvec, 1);
             mem_sys_free((yyvsp[(2) - (3)].s));
-         }
+         ;}
     break;
 
   case 38:
-#line 1262 "compilers/imcc/imcc.y"
+#line 1275 "compilers/imcc/imcc.y"
     {
            imc_close_unit(interp, IMCC_INFO(interp)->cur_unit);
            IMCC_INFO(interp)->cur_unit = imc_open_unit(interp, IMC_PASM);
-         }
+         ;}
     break;
 
   case 39:
-#line 1267 "compilers/imcc/imcc.y"
+#line 1280 "compilers/imcc/imcc.y"
     {
            (yyval.i) = iSUBROUTINE(interp,
                     IMCC_INFO(interp)->cur_unit,
                     mk_sub_label(interp, (yyvsp[(4) - (4)].s)));
            IMCC_INFO(interp)->cur_call->pcc_sub->pragma = (yyvsp[(3) - (4)].t);
-         }
+           mem_sys_free((yyvsp[(4) - (4)].s));
+         ;}
     break;
 
   case 40:
-#line 1274 "compilers/imcc/imcc.y"
+#line 1288 "compilers/imcc/imcc.y"
     {
            (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "null", 1, (yyvsp[(2) - (2)].sr));
-         }
+         ;}
     break;
 
   case 41:
-#line 1278 "compilers/imcc/imcc.y"
+#line 1292 "compilers/imcc/imcc.y"
     {
            SymReg *r = mk_pasm_reg(interp, (yyvsp[(4) - (4)].s));
            SymReg *n = mk_const(interp, (yyvsp[(2) - (4)].s), 'S');
@@ -3430,32 +3444,32 @@
            (yyval.i) = 0;
            mem_sys_free((yyvsp[(2) - (4)].s));
            mem_sys_free((yyvsp[(4) - (4)].s));
-         }
+         ;}
     break;
 
   case 42:
-#line 1286 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0;}
+#line 1300 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0;;}
     break;
 
   case 44:
-#line 1294 "compilers/imcc/imcc.y"
-    { IMCC_INFO(interp)->cur_unit = imc_open_unit(interp, IMC_PASM); }
+#line 1308 "compilers/imcc/imcc.y"
+    { IMCC_INFO(interp)->cur_unit = imc_open_unit(interp, IMC_PASM); ;}
     break;
 
   case 45:
-#line 1297 "compilers/imcc/imcc.y"
+#line 1311 "compilers/imcc/imcc.y"
     {
            /* if (optimizer_level & OPT_PASM)
                          imc_compile_unit(interp, IMCC_INFO(interp)->cur_unit);
                          emit_flush(interp);
            */
            (yyval.i) = 0;
-         }
+         ;}
     break;
 
   case 48:
-#line 1313 "compilers/imcc/imcc.y"
+#line 1327 "compilers/imcc/imcc.y"
     {
            int re_open = 0;
            (yyval.i) = 0;
@@ -3466,90 +3480,90 @@
            IMCC_INFO(interp)->cur_namespace = (yyvsp[(2) - (3)].sr);
            if (re_open)
                IMCC_INFO(interp)->cur_unit = imc_open_unit(interp, IMC_PASM);
-         }
+         ;}
     break;
 
   case 49:
-#line 1328 "compilers/imcc/imcc.y"
+#line 1342 "compilers/imcc/imcc.y"
     {
             if (IMCC_INFO(interp)->in_slice)
                 IMCC_fataly(interp, EXCEPTION_SYNTAX_ERROR,
                     "Slice not allowed in namespace.");
 
             (yyval.sr) = (yyvsp[(2) - (3)].sr);
-        }
+        ;}
     break;
 
   case 50:
-#line 1335 "compilers/imcc/imcc.y"
-    { (yyval.sr) = NULL; }
+#line 1349 "compilers/imcc/imcc.y"
+    { (yyval.sr) = NULL; ;}
     break;
 
   case 51:
-#line 1340 "compilers/imcc/imcc.y"
+#line 1354 "compilers/imcc/imcc.y"
     {
            IMCC_INFO(interp)->cur_unit = imc_open_unit(interp, IMC_PCCSUB);
-         }
+         ;}
     break;
 
   case 52:
-#line 1344 "compilers/imcc/imcc.y"
+#line 1358 "compilers/imcc/imcc.y"
     {
            iSUBROUTINE(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(3) - (3)].sr));
-         }
+         ;}
     break;
 
   case 53:
-#line 1348 "compilers/imcc/imcc.y"
+#line 1362 "compilers/imcc/imcc.y"
     {
           IMCC_INFO(interp)->cur_call->pcc_sub->pragma = (yyvsp[(5) - (6)].t);
           if (!IMCC_INFO(interp)->cur_unit->instructions->symregs[0]->subid) {
-            IMCC_INFO(interp)->cur_unit->instructions->symregs[0]->subid = str_dup(
+            IMCC_INFO(interp)->cur_unit->instructions->symregs[0]->subid = mem_sys_strdup(
             IMCC_INFO(interp)->cur_unit->instructions->symregs[0]->name);
           }
-        }
+        ;}
     break;
 
   case 54:
-#line 1356 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; IMCC_INFO(interp)->cur_call = NULL; }
+#line 1370 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; IMCC_INFO(interp)->cur_call = NULL; ;}
     break;
 
   case 55:
-#line 1360 "compilers/imcc/imcc.y"
-    { (yyval.sr) = 0; }
+#line 1374 "compilers/imcc/imcc.y"
+    { (yyval.sr) = 0; ;}
     break;
 
   case 56:
-#line 1361 "compilers/imcc/imcc.y"
-    { (yyval.sr) = 0; }
+#line 1375 "compilers/imcc/imcc.y"
+    { (yyval.sr) = 0; ;}
     break;
 
   case 57:
-#line 1363 "compilers/imcc/imcc.y"
+#line 1377 "compilers/imcc/imcc.y"
     {
            if (IMCC_INFO(interp)->adv_named_id) {
-                 add_pcc_named_param(interp, IMCC_INFO(interp)->cur_call,
+                 add_pcc_named_param(IMCC_INFO(interp)->cur_call,
                                      IMCC_INFO(interp)->adv_named_id, (yyvsp[(2) - (3)].sr));
                  IMCC_INFO(interp)->adv_named_id = NULL;
            }
            else
                add_pcc_arg(IMCC_INFO(interp)->cur_call, (yyvsp[(2) - (3)].sr));
-         }
+         ;}
     break;
 
   case 58:
-#line 1375 "compilers/imcc/imcc.y"
-    { pesky_global__is_def=1; }
+#line 1389 "compilers/imcc/imcc.y"
+    { pesky_global__is_def=1; ;}
     break;
 
   case 59:
-#line 1375 "compilers/imcc/imcc.y"
-    { (yyval.sr) = (yyvsp[(3) - (3)].sr); pesky_global__is_def=0; }
+#line 1389 "compilers/imcc/imcc.y"
+    { (yyval.sr) = (yyvsp[(3) - (3)].sr); pesky_global__is_def=0; ;}
     break;
 
   case 60:
-#line 1380 "compilers/imcc/imcc.y"
+#line 1394 "compilers/imcc/imcc.y"
     {
            if ((yyvsp[(3) - (3)].t) & VT_UNIQUE_REG)
                (yyval.sr) = mk_ident_ur(interp, (yyvsp[(2) - (3)].s), (yyvsp[(1) - (3)].t));
@@ -3557,157 +3571,157 @@
                (yyval.sr) = mk_ident(interp, (yyvsp[(2) - (3)].s), (yyvsp[(1) - (3)].t));
            (yyval.sr)->type |= (yyvsp[(3) - (3)].t);
            mem_sys_free((yyvsp[(2) - (3)].s));
-          }
+          ;}
     break;
 
   case 61:
-#line 1393 "compilers/imcc/imcc.y"
-    { (yyval.t) = 0; }
+#line 1407 "compilers/imcc/imcc.y"
+    { (yyval.t) = 0; ;}
     break;
 
   case 62:
-#line 1398 "compilers/imcc/imcc.y"
+#line 1412 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            IMCC_INFO(interp)->cur_unit->outer = mk_sub_address_fromc(interp, (yyvsp[(3) - (4)].s));
            mem_sys_free((yyvsp[(3) - (4)].s));
-         }
+         ;}
     break;
 
   case 63:
-#line 1404 "compilers/imcc/imcc.y"
+#line 1418 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            IMCC_INFO(interp)->cur_unit->outer = mk_const(interp, (yyvsp[(3) - (4)].s), 'S');
            mem_sys_free((yyvsp[(3) - (4)].s));
-         }
+         ;}
     break;
 
   case 64:
-#line 1413 "compilers/imcc/imcc.y"
+#line 1427 "compilers/imcc/imcc.y"
     {
            (yyval.t) = P_VTABLE;
            IMCC_INFO(interp)->cur_unit->vtable_name      = NULL;
            IMCC_INFO(interp)->cur_unit->is_vtable_method = 1;
-         }
+         ;}
     break;
 
   case 65:
-#line 1419 "compilers/imcc/imcc.y"
+#line 1433 "compilers/imcc/imcc.y"
     {
            (yyval.t) = P_VTABLE;
            IMCC_INFO(interp)->cur_unit->vtable_name      = (yyvsp[(3) - (4)].s);
            IMCC_INFO(interp)->cur_unit->is_vtable_method = 1;
-         }
+         ;}
     break;
 
   case 66:
-#line 1428 "compilers/imcc/imcc.y"
+#line 1442 "compilers/imcc/imcc.y"
     {
            (yyval.t) = P_METHOD;
            IMCC_INFO(interp)->cur_unit->method_name = NULL;
            IMCC_INFO(interp)->cur_unit->is_method   = 1;
-         }
+         ;}
     break;
 
   case 67:
-#line 1434 "compilers/imcc/imcc.y"
+#line 1448 "compilers/imcc/imcc.y"
     {
            (yyval.t) = P_METHOD;
            IMCC_INFO(interp)->cur_unit->method_name = (yyvsp[(3) - (4)].s);
            IMCC_INFO(interp)->cur_unit->is_method   = 1;
-         }
+         ;}
     break;
 
   case 68:
-#line 1443 "compilers/imcc/imcc.y"
+#line 1457 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            IMCC_INFO(interp)->cur_unit->ns_entry_name     = NULL;
            IMCC_INFO(interp)->cur_unit->has_ns_entry_name = 1;
-         }
+         ;}
     break;
 
   case 69:
-#line 1449 "compilers/imcc/imcc.y"
+#line 1463 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            IMCC_INFO(interp)->cur_unit->ns_entry_name = (yyvsp[(3) - (4)].s);
            IMCC_INFO(interp)->cur_unit->has_ns_entry_name = 1;
-         }
+         ;}
     break;
 
   case 70:
-#line 1458 "compilers/imcc/imcc.y"
+#line 1472 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            IMCC_INFO(interp)->cur_unit->instance_of = (yyvsp[(3) - (4)].s);
-         }
+         ;}
     break;
 
   case 71:
-#line 1466 "compilers/imcc/imcc.y"
+#line 1480 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            IMCC_INFO(interp)->cur_unit->subid = NULL;
-         }
+         ;}
     break;
 
   case 72:
-#line 1471 "compilers/imcc/imcc.y"
+#line 1485 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            IMCC_INFO(interp)->cur_unit->subid = mk_const(interp, (yyvsp[(3) - (4)].s), 'S');
            IMCC_INFO(interp)->cur_unit->instructions->symregs[0]->subid = str_dup_remove_quotes((yyvsp[(3) - (4)].s));
            mem_sys_free((yyvsp[(3) - (4)].s));
-         }
+         ;}
     break;
 
   case 73:
-#line 1481 "compilers/imcc/imcc.y"
+#line 1495 "compilers/imcc/imcc.y"
     {
            add_pcc_multi(IMCC_INFO(interp)->cur_call, NULL);
-         }
+         ;}
     break;
 
   case 74:
-#line 1485 "compilers/imcc/imcc.y"
+#line 1499 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            add_pcc_multi(IMCC_INFO(interp)->cur_call, (yyvsp[(3) - (3)].sr));
-         }
+         ;}
     break;
 
   case 75:
-#line 1490 "compilers/imcc/imcc.y"
+#line 1504 "compilers/imcc/imcc.y"
     {
            (yyval.t) = 0;
            add_pcc_multi(IMCC_INFO(interp)->cur_call, (yyvsp[(1) - (1)].sr));
-         }
+         ;}
     break;
 
   case 76:
-#line 1497 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_const(interp, "INTVAL",   'S'); }
+#line 1511 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_const(interp, "INTVAL",   'S'); ;}
     break;
 
   case 77:
-#line 1498 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_const(interp, "FLOATVAL", 'S'); }
+#line 1512 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_const(interp, "FLOATVAL", 'S'); ;}
     break;
 
   case 78:
-#line 1499 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_const(interp, "PMC",      'S'); }
+#line 1513 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_const(interp, "PMC",      'S'); ;}
     break;
 
   case 79:
-#line 1500 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_const(interp, "STRING",   'S'); }
+#line 1514 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_const(interp, "STRING",   'S'); ;}
     break;
 
   case 80:
-#line 1502 "compilers/imcc/imcc.y"
+#line 1516 "compilers/imcc/imcc.y"
     {
            SymReg *r;
            if (strcmp((yyvsp[(1) - (1)].s), "_") != 0)
@@ -3717,11 +3731,11 @@
            }
            mem_sys_free((yyvsp[(1) - (1)].s));
            (yyval.sr) = r;
-         }
+         ;}
     break;
 
   case 81:
-#line 1513 "compilers/imcc/imcc.y"
+#line 1527 "compilers/imcc/imcc.y"
     {
            SymReg *r;
            if (strcmp((yyvsp[(1) - (1)].s), "_") != 0)
@@ -3731,16 +3745,16 @@
            }
            mem_sys_free((yyvsp[(1) - (1)].s));
            (yyval.sr) = r;
-         }
+         ;}
     break;
 
   case 82:
-#line 1523 "compilers/imcc/imcc.y"
-    { (yyval.sr) = (yyvsp[(2) - (3)].sr); }
+#line 1537 "compilers/imcc/imcc.y"
+    { (yyval.sr) = (yyvsp[(2) - (3)].sr); ;}
     break;
 
   case 85:
-#line 1533 "compilers/imcc/imcc.y"
+#line 1547 "compilers/imcc/imcc.y"
     {
            char name[128];
            SymReg *r, *r1;
@@ -3763,179 +3777,179 @@
            r1 = IMCC_INFO(interp)->cur_unit->instructions->symregs[0];
            if (r1 && r1->pcc_sub)
                r1->pcc_sub->calls_a_sub |= 1;
-         }
+         ;}
     break;
 
   case 86:
-#line 1561 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; IMCC_INFO(interp)->cur_call = NULL; }
+#line 1575 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; IMCC_INFO(interp)->cur_call = NULL; ;}
     break;
 
   case 87:
-#line 1565 "compilers/imcc/imcc.y"
-    { (yyval.i) = NULL; IMCC_INFO(interp)->cur_call->pcc_sub->label = 0; }
+#line 1579 "compilers/imcc/imcc.y"
+    { (yyval.i) = NULL; IMCC_INFO(interp)->cur_call->pcc_sub->label = 0; ;}
     break;
 
   case 88:
-#line 1566 "compilers/imcc/imcc.y"
-    { (yyval.i) = NULL; IMCC_INFO(interp)->cur_call->pcc_sub->label = 1; }
+#line 1580 "compilers/imcc/imcc.y"
+    { (yyval.i) = NULL; IMCC_INFO(interp)->cur_call->pcc_sub->label = 1; ;}
     break;
 
   case 89:
-#line 1570 "compilers/imcc/imcc.y"
-    { (yyval.i) = NULL; }
+#line 1584 "compilers/imcc/imcc.y"
+    { (yyval.i) = NULL; ;}
     break;
 
   case 90:
-#line 1571 "compilers/imcc/imcc.y"
-    { (yyval.i) = NULL;  IMCC_INFO(interp)->cur_call->pcc_sub->object = (yyvsp[(2) - (3)].sr); }
+#line 1585 "compilers/imcc/imcc.y"
+    { (yyval.i) = NULL;  IMCC_INFO(interp)->cur_call->pcc_sub->object = (yyvsp[(2) - (3)].sr); ;}
     break;
 
   case 91:
-#line 1575 "compilers/imcc/imcc.y"
-    { (yyval.t) = 0; }
+#line 1589 "compilers/imcc/imcc.y"
+    { (yyval.t) = 0; ;}
     break;
 
   case 93:
-#line 1580 "compilers/imcc/imcc.y"
-    { (yyval.t) = (yyvsp[(1) - (1)].t); }
+#line 1594 "compilers/imcc/imcc.y"
+    { (yyval.t) = (yyvsp[(1) - (1)].t); ;}
     break;
 
   case 94:
-#line 1581 "compilers/imcc/imcc.y"
-    { (yyval.t) = (yyvsp[(1) - (2)].t) | (yyvsp[(2) - (2)].t); }
+#line 1595 "compilers/imcc/imcc.y"
+    { (yyval.t) = (yyvsp[(1) - (2)].t) | (yyvsp[(2) - (2)].t); ;}
     break;
 
   case 95:
-#line 1585 "compilers/imcc/imcc.y"
-    { (yyval.t) = P_LOAD; }
+#line 1599 "compilers/imcc/imcc.y"
+    { (yyval.t) = P_LOAD; ;}
     break;
 
   case 96:
-#line 1586 "compilers/imcc/imcc.y"
-    { (yyval.t) = P_INIT; }
+#line 1600 "compilers/imcc/imcc.y"
+    { (yyval.t) = P_INIT; ;}
     break;
 
   case 97:
-#line 1587 "compilers/imcc/imcc.y"
-    { (yyval.t) = P_MAIN; }
+#line 1601 "compilers/imcc/imcc.y"
+    { (yyval.t) = P_MAIN; ;}
     break;
 
   case 98:
-#line 1588 "compilers/imcc/imcc.y"
-    { (yyval.t) = P_IMMEDIATE; }
+#line 1602 "compilers/imcc/imcc.y"
+    { (yyval.t) = P_IMMEDIATE; ;}
     break;
 
   case 99:
-#line 1589 "compilers/imcc/imcc.y"
-    { (yyval.t) = P_POSTCOMP; }
+#line 1603 "compilers/imcc/imcc.y"
+    { (yyval.t) = P_POSTCOMP; ;}
     break;
 
   case 100:
-#line 1590 "compilers/imcc/imcc.y"
-    { (yyval.t) = P_ANON; }
+#line 1604 "compilers/imcc/imcc.y"
+    { (yyval.t) = P_ANON; ;}
     break;
 
   case 101:
-#line 1591 "compilers/imcc/imcc.y"
-    { (yyval.t) = P_NEED_LEX; }
+#line 1605 "compilers/imcc/imcc.y"
+    { (yyval.t) = P_NEED_LEX; ;}
     break;
 
   case 109:
-#line 1603 "compilers/imcc/imcc.y"
+#line 1617 "compilers/imcc/imcc.y"
     {
            add_pcc_sub(IMCC_INFO(interp)->cur_call, (yyvsp[(2) - (5)].sr));
            add_pcc_cc(IMCC_INFO(interp)->cur_call, (yyvsp[(4) - (5)].sr));
-         }
+         ;}
     break;
 
   case 110:
-#line 1608 "compilers/imcc/imcc.y"
+#line 1622 "compilers/imcc/imcc.y"
     {
            add_pcc_sub(IMCC_INFO(interp)->cur_call, (yyvsp[(2) - (3)].sr));
-         }
+         ;}
     break;
 
   case 111:
-#line 1612 "compilers/imcc/imcc.y"
+#line 1626 "compilers/imcc/imcc.y"
     {
            add_pcc_sub(IMCC_INFO(interp)->cur_call, (yyvsp[(2) - (3)].sr));
            IMCC_INFO(interp)->cur_call->pcc_sub->flags |= isNCI;
-         }
+         ;}
     break;
 
   case 112:
-#line 1617 "compilers/imcc/imcc.y"
+#line 1631 "compilers/imcc/imcc.y"
     {
            add_pcc_sub(IMCC_INFO(interp)->cur_call, (yyvsp[(2) - (3)].sr));
-         }
+         ;}
     break;
 
   case 113:
-#line 1621 "compilers/imcc/imcc.y"
+#line 1635 "compilers/imcc/imcc.y"
     {
            add_pcc_sub(IMCC_INFO(interp)->cur_call, mk_const(interp, (yyvsp[(2) - (3)].s), 'S'));
-         }
+         ;}
     break;
 
   case 114:
-#line 1625 "compilers/imcc/imcc.y"
+#line 1639 "compilers/imcc/imcc.y"
     {
            add_pcc_sub(IMCC_INFO(interp)->cur_call, (yyvsp[(2) - (5)].sr));
            add_pcc_cc(IMCC_INFO(interp)->cur_call, (yyvsp[(4) - (5)].sr));
-         }
+         ;}
     break;
 
   case 115:
-#line 1630 "compilers/imcc/imcc.y"
+#line 1644 "compilers/imcc/imcc.y"
     {
            add_pcc_sub(IMCC_INFO(interp)->cur_call, mk_const(interp, (yyvsp[(2) - (5)].s), 'S'));
            add_pcc_cc(IMCC_INFO(interp)->cur_call, (yyvsp[(4) - (5)].sr));
-         }
+         ;}
     break;
 
   case 116:
-#line 1638 "compilers/imcc/imcc.y"
-    { (yyval.sr) = 0; }
+#line 1652 "compilers/imcc/imcc.y"
+    { (yyval.sr) = 0; ;}
     break;
 
   case 117:
-#line 1639 "compilers/imcc/imcc.y"
-    { add_pcc_arg(IMCC_INFO(interp)->cur_call, (yyvsp[(2) - (3)].sr)); }
+#line 1653 "compilers/imcc/imcc.y"
+    { add_pcc_arg(IMCC_INFO(interp)->cur_call, (yyvsp[(2) - (3)].sr)); ;}
     break;
 
   case 118:
-#line 1643 "compilers/imcc/imcc.y"
-    { (yyval.sr) = (yyvsp[(2) - (2)].sr); }
+#line 1657 "compilers/imcc/imcc.y"
+    { (yyval.sr) = (yyvsp[(2) - (2)].sr); ;}
     break;
 
   case 119:
-#line 1648 "compilers/imcc/imcc.y"
-    { (yyval.sr) = 0; }
+#line 1662 "compilers/imcc/imcc.y"
+    { (yyval.sr) = 0; ;}
     break;
 
   case 120:
-#line 1650 "compilers/imcc/imcc.y"
+#line 1664 "compilers/imcc/imcc.y"
     {
            if ((yyvsp[(2) - (3)].sr))
                add_pcc_result(IMCC_INFO(interp)->cur_call, (yyvsp[(2) - (3)].sr));
-         }
+         ;}
     break;
 
   case 121:
-#line 1657 "compilers/imcc/imcc.y"
-    { (yyval.sr) = (yyvsp[(2) - (3)].sr); (yyval.sr)->type |= (yyvsp[(3) - (3)].t); }
+#line 1671 "compilers/imcc/imcc.y"
+    { (yyval.sr) = (yyvsp[(2) - (3)].sr); (yyval.sr)->type |= (yyvsp[(3) - (3)].t); ;}
     break;
 
   case 122:
-#line 1658 "compilers/imcc/imcc.y"
-    { pesky_global__is_def=1; }
+#line 1672 "compilers/imcc/imcc.y"
+    { pesky_global__is_def=1; ;}
     break;
 
   case 123:
-#line 1659 "compilers/imcc/imcc.y"
+#line 1673 "compilers/imcc/imcc.y"
     {
-           IdList *l = (yyvsp[(4) - (4)].idlist);
+           IdList * const l = (yyvsp[(4) - (4)].idlist);
            SymReg *ignored;
            if (l->unique_reg)
                ignored = mk_ident_ur(interp, l->id, (yyvsp[(3) - (4)].t));
@@ -3944,317 +3958,317 @@
            UNUSED(ignored);
            pesky_global__is_def=0;
            (yyval.sr)=0;
-         }
+         ;}
     break;
 
   case 124:
-#line 1673 "compilers/imcc/imcc.y"
-    { (yyval.t) = 0; }
+#line 1687 "compilers/imcc/imcc.y"
+    { (yyval.t) = 0; ;}
     break;
 
   case 125:
-#line 1674 "compilers/imcc/imcc.y"
-    { (yyval.t) = (yyvsp[(1) - (2)].t) | (yyvsp[(2) - (2)].t); }
+#line 1688 "compilers/imcc/imcc.y"
+    { (yyval.t) = (yyvsp[(1) - (2)].t) | (yyvsp[(2) - (2)].t); ;}
     break;
 
   case 126:
-#line 1678 "compilers/imcc/imcc.y"
-    { (yyval.t) = VT_FLAT;   }
+#line 1692 "compilers/imcc/imcc.y"
+    { (yyval.t) = VT_FLAT;   ;}
     break;
 
   case 127:
-#line 1679 "compilers/imcc/imcc.y"
-    { (yyval.t) = VT_OPTIONAL; }
+#line 1693 "compilers/imcc/imcc.y"
+    { (yyval.t) = VT_OPTIONAL; ;}
     break;
 
   case 128:
-#line 1680 "compilers/imcc/imcc.y"
-    { (yyval.t) = VT_OPT_FLAG; }
+#line 1694 "compilers/imcc/imcc.y"
+    { (yyval.t) = VT_OPT_FLAG; ;}
     break;
 
   case 129:
-#line 1681 "compilers/imcc/imcc.y"
-    { (yyval.t) = VT_NAMED; }
+#line 1695 "compilers/imcc/imcc.y"
+    { (yyval.t) = VT_NAMED; ;}
     break;
 
   case 130:
-#line 1682 "compilers/imcc/imcc.y"
-    { adv_named_set(interp, (yyvsp[(3) - (4)].s));   (yyval.t) = 0; mem_sys_free((yyvsp[(3) - (4)].s)); }
+#line 1696 "compilers/imcc/imcc.y"
+    { adv_named_set(interp, (yyvsp[(3) - (4)].s));   (yyval.t) = 0; mem_sys_free((yyvsp[(3) - (4)].s)); ;}
     break;
 
   case 131:
-#line 1683 "compilers/imcc/imcc.y"
-    { adv_named_set_u(interp, (yyvsp[(3) - (4)].s)); (yyval.t) = 0; mem_sys_free((yyvsp[(3) - (4)].s)); }
+#line 1697 "compilers/imcc/imcc.y"
+    { adv_named_set_u(interp, (yyvsp[(3) - (4)].s)); (yyval.t) = 0; mem_sys_free((yyvsp[(3) - (4)].s)); ;}
     break;
 
   case 132:
-#line 1684 "compilers/imcc/imcc.y"
-    { (yyval.t) = VT_UNIQUE_REG; }
+#line 1698 "compilers/imcc/imcc.y"
+    { (yyval.t) = VT_UNIQUE_REG; ;}
     break;
 
   case 133:
-#line 1689 "compilers/imcc/imcc.y"
-    { begin_return_or_yield(interp, 0); }
+#line 1703 "compilers/imcc/imcc.y"
+    { begin_return_or_yield(interp, 0); ;}
     break;
 
   case 134:
-#line 1691 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; IMCC_INFO(interp)->asm_state = AsmDefault; }
+#line 1705 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; IMCC_INFO(interp)->asm_state = AsmDefault; ;}
     break;
 
   case 135:
-#line 1693 "compilers/imcc/imcc.y"
+#line 1707 "compilers/imcc/imcc.y"
     {
            IMCC_INFO(interp)->asm_state = AsmDefault;
            (yyval.i) = 0;
-         }
+         ;}
     break;
 
   case 136:
-#line 1700 "compilers/imcc/imcc.y"
-    { begin_return_or_yield(interp, 1); }
+#line 1714 "compilers/imcc/imcc.y"
+    { begin_return_or_yield(interp, 1); ;}
     break;
 
   case 137:
-#line 1702 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; IMCC_INFO(interp)->asm_state = AsmDefault; }
+#line 1716 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; IMCC_INFO(interp)->asm_state = AsmDefault; ;}
     break;
 
   case 138:
-#line 1706 "compilers/imcc/imcc.y"
-    { (yyval.sr) = 0; }
+#line 1720 "compilers/imcc/imcc.y"
+    { (yyval.sr) = 0; ;}
     break;
 
   case 139:
-#line 1708 "compilers/imcc/imcc.y"
+#line 1722 "compilers/imcc/imcc.y"
     {
            if ((yyvsp[(1) - (2)].sr))
                add_pcc_result(IMCC_INFO(interp)->sr_return, (yyvsp[(1) - (2)].sr));
-         }
+         ;}
     break;
 
   case 140:
-#line 1713 "compilers/imcc/imcc.y"
+#line 1727 "compilers/imcc/imcc.y"
     {
            if ((yyvsp[(2) - (3)].sr))
                add_pcc_result(IMCC_INFO(interp)->sr_return, (yyvsp[(2) - (3)].sr));
-         }
+         ;}
     break;
 
   case 141:
-#line 1720 "compilers/imcc/imcc.y"
-    { (yyval.sr) = 0; }
+#line 1734 "compilers/imcc/imcc.y"
+    { (yyval.sr) = 0; ;}
     break;
 
   case 142:
-#line 1722 "compilers/imcc/imcc.y"
+#line 1736 "compilers/imcc/imcc.y"
     {
            if ((yyvsp[(1) - (2)].sr))
                add_pcc_result(IMCC_INFO(interp)->sr_return, (yyvsp[(1) - (2)].sr));
-         }
+         ;}
     break;
 
   case 143:
-#line 1727 "compilers/imcc/imcc.y"
+#line 1741 "compilers/imcc/imcc.y"
     {
            if ((yyvsp[(2) - (3)].sr))
                add_pcc_result(IMCC_INFO(interp)->sr_return, (yyvsp[(2) - (3)].sr));
-         }
+         ;}
     break;
 
   case 144:
-#line 1734 "compilers/imcc/imcc.y"
-    { (yyval.sr) = (yyvsp[(2) - (3)].sr); (yyval.sr)->type |= (yyvsp[(3) - (3)].t); }
+#line 1748 "compilers/imcc/imcc.y"
+    { (yyval.sr) = (yyvsp[(2) - (3)].sr); (yyval.sr)->type |= (yyvsp[(3) - (3)].t); ;}
     break;
 
   case 145:
-#line 1738 "compilers/imcc/imcc.y"
-    { (yyval.sr) = (yyvsp[(2) - (3)].sr); (yyval.sr)->type |= (yyvsp[(3) - (3)].t); }
+#line 1752 "compilers/imcc/imcc.y"
+    { (yyval.sr) = (yyvsp[(2) - (3)].sr); (yyval.sr)->type |= (yyvsp[(3) - (3)].t); ;}
     break;
 
   case 146:
-#line 1743 "compilers/imcc/imcc.y"
+#line 1757 "compilers/imcc/imcc.y"
     {
           if (IMCC_INFO(interp)->asm_state == AsmDefault)
               begin_return_or_yield(interp, (yyvsp[(1) - (2)].t));
-        }
+        ;}
     break;
 
   case 147:
-#line 1748 "compilers/imcc/imcc.y"
+#line 1762 "compilers/imcc/imcc.y"
     {
           IMCC_INFO(interp)->asm_state = AsmDefault;
           (yyval.t) = 0;
-        }
+        ;}
     break;
 
   case 148:
-#line 1755 "compilers/imcc/imcc.y"
-    { (yyval.t) = 0; }
+#line 1769 "compilers/imcc/imcc.y"
+    { (yyval.t) = 0; ;}
     break;
 
   case 149:
-#line 1756 "compilers/imcc/imcc.y"
-    { (yyval.t) = 1; }
+#line 1770 "compilers/imcc/imcc.y"
+    { (yyval.t) = 1; ;}
     break;
 
   case 150:
-#line 1760 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; }
+#line 1774 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; ;}
     break;
 
   case 151:
-#line 1762 "compilers/imcc/imcc.y"
+#line 1776 "compilers/imcc/imcc.y"
     {
            if (IMCC_INFO(interp)->adv_named_id) {
-               add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return,
+               add_pcc_named_return(IMCC_INFO(interp)->sr_return,
                                     IMCC_INFO(interp)->adv_named_id, (yyvsp[(1) - (1)].sr));
                IMCC_INFO(interp)->adv_named_id = NULL;
            }
            else
                add_pcc_result(IMCC_INFO(interp)->sr_return, (yyvsp[(1) - (1)].sr));
-         }
+         ;}
     break;
 
   case 152:
-#line 1772 "compilers/imcc/imcc.y"
+#line 1786 "compilers/imcc/imcc.y"
     {
-            SymReg *name = mk_const(interp, (yyvsp[(1) - (3)].s), 'S');
-            add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return, name, (yyvsp[(3) - (3)].sr));
-         }
+            SymReg * const name = mk_const(interp, (yyvsp[(1) - (3)].s), 'S');
+            add_pcc_named_return(IMCC_INFO(interp)->sr_return, name, (yyvsp[(3) - (3)].sr));
+         ;}
     break;
 
   case 153:
-#line 1777 "compilers/imcc/imcc.y"
+#line 1791 "compilers/imcc/imcc.y"
     {
            if (IMCC_INFO(interp)->adv_named_id) {
-               add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return,
+               add_pcc_named_return(IMCC_INFO(interp)->sr_return,
                                     IMCC_INFO(interp)->adv_named_id, (yyvsp[(3) - (3)].sr));
                IMCC_INFO(interp)->adv_named_id = NULL;
              }
              else
                  add_pcc_result(IMCC_INFO(interp)->sr_return, (yyvsp[(3) - (3)].sr));
-         }
+         ;}
     break;
 
   case 154:
-#line 1787 "compilers/imcc/imcc.y"
+#line 1801 "compilers/imcc/imcc.y"
     {
-           SymReg *name = mk_const(interp, (yyvsp[(3) - (5)].s), 'S');
-           add_pcc_named_return(interp, IMCC_INFO(interp)->sr_return, name, (yyvsp[(5) - (5)].sr));
-         }
+           SymReg * const name = mk_const(interp, (yyvsp[(3) - (5)].s), 'S');
+           add_pcc_named_return(IMCC_INFO(interp)->sr_return, name, (yyvsp[(5) - (5)].sr));
+         ;}
     break;
 
   case 157:
-#line 1808 "compilers/imcc/imcc.y"
-    { clear_state(interp); }
+#line 1822 "compilers/imcc/imcc.y"
+    { clear_state(interp); ;}
     break;
 
   case 158:
-#line 1813 "compilers/imcc/imcc.y"
-    { (yyval.i) = (yyvsp[(2) - (2)].i); }
+#line 1827 "compilers/imcc/imcc.y"
+    { (yyval.i) = (yyvsp[(2) - (2)].i); ;}
     break;
 
   case 159:
-#line 1814 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; }
+#line 1828 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; ;}
     break;
 
   case 160:
-#line 1815 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; }
+#line 1829 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; ;}
     break;
 
   case 161:
-#line 1816 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; }
+#line 1830 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; ;}
     break;
 
   case 162:
-#line 1817 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; }
+#line 1831 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; ;}
     break;
 
   case 163:
-#line 1818 "compilers/imcc/imcc.y"
-    { (yyval.i) = (yyvsp[(1) - (1)].i); }
+#line 1832 "compilers/imcc/imcc.y"
+    { (yyval.i) = (yyvsp[(1) - (1)].i); ;}
     break;
 
   case 164:
-#line 1822 "compilers/imcc/imcc.y"
-    { (yyval.i) = NULL; }
+#line 1836 "compilers/imcc/imcc.y"
+    { (yyval.i) = NULL; ;}
     break;
 
   case 168:
-#line 1833 "compilers/imcc/imcc.y"
+#line 1847 "compilers/imcc/imcc.y"
     {
-             Instruction *i = iLABEL(interp, IMCC_INFO(interp)->cur_unit, mk_local_label(interp, (yyvsp[(1) - (1)].s)));
+             Instruction * const i = iLABEL(interp, IMCC_INFO(interp)->cur_unit, mk_local_label(interp, (yyvsp[(1) - (1)].s)));
              mem_sys_free((yyvsp[(1) - (1)].s));
              (yyval.i) = i;
-         }
+         ;}
     break;
 
   case 169:
-#line 1843 "compilers/imcc/imcc.y"
-    { (yyval.i) = (yyvsp[(2) - (3)].i); }
+#line 1857 "compilers/imcc/imcc.y"
+    { (yyval.i) = (yyvsp[(2) - (3)].i); ;}
     break;
 
   case 170:
-#line 1845 "compilers/imcc/imcc.y"
+#line 1859 "compilers/imcc/imcc.y"
     {
            if (yynerrs >= PARROT_MAX_RECOVER_ERRORS) {
                IMCC_warning(interp, "Too many errors. Correct some first.\n");
                YYABORT;
            }
            yyerrok;
-         }
+         ;}
     break;
 
   case 171:
-#line 1856 "compilers/imcc/imcc.y"
+#line 1870 "compilers/imcc/imcc.y"
     {
-           IdList* l = (yyvsp[(1) - (1)].idlist);
+           IdList* const l = (yyvsp[(1) - (1)].idlist);
            l->next = NULL;
            (yyval.idlist) = l;
-         }
+         ;}
     break;
 
   case 172:
-#line 1863 "compilers/imcc/imcc.y"
+#line 1877 "compilers/imcc/imcc.y"
     {
-           IdList* l = (yyvsp[(3) - (3)].idlist);
+           IdList* const l = (yyvsp[(3) - (3)].idlist);
            l->next = (yyvsp[(1) - (3)].idlist);
            (yyval.idlist) = l;
-         }
+         ;}
     break;
 
   case 173:
-#line 1872 "compilers/imcc/imcc.y"
+#line 1886 "compilers/imcc/imcc.y"
     {
            IdList* const l = mem_allocate_n_zeroed_typed(1, IdList);
            l->id           = (yyvsp[(1) - (2)].s);
            l->unique_reg   = (yyvsp[(2) - (2)].t);
            (yyval.idlist) = l;
-         }
+         ;}
     break;
 
   case 174:
-#line 1881 "compilers/imcc/imcc.y"
-    { (yyval.t) = 0; }
+#line 1895 "compilers/imcc/imcc.y"
+    { (yyval.t) = 0; ;}
     break;
 
   case 175:
-#line 1882 "compilers/imcc/imcc.y"
-    { (yyval.t) = 1; }
+#line 1896 "compilers/imcc/imcc.y"
+    { (yyval.t) = 1; ;}
     break;
 
   case 178:
-#line 1889 "compilers/imcc/imcc.y"
-    { pesky_global__is_def=1; }
+#line 1903 "compilers/imcc/imcc.y"
+    { pesky_global__is_def=1; ;}
     break;
 
   case 179:
-#line 1890 "compilers/imcc/imcc.y"
+#line 1904 "compilers/imcc/imcc.y"
     {
            IdList *l = (yyvsp[(4) - (4)].idlist);
            while (l) {
@@ -4269,73 +4283,73 @@
                mem_sys_free(l1);
            }
            pesky_global__is_def=0; (yyval.i)=0;
-         }
+         ;}
     break;
 
   case 180:
-#line 1906 "compilers/imcc/imcc.y"
+#line 1920 "compilers/imcc/imcc.y"
     {
-           SymReg *n = mk_const(interp, (yyvsp[(2) - (4)].s), 'S');
+           SymReg * const n = mk_const(interp, (yyvsp[(2) - (4)].s), 'S');
            set_lexical(interp, (yyvsp[(4) - (4)].sr), n); (yyval.i) = 0;
            mem_sys_free((yyvsp[(2) - (4)].s));
-         }
+         ;}
     break;
 
   case 181:
-#line 1912 "compilers/imcc/imcc.y"
+#line 1926 "compilers/imcc/imcc.y"
     {
-           SymReg *n = mk_const(interp, (yyvsp[(2) - (4)].s), 'U');
+           SymReg * const n = mk_const(interp, (yyvsp[(2) - (4)].s), 'U');
            set_lexical(interp, (yyvsp[(4) - (4)].sr), n); (yyval.i) = 0;
            mem_sys_free((yyvsp[(2) - (4)].s));
-         }
+         ;}
     break;
 
   case 182:
-#line 1917 "compilers/imcc/imcc.y"
-    { pesky_global__is_def=1; }
+#line 1931 "compilers/imcc/imcc.y"
+    { pesky_global__is_def=1; ;}
     break;
 
   case 183:
-#line 1918 "compilers/imcc/imcc.y"
+#line 1932 "compilers/imcc/imcc.y"
     {
            mk_const_ident(interp, (yyvsp[(4) - (6)].s), (yyvsp[(3) - (6)].t), (yyvsp[(6) - (6)].sr), 0);
            pesky_global__is_def=0;
            mem_sys_free((yyvsp[(4) - (6)].s));
-         }
+         ;}
     break;
 
   case 185:
-#line 1925 "compilers/imcc/imcc.y"
-    { pesky_global__is_def=1; }
+#line 1939 "compilers/imcc/imcc.y"
+    { pesky_global__is_def=1; ;}
     break;
 
   case 186:
-#line 1926 "compilers/imcc/imcc.y"
+#line 1940 "compilers/imcc/imcc.y"
     {
            mk_const_ident(interp, (yyvsp[(4) - (6)].s), (yyvsp[(3) - (6)].t), (yyvsp[(6) - (6)].sr), 1);
            pesky_global__is_def=0;
            mem_sys_free((yyvsp[(4) - (6)].s));
-         }
+         ;}
     break;
 
   case 187:
-#line 1932 "compilers/imcc/imcc.y"
+#line 1946 "compilers/imcc/imcc.y"
     {
            (yyval.i) = NULL;
            IMCC_INFO(interp)->cur_call->pcc_sub->flags |= isTAIL_CALL;
            IMCC_INFO(interp)->cur_call = NULL;
-         }
+         ;}
     break;
 
   case 188:
-#line 1938 "compilers/imcc/imcc.y"
+#line 1952 "compilers/imcc/imcc.y"
     {
             (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "branch", 1, (yyvsp[(2) - (2)].sr));
-         }
+         ;}
     break;
 
   case 189:
-#line 1942 "compilers/imcc/imcc.y"
+#line 1956 "compilers/imcc/imcc.y"
     {
            (yyval.i) = INS(interp,
                     IMCC_INFO(interp)->cur_unit,
@@ -4346,379 +4360,379 @@
                     IMCC_INFO(interp)->keyvec,
                     1);
            mem_sys_free((yyvsp[(1) - (2)].s));
-         }
+         ;}
     break;
 
   case 190:
-#line 1953 "compilers/imcc/imcc.y"
-    { (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "null", 1, (yyvsp[(2) - (2)].sr)); }
+#line 1967 "compilers/imcc/imcc.y"
+    { (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "null", 1, (yyvsp[(2) - (2)].sr)); ;}
     break;
 
   case 191:
-#line 1954 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; IMCC_INFO(interp)->cur_call = NULL; }
+#line 1968 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; IMCC_INFO(interp)->cur_call = NULL; ;}
     break;
 
   case 192:
-#line 1955 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0; }
+#line 1969 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0; ;}
     break;
 
   case 195:
-#line 1958 "compilers/imcc/imcc.y"
-    { (yyval.i) = 0;}
+#line 1972 "compilers/imcc/imcc.y"
+    { (yyval.i) = 0;;}
     break;
 
   case 196:
-#line 1962 "compilers/imcc/imcc.y"
-    { (yyval.t) = 'I'; }
+#line 1976 "compilers/imcc/imcc.y"
+    { (yyval.t) = 'I'; ;}
     break;
 
   case 197:
-#line 1963 "compilers/imcc/imcc.y"
-    { (yyval.t) = 'N'; }
+#line 1977 "compilers/imcc/imcc.y"
+    { (yyval.t) = 'N'; ;}
     break;
 
   case 198:
-#line 1964 "compilers/imcc/imcc.y"
-    { (yyval.t) = 'S'; }
+#line 1978 "compilers/imcc/imcc.y"
+    { (yyval.t) = 'S'; ;}
     break;
 
   case 199:
-#line 1965 "compilers/imcc/imcc.y"
-    { (yyval.t) = 'P'; }
+#line 1979 "compilers/imcc/imcc.y"
+    { (yyval.t) = 'P'; ;}
     break;
 
   case 200:
-#line 1970 "compilers/imcc/imcc.y"
+#line 1984 "compilers/imcc/imcc.y"
     {
-           /* there'd normally be a str_dup() here, but the lexer already
+           /* there'd normally be a mem_sys_strdup() here, but the lexer already
             * copied the string, so it's safe to use directly */
            if ((IMCC_INFO(interp)->cur_pmc_type = pmc_type(interp,
                Parrot_str_new(interp, (yyvsp[(1) - (1)].s), 0))) <= 0) {
                IMCC_fataly(interp, EXCEPTION_SYNTAX_ERROR,
                     "Unknown PMC type '%s'\n", (yyvsp[(1) - (1)].s));
            }
-         }
+         ;}
     break;
 
   case 201:
-#line 1983 "compilers/imcc/imcc.y"
-    { (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "set", 2, (yyvsp[(1) - (3)].sr), (yyvsp[(3) - (3)].sr));  }
+#line 1997 "compilers/imcc/imcc.y"
+    { (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "set", 2, (yyvsp[(1) - (3)].sr), (yyvsp[(3) - (3)].sr));  ;}
     break;
 
   case 202:
-#line 1985 "compilers/imcc/imcc.y"
-    { (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(3) - (4)].s), 2, (yyvsp[(1) - (4)].sr), (yyvsp[(4) - (4)].sr));  }
+#line 1999 "compilers/imcc/imcc.y"
+    { (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(3) - (4)].s), 2, (yyvsp[(1) - (4)].sr), (yyvsp[(4) - (4)].sr));  ;}
     break;
 
   case 203:
-#line 1987 "compilers/imcc/imcc.y"
-    { (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(4) - (5)].s), 3, (yyvsp[(1) - (5)].sr), (yyvsp[(3) - (5)].sr), (yyvsp[(5) - (5)].sr));  }
+#line 2001 "compilers/imcc/imcc.y"
+    { (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(4) - (5)].s), 3, (yyvsp[(1) - (5)].sr), (yyvsp[(3) - (5)].sr), (yyvsp[(5) - (5)].sr));  ;}
     break;
 
   case 204:
-#line 1989 "compilers/imcc/imcc.y"
-    { (yyval.i) = iINDEXFETCH(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(1) - (6)].sr), (yyvsp[(3) - (6)].sr), (yyvsp[(5) - (6)].sr)); }
+#line 2003 "compilers/imcc/imcc.y"
+    { (yyval.i) = iINDEXFETCH(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(1) - (6)].sr), (yyvsp[(3) - (6)].sr), (yyvsp[(5) - (6)].sr)); ;}
     break;
 
   case 205:
-#line 1991 "compilers/imcc/imcc.y"
-    { (yyval.i) = iINDEXSET(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(1) - (6)].sr), (yyvsp[(3) - (6)].sr), (yyvsp[(6) - (6)].sr)); }
+#line 2005 "compilers/imcc/imcc.y"
+    { (yyval.i) = iINDEXSET(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(1) - (6)].sr), (yyvsp[(3) - (6)].sr), (yyvsp[(6) - (6)].sr)); ;}
     break;
 
   case 206:
-#line 1996 "compilers/imcc/imcc.y"
-    { (yyval.i) = iNEW(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(1) - (7)].sr), (yyvsp[(4) - (7)].s), (yyvsp[(6) - (7)].sr), 1); }
+#line 2010 "compilers/imcc/imcc.y"
+    { (yyval.i) = iNEW(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(1) - (7)].sr), (yyvsp[(4) - (7)].s), (yyvsp[(6) - (7)].sr), 1); ;}
     break;
 
   case 207:
-#line 1999 "compilers/imcc/imcc.y"
+#line 2013 "compilers/imcc/imcc.y"
     {
            add_pcc_result((yyvsp[(3) - (3)].i)->symregs[0], (yyvsp[(1) - (3)].sr));
            IMCC_INFO(interp)->cur_call = NULL;
            (yyval.i) = 0;
-         }
+         ;}
     break;
 
   case 208:
-#line 2005 "compilers/imcc/imcc.y"
+#line 2019 "compilers/imcc/imcc.y"
     {
            (yyval.i) = IMCC_create_itcall_label(interp);
-         }
+         ;}
     break;
 
   case 209:
-#line 2009 "compilers/imcc/imcc.y"
+#line 2023 "compilers/imcc/imcc.y"
     {
            IMCC_itcall_sub(interp, (yyvsp[(6) - (9)].sr));
            IMCC_INFO(interp)->cur_call = NULL;
-         }
+         ;}
     break;
 
   case 213:
-#line 2017 "compilers/imcc/imcc.y"
+#line 2031 "compilers/imcc/imcc.y"
     {
            (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "null", 1, (yyvsp[(1) - (3)].sr));
-         }
+         ;}
     break;
 
   case 214:
-#line 2024 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"not"; }
+#line 2038 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"not"; ;}
     break;
 
   case 215:
-#line 2025 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"bnot"; }
+#line 2039 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"bnot"; ;}
     break;
 
   case 216:
-#line 2026 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"neg"; }
+#line 2040 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"neg"; ;}
     break;
 
   case 217:
-#line 2030 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"sub"; }
+#line 2044 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"sub"; ;}
     break;
 
   case 218:
-#line 2031 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"add"; }
+#line 2045 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"add"; ;}
     break;
 
   case 219:
-#line 2032 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"mul"; }
+#line 2046 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"mul"; ;}
     break;
 
   case 220:
-#line 2033 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"div"; }
+#line 2047 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"div"; ;}
     break;
 
   case 221:
-#line 2034 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"mod"; }
+#line 2048 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"mod"; ;}
     break;
 
   case 222:
-#line 2035 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"fdiv"; }
+#line 2049 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"fdiv"; ;}
     break;
 
   case 223:
-#line 2036 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"pow"; }
+#line 2050 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"pow"; ;}
     break;
 
   case 224:
-#line 2037 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"concat"; }
+#line 2051 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"concat"; ;}
     break;
 
   case 225:
-#line 2038 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"iseq"; }
+#line 2052 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"iseq"; ;}
     break;
 
   case 226:
-#line 2039 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"isne"; }
+#line 2053 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"isne"; ;}
     break;
 
   case 227:
-#line 2040 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"isgt"; }
+#line 2054 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"isgt"; ;}
     break;
 
   case 228:
-#line 2041 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"isge"; }
+#line 2055 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"isge"; ;}
     break;
 
   case 229:
-#line 2042 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"islt"; }
+#line 2056 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"islt"; ;}
     break;
 
   case 230:
-#line 2043 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"isle"; }
+#line 2057 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"isle"; ;}
     break;
 
   case 231:
-#line 2044 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"shl"; }
+#line 2058 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"shl"; ;}
     break;
 
   case 232:
-#line 2045 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"shr"; }
+#line 2059 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"shr"; ;}
     break;
 
   case 233:
-#line 2046 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"lsr"; }
+#line 2060 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"lsr"; ;}
     break;
 
   case 234:
-#line 2047 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"and"; }
+#line 2061 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"and"; ;}
     break;
 
   case 235:
-#line 2048 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"or"; }
+#line 2062 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"or"; ;}
     break;
 
   case 236:
-#line 2049 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"xor"; }
+#line 2063 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"xor"; ;}
     break;
 
   case 237:
-#line 2050 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"band"; }
+#line 2064 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"band"; ;}
     break;
 
   case 238:
-#line 2051 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"bor"; }
+#line 2065 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"bor"; ;}
     break;
 
   case 239:
-#line 2052 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"bxor"; }
+#line 2066 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"bxor"; ;}
     break;
 
   case 240:
-#line 2058 "compilers/imcc/imcc.y"
+#line 2072 "compilers/imcc/imcc.y"
     {
            (yyval.i) = IMCC_create_itcall_label(interp);
            (yyval.i)->type &= ~ITCALL;
            (yyval.i)->type |= ITRESULT;
-         }
+         ;}
     break;
 
   case 241:
-#line 2063 "compilers/imcc/imcc.y"
-    {  (yyval.i) = 0; }
+#line 2077 "compilers/imcc/imcc.y"
+    {  (yyval.i) = 0; ;}
     break;
 
   case 242:
-#line 2070 "compilers/imcc/imcc.y"
+#line 2084 "compilers/imcc/imcc.y"
     {
            (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(2) - (3)].s), 2, (yyvsp[(1) - (3)].sr), (yyvsp[(3) - (3)].sr));
-         }
+         ;}
     break;
 
   case 243:
-#line 2076 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"add"; }
+#line 2090 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"add"; ;}
     break;
 
   case 244:
-#line 2077 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"sub"; }
+#line 2091 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"sub"; ;}
     break;
 
   case 245:
-#line 2078 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"mul"; }
+#line 2092 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"mul"; ;}
     break;
 
   case 246:
-#line 2079 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"div"; }
+#line 2093 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"div"; ;}
     break;
 
   case 247:
-#line 2080 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"mod"; }
+#line 2094 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"mod"; ;}
     break;
 
   case 248:
-#line 2081 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"fdiv"; }
+#line 2095 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"fdiv"; ;}
     break;
 
   case 249:
-#line 2082 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"concat"; }
+#line 2096 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"concat"; ;}
     break;
 
   case 250:
-#line 2083 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"band"; }
+#line 2097 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"band"; ;}
     break;
 
   case 251:
-#line 2084 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"bor"; }
+#line 2098 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"bor"; ;}
     break;
 
   case 252:
-#line 2085 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"bxor"; }
+#line 2099 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"bxor"; ;}
     break;
 
   case 253:
-#line 2086 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"shr"; }
+#line 2100 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"shr"; ;}
     break;
 
   case 254:
-#line 2087 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"shl"; }
+#line 2101 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"shl"; ;}
     break;
 
   case 255:
-#line 2088 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"lsr"; }
+#line 2102 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"lsr"; ;}
     break;
 
   case 256:
-#line 2094 "compilers/imcc/imcc.y"
+#line 2108 "compilers/imcc/imcc.y"
     {
         (yyval.i) = func_ins(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(1) - (4)].sr), (yyvsp[(3) - (4)].s),
                       IMCC_INFO(interp) -> regs,
                       IMCC_INFO(interp) -> nargs,
                       IMCC_INFO(interp) -> keyvec, 1);
          mem_sys_free((yyvsp[(3) - (4)].s));
-       }
+       ;}
     break;
 
   case 257:
-#line 2104 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_sub_address(interp, (yyvsp[(1) - (1)].s));       mem_sys_free((yyvsp[(1) - (1)].s)); }
+#line 2118 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_sub_address(interp, (yyvsp[(1) - (1)].s));       mem_sys_free((yyvsp[(1) - (1)].s)); ;}
     break;
 
   case 258:
-#line 2105 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_sub_address_fromc(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); }
+#line 2119 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_sub_address_fromc(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); ;}
     break;
 
   case 259:
-#line 2106 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_sub_address_u(interp, (yyvsp[(1) - (1)].s));     mem_sys_free((yyvsp[(1) - (1)].s)); }
+#line 2120 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_sub_address_u(interp, (yyvsp[(1) - (1)].s));     mem_sys_free((yyvsp[(1) - (1)].s)); ;}
     break;
 
   case 260:
-#line 2108 "compilers/imcc/imcc.y"
+#line 2122 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = (yyvsp[(1) - (1)].sr);
            if ((yyvsp[(1) - (1)].sr)->set != 'P')
                IMCC_fataly(interp, EXCEPTION_SYNTAX_ERROR, "Sub isn't a PMC");
-         }
+         ;}
     break;
 
   case 261:
-#line 2114 "compilers/imcc/imcc.y"
+#line 2128 "compilers/imcc/imcc.y"
     {
             /* disallow bareword method names; SREG name constants are fine */
-            char *name = (yyvsp[(3) - (3)].sr)->name;
+            const char * const name = (yyvsp[(3) - (3)].sr)->name;
             if (!((yyvsp[(3) - (3)].sr)->type & VTREG)) {
                 if (*name != '\'' || *name != '\"')
                     IMCC_fataly(interp, EXCEPTION_SYNTAX_ERROR,
@@ -4728,456 +4742,456 @@
 
             IMCC_INFO(interp)->cur_obj = (yyvsp[(1) - (3)].sr);
             (yyval.sr)                         = (yyvsp[(3) - (3)].sr);
-        }
+        ;}
     break;
 
   case 262:
-#line 2128 "compilers/imcc/imcc.y"
+#line 2142 "compilers/imcc/imcc.y"
     {
             IMCC_INFO(interp)->cur_obj = (yyvsp[(1) - (3)].sr);
             (yyval.sr)                         = mk_const(interp, (yyvsp[(3) - (3)].s), 'U');
             mem_sys_free((yyvsp[(3) - (3)].s));
-         }
+         ;}
     break;
 
   case 263:
-#line 2134 "compilers/imcc/imcc.y"
+#line 2148 "compilers/imcc/imcc.y"
     {
             IMCC_INFO(interp)->cur_obj = (yyvsp[(1) - (3)].sr);
             (yyval.sr)                         = mk_const(interp, (yyvsp[(3) - (3)].s), 'S');
             mem_sys_free((yyvsp[(3) - (3)].s));
-         }
+         ;}
     break;
 
   case 264:
-#line 2139 "compilers/imcc/imcc.y"
-    { IMCC_INFO(interp)->cur_obj = (yyvsp[(1) - (3)].sr); (yyval.sr) = (yyvsp[(3) - (3)].sr); }
+#line 2153 "compilers/imcc/imcc.y"
+    { IMCC_INFO(interp)->cur_obj = (yyvsp[(1) - (3)].sr); (yyval.sr) = (yyvsp[(3) - (3)].sr); ;}
     break;
 
   case 265:
-#line 2145 "compilers/imcc/imcc.y"
+#line 2159 "compilers/imcc/imcc.y"
     {
            (yyval.i) = IMCC_create_itcall_label(interp);
            IMCC_itcall_sub(interp, (yyvsp[(1) - (1)].sr));
-         }
+         ;}
     break;
 
   case 266:
-#line 2149 "compilers/imcc/imcc.y"
-    { (yyval.i) = (yyvsp[(2) - (5)].i); }
+#line 2163 "compilers/imcc/imcc.y"
+    { (yyval.i) = (yyvsp[(2) - (5)].i); ;}
     break;
 
   case 267:
-#line 2153 "compilers/imcc/imcc.y"
-    { (yyval.sr) = 0; }
+#line 2167 "compilers/imcc/imcc.y"
+    { (yyval.sr) = 0; ;}
     break;
 
   case 268:
-#line 2155 "compilers/imcc/imcc.y"
+#line 2169 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = 0;
            if (IMCC_INFO(interp)->adv_named_id) {
-               add_pcc_named_arg(interp, IMCC_INFO(interp)->cur_call, IMCC_INFO(interp)->adv_named_id, (yyvsp[(3) - (3)].sr));
+               add_pcc_named_arg(IMCC_INFO(interp)->cur_call, IMCC_INFO(interp)->adv_named_id, (yyvsp[(3) - (3)].sr));
                IMCC_INFO(interp)->adv_named_id = NULL;
            }
            else
                add_pcc_arg(IMCC_INFO(interp)->cur_call, (yyvsp[(3) - (3)].sr));
-         }
+         ;}
     break;
 
   case 269:
-#line 2165 "compilers/imcc/imcc.y"
+#line 2179 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = 0;
            if (IMCC_INFO(interp)->adv_named_id) {
-               add_pcc_named_arg(interp, IMCC_INFO(interp)->cur_call, IMCC_INFO(interp)->adv_named_id, (yyvsp[(1) - (1)].sr));
+               add_pcc_named_arg(IMCC_INFO(interp)->cur_call, IMCC_INFO(interp)->adv_named_id, (yyvsp[(1) - (1)].sr));
                IMCC_INFO(interp)->adv_named_id = NULL;
            }
            else
                add_pcc_arg(IMCC_INFO(interp)->cur_call, (yyvsp[(1) - (1)].sr));
-         }
+         ;}
     break;
 
   case 270:
-#line 2175 "compilers/imcc/imcc.y"
+#line 2189 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = 0;
-           add_pcc_named_arg(interp, IMCC_INFO(interp)->cur_call,
+           add_pcc_named_arg(IMCC_INFO(interp)->cur_call,
                 mk_const(interp, (yyvsp[(3) - (5)].s), 'S'), (yyvsp[(5) - (5)].sr));
            mem_sys_free((yyvsp[(3) - (5)].s));
-         }
+         ;}
     break;
 
   case 271:
-#line 2182 "compilers/imcc/imcc.y"
+#line 2196 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = 0;
-           add_pcc_named_arg_var(interp, IMCC_INFO(interp)->cur_call, (yyvsp[(1) - (3)].sr), (yyvsp[(3) - (3)].sr));
-         }
+           add_pcc_named_arg_var(IMCC_INFO(interp)->cur_call, (yyvsp[(1) - (3)].sr), (yyvsp[(3) - (3)].sr));
+         ;}
     break;
 
   case 272:
-#line 2187 "compilers/imcc/imcc.y"
+#line 2201 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = 0;
-           add_pcc_named_arg(interp, IMCC_INFO(interp)->cur_call,
+           add_pcc_named_arg(IMCC_INFO(interp)->cur_call,
                 mk_const(interp, (yyvsp[(1) - (3)].s), 'S'), (yyvsp[(3) - (3)].sr));
            mem_sys_free((yyvsp[(1) - (3)].s));
-         }
+         ;}
     break;
 
   case 273:
-#line 2196 "compilers/imcc/imcc.y"
-    { (yyval.sr) = (yyvsp[(1) - (2)].sr); (yyval.sr)->type |= (yyvsp[(2) - (2)].t); }
+#line 2210 "compilers/imcc/imcc.y"
+    { (yyval.sr) = (yyvsp[(1) - (2)].sr); (yyval.sr)->type |= (yyvsp[(2) - (2)].t); ;}
     break;
 
   case 274:
-#line 2200 "compilers/imcc/imcc.y"
-    { (yyval.t) = 0; }
+#line 2214 "compilers/imcc/imcc.y"
+    { (yyval.t) = 0; ;}
     break;
 
   case 275:
-#line 2201 "compilers/imcc/imcc.y"
-    { (yyval.t) = (yyvsp[(1) - (2)].t) | (yyvsp[(2) - (2)].t); }
+#line 2215 "compilers/imcc/imcc.y"
+    { (yyval.t) = (yyvsp[(1) - (2)].t) | (yyvsp[(2) - (2)].t); ;}
     break;
 
   case 276:
-#line 2205 "compilers/imcc/imcc.y"
-    { (yyval.t) = VT_FLAT; }
+#line 2219 "compilers/imcc/imcc.y"
+    { (yyval.t) = VT_FLAT; ;}
     break;
 
   case 277:
-#line 2206 "compilers/imcc/imcc.y"
-    { (yyval.t) = VT_NAMED; }
+#line 2220 "compilers/imcc/imcc.y"
+    { (yyval.t) = VT_NAMED; ;}
     break;
 
   case 278:
-#line 2209 "compilers/imcc/imcc.y"
-    { adv_named_set_u(interp, (yyvsp[(3) - (4)].s)); (yyval.t) = 0; }
+#line 2223 "compilers/imcc/imcc.y"
+    { adv_named_set_u(interp, (yyvsp[(3) - (4)].s)); (yyval.t) = 0; ;}
     break;
 
   case 279:
-#line 2210 "compilers/imcc/imcc.y"
-    { adv_named_set(interp, (yyvsp[(3) - (4)].s));   (yyval.t) = 0; }
+#line 2224 "compilers/imcc/imcc.y"
+    { adv_named_set(interp, (yyvsp[(3) - (4)].s));   (yyval.t) = 0; ;}
     break;
 
   case 280:
-#line 2214 "compilers/imcc/imcc.y"
-    { (yyval.sr) = (yyvsp[(1) - (2)].sr); (yyval.sr)->type |= (yyvsp[(2) - (2)].t); }
+#line 2228 "compilers/imcc/imcc.y"
+    { (yyval.sr) = (yyvsp[(1) - (2)].sr); (yyval.sr)->type |= (yyvsp[(2) - (2)].t); ;}
     break;
 
   case 281:
-#line 2219 "compilers/imcc/imcc.y"
+#line 2233 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = 0;
            if (IMCC_INFO(interp)->adv_named_id) {
-               add_pcc_named_result(interp, IMCC_INFO(interp)->cur_call, IMCC_INFO(interp)->adv_named_id, (yyvsp[(3) - (3)].sr));
+               add_pcc_named_result(IMCC_INFO(interp)->cur_call, IMCC_INFO(interp)->adv_named_id, (yyvsp[(3) - (3)].sr));
                IMCC_INFO(interp)->adv_named_id = NULL;
            }
            else
                add_pcc_result(IMCC_INFO(interp)->cur_call, (yyvsp[(3) - (3)].sr));
-         }
+         ;}
     break;
 
   case 282:
-#line 2229 "compilers/imcc/imcc.y"
+#line 2243 "compilers/imcc/imcc.y"
     {
-            add_pcc_named_result(interp, IMCC_INFO(interp)->cur_call,
+            add_pcc_named_result(IMCC_INFO(interp)->cur_call,
             mk_const(interp, (yyvsp[(3) - (5)].s), 'S'), (yyvsp[(5) - (5)].sr));
             mem_sys_free((yyvsp[(3) - (5)].s));
-         }
+         ;}
     break;
 
   case 283:
-#line 2235 "compilers/imcc/imcc.y"
+#line 2249 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = 0;
            if (IMCC_INFO(interp)->adv_named_id) {
-               add_pcc_named_result(interp, IMCC_INFO(interp)->cur_call, IMCC_INFO(interp)->adv_named_id, (yyvsp[(1) - (1)].sr));
+               add_pcc_named_result(IMCC_INFO(interp)->cur_call, IMCC_INFO(interp)->adv_named_id, (yyvsp[(1) - (1)].sr));
                IMCC_INFO(interp)->adv_named_id = NULL;
            }
            else
                add_pcc_result(IMCC_INFO(interp)->cur_call, (yyvsp[(1) - (1)].sr));
-         }
+         ;}
     break;
 
   case 284:
-#line 2245 "compilers/imcc/imcc.y"
+#line 2259 "compilers/imcc/imcc.y"
     {
-           add_pcc_named_result(interp, IMCC_INFO(interp)->cur_call, mk_const(interp, (yyvsp[(1) - (3)].s), 'S'), (yyvsp[(3) - (3)].sr));
+           add_pcc_named_result(IMCC_INFO(interp)->cur_call, mk_const(interp, (yyvsp[(1) - (3)].s), 'S'), (yyvsp[(3) - (3)].sr));
            mem_sys_free((yyvsp[(1) - (3)].s));
-         }
+         ;}
     break;
 
   case 285:
-#line 2249 "compilers/imcc/imcc.y"
-    { (yyval.sr) = 0; }
+#line 2263 "compilers/imcc/imcc.y"
+    { (yyval.sr) = 0; ;}
     break;
 
   case 286:
-#line 2253 "compilers/imcc/imcc.y"
-    { (yyval.i) = (yyvsp[(1) - (1)].i); }
+#line 2267 "compilers/imcc/imcc.y"
+    { (yyval.i) = (yyvsp[(1) - (1)].i); ;}
     break;
 
   case 287:
-#line 2254 "compilers/imcc/imcc.y"
-    { (yyval.i) = (yyvsp[(1) - (1)].i); }
+#line 2268 "compilers/imcc/imcc.y"
+    { (yyval.i) = (yyvsp[(1) - (1)].i); ;}
     break;
 
   case 288:
-#line 2259 "compilers/imcc/imcc.y"
+#line 2273 "compilers/imcc/imcc.y"
     {
            (yyval.i) =MK_I(interp, IMCC_INFO(interp)->cur_unit, inv_op((yyvsp[(3) - (6)].s)), 3, (yyvsp[(2) - (6)].sr), (yyvsp[(4) - (6)].sr), (yyvsp[(6) - (6)].sr));
-         }
+         ;}
     break;
 
   case 289:
-#line 2263 "compilers/imcc/imcc.y"
+#line 2277 "compilers/imcc/imcc.y"
     {
            (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "unless_null", 2, (yyvsp[(3) - (5)].sr), (yyvsp[(5) - (5)].sr));
-         }
+         ;}
     break;
 
   case 290:
-#line 2267 "compilers/imcc/imcc.y"
+#line 2281 "compilers/imcc/imcc.y"
     {
            (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "unless", 2, (yyvsp[(2) - (4)].sr), (yyvsp[(4) - (4)].sr));
-         }
+         ;}
     break;
 
   case 291:
-#line 2274 "compilers/imcc/imcc.y"
+#line 2288 "compilers/imcc/imcc.y"
     {
            (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "if", 2, (yyvsp[(2) - (4)].sr), (yyvsp[(4) - (4)].sr));
-         }
+         ;}
     break;
 
   case 292:
-#line 2278 "compilers/imcc/imcc.y"
+#line 2292 "compilers/imcc/imcc.y"
     {
            (yyval.i) =MK_I(interp, IMCC_INFO(interp)->cur_unit, (yyvsp[(3) - (6)].s), 3, (yyvsp[(2) - (6)].sr), (yyvsp[(4) - (6)].sr), (yyvsp[(6) - (6)].sr));
-         }
+         ;}
     break;
 
   case 293:
-#line 2282 "compilers/imcc/imcc.y"
+#line 2296 "compilers/imcc/imcc.y"
     {
            (yyval.i) = MK_I(interp, IMCC_INFO(interp)->cur_unit, "if_null", 2, (yyvsp[(3) - (5)].sr), (yyvsp[(5) - (5)].sr));
-         }
+         ;}
     break;
 
   case 294:
-#line 2288 "compilers/imcc/imcc.y"
-    { (yyval.t) = 0; }
+#line 2302 "compilers/imcc/imcc.y"
+    { (yyval.t) = 0; ;}
     break;
 
   case 295:
-#line 2289 "compilers/imcc/imcc.y"
-    { (yyval.t) = 0; }
+#line 2303 "compilers/imcc/imcc.y"
+    { (yyval.t) = 0; ;}
     break;
 
   case 296:
-#line 2293 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"eq"; }
+#line 2307 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"eq"; ;}
     break;
 
   case 297:
-#line 2294 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"ne"; }
+#line 2308 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"ne"; ;}
     break;
 
   case 298:
-#line 2295 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"gt"; }
+#line 2309 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"gt"; ;}
     break;
 
   case 299:
-#line 2296 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"ge"; }
+#line 2310 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"ge"; ;}
     break;
 
   case 300:
-#line 2297 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"lt"; }
+#line 2311 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"lt"; ;}
     break;
 
   case 301:
-#line 2298 "compilers/imcc/imcc.y"
-    { (yyval.s) = (char *)"le"; }
+#line 2312 "compilers/imcc/imcc.y"
+    { (yyval.s) = (char *)"le"; ;}
     break;
 
   case 304:
-#line 2307 "compilers/imcc/imcc.y"
-    { (yyval.sr) = NULL; }
+#line 2321 "compilers/imcc/imcc.y"
+    { (yyval.sr) = NULL; ;}
     break;
 
   case 305:
-#line 2308 "compilers/imcc/imcc.y"
-    { (yyval.sr) = (yyvsp[(1) - (1)].sr); }
+#line 2322 "compilers/imcc/imcc.y"
+    { (yyval.sr) = (yyvsp[(1) - (1)].sr); ;}
     break;
 
   case 306:
-#line 2312 "compilers/imcc/imcc.y"
-    { (yyval.sr) = IMCC_INFO(interp)->regs[0]; }
+#line 2326 "compilers/imcc/imcc.y"
+    { (yyval.sr) = IMCC_INFO(interp)->regs[0]; ;}
     break;
 
   case 308:
-#line 2317 "compilers/imcc/imcc.y"
-    { IMCC_INFO(interp)->regs[IMCC_INFO(interp)->nargs++] = (yyvsp[(1) - (1)].sr); }
+#line 2331 "compilers/imcc/imcc.y"
+    { IMCC_INFO(interp)->regs[IMCC_INFO(interp)->nargs++] = (yyvsp[(1) - (1)].sr); ;}
     break;
 
   case 309:
-#line 2319 "compilers/imcc/imcc.y"
+#line 2333 "compilers/imcc/imcc.y"
     {
            IMCC_INFO(interp) -> regs[IMCC_INFO(interp)->nargs++] = (yyvsp[(1) - (4)].sr);
            IMCC_INFO(interp) -> keyvec |= KEY_BIT(IMCC_INFO(interp)->nargs);
            IMCC_INFO(interp) -> regs[IMCC_INFO(interp)->nargs++] = (yyvsp[(3) - (4)].sr);
            (yyval.sr) = (yyvsp[(1) - (4)].sr);
-         }
+         ;}
     break;
 
   case 310:
-#line 2326 "compilers/imcc/imcc.y"
+#line 2340 "compilers/imcc/imcc.y"
     {
            IMCC_INFO(interp) -> regs[IMCC_INFO(interp)->nargs++] = (yyvsp[(2) - (3)].sr);
            (yyval.sr) = (yyvsp[(2) - (3)].sr);
-         }
+         ;}
     break;
 
   case 312:
-#line 2333 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_sub_address_fromc(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); }
+#line 2347 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_sub_address_fromc(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); ;}
     break;
 
   case 313:
-#line 2334 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_sub_address_u(interp, (yyvsp[(1) - (1)].s));  mem_sys_free((yyvsp[(1) - (1)].s)); }
+#line 2348 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_sub_address_u(interp, (yyvsp[(1) - (1)].s));  mem_sys_free((yyvsp[(1) - (1)].s)); ;}
     break;
 
   case 314:
-#line 2338 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_sub_address(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); }
+#line 2352 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_sub_address(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); ;}
     break;
 
   case 315:
-#line 2339 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_sub_address(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); }
+#line 2353 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_sub_address(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); ;}
     break;
 
   case 316:
-#line 2343 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_label_address(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); }
+#line 2357 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_label_address(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); ;}
     break;
 
   case 317:
-#line 2344 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_label_address(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); }
+#line 2358 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_label_address(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); ;}
     break;
 
   case 322:
-#line 2358 "compilers/imcc/imcc.y"
+#line 2372 "compilers/imcc/imcc.y"
     {
            IMCC_INFO(interp)->nkeys    = 0;
            IMCC_INFO(interp)->in_slice = 0;
-         }
+         ;}
     break;
 
   case 323:
-#line 2363 "compilers/imcc/imcc.y"
+#line 2377 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = link_keys(interp,
                           IMCC_INFO(interp)->nkeys,
                           IMCC_INFO(interp)->keys, 0);
-         }
+         ;}
     break;
 
   case 324:
-#line 2371 "compilers/imcc/imcc.y"
+#line 2385 "compilers/imcc/imcc.y"
     {
            IMCC_INFO(interp)->nkeys = 0;
            IMCC_INFO(interp)->in_slice = 0;
-         }
+         ;}
     break;
 
   case 325:
-#line 2376 "compilers/imcc/imcc.y"
+#line 2390 "compilers/imcc/imcc.y"
     {
            (yyval.sr) = link_keys(interp,
                           IMCC_INFO(interp)->nkeys,
                           IMCC_INFO(interp)->keys, 1);
-         }
+         ;}
     break;
 
   case 326:
-#line 2384 "compilers/imcc/imcc.y"
-    { IMCC_INFO(interp)->keys[IMCC_INFO(interp)->nkeys++] = (yyvsp[(1) - (1)].sr); }
+#line 2398 "compilers/imcc/imcc.y"
+    { IMCC_INFO(interp)->keys[IMCC_INFO(interp)->nkeys++] = (yyvsp[(1) - (1)].sr); ;}
     break;
 
   case 327:
-#line 2386 "compilers/imcc/imcc.y"
+#line 2400 "compilers/imcc/imcc.y"
     {
            IMCC_INFO(interp)->keys[IMCC_INFO(interp)->nkeys++] = (yyvsp[(3) - (3)].sr);
            (yyval.sr) = IMCC_INFO(interp)->keys[0];
-         }
+         ;}
     break;
 
   case 328:
-#line 2394 "compilers/imcc/imcc.y"
+#line 2408 "compilers/imcc/imcc.y"
     {
            if (IMCC_INFO(interp)->in_slice)
                (yyvsp[(1) - (1)].sr)->type |= VT_START_SLICE | VT_END_SLICE;
            (yyval.sr) = (yyvsp[(1) - (1)].sr);
-         }
+         ;}
     break;
 
   case 329:
-#line 2402 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_symreg(interp, (yyvsp[(1) - (1)].s), 'I'); }
+#line 2416 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_symreg(interp, (yyvsp[(1) - (1)].s), 'I'); ;}
     break;
 
   case 330:
-#line 2403 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_symreg(interp, (yyvsp[(1) - (1)].s), 'N'); }
+#line 2417 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_symreg(interp, (yyvsp[(1) - (1)].s), 'N'); ;}
     break;
 
   case 331:
-#line 2404 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_symreg(interp, (yyvsp[(1) - (1)].s), 'S'); }
+#line 2418 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_symreg(interp, (yyvsp[(1) - (1)].s), 'S'); ;}
     break;
 
   case 332:
-#line 2405 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_symreg(interp, (yyvsp[(1) - (1)].s), 'P'); }
+#line 2419 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_symreg(interp, (yyvsp[(1) - (1)].s), 'P'); ;}
     break;
 
   case 333:
-#line 2406 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_pasm_reg(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); }
+#line 2420 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_pasm_reg(interp, (yyvsp[(1) - (1)].s)); mem_sys_free((yyvsp[(1) - (1)].s)); ;}
     break;
 
   case 334:
-#line 2410 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_const(interp, (yyvsp[(1) - (1)].s), 'I'); mem_sys_free((yyvsp[(1) - (1)].s)); }
+#line 2424 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_const(interp, (yyvsp[(1) - (1)].s), 'I'); mem_sys_free((yyvsp[(1) - (1)].s)); ;}
     break;
 
   case 335:
-#line 2411 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_const(interp, (yyvsp[(1) - (1)].s), 'N'); mem_sys_free((yyvsp[(1) - (1)].s)); }
+#line 2425 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_const(interp, (yyvsp[(1) - (1)].s), 'N'); mem_sys_free((yyvsp[(1) - (1)].s)); ;}
     break;
 
   case 336:
-#line 2412 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_const(interp, (yyvsp[(1) - (1)].s), 'S'); mem_sys_free((yyvsp[(1) - (1)].s)); }
+#line 2426 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_const(interp, (yyvsp[(1) - (1)].s), 'S'); mem_sys_free((yyvsp[(1) - (1)].s)); ;}
     break;
 
   case 337:
-#line 2413 "compilers/imcc/imcc.y"
-    { (yyval.sr) = mk_const(interp, (yyvsp[(1) - (1)].s), 'U'); mem_sys_free((yyvsp[(1) - (1)].s)); }
+#line 2427 "compilers/imcc/imcc.y"
+    { (yyval.sr) = mk_const(interp, (yyvsp[(1) - (1)].s), 'U'); mem_sys_free((yyvsp[(1) - (1)].s)); ;}
     break;
 
 
 /* Line 1267 of yacc.c.  */
-#line 5170 "compilers/imcc/imcparser.c"
+#line 5184 "compilers/imcc/imcparser.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -5391,7 +5405,7 @@
 }
 
 
-#line 2419 "compilers/imcc/imcc.y"
+#line 2433 "compilers/imcc/imcc.y"
 
 
 /* I need this prototype somewhere... */

Modified: branches/tt761_keys_revamp/compilers/imcc/imcparser.h
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/imcparser.h	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/imcparser.h	Sat Jul  4 21:38:28 2009	(r39884)
@@ -295,7 +295,7 @@
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 1035 "compilers/imcc/imcc.y"
+#line 1048 "compilers/imcc/imcc.y"
 {
     IdList * idlist;
     int t;
@@ -303,7 +303,7 @@
     SymReg * sr;
     Instruction *i;
 }
-/* Line 1489 of yacc.c.  */
+/* Line 1529 of yacc.c.  */
 #line 297 "compilers/imcc/imcparser.h"
 	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */

Modified: branches/tt761_keys_revamp/compilers/imcc/instructions.c
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/instructions.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/instructions.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -103,8 +103,8 @@
         (Instruction*)mem_sys_allocate_zeroed(sizeof (Instruction) + reg_space);
     int i;
 
-    ins->opname       = str_dup(op);
-    ins->format       = str_dup(fmt);
+    ins->opname       = mem_sys_strdup(op);
+    ins->format       = mem_sys_strdup(fmt);
     ins->symreg_count = n;
 
     for (i = 0; i < n; i++)
@@ -665,6 +665,7 @@
 */
 
 #define REGB_SIZE 256
+PARROT_IGNORABLE_RESULT
 int
 ins_print(PARROT_INTERP, ARGIN(PMC *io), ARGIN(const Instruction *ins))
 {

Modified: branches/tt761_keys_revamp/compilers/imcc/instructions.h
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/instructions.h	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/instructions.h	Sat Jul  4 21:38:28 2009	(r39884)
@@ -160,7 +160,11 @@
 void imcc_init_tables(PARROT_INTERP)
         __attribute__nonnull__(1);
 
-int ins_print(PARROT_INTERP, ARGIN(PMC *io), ARGIN(const Instruction *ins))
+PARROT_IGNORABLE_RESULT
+int /*@alt void@*/
+ins_print(PARROT_INTERP,
+    ARGIN(PMC *io),
+    ARGIN(const Instruction *ins))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3);

Modified: branches/tt761_keys_revamp/compilers/imcc/main.c
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/main.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/main.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -408,13 +408,13 @@
                 break;
             case 't':
                 if (opt.opt_arg && is_all_hex_digits(opt.opt_arg))
-                    SET_TRACE(strtoul(opt.opt_arg, 0, 16));
+                    SET_TRACE(strtoul(opt.opt_arg, NULL, 16));
                 else
                     SET_TRACE(PARROT_TRACE_OPS_FLAG);
                 break;
             case 'd':
                 if (opt.opt_arg && is_all_hex_digits(opt.opt_arg)) {
-                    IMCC_INFO(interp)->debug = strtoul(opt.opt_arg, 0, 16);
+                    IMCC_INFO(interp)->debug = strtoul(opt.opt_arg, NULL, 16);
                 }
                 else {
                     IMCC_INFO(interp)->debug++;
@@ -422,7 +422,7 @@
                 break;
             case 'D':
                 if (opt.opt_arg && is_all_hex_digits(opt.opt_arg)) {
-                    SET_DEBUG(strtoul(opt.opt_arg, 0, 16));
+                    SET_DEBUG(strtoul(opt.opt_arg, NULL, 16));
                 }
                 else
                     SET_DEBUG(PARROT_MEM_STAT_DEBUG_FLAG);
@@ -828,7 +828,7 @@
     PackFile_pack(interp, interp->code->base.pf, packed);
     if (STREQ(output_file, "-"))
         fp = stdout;
-    else if ((fp = fopen(output_file, "wb")) == 0)
+    else if ((fp = fopen(output_file, "wb")) == NULL)
         IMCC_fatal_standalone(interp, EXCEPTION_EXTERNAL_ERROR,
             "Couldn't open %s\n", output_file);
 
@@ -955,7 +955,7 @@
     Parrot_pbc_load(interp, pf);
 
     IMCC_push_parser_state(interp);
-    IMCC_INFO(interp)->state->file = strdup(sourcefile);
+    IMCC_INFO(interp)->state->file = mem_sys_strdup(sourcefile);
 
     emit_open(interp, per_pbc, per_pbc ? NULL : (void*)output_file);
 

Modified: branches/tt761_keys_revamp/compilers/imcc/optimizer.c
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/optimizer.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/optimizer.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -291,9 +291,9 @@
 get_neg_op(ARGIN(const char *op), ARGOUT(int *n))
 {
     ASSERT_ARGS(get_neg_op)
-    static const struct br_pairs {
-        const char * const op;
-        const char * const nop;
+    PARROT_OBSERVER static const struct br_pairs {
+        PARROT_OBSERVER const char * const op;
+        PARROT_OBSERVER const char * const nop;
         int n;
     } br_pairs[] = {
         { "if", "unless", 2 },
@@ -360,15 +360,15 @@
                 IMCC_debug(interp, DEBUG_OPT1, "if_branch %s ... %s\n",
                         last->opname, br_dest->name);
                 /* find the negated op (e.g if->unless, ne->eq ... */
-                if ((neg_op = get_neg_op(last->opname, &args)) != 0) {
+                if ((neg_op = get_neg_op(last->opname, &args)) != NULL) {
                     Instruction * tmp;
                     last->symregs[reg] = go;
-                    tmp = INS(interp, unit, (char*)neg_op, "",
+                    tmp = INS(interp, unit, neg_op, "",
                               last->symregs, args, 0, 0);
                     last->opnum = tmp->opnum;
                     last->opsize = tmp->opsize;
                     free(last->opname);
-                    last->opname = str_dup(tmp->opname);
+                    last->opname = mem_sys_strdup(tmp->opname);
                     free_ins(tmp);
 
                     /* delete branch */
@@ -757,7 +757,7 @@
 {
     ASSERT_ARGS(IMCC_subst_constants_umix)
     Instruction *tmp;
-    const char * const ops[] = {
+    PARROT_OBSERVER const char * const ops[] = {
         "abs", "add", "div", "mul", "sub", "fdiv"
     };
     size_t i;
@@ -882,7 +882,7 @@
 {
     ASSERT_ARGS(IMCC_subst_constants)
     Instruction *tmp;
-    const char * const ops[] = {
+    PARROT_OBSERVER const char * const ops[] = {
         "add", "sub", "mul", "div", "fdiv", "pow",
         "cmod", "mod", "atan",
         "shr", "shl", "lsr",
@@ -892,16 +892,16 @@
         "and", "or", "xor",
         "iseq", "isne", "islt", "isle", "isgt", "isge", "cmp", "concat"
     };
-    const char * const ops2[] = {
+    PARROT_OBSERVER const char * const ops2[] = {
         "abs", "neg", "not", "fact", "sqrt", "ceil", "floor"
         "acos", "asec", "asin",
         "atan", "cos", "cosh", "exp", "ln", "log10", "log2", "sec",
         "sech", "sin", "sinh", "tan", "tanh", "fact"
     };
-    const char * const ops3[] = {
+    PARROT_OBSERVER const char * const ops3[] = {
         "eq", "ne", "gt", "ge", "lt", "le"
     };
-    const char * const ops4[] = {
+    PARROT_OBSERVER const char * const ops4[] = {
         "if", "unless"
     };
 
@@ -1002,6 +1002,7 @@
         return NULL;
     }
 
+    /* XXX We can get to this point with debug_fmt = NULL */
     IMCC_debug(interp, DEBUG_OPT1, debug_fmt, name);
     /* we construct a parrot instruction
      * here and let parrot do the calculation in a
@@ -1245,7 +1246,7 @@
 
         for (count = 1; count != 999; ++count) {
             snprintf(label, size, "%s_post%d", branch->symregs[0]->name, count);
-            if (get_sym(interp, label) == 0) {
+            if (get_sym(interp, label) == NULL) {
                 found = 1;
                 break;
             }

Modified: branches/tt761_keys_revamp/compilers/imcc/parser_util.c
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/parser_util.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/parser_util.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -677,7 +677,7 @@
         IMCC_INFO(interp)->state->next = NULL;
 
     IMCC_INFO(interp)->state->pasm_file = pasm_file;
-    IMCC_INFO(interp)->state->file      = name;
+    IMCC_INFO(interp)->state->file      = mem_sys_strdup(name);
     IMCC_INFO(interp)->expect_pasm      = 0;
 
     compile_string(interp, s, yyscanner);
@@ -941,7 +941,7 @@
     IMCC_push_parser_state(interp);
     {
         /* Store a copy, in order to know how to free it later */
-        char *copyname = strdup(fullname);
+        char *copyname = mem_sys_strdup(fullname);
         IMCC_INFO(interp)->state->file = copyname;
         ext                            = strrchr(copyname, '.');
     }
@@ -1221,8 +1221,8 @@
 {
     ASSERT_ARGS(try_rev_cmp)
     static struct br_pairs {
-        ARGIN(const char * const op);
-        ARGIN(const char * const nop);
+        PARROT_OBSERVER const char * const op;
+        PARROT_OBSERVER const char * const nop;
         const int to_swap;
     } br_pairs[] = {
         { "gt",   "lt",   0 },
@@ -1265,8 +1265,9 @@
 
 */
 
+PARROT_IGNORABLE_RESULT
 int
-imcc_vfprintf(PARROT_INTERP, ARGIN(PMC *io), ARGIN(const char *format), va_list ap)
+imcc_vfprintf(PARROT_INTERP, ARGMOD(PMC *io), ARGIN(const char *format), va_list ap)
 {
     ASSERT_ARGS(imcc_vfprintf)
     return Parrot_io_putps(interp, io, Parrot_vsprintf_c(interp, format, ap));

Modified: branches/tt761_keys_revamp/compilers/imcc/pbc.c
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/pbc.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/pbc.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -66,7 +66,9 @@
 static int add_const_num(PARROT_INTERP, ARGIN_NULLOK(const char *buf))
         __attribute__nonnull__(1);
 
-static int add_const_pmc_sub(PARROT_INTERP,
+PARROT_IGNORABLE_RESULT
+static int /*@alt void@*/
+add_const_pmc_sub(PARROT_INTERP,
     ARGMOD(SymReg *r),
     size_t offs,
     size_t end)
@@ -1314,6 +1316,7 @@
     (x) = NULL; \
   } while (0);
 
+PARROT_IGNORABLE_RESULT
 static int
 add_const_pmc_sub(PARROT_INTERP, ARGMOD(SymReg *r), size_t offs, size_t end)
 {
@@ -1323,8 +1326,8 @@
     Parrot_sub          *sub, *outer_sub;
 
     const int            k            = add_const_table(interp);
-    PackFile_ConstTable *ct           = interp->code->const_table;
-    PackFile_Constant   *pfc          = ct->constants[k];
+    PackFile_ConstTable * const ct    = interp->code->const_table;
+    PackFile_Constant   * const pfc   = ct->constants[k];
     IMC_Unit            * const unit  =
         IMCC_INFO(interp)->globals->cs->subs->unit;
 
@@ -1348,7 +1351,7 @@
         ns_const  = ns->color;
 
         if (real_name) {
-            char * const p = str_dup(real_name + 1);
+            char * const p = mem_sys_strdup(real_name + 1);
             free(r->name);
             r->name = p;
         }
@@ -1394,7 +1397,7 @@
         unit->subid = r;
     else {
         /* trim the quotes  */
-        unit->subid->name = str_dup(unit->subid->name + 1);
+        unit->subid->name = mem_sys_strdup(unit->subid->name + 1);
         unit->subid->name[strlen(unit->subid->name) - 1] = 0;
 
         /* create string constant for it. */
@@ -1756,28 +1759,37 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 INTVAL
 IMCC_int_from_reg(PARROT_INTERP, ARGIN(const SymReg *r))
 {
     ASSERT_ARGS(IMCC_int_from_reg)
     INTVAL i;
-
-    errno = 0;
+    const char *digits;
+    int base;
 
     if (r->type & VT_CONSTP)
         r = r->reg;
 
-    if (r->name[0] == '0' && (r->name[1] == 'x' || r->name[1] == 'X'))
-        i = strtoul(r->name + 2, 0, 16);
-
-    else if (r->name[0] == '0' && (r->name[1] == 'O' || r->name[1] == 'o'))
-        i = strtoul(r->name + 2, 0, 8);
+    digits = r->name;
+    base   = 10;
+    errno  = 0;
 
-    else if (r->name[0] == '0' && (r->name[1] == 'b' || r->name[1] == 'B'))
-        i = strtoul(r->name + 2, 0, 2);
+    if (digits[0] == '0') {
+        switch (toupper((unsigned char)digits[1])) {
+            case 'B': base =  2; break;
+            case 'O': base =  8; break;
+            case 'X': base = 16; break;
+            default: break;
+        }
+    }
 
-    else
-        i = strtol(r->name, 0, 10);
+    if (base == 10) {
+        i = strtol(digits, NULL, base);
+    }
+    else {
+        i = strtoul(digits + 2, NULL, base);
+    }
 
     /*
      * TODO
@@ -1809,6 +1821,9 @@
     STRING *s;
     PMC    *p;
 
+    if (PMC_IS_NULL(_class))
+        IMCC_fatal(interp, 1, "make_pmc_const: no such pmc");
+
     if (*r->name == '"')
         s = Parrot_str_unescape(interp, r->name + 1, '"', NULL);
 
@@ -2114,7 +2129,6 @@
         ARGIN(const Instruction *ins))
 {
     ASSERT_ARGS(e_pbc_emit)
-    op_info_t *op_info;
     int        ok = 0;
     int        op, i;
 
@@ -2249,6 +2263,7 @@
     }
     else if (ins->opname && *ins->opname) {
         SymReg  *addr, *r;
+        op_info_t *op_info;
         opcode_t last_label = 1;
 
 #if IMC_TRACE_HIGH
@@ -2256,7 +2271,7 @@
 #endif
 
         if ((ins->type & ITBRANCH)
-        &&  (addr = get_branch_reg(ins)) != 0
+        && ((addr = get_branch_reg(ins)) != NULL)
         && !REG_NEEDS_ALLOC(addr)) {
             /* fixup local jumps - calc offset */
             if (addr->color == -1)

Modified: branches/tt761_keys_revamp/compilers/imcc/pbc.h
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/pbc.h	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/pbc.h	Sat Jul  4 21:38:28 2009	(r39884)
@@ -31,6 +31,7 @@
 int e_pbc_open(PARROT_INTERP, SHIM(void *param))
         __attribute__nonnull__(1);
 
+PARROT_WARN_UNUSED_RESULT
 INTVAL IMCC_int_from_reg(PARROT_INTERP, ARGIN(const SymReg *r))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);

Modified: branches/tt761_keys_revamp/compilers/imcc/pcc.c
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/pcc.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/pcc.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -743,6 +743,9 @@
 
     SymReg * const sub = ins->symregs[0];
 
+    PARROT_ASSERT(sub);
+    PARROT_ASSERT(sub->pcc_sub);
+
     if (ins->type & ITRESULT) {
         const int n = sub->pcc_sub->nret;
         ins         = pcc_get_args(interp, unit, ins, "get_results", n,
@@ -767,6 +770,11 @@
 
     if (ins->type & ITCALL) {
         SymReg * const the_sub = sub->pcc_sub->sub;
+        /* If this condition is true the generator must haven't be called,
+         * but check it as a last resort.
+         * See also TT #737 */
+        if (the_sub == NULL)
+            IMCC_fatal(interp, 1, "expand_pcc_sub_call: no such sub");
 
         if (!meth_call && (the_sub->type & VTADDRESS)) {
             /* sub->pcc_sub->sub is an actual subroutine name, not a variable */

Modified: branches/tt761_keys_revamp/compilers/imcc/reg_alloc.c
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/reg_alloc.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/reg_alloc.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -72,16 +72,20 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*r);
 
-static int first_avail(
+PARROT_WARN_UNUSED_RESULT
+static unsigned int first_avail(
     ARGIN(const IMC_Unit *unit),
     int reg_set,
     ARGOUT_NULLOK(Set **avail))
         __attribute__nonnull__(1)
         FUNC_MODIFIES(*avail);
 
+PARROT_WARN_UNUSED_RESULT
+PARROT_MALLOC
 PARROT_CANNOT_RETURN_NULL
 static unsigned int* ig_allocate(int N);
 
+PARROT_WARN_UNUSED_RESULT
 static int ig_find_color(
     ARGIN(const IMC_Unit *unit),
     ARGIN(const char *avail))
@@ -145,6 +149,7 @@
         __attribute__nonnull__(1)
         FUNC_MODIFIES(*unit);
 
+PARROT_WARN_UNUSED_RESULT
 static int reg_sort_f(ARGIN(const void *a), ARGIN(const void *b))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
@@ -153,6 +158,7 @@
         __attribute__nonnull__(1)
         FUNC_MODIFIES(*unit);
 
+PARROT_WARN_UNUSED_RESULT
 static int try_allocate(PARROT_INTERP, ARGIN(IMC_Unit *unit))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
@@ -237,7 +243,7 @@
             ARGMOD(int *bit_ofs))
 {
     ASSERT_ARGS(ig_get_word)
-    unsigned int bit = i * N + j;
+    const unsigned int bit = i * N + j;
     *bit_ofs        = bit % sizeof (*graph);
 
     return &graph[bit / sizeof (*graph)];
@@ -256,7 +262,7 @@
 {
     ASSERT_ARGS(ig_set)
     int bit_ofs;
-    unsigned int *word = ig_get_word(i, j, N, graph, &bit_ofs);
+    unsigned int * const word = ig_get_word(i, j, N, graph, &bit_ofs);
     *word |= (1 << bit_ofs);
 }
 
@@ -268,6 +274,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 unsigned int
 ig_test(int i, int j, int N, ARGIN(unsigned int *graph))
 {
@@ -285,6 +292,8 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
+PARROT_MALLOC
 PARROT_CANNOT_RETURN_NULL
 static unsigned int*
 ig_allocate(int N)
@@ -422,7 +431,7 @@
 #endif
     if (unit->interference_graph) {
         free(unit->interference_graph);
-        unit->interference_graph =  0;
+        unit->interference_graph = NULL;
     }
 
     if (unit->reglist) {
@@ -594,6 +603,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 static int
 reg_sort_f(ARGIN(const void *a), ARGIN(const void *b))
 {
@@ -812,7 +822,7 @@
 compute_du_chain(ARGMOD(IMC_Unit *unit))
 {
     ASSERT_ARGS(compute_du_chain)
-    Instruction *ins        = unit->instructions;
+    Instruction *ins = unit->instructions;
     Instruction *lastbranch = NULL;
     unsigned int i;
 
@@ -854,14 +864,14 @@
     /* We cannot rely on computing the value of r->first when parsing,
      * since the situation can be changed at any time by the register
      * allocation algorithm */
-    r->first_ins = 0;
-    r->use_count = r->lhs_use_count = 0;
+    r->first_ins     = NULL;
+    r->use_count     = 0;
+    r->lhs_use_count = 0;
 
     for (ins = unit->instructions; ins; ins = ins->next) {
-        const int ro = instruction_reads(ins, r);
         const int rw = instruction_writes(ins, r);
 
-        if (ro || rw) {
+        if (rw || instruction_reads(ins, r)) {
             if (!r->first_ins)
                 r->first_ins = ins;
 
@@ -987,6 +997,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 static int
 ig_find_color(ARGIN(const IMC_Unit *unit), ARGIN(const char *avail))
 {
@@ -1015,6 +1026,7 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 static int
 try_allocate(PARROT_INTERP, ARGIN(IMC_Unit *unit))
 {
@@ -1037,7 +1049,7 @@
 
     for (i = 0; i < unit->n_symbols; ++i) {
         int     already_allocated, color;
-        SymReg *r = reglist[i];
+        SymReg * const r = reglist[i];
         int     t = -1;
 
         if (r->color >= 0)
@@ -1110,7 +1122,8 @@
 
 /*
 
-=item C<static int first_avail(const IMC_Unit *unit, int reg_set, Set **avail)>
+=item C<static unsigned int first_avail(const IMC_Unit *unit, int reg_set, Set
+**avail)>
 
 find first available register of the given reg_set
 
@@ -1118,7 +1131,8 @@
 
 */
 
-static int
+PARROT_WARN_UNUSED_RESULT
+static unsigned int
 first_avail(ARGIN(const IMC_Unit *unit), int reg_set, ARGOUT_NULLOK(Set **avail))
 {
     ASSERT_ARGS(first_avail)
@@ -1188,10 +1202,10 @@
             &&  r->color == -1
             && (r->usage & usage)
             && r->use_count) {
-                Set *avail    = sets[j];
-                int first_reg = avail
-                              ? set_first_zero(avail)
-                              : first_avail(unit, (int)r->set, &avail);
+                Set         *avail     = sets[j];
+                unsigned int first_reg = avail
+                                       ? set_first_zero(avail)
+                                       : first_avail(unit, (int)r->set, &avail);
                 set_add(avail, first_reg);
                 r->color = first_reg++;
 
@@ -1233,15 +1247,15 @@
 vanilla_reg_alloc(SHIM_INTERP, ARGMOD(IMC_Unit *unit))
 {
     ASSERT_ARGS(vanilla_reg_alloc)
-    char         type[] = "INSP";
+    const char   type[] = "INSP";
     SymHash     *hsh    = &unit->hash;
     Set         *avail;
-    SymReg      *r;
     unsigned int i, j;
     int          reg_set, first_reg;
 
     /* Clear the pre-assigned colors. */
     for (i = 0; i < hsh->size; i++) {
+        SymReg *r;
         for (r = hsh->data[i]; r; r = r->next) {
             /* TODO Ignore non-volatiles */
             if (REG_NEEDS_ALLOC(r) && r->use_count)
@@ -1254,7 +1268,9 @@
         reg_set   = type[j];
         first_reg = first_avail(unit, reg_set, &avail);
 
+        /* XXX Use a different loop variable that doesn't shadow outer i */
         for (i = 0; i < hsh->size; i++) {
+            SymReg *r;
             for (r = hsh->data[i]; r; r = r->next) {
                 if (r->set != reg_set)
                     continue;

Modified: branches/tt761_keys_revamp/compilers/imcc/symreg.c
==============================================================================
--- branches/tt761_keys_revamp/compilers/imcc/symreg.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/imcc/symreg.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -74,6 +74,15 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static SymReg * get_sym_by_name(
+    ARGIN(const SymHash *hsh),
+    ARGIN(const char *name))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_WARN_UNUSED_RESULT
 static int int_overflows(ARGIN(const SymReg *r))
         __attribute__nonnull__(1);
 
@@ -105,6 +114,9 @@
 #define ASSERT_ARGS_add_ns __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(name)
+#define ASSERT_ARGS_get_sym_by_name __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(hsh) \
+    || PARROT_ASSERT_ARG(name)
 #define ASSERT_ARGS_int_overflows __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(r)
 #define ASSERT_ARGS_mk_pmc_const_2 __attribute__unused__ int _ASSERT_ARGS_CHECK = \
@@ -134,7 +146,7 @@
     Namespace * const ns = mem_allocate_zeroed_typed(Namespace);
 
     ns->parent = pesky_global__namespace;
-    ns->name   = str_dup(name);
+    ns->name   = mem_sys_strdup(name);
     pesky_global__namespace = ns;
 }
 
@@ -203,6 +215,35 @@
 }
 
 
+/*
+
+=item C<static SymReg * get_sym_by_name(const SymHash *hsh, const char *name)>
+
+Gets a symbol from the hash, with the given C<name>.
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static SymReg *
+get_sym_by_name(ARGIN(const SymHash *hsh), ARGIN(const char *name))
+{
+    ASSERT_ARGS(get_sym_by_name)
+
+    SymReg            *p;
+    const unsigned int i = hash_str(name) % hsh->size;
+
+    for (p = hsh->data[i]; p; p = p->next) {
+        if (STREQ(name, p->name))
+            return p;
+    }
+
+    return NULL;
+}
+
+
 /* symbolic registers */
 
 /*
@@ -227,7 +268,7 @@
         r             = mem_allocate_zeroed_typed(SymReg);
         r->set        = t;
         r->type       = VTREG;
-        r->name       = str_dup(name);
+        r->name       = mem_sys_strdup(name);
         r->color      = -1;
         r->want_regno = -1;
 
@@ -579,7 +620,7 @@
         return result;
     }
 
-    return str_dup(name);
+    return mem_sys_strdup(name);
 }
 
 
@@ -600,10 +641,16 @@
 {
     ASSERT_ARGS(mk_ident)
     char   * const fullname = _mk_fullname(pesky_global__namespace, name);
-    SymReg        *r        = mk_symreg(interp, fullname, t);
+    SymReg *r = get_sym_by_name(&(IMCC_INFO(interp)->last_unit->hash), name);
+    if (r && r->set != t) {
+        IMCC_print_inc(interp);
+        IMCC_warning(interp, "Duplicated IDENTIFIER '%s'\n", fullname);
+    }
 
+    r = mk_symreg(interp, fullname, t);
     r->type = VTIDENTIFIER;
 
+
     if (pesky_global__namespace) {
         Identifier * const ident = mem_allocate_zeroed_typed(Identifier);
 
@@ -676,7 +723,7 @@
     r[0] = left;
 
     /* strip delimiters */
-    name          = str_dup(rhs->name + 1);
+    name          = mem_sys_strdup(rhs->name + 1);
     len           = strlen(name);
     name[len - 1] = '\0';
 
@@ -801,28 +848,39 @@
 
 */
 
+PARROT_WARN_UNUSED_RESULT
 static int
 int_overflows(ARGIN(const SymReg *r))
 {
     ASSERT_ARGS(int_overflows)
     INTVAL i;
-    errno = 0;
+    int base;
+    const char *digits;
 
     if (r->type & VT_CONSTP)
         r = r->reg;
 
-    if (r->name[0] == '0' && (r->name[1] == 'x' || r->name[1] == 'X')) {
-        i = strtoul(r->name + 2, 0, 16);
+    /* Refactor this code to hoist common from functionality between
+     * this function and IMCC_int_from_reg in pbc.c */
+    digits = r->name;
+    base   = 10;
+
+    if (digits[0] == '0') {
+        switch (toupper((unsigned char)digits[1])) {
+            case 'B': base =  2; break;
+            case 'O': base =  8; break;
+            case 'X': base = 16; break;
+            default: break;
+        }
     }
 
-    else if (r->name[0] == '0' && (r->name[1] == 'O' || r->name[1] == 'o'))
-        i = strtoul(r->name + 2, 0, 8);
-
-    else if (r->name[0] == '0' && (r->name[1] == 'b' || r->name[1] == 'B'))
-        i = strtoul(r->name + 2, 0, 2);
-
-    else
-        i = strtol(r->name, 0, 10);
+    errno = 0;
+    if (base == 10) {
+        i = strtol(digits, NULL, base);
+    }
+    else {
+        i = strtoul(digits + 2, NULL, base);
+    }
 
     return errno ? 1 : 0;
 }
@@ -874,7 +932,7 @@
 
     if (!IMCC_INFO(interp)->cur_namespace
     || (l = strlen(IMCC_INFO(interp)->cur_namespace->name)) <= 2)
-        return str_dup(name);
+        return mem_sys_strdup(name);
 
     /* TODO keyed syntax */
     len     = strlen(name) + l  + 4;
@@ -921,7 +979,7 @@
     if (uniq == U_add_all) {
         r       = mem_allocate_zeroed_typed(SymReg);
         r->type = VTADDRESS;
-        r->name = str_dup(name);
+        r->name = mem_sys_strdup(name);
         _store_symreg(hsh, r);
     }
     else {
@@ -1104,7 +1162,7 @@
     ASSERT_ARGS(dup_sym)
     SymReg * const new_sym = mem_allocate_zeroed_typed(SymReg);
     STRUCT_COPY(new_sym, r);
-    new_sym->name = str_dup(r->name);
+    new_sym->name = mem_sys_strdup(r->name);
 
     if (r->nextkey)
         new_sym->nextkey = dup_sym(r->nextkey);

Modified: branches/tt761_keys_revamp/compilers/nqp/src/Grammar/Actions.pir
==============================================================================
--- branches/tt761_keys_revamp/compilers/nqp/src/Grammar/Actions.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/nqp/src/Grammar/Actions.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -715,7 +715,6 @@
     $S0 = expr.'name'()
     if $S0 != 'infix:,' goto one_arg
   comma_arg:
-    .local pmc iter
     iter = expr.'iterator'()
   iter_loop:
     unless iter goto end

Modified: branches/tt761_keys_revamp/compilers/pct/src/PAST/Compiler.pir
==============================================================================
--- branches/tt761_keys_revamp/compilers/pct/src/PAST/Compiler.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/pct/src/PAST/Compiler.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -406,7 +406,6 @@
 
     .local pmc iter
     .local string rtype
-    .local int sigidx
     iter = node.'iterator'()
     sigidx = 1
     rtype = substr signature, sigidx, 1
@@ -1423,7 +1422,7 @@
     collpast = node[0]
     bodypast = node[1]
 
-    .local pmc collpost, testpost
+    .local pmc collpost
     collpost = self.'as_post'(collpast, 'rtype'=>'P')
     ops.'push'(collpost)
 

Modified: branches/tt761_keys_revamp/compilers/pct/src/PCT/Dumper.pir
==============================================================================
--- branches/tt761_keys_revamp/compilers/pct/src/PCT/Dumper.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/pct/src/PCT/Dumper.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -8,7 +8,8 @@
 =head1 DESCRIPTION
 
 This file implements a dumper that attempts to output PAST,
-Match, and Capture objects in a YAML-compatible format.
+Match, and Capture objects in a format that can be easily
+consumed by syntax highlighters (such as Padre).
 Yes, the code is probably much uglier and convoluted than
 it should be.  No, I'm not proud of it, but it works for now.
 

Modified: branches/tt761_keys_revamp/compilers/pge/PGE/Match.pir
==============================================================================
--- branches/tt761_keys_revamp/compilers/pge/PGE/Match.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/pge/PGE/Match.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -64,7 +64,6 @@
     .local pmc target, grammar_class
     issrcmatch = isa src, ['PGE';'Match']
     if issrcmatch goto target_from_src
-    .local pmc target
     target = new 'CodeString'
     assign target, src
     pos = 0

Modified: branches/tt761_keys_revamp/compilers/pge/PGE/OPTable.pir
==============================================================================
--- branches/tt761_keys_revamp/compilers/pge/PGE/OPTable.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/pge/PGE/OPTable.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -614,8 +614,13 @@
     .return (mob)
 
   err_ternary:
-    print "Ternary error\n"
-    end
+    $S1 = pos
+    $S0 = concat 'Ternary error at offset ', $S1
+    $S0 .= ", found '"
+    $S1 = substr target, pos, 1
+    $S0 .= $S1
+    $S0 .= "'"
+    die $S0
 .end
 
 

Modified: branches/tt761_keys_revamp/compilers/pge/PGE/Perl6Regex.pir
==============================================================================
--- branches/tt761_keys_revamp/compilers/pge/PGE/Perl6Regex.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/compilers/pge/PGE/Perl6Regex.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -107,7 +107,7 @@
     .return ($P0)
 
   analyze:
-    .local pmc exp, pad
+    .local pmc pad
     exp = match['expr']
     pad = clone adverbs
     $P0 = new 'Hash'

Deleted: branches/tt761_keys_revamp/compilers/pge/demo.pir
==============================================================================
--- branches/tt761_keys_revamp/compilers/pge/demo.pir	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,128 +0,0 @@
-# Copyright (C) 2005-2009, Parrot Foundation.
-# $Id$
-
-.include "errors.pasm"
-.sub _main
-    .local string x
-    .local string pattern
-    .local int istraced
-    .local pmc stdin
-    .local pmc rulesub
-    .local pmc pir
-    .local pmc exp
-    .local pmc match
-    .local pmc p6rule_compile
-    .local pmc p5regexp_compile
-    .local pmc glob_compile
-    .local int istrace
-    .local string gname
-
-    errorson .PARROT_ERRORS_PARAM_COUNT_FLAG
-
-    load_bytecode "PGE.pbc"
-    load_bytecode "dumper.pir"
-    load_bytecode "PGE/Dumper.pir"
-    load_bytecode "PGE/Glob.pir"
-    load_bytecode "PGE/Text.pir"
-    load_bytecode "PGE/Util.pir"
-    p6rule_compile = compreg "PGE::Perl6Regex"
-    glob_compile = compreg "PGE::Glob"
-    p5regexp_compile = compreg "PGE::P5Regex"
-    istrace = 0
-    null rulesub
-
-  read_loop:
-    print "\ninput \"regex <pattern>\", \"glob <pattern>\", \"save <name>\",\n"
-    print "target string, \"pir\", \"exp\", \"trace\", \"next\"\n"
-    getstdin stdin
-    readline x, stdin
-    length $I0, x
-    if $I0 < 1 goto end_demo
-    $I0 = index x, " "
-    if $I0 > 0 goto get_cmd
-    $I0 = index x, "\n"
-  get_cmd:
-    $S0 = substr x, 0, $I0
-    chopn x, 1
-    if $S0 == "next" goto match_next
-    if $S0 == "regex" goto make_p6rule
-    if $S0 == "glob" goto make_glob
-    if $S0 == "save" goto save_rule
-    if $S0 == "pir" goto print_pir
-    if $S0 == "exp" goto print_exp
-    if $S0 == "trace" goto toggle_trace
-    if $S0 == "p5regex" goto make_regexp
-
-    if_null rulesub, match_nopattern
-    match = rulesub(x)
-  match_result:
-    unless match goto match_fail
-    print "match succeeded\n"
-    $P0 = find_global "_dumper"
-    $P0(match, "$/")
-    goto read_loop
-  match_fail:
-    print "match failed\n"
-    goto read_loop
-  match_nopattern:
-    print "no pattern entered yet\n"
-    goto read_loop
-
-  match_next:
-    match."next"()
-    goto match_result
-
-  make_glob:
-    pattern = substr x, 5
-    (rulesub) = glob_compile(pattern)
-    goto read_loop
-
-  make_p6rule:
-    pattern = substr x, 5
-    (rulesub) = p6rule_compile(pattern)
-    goto read_loop
-
-  make_regexp:
-    pattern = substr x, 7
-    (rulesub) = p5regexp_compile(pattern)
-    goto read_loop
-
-  save_rule:
-    if_null rulesub, match_nopattern
-    x = substr x, 5
-    store_global x, rulesub
-    print "Saved as "
-    print x
-    print "\n"
-    goto read_loop
-
-
-  print_pir:
-    if_null rulesub, match_nopattern
-    print pir
-    goto read_loop
-
-  print_exp:
-    if_null rulesub, match_nopattern
-    $P0 = find_global "_dumper"
-    $P0(exp, "exp")
-    goto read_loop
-
-  toggle_trace:
-    istrace = not istrace
-    trace istrace
-    unless istrace goto trace_off
-    print "Tracing is now on\n"
-    goto read_loop
-  trace_off:
-    print "Tracing is now off\n"
-    goto read_loop
-
-  end_demo:
-.end
-
-# Local Variables:
-#   mode: pir
-#   fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/tt761_keys_revamp/config/auto/gcc.pm
==============================================================================
--- branches/tt761_keys_revamp/config/auto/gcc.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/config/auto/gcc.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -88,7 +88,7 @@
     my $ccwarn = $conf->data->get('ccwarn');
 
     $conf->data->set( sym_export => '__attribute__ ((visibility("default")))' )
-        if $gccversion >= 4.0;
+        if $gccversion >= 4.0 && !$conf->data->get('sym_export');
 
     $conf->data->set(
         ccwarn              => "$ccwarn",

Modified: branches/tt761_keys_revamp/config/auto/icu.pm
==============================================================================
--- branches/tt761_keys_revamp/config/auto/icu.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/config/auto/icu.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -394,10 +394,20 @@
         }
     }
     else {
+        my $icuheaders = $arg->{icuheaders};
+
+        my $icuflags;
+        if ($icuheaders =~ /\s/) {
+            $icuflags = "-I \"$arg->{icuheaders}\"";
+        }
+        else {
+            $icuflags = "-I $arg->{icuheaders}";
+        }
+
         if ($arg->{verbose}) {
-            print "Adding -I $arg->{icuheaders} to ccflags for icu headers.\n";
+            print "Adding $icuflags to ccflags for icu headers.\n";
         }
-        $conf->data->add( ' ', ccflags => "-I $arg->{icuheaders}" );
+        $conf->data->add( ' ', ccflags => $icuflags );
     }
 }
 

Modified: branches/tt761_keys_revamp/config/gen/config_h/config_h.in
==============================================================================
--- branches/tt761_keys_revamp/config/gen/config_h/config_h.in	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/config/gen/config_h/config_h.in	Sat Jul  4 21:38:28 2009	(r39884)
@@ -1,5 +1,6 @@
-/* Copyright (C) 2001-2007, Parrot Foundation. */
-/* $Id$ */
+/* Copyright (C) 2001-2009, Parrot Foundation.
+ * $Id$
+ */
 
 /* config.h
  *
@@ -45,17 +46,17 @@
 
 #include "parrot/platform_limits.h"
 #ifndef PARROT_INTVAL_MIN
-#define PARROT_INTVAL_MIN              @intvalmin@
+#  define PARROT_INTVAL_MIN              @intvalmin@
 #endif
 #ifndef PARROT_INTVAL_MAX
-#define PARROT_INTVAL_MAX              @intvalmax@
+#  define PARROT_INTVAL_MAX              @intvalmax@
 #endif
 
 #ifndef PARROT_FLOATVAL_MIN
-#define PARROT_FLOATVAL_MIN            @floatvalmin@
+#  define PARROT_FLOATVAL_MIN            @floatvalmin@
 #endif
 #ifndef PARROT_FLOATVAL_MAX
-#define PARROT_FLOATVAL_MAX            @floatvalmax@
+#  define PARROT_FLOATVAL_MAX            @floatvalmax@
 #endif
 
 /* Temporary until we find a way to make it work in the right place. */
@@ -65,21 +66,21 @@
  * PARROT_IN_CORE won't always imply !PARROT_IN_EXTENSION. */
 #if defined(PARROT_IN_EXTENSION)
 #if defined(__cplusplus)
-#define PARROT_EXPORT extern "C" @sym_import@
-#define PARROT_DATA extern "C" @sym_import@
-#define PARROT_DYNEXT_EXPORT extern "C" @sym_export@
+#  define PARROT_EXPORT extern "C" @sym_import@
+#  define PARROT_DATA extern "C" @sym_import@
+#  define PARROT_DYNEXT_EXPORT extern "C" @sym_export@
 #else
-#define PARROT_EXPORT @sym_import@
-#define PARROT_DATA extern @sym_import@
-#define PARROT_DYNEXT_EXPORT @sym_export@
+#  define PARROT_EXPORT @sym_import@
+#  define PARROT_DATA extern @sym_import@
+#  define PARROT_DYNEXT_EXPORT @sym_export@
 #endif
 #else
 #if defined(__cplusplus)
-#define PARROT_EXPORT extern "C" @sym_export@
-#define PARROT_DATA extern "C" @sym_export@
+#  define PARROT_EXPORT extern "C" @sym_export@
+#  define PARROT_DATA extern "C" @sym_export@
 #else
-#define PARROT_EXPORT @sym_export@
-#define PARROT_DATA extern @sym_export@
+#  define PARROT_EXPORT @sym_export@
+#  define PARROT_DATA extern @sym_export@
 #endif
 #endif
 
@@ -118,19 +119,19 @@
 /* We don't have a portable config for 64-bit
  * registers yet. */
 #if 0
-# if INTVAL_SIZE >= 8
+#  if INTVAL_SIZE >= 8
 typedef Parrot_Int   INTVAL64;
 typedef Parrot_Int   Parrot_Int64;
-# else
-#  if HUGEINTVAL_SIZE >= 8
+#  else
+#    if HUGEINTVAL_SIZE >= 8
 typedef HUGEINTVAL   INTVAL64;
 typedef HUGEINTVAL   Parrot_Int64;
-#  else
+#    else
 /* No 64-bit type available? */
 typedef union { unsigned char b[8]; } INTVAL64;
 typedef INTVAL64   Parrot_Int64;
+#    endif
 #  endif
-# endif
 #endif
 
 

Modified: branches/tt761_keys_revamp/config/gen/crypto.pm
==============================================================================
--- branches/tt761_keys_revamp/config/gen/crypto.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/config/gen/crypto.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -95,6 +95,7 @@
         $conf->genfile( $self->{digest_pmc_template} => "src/dynpmc/${file}.pmc" );
         $conf->genfile( $self->{digest_t_template} => "t/dynpmc/${file}.t" );
     }
+    $conf->cc_clean();
 
     return 1;
 }

Modified: branches/tt761_keys_revamp/config/gen/makefiles/root.in
==============================================================================
--- branches/tt761_keys_revamp/config/gen/makefiles/root.in	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/config/gen/makefiles/root.in	Sat Jul  4 21:38:28 2009	(r39884)
@@ -262,6 +262,7 @@
     $(LIBRARY_DIR)/ncurses.pbc \
 #IF(has_opengl):    $(LIBRARY_DIR)/OpenGL.pbc \
 #IF(has_opengl):    $(LIBRARY_DIR)/OpenGL_funcs.pbc \
+#IF(has_opengl):    $(LIBRARY_DIR)/OpenGL/Math.pbc \
     $(LIBRARY_DIR)/P6object.pbc \
     $(LIBRARY_DIR)/parrotlib.pbc \
     $(LIBRARY_DIR)/pcore.pbc \
@@ -508,7 +509,9 @@
 #ELSE:LIBPARROT_SHARED  := @blib_dir@/@libparrot_shared@
 
 # This line controls whether a static or shared library is built
-LIBPARROT           := @libparrot@
+# by Parrot's make.  It is not useful otherwise (e.g., in
+# lib/Parrot/Config/Generated.pm or config_lib.pasm).
+LIBPARROT           := @libparrot_for_makefile_only@
 
 #IF(has_icu):ICU_SHARED  := @icu_shared@
 ALL_PARROT_LIBS     := @libparrot_linkflags@ $(ICU_SHARED) $(C_LIBS)

Modified: branches/tt761_keys_revamp/config/gen/opengl.pm
==============================================================================
--- branches/tt761_keys_revamp/config/gen/opengl.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/config/gen/opengl.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -107,6 +107,7 @@
 # alter the typemaps to fit this bug.
 
 my %C_TYPE = (
+    VOID                    => 'void',
     GLvoid                  => 'void',
     GLUnurbs                => 'void',
     GLUquadric              => 'void',
@@ -147,11 +148,20 @@
     WindowRef               => 'void*',
     HIViewRef               => 'void*',
     Style                   => 'void*',
+    HANDLE                  => 'void*',
+    HPBUFFERARB             => 'void*',
+    HPBUFFEREXT             => 'void*',
+    HVIDEOOUTPUTDEVICENV    => 'void*',
+    HPVIDEODEV              => 'void*',
+    HPGPUNV                 => 'void*',
+    HGPUNV                  => 'void*',
     HDC                     => 'void*',
     HGLRC                   => 'void*',
     LPGLYPHMETRICSFLOAT     => 'void*',
     LPLAYERPLANEDESCRIPTOR  => 'void*',
     LPPIXELFORMATDESCRIPTOR => 'void*',
+    LPVOID                  => 'void*',
+    PGPU_DEVICE             => 'void*',
 
     GLchar                  => 'char',
     GLcharARB               => 'char',
@@ -160,10 +170,12 @@
     GLboolean               => 'unsigned char',
 
     GLshort                 => 'short',
+    USHORT                  => 'unsigned short',
     GLushort                => 'unsigned short',
     GLhalfARB               => 'unsigned short',
     GLhalfNV                => 'unsigned short',
 
+    BOOL                    => 'int',
     Bool                    => 'int',
     Status                  => 'int',
     GLint                   => 'int',
@@ -171,6 +183,8 @@
     GLfixed                 => 'int',
     GLclampx                => 'int',
     int32_t                 => 'int',
+    INT32                   => 'int',
+    INT                     => 'int',
 
     GLenum                  => 'unsigned int',
     GLCenum                 => 'unsigned int',
@@ -182,11 +196,13 @@
     CGLError                => 'unsigned int',
     SphereMapFlags          => 'unsigned int',
 
+    UINT                    => 'unsigned int',
     GLuint                  => 'unsigned int',
     GLbitfield              => 'unsigned int',
     GLhandleARB             => 'unsigned int',
     GLXVideoDeviceNV        => 'unsigned int',
 
+    DWORD                   => 'unsigned long',
     GLulong                 => 'unsigned long',
     XID                     => 'unsigned long',
     Window                  => 'unsigned long',
@@ -208,9 +224,11 @@
     GLXVideoSourceSGIX      => 'unsigned long',
 
     int64_t                 => 'long long',
+    INT64                   => 'long long',
     GLint64EXT              => 'signed long long',
     GLuint64EXT             => 'unsigned long long',
 
+    FLOAT                   => 'float',
     GLfloat                 => 'float',
     GLclampf                => 'float',
     GLdouble                => 'double',
@@ -307,11 +325,19 @@
     'SetPixelFormat',
 
     # Can't handle longlong until RT 53406 is done
+    'glBufferAddressRangeNV',
+    'glUniformui64NV',
+    'glProgramUniformui64NV',
     'glPresentFrameKeyedNV',
     'glPresentFrameDualFillNV',
     'glXSwapBuffersMscOML',
     'glXWaitForMscOML',
     'glXWaitForSbcOML',
+    'wglGetSyncValuesOML',
+    'wglSwapBuffersMscOML',
+    'wglSwapLayerBuffersMscOML',
+    'wglWaitForMscOML',
+    'wglWaitForSbcOML',
 
     # Can't handle weird data types specified only in proprietary headers
     'glXCreateGLXVideoSourceSGIX',
@@ -431,6 +457,7 @@
         (map "$_/gl/*.h" => @include_paths_win32),
 
 #         # Portability testing headers
+#         "$ENV{HOME}/src/gentoo3/*.h",
 #         "$ENV{HOME}/src/osx/headers/GLUT/*.h",
 #         "$ENV{HOME}/src/osx/headers/OpenGL/*.h",
 #         "$ENV{HOME}/src/osx-10.4/GLUT/*.h",

Modified: branches/tt761_keys_revamp/config/init/hints/darwin.pm
==============================================================================
--- branches/tt761_keys_revamp/config/init/hints/darwin.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/config/init/hints/darwin.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -16,6 +16,8 @@
 sub runstep {
     my ( $self, $conf ) = @_;
 
+    my $share_ext = $conf->option_or_data('share_ext');
+    my $version   = $conf->option_or_data('VERSION');
     my $verbose = $conf->options->get('verbose');
 
     # The hash referenced by $flagsref is the list of options that have -arch
@@ -61,8 +63,8 @@
         # of the library.
 
         parrot_is_shared       => 1,
-        libparrot_shared       => 'libparrot.$(SOVERSION)$(SHARE_EXT)',
-        libparrot_shared_alias => 'libparrot$(SHARE_EXT)',
+        libparrot_shared       => "libparrot.$version$share_ext",
+        libparrot_shared_alias => "libparrot$share_ext",
         rpath                  => "-L",
         libparrot_soname       => "-install_name "
             . $lib_dir

Modified: branches/tt761_keys_revamp/config/init/hints/dragonfly.pm
==============================================================================
--- branches/tt761_keys_revamp/config/init/hints/dragonfly.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/config/init/hints/dragonfly.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -9,6 +9,8 @@
 sub runstep {
     my ( $self, $conf ) = @_;
 
+    my $share_ext = $conf->option_or_data('share_ext');
+    my $version   = $conf->option_or_data('VERSION');
     my $libs = $conf->data->get('libs');
 
     $libs .= ' -pthread' unless $libs =~ /pthread/;
@@ -20,9 +22,9 @@
 
         has_dynamic_linking    => 1,
         parrot_is_shared       => 1,
-        libparrot_shared       => 'libparrot$(SHARE_EXT).$(SOVERSION)',
-        libparrot_shared_alias => 'libparrot$(SHARE_EXT)',
-        libparrot_soname       => '-Wl,-soname=libparrot$(SHARE_EXT).$(SOVERSION)',
+        libparrot_shared       => "libparrot$share_ext.$version",
+        libparrot_shared_alias => "libparrot$share_ext",
+        libparrot_soname       => "-Wl,-soname=libparrot$share_ext.$version",
     );
 }
 

Modified: branches/tt761_keys_revamp/config/init/hints/freebsd.pm
==============================================================================
--- branches/tt761_keys_revamp/config/init/hints/freebsd.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/config/init/hints/freebsd.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -9,6 +9,8 @@
 sub runstep {
     my ( $self, $conf ) = @_;
 
+    my $share_ext = $conf->option_or_data('share_ext');
+    my $version   = $conf->option_or_data('VERSION');
     my $libs = $conf->data->get('libs');
 
     # get rid of old pthread-stuff, if any
@@ -35,9 +37,9 @@
 
         has_dynamic_linking    => 1,
         parrot_is_shared       => 1,
-        libparrot_shared       => 'libparrot$(SHARE_EXT).$(SOVERSION)',
-        libparrot_shared_alias => 'libparrot$(SHARE_EXT)',
-        libparrot_soname       => '-Wl,-soname=libparrot$(SHARE_EXT).$(SOVERSION)',
+        libparrot_shared       => "libparrot$share_ext.$version",
+        libparrot_shared_alias => "libparrot$share_ext",
+        libparrot_soname       => "-Wl,-soname=libparrot$share_ext.$version",
     );
 }
 

Modified: branches/tt761_keys_revamp/config/init/hints/linux.pm
==============================================================================
--- branches/tt761_keys_revamp/config/init/hints/linux.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/config/init/hints/linux.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -13,6 +13,8 @@
     my $ccflags   = $conf->option_or_data('ccflags');
     my $cc        = $conf->option_or_data('cc');
     my $linkflags = $conf->option_or_data('linkflags');
+    my $share_ext = $conf->option_or_data('share_ext');
+    my $version   = $conf->option_or_data('VERSION');
     my $verbose;
 
     $verbose = $conf->options->get('verbose');
@@ -142,9 +144,9 @@
 
         has_dynamic_linking    => 1,
         parrot_is_shared       => 1,
-        libparrot_shared       => 'libparrot$(SHARE_EXT).$(SOVERSION)',
-        libparrot_shared_alias => 'libparrot$(SHARE_EXT)',
-        libparrot_soname       => '-Wl,-soname=libparrot$(SHARE_EXT).$(SOVERSION)',
+        libparrot_shared       => "libparrot$share_ext.$version",
+        libparrot_shared_alias => "libparrot$share_ext",
+        libparrot_soname       => "-Wl,-soname=libparrot$share_ext.$version",
     );
 
      if ( ( split( m/-/, $conf->data->get_p5('archname'), 2 ) )[0] eq 'ia64' ) {

Modified: branches/tt761_keys_revamp/config/init/hints/mswin32.pm
==============================================================================
--- branches/tt761_keys_revamp/config/init/hints/mswin32.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/config/init/hints/mswin32.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -13,6 +13,8 @@
     my $libs      = $conf->option_or_data('libs');
     my $ccflags   = $conf->option_or_data('ccflags');
     my $cc        = $conf->option_or_data('cc');
+    my $share_ext = $conf->option_or_data('share_ext');
+    my $version   = $conf->option_or_data('VERSION');
 
     # Later in the Parrot::Configure::runsteps() process,
     # inter::progs will merge the command-line overrides with the defaults.
@@ -93,7 +95,7 @@
             ldflags             => '-nologo -nodefaultlib',
             libs                => 'kernel32.lib ws2_32.lib msvcrt.lib oldnames.lib ',
             libparrot_static    => 'libparrot' . $conf->data->get('a'),
-            libparrot_shared    => 'libparrot$(SHARE_EXT)',
+            libparrot_shared    => "libparrot$share_ext",
             ar_flags            => '',
             ar_out              => '-out:',
             slash               => '\\',

Modified: branches/tt761_keys_revamp/config/init/hints/openbsd.pm
==============================================================================
--- branches/tt761_keys_revamp/config/init/hints/openbsd.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/config/init/hints/openbsd.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -9,6 +9,8 @@
 sub runstep {
     my ( $self, $conf ) = @_;
 
+    my $share_ext = $conf->option_or_data('share_ext');
+    my $version   = $conf->option_or_data('VERSION');
     my $ccflags = $conf->data->get('ccflags');
     if ( $ccflags !~ /-pthread/ ) {
         $ccflags .= ' -pthread';
@@ -26,9 +28,9 @@
 
         has_dynamic_linking    => 1,
         parrot_is_shared       => 1,
-        libparrot_shared       => 'libparrot$(SHARE_EXT).$(SOVERSION)',
-        libparrot_shared_alias => 'libparrot$(SHARE_EXT)',
-        libparrot_soname       => '-Wl,-soname=libparrot$(SHARE_EXT).$(SOVERSION)',
+        libparrot_shared       => "libparrot$share_ext.$version",
+        libparrot_shared_alias => "libparrot$share_ext",
+        libparrot_soname       => "-Wl,-soname=libparrot$share_ext.$version",
     );
 
     if ( ( split( m/-/, $conf->data->get_p5('archname'), 2 ) )[0] eq 'powerpc' ) {

Modified: branches/tt761_keys_revamp/config/inter/libparrot.pm
==============================================================================
--- branches/tt761_keys_revamp/config/inter/libparrot.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/config/inter/libparrot.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -91,9 +91,9 @@
     $conf->data->set(
         parrot_is_shared => $parrot_is_shared,
 
-        libparrot => $parrot_is_shared
-        ? '$(LIBPARROT_SHARED)'
-        : '$(LIBPARROT_STATIC)',
+        libparrot_for_makefile_only => $parrot_is_shared
+            ? '$(LIBPARROT_SHARED)'
+            : '$(LIBPARROT_STATIC)',
     );
 
     # Set -rpath (or equivalent) for executables to find the

Deleted: branches/tt761_keys_revamp/docs/book/README
==============================================================================
--- branches/tt761_keys_revamp/docs/book/README	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,24 +0,0 @@
-The book will have the following chapters.
-
-1) Overview
-2) Getting Started
-3) Parrot Intermediate Representation (PIR)
-4) Compiler Tools (PCT)
-5) Grammar Engine (PGE)
-6) Grammar Actions (NQP)
-7) Dynamic C-level Objects (PMCs)
-8) Dynamic Opcodes
-9) Parrot Assembly Language (PASM)
-10) Instruction Reference
-11) Directive Reference
-12) Operator Reference
-Appendix A) Glossary
-Appendix B) Patch Submission
-Appendix C) Command-Line Options
-Appendix D) Build Options
-Appendix E) Source Code
-
-
-Top-level headings in each chapter (the chapter title) are level 1 headings.
-All sub-headings in the chapter are level 2 and below. All chapter files should
-contain the VIM suffix (which is a codingstd for all of the Parrot repo).

Deleted: branches/tt761_keys_revamp/docs/book/appa_glossary.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/book/appa_glossary.pod	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,321 +0,0 @@
-=pod
-
-=head1 Glossary
-
-Short descriptions of words and acronyms found in Parrot development.
-
-=over 4
-
-=item AST
-
-Abstract Syntax Tree: a data structure typically generated by a language
-parser.
-
-=item Continuations
-
-Think of continuations as an execution "context". This context includes
-everything local to that execution path, not just the stack. It is a snapshot
-in time (minus global variables). While it is similar to C's C<setjmp> (taking
-the continuation)/C<longjmp> (invoking the continuation), C<longjmp>'ing only
-works "down" the stack; jumping "up" the stack (ie, back to a frame that has
-returned) is bad. Continuations can work either way.
-
-We can do two important things with continuations:
-
-=over 4
-
-=item 1
-
-Create and pass a continuation object to a subroutine, which may recursively
-pass that object up the call chain until, at some point, the continuation can
-be called/executed to handle the final computation or return value. This is
-pretty much tail recursion.
-
-=item 2
-
-Continuations can be taken at an arbitrary call depth, freezing the call chain
-(context) at that point in time. If we save that continuation object into a
-variable, we can later reinstate the complete context by its "handle". This
-allows neat things like backtracking that aren't easily done in conventional
-stacked languages, such as C. Since continuations represent "branches" in
-context, it requires an environment that uses some combination of heap-based
-stacks, stack trees and/or stack copying.
-
-=back
-
-It is common in a system that supports continuations to implement
-L<co-routines|"Co-Routines"> on top of them.
-
-A continuation is a sort of super-closure. When you take a continuation, it
-makes a note of the current call stack and lexical scratchpads, along with the
-current location in the code. When you invoke a continuation, the system drops
-what it's doing, puts the call stack and scratchpads back, and jumps to the
-execution point you were at when the continuation was taken. It is, in effect,
-like you never left that point in your code.
-
-Note that, like with closures, it only puts the B<scratchpads> back in scope -
-it doesn't do anything with the values in the variables that are in those
-scratchpads.
-
-=item Co-Routines
-
-Co-routines are virtually identical to normal subroutines, except while
-subroutines always execute from their starting instruction to where they
-return, co-routines may suspend themselves (or be suspended asynchronously if
-the language permits) and resume at that point later. We can implement things
-like "factories" with co-routines. If the co-routine never returns, every time
-we call it, we "resume" the routine.
-
-A co-routine is a subroutine that can stop in the middle, and start back up
-later at the point you stopped. For example:
-
-    sub sample : coroutine {
-       print "A\n";
-       yield;
-       print "B\n";
-       return;
-    }
-
-    sample();
-    print "Foo!\n";
-    sample();
-
-will print
-
-     A
-     Foo!
-     B
-
-Basically, the C<yield> keyword says, "Stop here, but the next time we're
-called, pick up at the next statement." If you return from a co-routine, the
-next invocation starts back at the beginning.  Co-routines remember all their
-state, local variables, and suchlike things.
-
-=item COW
-
-Copy On Write: a technique that copies strings lazily.
-
-If you have a string A, and make a copy of it to get string B, the two strings
-should be identical, at least to start. With COW, they are, because string A
-and string B aren't actually two separate strings - they're the same string,
-marked COW. If either string A or string B are changed, the system notes it and
-only at that point does it make a copy of the string data and change it.
-
-If the program never actually changes the string - something that's fairly
-common - the program need never make a copy, saving both memory and time.
-
-=item destruction
-
-Destruction is low level memory clean up, such as calling C<free> on
-C<malloc>ed memory.  This happens after L<"finalization">, and if resources are
-adequate, may only happen as a side effect of program exit.
-
-=item DOD
-
-Dead Object Detection: the process of sweeping through all the objects,
-variables, and whatnot inside of Parrot, and deciding which ones are in use and
-which ones aren't. The ones that aren't in use are then freed up for later
-reuse. (After they're destroyed, if active destruction is warranted.)
-
-See also: L<"GC">
-
-=item finalization
-
-Finalization is high-level, user visible cleanup of objects, such as closing an
-associated DB handle. Finalization reduces active objects down to passive
-blocks of memory, but does not actually reclaim that memory. Memory is
-reclaimed by the related L<"destruction"> operation, as and when necessary.
-
-=item GC
-
-Garbage Collection: the process of sweeping through all the active objects,
-variables, and structures, marking the memory they're using as in use, and all
-other memory is freed up for later reuse.
-
-Garbage Collection and Dead Object Detection are separate in Parrot, since we
-generally chew through memory segments faster than we chew through objects.
-(This is a characteristic peculiar to Perl and other languages that do string
-processing. Other languages chew through objects faster than memory)
-
-See also: L<"DOD">
-
-=item HLL
-
-High-Level Language; Any of the languages that target the parrot virtual
-machine.
-
-=item ICU
-
-International Components for Unicode
-
-ICU is a C and C++ library that provides support for Unicode on a variety of
-platforms. It was distributed with parrot at one time, but current releases
-require you to get your own copy.
-
-L<http://oss.software.ibm.com/icu/index.html>
-
-=item IMCC
-
-Intermediate Code Compiler: the component of parrot that compiles PASM
-and PIR into bytecode.
-
-See also L<"PIR">.
-
-=item MRO
-
-Method resolution order
-
-=item NCI
-
-Native Call Interface: parrot's interface to native "C" libraries,
-without a C-compiler.
-
-=item NQP
-
-Not Quite Perl (6):  designed to be a very small compiler for
-quickly generating PIR routines to create transformers for Parrot (especially
-HLL compilers).
-
-See also L<"PCT">.
-
-=item Packfile
-
-Another name for a PBC file, due to the names used for data structures in one
-of the early implementations in Perl 5.
-
-=item PAST
-
-Acronym for Parrot Abstract Syntax Tree, a set of classes that represent an
-abstract syntax tree.
-
-See also L<"PCT">.
-
-=item PBC
-
-Parrot Bytecode. The name for the "executable" files that can be passed to the
-Parrot interpreter for immediate execution (although PASM and IMC files can be
-executed directly, too).
-
-See also L<"Packfile">.
-
-=item PCT
-
-Parrot Compiler Toolkit: a complete set of tools and libraries
-that are designed to create compilers targeting Parrot. The principal
-components of PCT are PGE, PCT::HLLCompiler (a compiler driver), PAST classes,
-POST classes, PCT::Grammar (a base class for PGE grammars).
-
-In the ideal case, a language can be implemented by providing its parser
-(using Perl 6 rules) which is generated by PGE, and providing a module written
-in NQP that contains the I<actions> that are to be invoked during the parse.
-These actions can then create the appropriate PAST nodes. A PAST to PIR
-transformation already exists. Depending on the language, other phases can
-be added, or overridden (for instance, the PAST to PIR transformation).
-
-=item PIRC
-
-Acronym for PIR Compiler, a PIR compiler currently under development.
-The purpose is to reimplement the PIR language, which is currently
-implemented by IMCC. PIRC is written using a Bison and Flex grammar
-specification.
-
-=item PDD
-
-Parrot Design Document: documents that describe the features parrot must
-implement.
-
-=item PGE
-
-Parrot Grammar Engine.
-
-See also L<"PCT">.
-
-=item PIR
-
-Parrot Intermediate Representation: A medium-level assembly language for Parrot
-that hides messy details like register allocation so language compiler writers
-who target Parrot don't have to roll their own. Files have the
-extension C<.pir>.
-
-=item PMC
-
-Polymorphic Container:  these classes are the primitives that
-HLLs use to represent their fundamental types, such as Perl's
-scalar values.
-
-=item Pod
-
-The preferred format for all kinds of documentation in Parrot.
-
-=item POST
-
-Parrot Opcode Syntax Tree: A set of classes that represent opcodes.
-
-See also L<"PCT">.
-
-=item Predereferencing
-
-=for comment
-XXX This section needs to be edited down.
-
-A bytecode transformation technique which reduces the amount of pointer
-dereferencing done in the inner loop of the interpreter by pre-converting
-opcode numbers into pointers to their opfuncs, and also converting the register
-numbers and constant numbers in the arguments to the ops into pointers.
-
-The original implementation by Gregor Purdy was posted on 2001-12-11.  On one
-test system, it resulted in a 22% speed increase on a test program with a tight
-inner loop.
-
-L<http://archive.develooper.com/perl6-internals@perl.org/msg06941.html>
-
-On 2001-12-18, predereferencing got a speed boost (to about 47% faster than the
-regular DO_OP inner loop -- without compiler optimizations turned on). This was
-due to an off-list (actually over lunch) suggestion by John Kennedy that
-instead of pre-initializing the new copy of the bytecode with NULL pointers, we
-pre-initialize it with pointers to a pseudo-opfunc that does the
-predereferencing whenever it is encountered.
-
-On 2002-04-11, Jason Gloudon suggested combining aspects of the Computed Goto
-Core and the Prederef[erencing] Core.
-
-L<http://archive.develooper.com/perl6-internals@perl.org/msg07064.html>
-
-The week of 2003-02-09, Leopold Toetsch combined Computed Goto and
-Predereferencing to produce the CGP core.
-
-L<http://dev.perl.org/perl6/list-summaries/2003/p6summary.2003-02-09.html#Week_of_the_alternative_runloops>
-
-Later, on 2003-02-14, Leopold Totsch and Nicholas Clark combined the JIT and
-the Computed Goto Prederef cores to great effect.
-
-L<http://www.perl.com/pub/a/2003/02/p6pdigest/20030216.html>
-
-=item Run Core
-
-aka run loop, aka runcore. The way Parrot executes PBCs.
-See L<running.pod> for a list of available runcores, and how to tell
-parrot which one to use.
-
-=item TGE
-
-Tree Grammar Engine: a tool that can be used to generate tree transformers.
-
-=item vtable
-
-A table of operations attached to some data types, such as PMCs and strings.
-Vtables are used to avoid using switches or long C<if> chains to handle
-different data types.  They're similar to method calls, except that their names
-are pre-selected, and there is no direct way to invoke them from PIR.
-
-=item Warnock's Dilemma
-
-The dilemma you face when posting a message to a public forum about something
-and not even getting an acknowledgment of its existence. This leaves you
-wondering if your problem is unimportant or previously addressed, if everyone's
-waiting on someone else to answer you,  or if maybe your mail never actually
-made it to anyone else in the forum.
-
-=back
-
-=cut

Deleted: branches/tt761_keys_revamp/docs/book/appb_patch_submission.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/book/appb_patch_submission.pod	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,138 +0,0 @@
-=pod
-
-=head1 Patch submission
-
-X<Parrot;patch submission>
-Parrot development proceeds through a continuous stream of patches.
-Patches are the currency of exchange in the project--the unit of
-work. Patches can fix bugs, add features, modify capabilities,
-remove cruft, and improve the suite of tests and the project
-documentation. If something needs to change, it will typically require
-the submission of a new patch.
-
-While anyone is free to submit a patch, only a small number of people have
-the ability to apply patches to the central Parrot repository.
-These people are called I<committers>. By allowing all people to get
-involved through patch submission and testing, the project can harness
-the efforts of a large group but still keep the same high quality
-as a small group of experienced developers.
-
-Every submitted patch is automatically forwarded to the p2 list where
-it's subject to peer review. Small patches typically spark little debate,
-and can be well-tested on many platforms before being committed to the
-repository. Patches tend to be small modular changes, which makes for
-easy testing and evaluation. Occasionally a large feature such as an entire
-language implementation is submitted in a single patch, but these are the
-exceptions.
-
-Submitting a patch is fairly straightforward. You create a file that
-lists all your changes, a diff or a patch, and email it to the ticket
-tracking system at U<parrotbug at parrotcode.org>. It's important to make
-sure your patch and your email have descriptive titles so that the
-committers and testers have a better idea about what it does. The body of
-your email should also include a good description about what you changed
-and why.
-
-It's important that you create your patches from a checked-out subversion
-repository, not from a tarball or a snapshot. This way, you can ensure
-that your diff is made against the latest version of the files. If you patch
-an old version, the problem may have already been resolved! Make sure
-the paths listed in the patch match those in the repository. There are two
-methods of creating patches that will do this for you. You can make changes
-directly in your checked-out copy of the subversion repository and
-then create diffs using the command C<svn diff>. Alternatively, you can
-make a copy of the repository and then create diffs between the two
-copies with the C<diff -u> command:
-
-  diff -u parrot/README parrot_changed/README
-
-Either method is fine, and both are equally common on p2. Your
-working style and the types of changes you make--small and modular
-versus large and sweeping--will influence which method you choose.
-
-Next, when you're making changes, take some extra time to consider how
-your patch affects the rest of the system. If your patch adds a new
-file, patch the main F<MANIFEST> file to include it. If you add a new
-feature, make sure to write tests for it. If you fix a bug, add a test
-to prove that it's fixed. See "Writing Tests" in Chapter
-9 for more on writing tests for Parrot. Tests are very important for
-Parrot development, and writing good tests is a valuable skill for
-developers to have. Before you submit a patch always recompile the
-system yourself with the patch included and run all tests to prove that
-it works. You can build and test Parrot completely by running the
-following commands:
-
-  make clean
-  perl Configure.pl
-  make
-  make test
-
-Consider the people who will review and apply your patch, and try
-to make their jobs easier. Patch filenames should be as descriptive as
-possible: F<fix_readme_aardvark_typo.patch> is far better than
-F<README.patch>. An attached file is better than a diff pasted into an
-email, because it can be applied without manual editing. The
-conventional extension for patch files is F<.patch>.
-
-In the email message, always start the subject with "[PATCH]", and
-make the subject as clear as possible: "[PATCH] misspelled aardvark in
-main README file" is better than "[PATCH] typo". The body of the
-message should clearly explain what the patch is supposed to do and
-why you're submitting it. Make a note if you're adding or deleting
-files so they won't be missed.
-
-Here is a good example of a patch submission using the subversion diff
-method (an actual patch from p2). It's short, sticks to the point, and
-clearly expresses the problem and the solution. The patch filename and
-the subject of the message are both descriptive:
-
-=for author
-
-Possible alternates: ticket #23501, #24053 (not from top level)
-
-=end for
-
-  Subject: [PATCH] Pointers in List_chunk not initialized
-  From: Bruce Gray
-  
-  On Win32, these tests are segfaulting due to invalid
-  pointers in List_chunk structs:
-  t/op/string.t             97-98
-  t/pmc/intlist.t           3-4
-  t/pmc/pmc.t               80
-  
-  The problem is caused by list.c/allocate_chunk not
-  initializing the pointers. This patch corrects the problem.
-  
-  --
-  Hope this helps,
-  Bruce Gray
-
-With the attached file F<list_chunk_initialize.patch>:
-
-
-  Index: list.c
-  =========================================
-  RCS file: /cvs/public/parrot/list.c,v
-  retrieving revision 1.23
-  diff -u -r1.23 list.c
-  --- list.c        27 Dec 2002 09:33:11 -0000        1.23
-  +++ list.c        28 Dec 2002 03:37:35 -0000
-  @@ -187,6 +187,10 @@
-       Parrot_block_GC_sweep(interpreter);
-       chunk = (List_chunk *)new_bufferlike_header(interpreter, sizeof(*chunk));
-       chunk->items = items;
-  +    chunk->n_chunks = 0;
-  +    chunk->n_items  = 0;
-  +    chunk->next     = NULL;
-  +    chunk->prev     = NULL;
-       Parrot_allocate_zeroed(interpreter, (Buffer *)chunk, size);
-       Parrot_unblock_GC_mark(interpreter);
-       Parrot_unblock_GC_sweep(interpreter);
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/tt761_keys_revamp/docs/book/appc_command_line_options.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/book/appc_command_line_options.pod	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,340 +0,0 @@
-=pod
-
-=head1 Command-Line Options
-
-Z<CHP-13-SECT-4>
-
-X<command-line options (Parrot)>
-X<Parrot;command-line options>
-X<running.pod file>
-Since Parrot is both an assembler and a bytecode interpreter, it
-has options to control both behaviors. Some options may have changed
-by the time you read this, especially options related to debugging and
-optimization. The document F<imcc/docs/running.pod> should
-have the latest details. Or just run F<parrot --help>.
-
-=head2 General Usage
-
-Z<CHP-13-SECT-4.1>
-
-  parrot [options] file [arguments]
-
-The R<file> is either an F<.pir> or F<.pasm> source file or a
-Parrot bytecode file. Parrot creates an C<Array> object to hold the
-command-line R<arguments> and stores it in C<P5> on program start.
-
-=head2 Assembler Options
-
-Z<CHP-13-SECT-4.2>
-
-=over 4
-
-=item -a, --pasm
-
-X<Parrot;assembler options>
-Assume PASM input on C<stdin>. When Parrot runs a source file with a
-F<.pasm> extension, it parses the file as pure PASM code. This switch
-turns on PASM parsing (instead of the default PIR parsing) when a
-source file is read from C<stdin>.
-
-=item -c,--pbc
-
-Assume PBC file on C<stdin>. When Parrot runs a bytecode file with a
-F<.pbc> extension, it immediately executes the file. This option tells
-Parrot to immediately execute a bytecode file piped in on C<stdin>.
-
-=item -d,--debug [R<hexbits>]
-
-Turn on debugging output. The C<-d> switch takes an optional argument,
-which is a hex value of debug bits. The individual bits are shown in
-Table 11-3. When R<hexbits> isn't specified,
-the default debugging level is 0001. If R<hexbits> is separated
-from the C<-d> switch by whitespace, it has to start with a number.
-
-=begin table picture Debug bits
-
-Z<CHP-13-TABLE-3>
-
-=headrow
-
-=row
-
-=cell Description
-
-=cell Debug bit
-
-=bodyrows
-
-=row
-
-=cell DEBUG_PARROT
-
-=cell 0001
-
-=row
-
-=cell DEBUG_LEXER
-
-=cell 0002
-
-=row
-
-=cell DEBUG_PARSER
-
-=cell 0004
-
-=row
-
-=cell DEBUG_IMC
-
-=cell 0008
-
-=row
-
-=cell DEBUG_CFG
-
-=cell 0010
-
-=row
-
-=cell DEBUG_OPT1
-
-=cell 0020
-
-=row
-
-=cell DEBUG_OPT2
-
-=cell 0040
-
-=row
-
-=cell DEBUG_PBC
-
-=cell 1000
-
-=row
-
-=cell DEBUG_PBC_CONST
-
-=cell 2000
-
-=row
-
-=cell DEBUG_PBC_FIXUP
-
-=cell 4000
-
-=end table
-
-X<Parrot;debugging bits>
-X<debugging bits (Parrot)>
-To produce a huge output on C<stderr>, turn on all the debugging bits:
-
-  $ parrot -d 0ffff ...
-
-
-=item --help-debug
-
-Show debug option bits.
-
-=item -h,--help
-
-Print a short summary of options to C<stdout> and exit.
-
-=item -o R<outputfile>
-
-Act like an assembler. With this switch Parrot won't run code unless
-it's combined with the C<-r> switch. If the name of R<outputfile> ends
-with a F<.pbc> extension, Parrot writes a Parrot bytecode file. If
-R<outputfile> ends with a F<.pasm> extension, Parrot writes a PASM
-source file, even if the input file was also PASM. This can be handy
-to check various optimizations when you run Parrot with the C<-Op>
-switch.
-
-If the extension is F<.o> or equivalent, Parrot generates an object
-file from the JITed program code, which can be used to create a
-standalone executable program. This isn't available on all platforms
-yet; see F<PLATFORMS> for which platforms support this.
-
-=item -r,--run-pbc
-
-Immediately execute bytecode. This is the default unless C<-o> is
-present. The combination of C<-r> C<-o> C<output.pbc> writes a
-bytecode file and executes the generated PBC.
-
-=item -v,--verbose
-
-One C<-v> switch (C<imcc> C<-v>) shows which files are worked on and
-prints a summary of register usage and optimization statistics. Two
-C<-v> switches (C<imcc> C<-v> C<-v>) also prints a line for each
-individual processing step.
-
-=item -y,--yydebug
-
-Turn on C<yydebug> for F<yacc>/F<bison>.
-
-=item -E,--pre-process-only
-
-Show output of macro expansions and quit.
-
-=item -V,--version
-
-Print the program version to C<stdout> and exit.
-
-=item -Ox
-
-Turn on optimizations. The flags currently implemented are shown in
-Table 11-4.
-
-X<Parrot;optimizations>
-X<optimizations (Parrot)>
-
-=begin table picture Optimizations
-
-Z<CHP-13-TABLE-4>
-
-=headrow
-
-=row
-
-=cell Flag
-
-=cell Meaning
-
-=bodyrows
-
-=row
-
-=cell C<-O0>
-
-=cell No optimization (default).
-
-=row
-
-=cell C<-O1>
-
-=cell Optimizations without life info (e.g. branches and constants).
-
-=row
-
-=cell C<-O2>
-
-=cell Optimizations with life info.
-
-=row
-
-=cell C<-Oc>
-
-=cell Optimize function call sequence.
-
-=row
-
-=cell C<-Op>
-
-=cell Rearrange PASM registers with the most-used first.
-
-=end table
-
-=back
-
-=head2 Runcore Options
-
-Z<CHP-13-SECT-4.3>
-
-X<Parrot;bytecode interpreter options>
-X<bytecode interpreter options (Parrot)>
-X<computed goto core>
-X<fast core>
-The interpreter options are mainly for selecting which run-time core to
-use for interpreting bytecode. The current default is the I<computed
-goto core> if it's available. Otherwise the I<fast core> is used.
-
-=over 4
-
-=item -R slow
-
-Run with the I<slow core>
-
-=item -R bounds
-
-Activate bounds checking. This also runs with the I<slow core> as a
-side effect.
-
-=item -R fast
-
-Run with the I<fast core>.
-
-=item -R cgoto
-
-Run the I<computed goto core> (CGoto).
-
-=item -R jit
-
-Run with the I<JIT core> if available.
-
-=item -R cgp
-
-Run with the I<CGoto-Prederefed> core.
-
-=item -R cgp-jit
-
-Run with the I<CGoto-Prederefed with jit> core.
-
-=item -R switch
-
-Run with the I<Switched core>.
-
-=item -R switch-jit
-
-Run with the I<Switched core with jit>.
-
-=item -R exec
-
-Run with the I<exec core>
-(uses JIT at compile time to generate native code)
-
-=item -R gcdebug
-
-Performs a full GC run before every op dispatch
-(good for debugging GC problems)
-
-=item -p,--profile
-
-Activate profiling. This prints a summary of opcode usage and
-execution times after the program stops. It also runs within the
-I<slow core>.
-
-=item -t,--trace
-
-Trace execution. This also turns on the I<slow core>.
-
-=item -w,--warnings
-
-Turn on warnings.
-
-=item -G,--no-gc
-
-Turn off GC. This is for debugging only.
-
-=item -.,--wait
-
-Wait for a keypress before running.
-
-=item --leak-test,--destroy-at-end
-
-Cleanup up allocated memory when the final interpreter is destroyed.
-C<Parrot> destroys created interpreters (e.g. threads) on exit  but
-doesn't normally free all memory for the last terminating interpreter,
-since the operating system will do this anyway. This can create false
-positives when C<Parrot> is run with a memory leak detector. To prevent
-this, use this option.
-
-=back
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/tt761_keys_revamp/docs/book/appd_build_options.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/book/appd_build_options.pod	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,93 +0,0 @@
-=pod
-
-=head1 Build Requirements
-
-There are a number of requirements for building Parrot from source, and a
-number of optional libraries and components that can be used to extend its
-capabilities. None of these requirements or optional components are necessary
-unless you are building Parrot from the source code.
-
-=over 4
-
-=item * C Compiler
-
-Parrot can be built with a number of C compilers. Parrot is written using the
-C89 standard, and the Parrot project officially supports the most recent
-C89 compiler on major systems, including the most recent versions of Microsoft
-C Compiler and the GNU Compiler Collection (GCC).
-
-=item * make
-
-Make is a program to manage and automate the build process. Unix-based systems
-will typically have access to the C<make> command as part of the normal
-development tools. Windows systems can get the C<nmake> utility to perform the
-same task.
-
-=item * Subversion
-
-Subversion is the source control system that is used by the Parrot project.
-You need subversion to checkout the latest version of the source code. You can
-get subversion at L<http://subversion.tigris.org>, or through one of the
-common packaging systems.
-
-=item * bison and flex
-
-Bison and Flex are used to create the lexical analyzer and parser components
-for the PIR compilers IMCC and PIRC. These are not necessary most of the time
-unless you are planning to hack on IMCC and PIRC directly.
-
-=item * ICU
-
-ICU is a library for handling and manipulating Unicode text strings. Without
-ICU libraries installed, you wont be able to use Unicode with your built
-Parrot.
-
-=item * GMP
-
-GMP is a mathematics library for manipulating arbitrary precision and
-arbitrary size numbers. GMP is an optional library used by the BigInt
-and BigNum PMCs.
-
-=item * Readline
-
-The readline library allows some advanced behaviors on the command line such
-as command history.
-
-=item * PCRE
-
-PCRE is a library that provides access to the Perl 5 regular expression syntax.
-In order to use these regular expressions, you will want to install PCRE. To
-do that on Linux you use the command:
-
-  sudo apt-get install libpcre3-dev
-
-=item * GDBM
-
-=item * PQ
-
-=item * GLUT
-
-GLUT is an interface to the OpenGL API. It enables programs running on Parrot
-to have access to 3D graphics. To get GLUT on Linux systems you can use the
-command:
-
-  sudo apt-get install libglut3-dev
-
-=back
-
-In addition to these build requirements listed above, there are a number
-of Perl libraries needed to enable the full set of tests and testing
-facilities, and to generate all the necessary documentation.
-
-To get the Perl packages for Parrot, you can use the commands:
-
-  sudo cpan Test::Base Test::Pod Test::Pod::Coverage Pod::Spell
-  sudo cpan File::HomeDir File::Which Readonly Regexp::Parser
-  sudo cpan Perl::Critic Perl::Critic::Bangs Test::Perl::Critic
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/tt761_keys_revamp/docs/book/appe_source_code.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/book/appe_source_code.pod	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,72 +0,0 @@
-=pod
-
-=head3 Use the source
-
-X<Parrot;source code>
-The second step to participating in Parrot development is to get a
-copy of the source code. If you just want to try it out--experiment
-with a few features and see how it feels--the best option is to
-download the most recent point release for your system. Point releases
-are usually packaged up for easy download and install for various
-platforms, including Windows, Debian, and Redhat. Point releases are
-available from U<http://www.parrot.org/download>.
-
-If you plan to get involved in development, you'll want to check out
-the source from the subversion repository directly. Anyone can get
-anonymous access to read the files and download a working copy to
-explore and test. For commit access, volunteers need a
-U<https://trac.parrot.org> username, and need to be approved by a
-Metacommitter. To download the most recent version from SVN, type this
-command into your terminal N<This is for Linux users, on Mac or
-Windows systems, follow the instructions from your SVN client>:
-
-  svn co https://svn.parrot.org/parrot/trunk parrot
-
-There's also a web interface for viewing files in the repository at
-U<http://svn.parrot.org/parrot/>. 
-
-The repository is large and complex, so it's worth taking a little bit
-of time to explore. The code changes constantly, but most files and
-functions have informative descriptions to help keep track of things.
-
-The most important top-level directory is F<docs/>.  The content isn't
-always up to date, but it is a good place to start. F<parrot.pod>
-provides a quick overview of what's in each documentation file. If you're
-a capable writer and know a thing or two about how Parrot works, the
-documentation is a great place to start contributing. This book that
-you're reading right now was created in F<docs/book/> by ordinary
-contributors. Most other documentation files found here are parsed and
-converted to HTML for display at U<http://www.parrot.org>.
-
-There are a number of existing language implementations for Parrot:
-Perl 6, Python ("Pynie"), Ruby ("Cardinal"), PHP ("Pipp"), Lisp, Lua,
-Tcl ("partcl"), WMLScript, Forth, Scheme, Befunge, BASIC, and many
-others. These language compilers are in various stages of partial
-completion. The page L<https://trac.parrot.org/parrot/wiki/Languages>
-provides meta information on these languages and where to find them.
-If you have a language you're particularly interested to see implemented
-on Parrot, you can see how far along the effort is, or you can start the
-work to implement it yourself. We'll talk more about creating new
-compilers in Chapter 10: High-Level Languages, if you're interested.
-
-The F<lib/> directory contains Perl 5 classes currently used in
-developing, building, and testing Parrot. The F<src/pmc/> directory
-contains the C source code for Parrot classes (PMCs, which you'll read
-more about in Chapter 11).
-
-Most Parrot development happens in F<src/> for the C source code, and
-F<include/parrot/> for the C development header files.
-
-Libraries for use by programs running on Parrot are found in F<runtime/>.
-
-The F<examples/> directory contains some example Parrot PIR and Assembly
-code, as well as benchmarks. More discussions about these topics will be
-found in Chapter 3, Chapter 5, and Chapter 7
-respectively.
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/tt761_keys_revamp/docs/book/ch01_introduction.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/book/ch01_introduction.pod	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,215 +0,0 @@
-=pod
-
-=head1 Introduction
-
-Parrot is a language-neutral virtual machine for dynamic languages such as
-Ruby, Python, PHP, and Perl. It hosts a powerful suite of compiler tools
-tailored to dynamic languages and a next generation regular expression engine.
-Its architecture is fundamentally different than existing virtual machines such
-as the JVM or CLR, with optimizations for dynamic languages included, a
-register-based system rather than stack-based, and the use of continuations as
-the core means of flow control.
-
-The name "Parrot" was inspired by Monty Python's Parrot sketch. As an April
-Fools' Day joke in 2001, Simon Cozens published "Programming Parrot", a
-fictional interview between Guido van Rossum and Larry Wall detailing their
-plans to merge Python and Perl into a new language called Parrot
-(U<http://www.perl.com/pub/a/2001/04/01/parrot.htm>).
-
-=head2 Parrot Resources
-
-The starting point for all things related to Parrot is the main website
-U<http://www.parrot.org/>. The site lists additional resources, well as recent
-news and information about the project and the Parrot Foundation, which holds
-the copyright over Parrot and helps guide development and the community.
-
-=head3 Documentation
-
-Parrot includes extensive documentation in the distribution. The full
-documentation for the latest release is available online at
-U<http://docs.parrot.org/>.
-
-=head3 Mailing Lists
-
-X<parrot-dev (Parrot mailing list)>
-X<mailing lists>
-
-The primary mailing list for Parrot is I<parrot-dev at lists.parrot.org>.  If
-you're interested in getting involved in development, you may also want to
-follow the I<parrot-commits> and I<parrot-tickets> lists.  Information on all
-the Parrot mailing lists and subscription forms for each is available at
-U<http://lists.parrot.org/mailman/listinfo>.
-
-The archives for I<parrot-dev> are also available on Google Groups at
-U<http://groups.google.com/group/parrot-dev> and via NNTP at
-U<nntp://news.gmane.org/gmane.comp.compilers.parrot.devel>.
-
-=head3 IRC
-
-X<#parrot (Parrot IRC channel)>
-X<IRC channel (#parrot)>
-
-Parrot developers and users congregate on IRC at C<#parrot> on the
-U<irc://irc.parrot.org> server. It's a good place to get real-time answers to
-questions or see how things are progressing.
-
-=head3 Issue Tracking & Wiki
-
-X<trac.parrot.org website>
-X<issue tracking (trac.parrot.org)>
-
-Parrot developers track issues with a Trac site at U<https://trac.parrot.org/>.
-Users can submit new tickets and track the status of existing tickets.  The
-site also includes a wiki used in project development, a source code browser,
-and the project roadmap.
-
-=head2 Parrot Development
-
-X<development cycles>
-
-Parrot's first release occurred in September 2001.  It reached 1.0 in March
-2009. The Parrot project makes releases on the third Tuesday of each month. Two
-releases a year E<mdash> occuring every January and July E<mdash> are
-"supported" releases intended for production use.  The other ten releases are
-development releases for language implementers and testers.
-
-Development proceeds in cycles around releases. Activity just before a release
-focuses on closing tickets, fixing bugs, reviewing documentation, and preparing
-for the release. Immediately after the release, larger changes occur, such as
-merging branches, adding large features, or removing deprecated features. This
-allows developers to ensure that changes have sufficient testing time before
-the next release.  Releases also encourage feedback as casual users and testers
-explore the newest versions.
-
-=head2 The Parrot Team
-
-Parrot developers fulfill several rules according to their skills and interests.
-
-=over 4
-
-=item Architect
-
-X<architect role>
-
-The architect has primary responsibility for setting the overall direction of
-the project, facilitating team communication, and explaining and evaluating
-architectural issues. The architect makes design decisions and documents them
-in Parrot Design Documents, and oversees design and documentation work
-delegated to other members of the team to provide a coherent vision across the
-project. The architect also works with the release managers to develop and
-maintain the release schedule. Allison Randal currently leads the Parrot
-project as architect.
-
-=item Release Managers
-
-X<release manager role>
-
-Release managers manage and produce monthly releases according to the release
-schedule. Parrot has multiple release managers who rotate the responsibility
-for each monthly release. The release managers develop and maintain the release
-schedule jointly with the project architect.
-
-=item Metacommitter
-
-X<metacommitter role>
-
-Metacommitters manage commit access to the Parrot repository. Once a
-contributor is selected for commit access, a metacommitter gives the new
-committer access to the SVN repository and the bugtracker. The architect is a
-metacommitter, but other team members also hold this role.
-
-=item Committer
-
-X<committer role>
-
-Contributors who submit numerous, high-quality patches may be considered to
-become a committer. Committers have commit access to the full Parrot
-repository, though they often specialize on particular parts of the project.
-Contributors may be considered for commit access either by being nominated by
-another committer, or by requesting it.
-
-=item Core Developer
-
-X<core developer role>
-
-Core developers develop and maintain core subsystems such as the I/O
-subsystem, the exceptions system, or the concurrency scheduler.
-
-=item Compiler Developer
-
-X<compiler developer role>
-
-Compiler developers develop and maintain one or more Parrot front-end
-compilers such as IMCC, PIRC, PGE and TGE.
-
-=item High-Level Language Developer
-
-X<HLL developer role>
-
-Developers who work on any of the high-level languages that target
-ParrotE<mdash>such as Lua, Perl, PHP, Python, Ruby, or TclE<mdash>are
-high-level language developers. The Parrot repository includes a few example
-languages. A full list of languages is available at
-U<https://trac.parrot.org/parrot/wiki/Languages>.
-
-=item Build Manager
-
-X<build manager role>
-
-Build managers maintain and extend configuration and build subsystems.
-They review smoke reports and attempt to extend platform support.
-
-=item Tester
-
-X<tester role>
-
-Testers develop, maintain, and extend the core test suite coverage and testing
-tools. Testers are also responsible for testing goals, including complete
-coverage of core components on targeted platforms.
-
-=item Patch Monsters
-
-X<patch monster role>
-
-Hackers and developers submit patches to Parrot every day, and it takes a keen
-eye and a steady hand to review and apply them all. Patch monsters check
-patches for conformance with coding standards and desirability of features,
-rework them as necessary, verify that the patches work as desired, and apply
-them.
-
-=item Cage Cleaners
-
-X<cage cleaner role>
-
-The cage cleaners ensure that development follows the project's coding
-standards, documentation is complete and accurate, all tests function properly,
-and new users have accurate and comprehensive coding examples. A special class
-of Trac tickets is available for these tasks.  Cage cleaning tasks run the
-gamut from entry-level to advanced; this is a good entry point for new users
-to work on Parrot.
-
-=item General Contributor
-
-X<contributor role>
-
-Contributors write code or documentation, report bugs, take part in email or
-online conversations, or contribute to the project in other ways. All volunteer
-contributions are appreciated.
-
-=back
-
-=head2 Licensing
-
-X<license>
-
-The Parrot foundation supports the Parrot development community and holds
-trademarks and copyrights to Parrot.  The project is available under the
-Artistic License 2.0, allowing free use in commercial and open source/free
-software contexts.
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/tt761_keys_revamp/docs/book/ch02_getting_started.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/book/ch02_getting_started.pod	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,182 +0,0 @@
-=pod
-
-=head1 Getting Started
-
-Before you can use Parrot, you have to get it running on your machine.
-
-=head2 Installing Parrot
-
-The simplest way to install Parrot is to use a pre-compiled binary for your
-operating system or distribution. Packages are available for many packaging
-systems, including Debian, Ubuntu, Fedora, Mandriva, FreeBSD, Cygwin, and
-MacPorts. The Parrot website lists all known packages at
-U<http://www.parrot.org/download>. A binary installer for Windows is also
-available at U<http://parrotwin32.sourceforge.net/>.
-
-If packages aren't available on your system, download the latest supported
-release from U<http://www.parrot.org/release/supported>.
-
-You need a C compiler and a make utility to build Parrot from source code --
-usually C<gcc> and C<make>, but Parrot can build with standard compiler
-toolchains on different operating systems.  Perl 5.8 is also a prerequiste for
-configuring and building Parrot.
-
-If you have these dependencies installed, build the core virtual machine and
-compiler toolkit and run the standard test suite with the commands:
-
-  $ B<perl Configure.pl>
-  $ B<make>
-  $ B<make test>
-
-By default, Parrot installs to directories F<bin/>, C<lib/>, et cetera under
-the prefix F</usr/local>.  If you have privileges to write to these
-directories, install Parrot with:
-
-  $ B<make install>
-
-To install Parrot beneath a different prefix, use the C<--prefix> option to
-C<Configure.pl>:
-
-    $ B<perl Configure.pl --prefix=/home/me/parrot>
-
-If you intend to I<develop> -- not just I<use> -- a language on Parrot, install
-the Parrot developer tools as well:
-
-  $ B<make install-dev>
-
-=head2 Running Parrot
-
-Once you've installed Parrot, run it.  Create a test file called F<news.pasm>.
-C<.pasm> files contain Parrot Assembly Language (PASM) instructions; this is a
-low-level language native to the Parrot virtual machine.
-
-=begin PASM
-
-  say "Here is the news for Parrots."
-  end
-
-=end PASM
-
-Now run this file with:
-
-  $ B<parrot news.pasm>
-
-which will print:
-
-  Here is the news for Parrots.
-
-=head2 Running a Language on Parrot
-
-Next, try out one of Parrot's high-level languages. Create a test file
-called F<more_news.nqp>:
-
-  say "No parrots were involved in an accident on the M1 today..."
-
-Then run it as:
-
-  $ nqp more_news.nqp
-
-which will print:
-
-  No parrots were involved in an accident on the M1 today...
-
-=head2 What Next?
-
-This book describes Parrot in terms of tasks it supports.  You may pick and
-choose chapters based on your area of interest:
-
-=over 4
-
-=item Chapter 3, I<Parrot Intermediate Representation>
-
-Parrot Intermediate Representation (PIR) is a mid-level language native to the
-Parrot virtual machine s commonly used for writing extensions and tools for
-Parrot.
-
-=item Chapter 4, I<Compiler Tools>
-
-The Parrot Compiler Toolkit (PCT) provides a common infrastructure and
-utilities for implementing languages on Parrot.
-
-=item Chapter 5, I<Grammar Engine>
-
-The Parrot Grammar Engine (PGE) is a powerful regular expression engine and
-recursive descent parser. PGE is part of the compiler tools; understanding PGE
-is essential to implementing a language on Parrot.
-
-=item Chapter 6, I<Grammar Actions>
-
-NQP (Not Quite Perl) is a lightweight language loosely inspired by Perl 6. NQP
-is part of the compiler tools used for transforming a Parrot-hosted language
-into instructions for Parrot to execute.
-
-=item Chapter 7, I<Dynamic PMCs>
-
-=for author
-
-This chapter suggests the need for a chapter on core PMCs.  Alternately, this
-chapter could cover PMCs in general and dynpmcs as a special case of PMCs.
-
-=end for
-
-Parrot allows language developers to extend Parrot's core data types to suit
-the needs of advanced languages.
-
-=item Chapter 8, I<Dynamic Opcodes>
-
-=for author
-
-The same point applies for ops and dynops.
-
-=end for
-
-Parrot allows language developers to extend Parrot's core instruction set --
-again to suit the needs of advanced languages.
-
-=item Chapter 10, I<Instruction Reference>
-
-Parrot's standard instruction set provides powerful behavior for primitive
-operations, control flow, object orientation, exception handling, and more.
-
-=item Chapter 11, I<Directive Reference>
-
-Parrot supports directives used within PIR and PASM code to change the behavior
-of code and to control what happens in bytecode.
-
-=item Chapter 13, I<Operator Reference>
-
-PIR provides several higher-level operators as a convenience to programmers and
-code generators.
-
-=item Appendix A, I<Glossary>
-
-Parrot and its environment have common jargon.
-
-=item Appendix B, I<Command-Line Options>
-
-Parrot supports several flags to control execution modes, debugging, library
-loading, and more.
-
-=item Appendix C, I<Build Options>
-
-Parrot's configuration process gives administrators and developers tremendous
-control over the build system.
-
-=item Appendix D, I<Source Code>
-
-Parrot's source code is organized along logical lines -- logical, once you know
-the layout.
-
-=item Appendix E, I<Patch Submission>
-
-Parrot depends on the combined efforts of numerous volunteers.  Your
-contributions are very welcome.
-
-=back
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/tt761_keys_revamp/docs/book/ch03_pir.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/book/ch03_pir.pod	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,2412 +0,0 @@
-=pod
-
-=head1 Parrot Intermediate Representation
-
-Z<CHP-3>
-
-X<Parrot Intermediate Representation;;(see PIR)>
-X<PIR (Parrot intermediate representation)>
-
-Parrot Intermediate Representation (PIR) is Parrot's native low-level
-language.N<Parrot has a pure native assembly language called PASM, described in
-Chapter 9.> PIR is fundamentally an assembly language, but it has some
-higher-level features such as operator syntax, syntactic sugar for subroutine
-and method calls, automatic register allocation, and more friendly conditional
-syntax.  PIR is commonly used to write Parrot libraries -- including some of
-PCT's compilers -- and is the target form when compiling high-level languages
-to Parrot.
-
-Even so, PIR is more rigid and "close to the machine" then some higher-level
-languages like C. X<.pir files> Files containing PIR code use the F<.pir>
-extension.
-
-=head2 Basics
-
-PIR has a relatively simple syntax. Every line is a comment, a label, a
-statement, or a directive. Each statement or directive stands on its own line.
-There is no end-of-line symbol (such as a semicolon in other languages).
-
-=head3 Comments
-
-X<PIR comments>
-A comment begins with the C<#> symbol, and continues until the end of the line.
-Comments can stand alone on a line or follow a statement or directive.
-
-    # This is a regular comment. The PIR
-    # interpreter ignores this.
-
-X<PIR POD>
-PIR also treats inline documentation in Pod format as a comment. An
-equals sign as the first character of a line marks the start of a Pod
-block.  A C<=cut> marker signals the end of a Pod block.
-
-  =head2
-
-  This is Pod documentation, and is treated like a
-  comment. The PIR interpreter ignores this.
-
-  =cut
-
-=head2 Labels
-
-Z<CHP-3-SECT-4>
-
-X<PIR (Parrot intermediate representation);labels> X<labels (PIR)> A label
-attaches to a line of code so other statements can refer to it.  Labels can
-contain letters, numbers, and underscores. By convention, labels use all
-capital letters to stand out from the rest of the source code. A label can be
-precede a line of code, though outdenting labels on separate lines improves
-readability:
-
-  GREET:
-      say "'Allo, 'allo, 'allo."
-
-Labels are vital to control flow.
-
-=head3 Statements
-
-Z<CHP-3-SECT-1>
-
-X<statements (PIR)>
-X<PIR (Parrot intermediate representation);statements>
-A statement is either an opcode or syntactic sugar for one or more opcodes. An
-opcode is a native instruction for the virtual machine; it consists of the name
-of the instruction followed by zero or more arguments.
-
-  say "Norwegian Blue"
-
-PIR also provides higher-level constructs, including symbol operators:
-
-  $I1 = 2 + 5
-
-Under the hood, these special statement forms are just syntactic sugar for
-regular opcodes. The C<+> symbol corresponds to the C<add> opcode, the C<->
-symbol to the C<sub> opcode, and so on.  The previous example is equivalent to:
-
-  add $I1, 2, 5
-
-=head3 Directives
-
-Directives begin with a period (C<.>); Parrot's parser handles them specially.
-Some directives specify actions that occur at compile time. Other directives
-represent complex operations that require the generation of multiple
-instructions.  The C<.local> directive declares a typed register.
-
-  .local string hello
-
-PIR also has a macro facility to create user-defined directives.
-
-=head3 Literals
-
-Integers and floating point numbers are numeric literals. They can be positive
-or negative.
-
-  $I0 = 42       # positive
-  $I1 = -1       # negative
-
-Integer literals can also be binary, octal, or hexadecimal:
-
-  $I3 = 0b01010  # binary
-  $I3 = 0o78     # octal
-  $I2 = 0xA5     # hexadecimal
-
-Floating point number literals have a decimal point, and can use scientific
-notation:
-
-  $N0 = 3.14
-  $N2 = -1.2e+4
-
-X<strings;in PIR>
-String literals are enclosed in single or double-quotes.N<L<Strings>
-explains the differences between the quoting types.>
-
-  $S0 = "This is a valid literal string"
-  $S1 = 'This is also a valid literal string'
-
-=head3 Variables
-
-PIR variables can store four different kinds of valuesE<mdash>integers, numbers
-(floating point), strings, and objects. The simplest way to work with these
-values is through register variables. Register variables always start with a
-dollar sign (C<$>) and a single character which specifies the type of the
-register: integer (C<I>), number (C<N>), string (C<S>), or PMC (C<P>).
-Registers have numbers as well; the "first" string register is
-C<$S0>.N<Register numbers may or may not correspond to the register used
-internally; Parrot's compiler remaps registers as appropriate.>
-
-  $S0 = "Who's a pretty boy, then?"
-  say $S0
-
-PIR also has named variables, which are declared with the C<.local> directive.
-As with registers, there are four valid types for named variables: C<int>,
-C<num>, C<string>, and C<pmc>.N<Again, for "I<P>olyI<M>orphic I<C>ontainer".>
-After declaring a named variable, you can use the name anywhere you would use a
-register:
-
-  .local string hello
-  set hello, "'Allo, 'allo, 'allo."
-  say hello
-
-Integer (C<I>) and Number (C<N>) registers use platform-dependent sizes and
-limitations.N<There are a few exceptions to this; Parrot smooths out some of the
-bumps and inconsistencies so that PIR code behaves the same way on all
-supported platforms.> Internally, Parrot treats both I and N registers as
-signed quantities internally for the purposes of arithmetic. Parrot's floating
-point values and operations all comply with the IEEE 754 standard.
-
-Strings (S) are buffers of variable-sized data. The most common use of S
-registers and variables is to store textual data. S registers I<may> also be
-buffers for binary or other non-textual data, though this is rare.N<In general,
-a custom PMC is mroe useful.>  Parrot strings are flexible and powerful, to
-account for all the complexity of human-readable (and computer-representable)
-textual data.
-
-The final data type is the PMC. PMC resemble classes and objects are in
-object-oriented languages. They are the basis for complex data structures and
-object-oriented behavior in Parrot.
-
-=head2 Strings
-
-Strings in double-quotes accept all sorts of escape sequences using
-backslashes. Strings in single-quotes only allow escapes for nested quotes:
-
-  $S0 = "This string is \n on two lines"
-  $S0 = 'This is a \n one-line string with a slash in it'
-
-Parrot supports several escape sequences in double-quoted strings:
-
-  \xhh        1..2 hex digits
-  \ooo        1..3 oct digits
-  \cX         Control char X
-  \x{h..h}    1..8 hex digits
-  \uhhhh      4 hex digits
-  \Uhhhhhhhh  8 hex digits
-  \a          An ASCII alarm character
-  \b          An ASCII backspace character
-  \t          A tab
-  \n          A newline
-  \v          A vertical tab
-  \f
-  \r
-  \e
-  \\          A backslash
-  \"          A quote
-
-If you need more flexibility in defining a string, use a X<heredoc string
-literal>.  The C<E<lt>E<lt>> operator starts a heredoc.  The string terminator
-immediately follows.  All text until the terminator is part of the heredoc.
-The terminator must appear on its own line, must appear at the beginning of the
-line, and may not have any trailing whitespace.
-
-  $S2 = << "End_Token"
-
-  This is a multi-line string literal. Notice that
-  it doesn't use quotation marks.
-
-  End_Token
-
-=head3 Strings: Encodings and Charsets
-
-X<charset>
-Strings are complicated; string declarations aren't the whole story.  In olden
-times, strings only needed to support the ASCII character set (or charset), a
-mapping of 128 bit patterns to symbols and English-language characters. This
-worked as long as everyone using a computer read and wrote English and used a
-small handful of punctuation symbols.
-
-In other words, it was woefully insufficient for international uses, polyglots, and more.
-
-A modern string system must manage several character encodings and charsets in
-order to make sense out of all the string data in the world.  Parrot does this.
-Every string has an associated encoding and an associated character set.  The
-default charset is 8-bit ASCII, which is simple to use and is almost
-universally supported.
-
-Double-quoted string constants can have an optional prefix specifying the the
-string's encoding and charset.N<As you might suspect, single-quoted strings do
-not support this.> Parrot will maintain these values internally, and will
-automatically convert strings when necessary to preserve the information.
-String prefixes are specified as C<encoding:charset:> at the front of the
-string. Here are some examples:
-
-  $S0 = utf8:unicode:"Hello UTF8 Unicode World!"
-  $S1 = utf16:unicode:"Hello UTF16 Unicode World!"
-  $S2 = ascii:"This is 8-bit ASCII"
-  $S3 = binary:"This is raw, unformatted binary data"
-
-The C<binary:> charset treats the string as a buffer of raw unformatted binary
-data. It isn't really a string per se, because binary data contains no readable
-characters.  As mentioned earlier, this exists to support libraries which
-manipulate binary data that doesn't easily fit into any other primitive data
-type.
-
-When Parrot combines two strings (such as through concatenation), they must
-both use the same character set and encoding.  Parrot will automatically
-upgrade one or both of the strings to use the next highest compatible format as
-necessary. ASCII strings will automatically upgrade to UTF-8 strings if needed,
-and UTF-8 will upgrade to UTF-16. All of these conversions happen inside
-Parrot; you the programmer don't need to worry about the details.
-
-=head2 Named Variables
-
-Z<CHP-3-SECT-2.3>
-
-X<named variables (PIR)>
-X<PIR (Parrot intermediate representation);named variables>
-
-=for author
-
-The declaration section earlier alludes to this.
-
-=end for
-
-Calling a value "$S0" isn't very descriptive, and usually it's a lot
-nicer to be able to refer to values using a helpful name. For this
-reason Parrot allows registers to be given temporary variable names to
-use instead. These named variables can be used anywhere a register
-would be used normally.N<...because they actually are registers, but
-with fancier names.> They're declared with the C<.local> statement
-which requires a variable type and a name:
-
-  .local string hello
-  set hello, "Hello, Polly."
-  say hello
-
-This snippet defines a string variable named C<hello>, assigns it the value
-"Hello, Polly.", and then prints the value. Under the hood these named
-variables are just normal registers of course, so any operation that a register
-can be used for a named variable can be used for as well.
-
-X<types;variable (PIR)>
-X<variables;types (PIR)>
-The valid types are C<int>, C<num>, C<string>, and C<pmc>
-It should come as no surprise that these are the same as Parrot's four
-built-in register types. Named variables are valid from the point of
-their definition to the end of the current subroutine.
-
-The name of a variable must be a valid PIR identifier. It can contain letters,
-digits and underscores but the first character has to be a letter or an
-underscore. There is no limit to the length of an identifier, other than good
-taste.
-
-As mentioned earlier, Parrot's internal compiler may remap named registers and
-symbolic registers to actual registers as necessary.  This happens
-transparently, and for the most part you never need to know about it.  There's
-one exception: when you know something outside of Parrot must refer to a
-specific register exactly.N<For example, when an NCI call takes a pointer to a
-register and returns a value through the pointer.>  Use the C<:unique_reg>
-modifier on a variable declaration to prevent potential register allocation
-changes:
-
-  .local pmc MyUniquePMC :unique_reg
-
-This attribute C<:unique_reg> will not affect the behavior of Parrot otherwise.
-
-=head2 PMC variables
-
-Z<CHP-3-SECT-2.4>
-
-PMC registers and variables act much like any integer, floating-point
-number, or string register or variable, but you have to instantiate a
-new PMC object into a type before you use it. The C<new> instruction creates
-a new PMC of the specified type:
-
-  $P0 = new 'String'
-  $P0 = "Hello, Polly."
-  say $P0
-
-This example creates a C<String> object, stores it in the PMC register C<$P0>,
-assigns it the value "Hello, Polly.", and prints it.  The type provided to the
-C<.local> directive is either the generic C<pmc> or a type compatible with the
-type passed to C<new>:
-
-  .local String hello    # or .local pmc hello
-  hello = new 'String'
-  hello = "Hello, Polly."
-  say hello
-
-PIR is a dynamic language; that dynamicism is evident in how Parrot handles PMC
-values. Primitive registers like strings, numbers, and integers perform a
-special action called X<autoboxing> when assigned to a PMC. Autoboxing is the
-process of converting a primitive type to a PMC object.  PMC classes exist for
-String, Number, and Integer; notice that the primitive types are in lower-case,
-while the PMC classes are capitalized. If you want to box a value explicitly,
-use the C<box> opcode:
-
-  $P0 = new 'Integer'       # The boxed form of int
-  $P0 = box 42
-  $P1 = new 'Number'        # The boxed form of num
-  $P1 = box 3.14
-  $P2 = new 'String'        # The boxed form of string
-  $P2 = "This is a string!"
-
-The PMC classes C<Integer>, C<Number>, and C<String> are thin overlays on the
-primitive types they represent. These PMC types have the benefit of the
-X<PMC;VTABLE Interface> VTABLE interface. VTABLEs are a standard API that all
-PMCs conform to for performing standard operations. These PMC types support
-custom methods to perform various operations, may be passed to subroutines that
-expect PMC arguments, and can be subclassed by a user-defined type.
-
-=head2 Named Constants
-
-Z<CHP-3-SECT-2.5>
-
-X<PIR (Parrot intermediate representation);named constants>
-X<named constants (PIR)>
-
-The C<.const> directive declares a named constant. It resembles C<.local>; it
-requires a type and a name. It also requires the assignment of a constant
-value.  As with named variables, named constants are visibl only within the
-compilation unit where they're declared. This example declares a named string
-constant C<hello> and prints the value:
-
-  .const string hello = "Hello, Polly."
-  say hello
-
-Named constants may be used in all the same places as literal constants,
-but have to be declared beforehand:
-
-  .const int    the_answer = 42        # integer constant
-  .const string mouse      = "Mouse"   # string constant
-  .const num    pi         = 3.14159   # floating point constant
-
-In addition to normal local constants, you can also specify a global constant
-which is accessible from everywhere in the current code file:
-
-  .globalconst int days = 365
-
-Currently there is no way to specify a PMC constant in PIR source code.
-
-=for author
-
-Why declare constants?
-
-=end for
-
-=head2 Symbol Operators
-
-Z<CHP-3-SECT-3>
-
-X<symbol operators in PIR>
-
-=for author
-
-An earlier section described this already too.
-
-=end for
-
-PIR has many other symbolic operators: arithmetic, concatenation, comparison,
-bitwise, and logical. All PIR operators are translated into one or more Parrot
-opcodes internally, but the details of this translation stay safely hidden from
-the programmer. Consider this example snippet:
-
-  .local int sum
-  sum = $I42 + 5
-  say sum
-
-The statement C<sum = $I42 + 5> translates to the equivalent statement C<add
-sum, $I42, 5>.  PIR symbolic operations are:
-
-  $I0 = $I1 + 5      # Addition
-  $N0 = $N1 - 7      # Subtraction
-  $I3 = 4 * 6        # Multiplication
-  $N7 = 3.14 / $N2   # Division
-  $S0 = $S1 . $S2    # String concatenation
-
-PIR also provides automatic assignment operators such as C<+=>, C<-=>,
-and C<<< >>= >>>. These operators help programmers to perform common
-manipulations on a data value in place, and save a few keystrokes while
-doing them.
-
-A complete list of PIR operators is available in Chapter 13.
-
-=head2 C<=> and Type Conversion
-
-The C<=> operator is very powerful.  Its simplest form stores a value into one
-of the Parrot registers. It can assign a string value to a C<string> register,
-an integer value to an C<int> register, a floating point value into a C<number>
-register, etc. However, the C<=> operator can assign I<any> type of value into
-I<any> type of register; Parrot will handle the conversion for you
-automatically:
-
-  $I0 = 5     # Integer. 5
-  $S0 = $I0   # Stringify. "5"
-  $N0 = $S0   # Numify. 5.0
-  $I0 = $N0   # Intify. 5
-
-Notice that conversions between the numeric formats and strings only makes
-sense when the value to convert is a number.
-
-  $S0 = "parrot"
-  $I0 = $S0        # 0
-
-An earlier example showed a string literal assigned to a PMC register of type
-C<String>. This works for all the primitive types and their autoboxed PMC
-equivalents:
-
-  $P0 = new 'Integer'
-  $P0 = 5
-  $S0 = $P0      # Stringify. "5"
-  $N0 = $P0      # Numify. 5.0
-  $I0 = $P0      # Unbox. $I0 = 5
-
-  $P1 = new 'String'
-  $P1 = "5 birds"
-  $S1 = $P1      # Unbox. $S1 = "5 birds"
-  $I1 = $P1      # Intify. 5
-  $N1 = $P1      # Numify. 5.0
-
-  $P2 = new 'Number'
-  $P2 = 3.14
-  $S2 = $P2      # Stringify. "3.14"
-  $I2 = $P2      # Intify. 3
-  $N2 = $P2      # Unbox. $N2 = 3.14
-
-=head2 Compilation Units
-
-Z<CHP-3-SECT-4.1>
-
-X<PIR (Parrot intermediate representation);subroutine> X<subroutine (PIR)>
-Subroutines in PIR are roughly equivalent to the subroutines or methods of a
-high-level language.  All code in a PIR source file must appear within a
-subroutine.  The simplest syntax for a PIR subroutine starts with the C<.sub>
-directive and ends with the C<.end> directive:
-
-=begin PIR
-
-  .sub 'main'
-      say "Hello, Polly."
-  .end
-
-=end PIR
-
-This example defines a subroutine named C<main> that prints a string C<"Hello,
-Polly.">. Parrot will normally execute the first subroutine it encounters in
-the first file it runs, but you can flag any subroutine as the first one to
-execute with the C<:main> marker:
-
-=begin PIR
-
-  .sub 'first'
-      say "Polly want a cracker?"
-  .end
-
-  .sub 'second' :main
-      say "Hello, Polly."
-  .end
-
-=end PIR
-
-This code prints out "Hello, Polly." but not "Polly want a cracker?".  Though
-the C<first> function appears first in the source code, C<second> has the
-C<:main> flag and gets called.  C<first> is never called.  Revising that
-program produces different results:
-
-=begin PIR
-
-  .sub 'first' :main
-      say "Polly want a cracker?"
-  .end
-
-  .sub 'second'
-      say "Hello, Polly."
-  .end
-
-=end PIR
-
-The output now is "Polly want a cracker?". Execution in PIR starts at the
-C<:main> function and continues until that function ends.  To perform other
-operations, you must call other functions explicitly.  Chapter 4 describes
-subroutines and their uses.
-
-=head2 Flow Control
-
-Z<CHP-3-SECT-5>
-
-X<PIR (Parrot intermediate representation);flow control>
-X<flow control;in PIR>
-
-Flow control in PIR occurs entirely with conditional and unconditional branches
-to labels. This may seem simplistic and primitive, but here PIR shows its roots
-as a thin overlay on the assembly language of a virtual processor.  PIR does
-not support high-level looping structures such as C<while> or C<for> loops. PIR
-has some support for basic C<if> branching constructs, but does not support
-more complicated C<if>/C<then>/C<else> branch structures.
-
-The control structures of high-level languages hew tightly to the semantics of
-those languages; Parrot provides the minimal feature set necessary to implement
-any semantic of an HLL without dictating how that HLL may implement its
-features.  Language agnosticism is an important design goal in Parrot, and
-creates a very flexible and powerful development environment for language
-developers.
-
-X<goto instruction (PIR)>
-The most basic branching instruction is the unconditional branch, C<goto>:
-
-=begin PIR
-
-  .sub 'main'
-      goto L1
-      say "never printed"
-
-  L1:
-      say "after branch"
-      end
-  .end
-
-=end PIR
-
-The first C<say> statement never runs because the C<goto> always skips over it
-to the label C<L1>.
-
-The conditional branches combine C<if> or C<unless> with C<goto>.
-
-=begin PIR
-
-  .sub 'main'
-      $I0 = 42
-      if $I0 goto L1
-      say "never printed"
-  L1:
-      say "after branch"
-      end
-  .end
-
-=end PIR
-
-X<if (conditional);instruction (PIR)> X<unless (conditional);instruction (PIR)>
-In this example, the C<goto> branches to the label C<L1> only if the value
-stored in C<$I0> is true. The C<unless> statement is similar, but it branches
-when the tested value is false.  You can use PMC and STRING registers with
-C<if> and C<unless>.  The op will call the C<get_bool> vtable entry on any PMC
-so used and will convert the STRING to a boolean value.  An undefined value, 0,
-or an empty string are all false values. All other values are true.
-
-The comparison operators (C<E<lt>>, C<E<lt>=>, C<==>, C<!=>, C<E<gt>>,
-C<E<gt>=>) can combine with C<if ...  goto>. These branch when the
-comparison is true:
-
-=begin PIR
-
-  .sub 'main'
-      $I0 = 42
-      $I1 = 43
-      if $I0 < $I1 goto L1
-      say "never printed"
-  L1:
-      say "after branch"
-      end
-  .end
-
-=end PIR
-
-This example compares C<$I0> to C<$I1> and branches to the label C<L1> if
-C<$I0> is less than C<$I1>. The C<if $I0 E<lt> $I1 goto L1> statement
-translates directly to the C<lt> branch operation.
-
-Chapter 11's "PIR Instructions" section summarizes the other comparison
-operators.
-
-X<loops;PIR>
-X<PIR (Parrot intermediate representation);loop constructs>
-PIR has no special loop constructs. A combination of conditional and
-unconditional branches handle iteration:
-
-=begin PIR
-
-  .sub 'main'
-      $I0 = 1               # product
-      $I1 = 5               # counter
-
-  REDO:                     # start of loop
-      $I0 = $I0 * $I1
-      dec $I1
-      if $I1 > 0 goto REDO  # end of loop
-
-      say $I0
-      end
-  .end
-
-=end PIR
-
-X<do-while style loop;(PIR)>
-This example calculates the factorial C<5!>. Each time through the loop it
-multiplies C<$I0> by the current value of the counter C<$I1>, decrements the
-counter, and branches to the start of the loop.  The loop ends when C<$I1>
-counts down to 0. This is a I<do while>-style loop with the condition test at
-the end so that the code always runs at least once through the loop.
-
-X<while-style loop (PIR)>
-For a I<while>-style loop with the condition test at the start, use a
-conditional branch with an unconditional branch:
-
-=begin PIR
-
-  .sub 'main'
-      $I0 = 1               # product
-      $I1 = 5               # counter
-
-  REDO:                     # start of loop
-      if $I1 <= 0 goto LAST
-      $I0 = $I0 * $I1
-      dec $I1
-      goto REDO
-  LAST:                     # end of loop
-
-      say $I0
-      end
-  .end
-
-=end PIR
-
-This example tests the counter C<$I1> at the start of the loop. At the end of
-the loop, it unconditionally branches back to the start of the loop and tests
-the condition again. The loop ends when the counter C<$I1> reaches 0 and the
-C<if> branches to the C<LAST> label. If the counter isn't a positive number
-before the loop, the loop will never execute.
-
-You can build any high-level flow control construct from conditional and
-unconditional branches; the lowest level of computer hardware works this way.
-All modern programming languages use branching constructs to implement their
-most complex flow control devices.
-
-That doesn't make complex code easier to write in PIR.  Fortunately, a series
-of macros exist to simplify flow control.
-
-=head2 Macros
-
-=for author
-
-Needs supplementing; needs moving.
-
-=end for
-
-=head2 Subroutines
-
-Z<CHP-4>
-
-X<PIR (Parrot intermediate representation);subroutines>
-X<subroutines;in PIR>
-The most basic building block of code reuse in PIR is the subroutine. A large
-program may perform a calculation like "the factorial of a number" several
-times.  Subroutines abstract this behavior into a single, named, stand-alone
-unit. PIR is a subroutine-based language in that all code in PIR must exist in
-a subroutine. Execution starts in the C<:main> subroutine, which itself can
-call other subroutines.  Subroutines can fit together into more elaborate
-chunks of code reusability such as methods and objects.
-
-Parrot supports multiple high-level languages.  Each language uses a different
-syntax for defining and calling subroutines. The goal of PIR is not to be a
-high-level language in itself, but to provide the basic tools that other
-languages can use to implement them. PIR's subroutine syntax may seem very
-primitive for this reason.
-
-=head2 Parrot Calling Conventions
-
-Z<CHP-4-SECT-1>
-
-X<PIR (Parrot intermediate representation);subroutines;Parrot calling conventions>
-X<subroutines;Parrot calling conventions;in PIR>
-
-The way that Parrot calls a subroutine -- passing arguments, altering control
-flow, and returning results -- is the "Parrot Calling Conventions" (PCC).
-Parrot generally hides the details of PCC from the programmer.  PIR has several
-constructs to gloss over these details, and the average programmer will not
-need to worry about them.  PCC uses the Continuation Passing Style
-X<Continuation Passing Style (CPS)>X<CPS (Continuation Passing Style)> (CPS) to
-pass control to subroutines and back again. Again, the details are irrelevant
-for most uses, but the power is available to anyone who wants to take advantage
-of it.
-
-=head3 Subroutine Calls
-
-X<PIR (Parrot intermediate representation);subroutine calls>
-PIR's simplest subroutine call syntax looks much like a subroutine
-call from a high-level language. This example calls the subroutine
-C<fact> with two arguments and assigns the result to C<$I0>:
-
-  $I0 = 'fact'(count, product)
-
-This simple statement hides much complexity. It generates a subroutine PMC
-object, creates a continuation PMC object to represent the control flow up to
-this point, passes the arguments, looks up the subroutine by name (and by
-signature, if necessary)), calls the subroutine, and assigns the results of the
-call to the appropriate integer register. This is all in addition to the
-computation the subroutine itself performs.
-
-=head3 Expanded Subroutine Syntax
-
-The single line subroutine call is incredibly convenient, but it isn't always
-flexible enough. PIR also has a more verbose call syntax that is still more
-convenient than manual calls. This example looks up the subroutine C<fact> out
-in the global symbol table and calls it:
-
-  find_global $P1, "fact"
-
-  .begin_call
-    .arg count
-    .arg product
-    .call $P1
-    .result $I0
-  .end_call
-
-X<.arg directive>
-X<.result directive>
-The whole chunk of code from C<.begin_call> to C<.end_call> acts as a single
-unit. The C<.arg> directive sets up and passes arguments to the call. The
-C<.call> directive calls the subroutine and identifies the point at which to
-return control flow after the subroutine has completed. The C<.result>
-directive retrieves returned values from the call.
-
-=head3 Subroutine Declarations
-
-X<.param directive> In addition to syntax for subroutine calls, PIR provides
-syntax for subroutine definitions: the C<.sub> and C<.end> directives shown in
-earlier examples.  The C<.param> directive defines input parameters and creates
-local named variables for them (similar to C<.local>):
-
-  .param int c
-
-X<.return directive>
-The C<.return> directive allows the subroutine to return control flow
-to the calling subroutine, and optionally returns result output values.
-
-Here's a complete code example that implements the factorial algorithm.  The
-subroutine C<fact> is a separate subroutine, assembled and processed after the
-C<main> function.  Parrot resolves global symbols like the C<fact> label
-between different units.
-
-=begin PIR
-
-  # factorial.pir
-  .sub 'main' :main
-     .local int count
-     .local int product
-     count   = 5
-     product = 1
-
-     $I0 = 'fact'(count, product)
-
-     say $I0
-     end
-  .end
-
-  .sub 'fact'
-     .param int c
-     .param int p
-
-  loop:
-     if c <= 1 goto fin
-     p = c * p
-     dec c
-     branch loop
-  fin:
-     .return (p)
-  .end
-
-=end PIR
-
-This example defines two local named variables, C<count> and C<product>, and
-assigns them the values 1 and 5. It calls the C<fact> subroutine with both
-variables as arguments.  The C<fact> subroutine uses C<.param> to retrieve
-these parameters and C<.return> to return the result.  The final printed result
-is 120.
-
-As usual, execution of the program starts at the C<:main> subroutine.
-
-=head3 Named Arguments
-
-=for author
-
-We have to get our terms straight here.  Which are "arguments" (passed in) and
-which are "parameters" (processed from within)?
-
-=end for
-
-X<positional arguments>
-X<named arguments>
-Parameters passed only by their order are I<positional arguments>. The only
-differentiator between positional arguments is their positions in the function
-call.  Putting positional arguments in a different order will produce different
-effects, or may cause errors. Parrot also supports I<named parameters>. Instead
-of passing parameters by their position in the string, parameters are passed by
-name and can be in any order.  Here's an example:
-
-=begin PIR
-
- .sub 'MySub'
-    .param string yrs :named("age")
-    .param string call :named("name")
-    $S0  = "Hello " . call
-    $S1  = "You are " . yrs
-    $S1 .= " years old"
-    say $S0
-    say $S1
- .end
-
- .sub 'main' :main
-    'MySub'("age" => 42, "name" => "Bob")
- .end
-
-=end PIR
-
-Named arguments are convenient because the order of the pairs does not matter.
-You can also pass these pairs in the opposite order:
-
-=begin PIR
-
- .sub 'main' :main
-    'MySub'("name" => "Bob", "age" => 42)    # Same!
- .end
-
-=end PIR
-
-=head3 Optional Arguments
-
-X<optional arguments>
-Some functions have arguments with appropriate default values so that callers
-don't always have to pass them.  Parrot provides a mechanism to identify
-optional arguments as well as flag values to determine if the
-caller has passed optional arguments.
-
-Optional parameters appear in PIR as if they're actually I<two> parameters:
-the value and a flag:
-
-  .param string name     :optional
-  .param int    has_name :opt_flag
-
-The C<:optional> flag specifies that the given parameter is optional.  The
-C<:opt_flag> specifies an integer which parameter contains a boolean flag; this
-flag is true if the value was passed, and false otherwise. To provide a default
-value for an optional parameter, you can write:
-
-    .param string name     :optional
-    .param int    has_name :opt_flag
-
-    if has_name goto we_have_a_name
-    name = "Default value"
-  we_have_a_name:
-
-Optional parameters can be positional or named parameters. Optional positional
-parameters must appear at the end of the list of positional parameters. Also,
-the C<:opt_flag> parameter must always appear directly after the C<:optional>
-parameter.
-
-  .sub 'Foo'
-    .param int optvalue :optional
-    .param int hasvalue :opt_flag
-    .param pmc notoptional          # WRONG!
-    ...
-
-  .sub 'Bar'
-     .param int hasvalue :opt_flag
-     .param int optvalue :optional  # WRONG!
-     ...
-
-  .sub 'Baz'
-    .param int optvalue :optional
-    .param pmc notoptional
-    .param int hasvalue :opt_flag   # WRONG!
-    ...
-
-You may mix optional parameters with named parameters:
-
-  .sub 'MySub'
-    .param int value     :named("answer") :optional
-    .param int has_value :opt_flag
-    ...
-
-You can call this function in two ways:
-
-  'MySub'("answer" => 42)  # with a value
-  'MySub'()                # without
-
-=head3 Sub PMCs
-
-Subroutines are a PMC type in Parrot. You can store them in PMC registers and
-manipulate them just as you do the other PMC types.  Look up a subroutine in
-the current namespace with the C<get_global> opcode:
-
-  $P0 = get_global "MySubName"
-
-To find a subroutine in a different namespace, first look up the appropriate
-the namespace PMC, then use that with C<get_global>:
-
-  $P0 = get_namespace "MyNameSpace"
-  $P1 = get_global $P0, "MySubName"
-
-You can obviously invoke a Sub PMC:
-
-  $P0(1, 2, 3)
-
-You can get or even I<change> its name:
-
-  $S0 = $P0               # Get the current name
-  $P0 = "MyNewSubName"    # Set a new name
-
-You can get a hash of the complete metadata for the subroutine:
-
-  $P1 = inspect $P0
-
-The metadata fields in this hash are
-
-=over 4
-
-=item * pos_required
-
-The number of required positional parameters to the Sub
-
-=item * pos_optional
-
-The number of optional positional parameters to the Sub
-
-=item * named_required
-
-The number of required named parameters to the Sub
-
-=item * named_optional
-
-The number of optional named parameters to the Sub
-
-=item * pos_slurpy
-
-Returns true if the sub has a slurpy parameter to eat up extra positional args
-
-=item * named_slurpy
-
-Returns true if the sub has a slurpy parameter to eat up extra named args
-
-=back
-
-Instead of getting the whole inspection hash, you ask about individual pieces
-of metadata:
-
-  $I0 = inspect $P0, "pos_required"
-
-To discover to get the total number of defined parameters to the Sub, call the
-C<arity> method:
-
-  $I0 = $P0.'arity'()
-
-To fetch the namespace PMC that the Sub was defined into, call the
-C<get_namespace> method:
-
-  $P1 = $P0.'get_namespace'()
-
-=head2 The Commandline
-
-Programs written in Parrot have access to arguments passed on the command
-line like any other program would:
-
-  .sub 'MyMain' :main
-    .param pmc all_args :slurpy
-    ...
-  .end
-
-=for author
-
-Please verify and expand.
-
-=end for
-
-The C<all_args> PMC is a ResizableStringArray PMC, which means you can loop
-over the results, access them individually, or even modify them.
-
-=head2 Continuation Passing Style
-
-X<continuations>
-X<continuation passing style>
-X<CPS>
-Continuations are snapshots of control flow: frozen images of the current
-execution state of the VM. Once you have a continuation, you can invoke it to
-return to the point where the continuation was first created. It's like a
-magical timewarp that allows the developer to arbitrarily move control flow
-back to any previous point in the program.
-
-Continuations are not a new concept; they've boggled the minds of new Lisp and
-Scheme programmers for many years.  Despite their power and heritage, they're
-not visible to most other modern programming languages or their runtimes.
-Parrot aims to change that: it performs almost all control flow through the use
-of continuations.  PIR and PCT hide most of this complexity from developers,
-but the full power of continuations is available.
-
-When Parrot invokes a function, it creates a continuation representing the
-current point in the program.  It passes this continuation as an invisible
-parameter to the function call.  When that function returns, it invokes the
-continuation -- in effect, it performs a goto to the point of creation of that
-continuation.  If you have a continuation, you can invoke it to return to its
-point of creation any time you want.
-
-This type of flow control -- invoking continuations instead of performing bare
-jumps -- is X<Continuation Passing Style;CPS> Continuation Passing Style (CPS).
-CPS allows parrot to offer all sorts of neat features, such as tail-call
-optimizations and lexical subroutines.
-
-=head3 Tailcalls
-
-A subroutine may set up and call another subroutine, then return the result of
-the second call directly. This is a X<tailcall> tailcall, and is an important
-opportunity for optimization.  Here's a contrived example in pseudocode:
-
-  call add_two(5)
-
-  subroutine add_two(value)
-    value = add_one(value)
-    return add_one(value)
-
-In this example, the subroutine C<add_two> makes two calls to c<add_one>. The
-second call to C<add_one> is the return value. C<add_one> gets called; its
-result gets returned to the caller of C<add_two>.  Nothing in C<add_two> uses
-that return value directly.
-
-A simple optimization is available for this type of code.  The second call to
-C<add_one> will return to the same place that C<add_two> returns; it's
-perfectly safe and correct to use the same return continuation that C<add_two>
-uses. The two subroutine calls can share a return continuation, instead of
-having to create a new continuation for each call.
-
-X<.tailcall directive>
-
-PIR provides the C<.tailcall> directive to identify similar situations.  Use it
-in place of the C<.return> directive. C<.tailcall> performs this optimization
-by reusing the return continuation of the parent function to make the tailcall:
-
-=begin PIR
-
-  .sub 'main' :main
-      .local int value
-      value = add_two(5)
-      say value
-  .end
-
-  .sub 'add_two'
-      .param int value
-      .local int val2
-      val2 = add_one(value)
-      .tailcall add_one(val2)
-  .end
-
-  .sub 'add_one'
-      .param int a
-      .local int b
-      b = a + 1
-      .return (b)
-  .end
-
-=end PIR
-
-This example above print the correct value "7".
-
-=head3 Creating and Using Continuations
-
-While Parrot's use of continuations and CPS is invisible to most code, you can
-create and use them explicitly if you like.  Continuations are like any other
-PMC. Create one with the C<new> opcode:
-
-  $P0 = new 'Continuation'
-
-The new continuation starts off in an undefined state. If you attempt to invoke
-a new continuation without initializing it, Parrot will raise an exception.  To
-prepare the continuation for use, assign it a destination label with the
-C<set_addr> opcode:
-
-    $P0 = new 'Continuation'
-    set_addr $P0, my_label
-
-  my_label:
-    ...
-
-To jump to the continuation's stored label and return the context to the state
-it was in I<at the point of its creation>, invoke the continuation:
-
-  invoke $P0  # Explicit using "invoke" opcode
-  $P0()       # Same, but nicer syntax
-
-Even though you can use the subroutine notation C<$P0()> to invoke the
-continuation, it doesn't make any sense to pass arguments or obtain return
-values:
-
-  $P0 = new 'Continuation'
-  set_addr $P0, my_label
-
-  $P0(1, 2)      # WRONG!
-
-  $P1 = $P0()    # WRONG!
-
-=head2 Lexical Subroutines
-
-X<Lexical Subroutines>
-
-Parrot offers support for lexical subroutines.  You can define a subroutine by
-name inside a larger subroutine, where the inner subroutine is only visible and
-callable from the outer. The inner subroutine inherits all the lexical
-variables from the outer subroutine, but can itself define its own lexical
-variables that the outer subroutine cannot access.   PIR lacks the concept of
-blocks or nested lexical scopes; this is how it performs the same function.
-
-If a subroutine is lexical, find its C<:outer> Sub with the C<get_outer>
-method:
-
-  $P1 = $P0.'get_outer'()
-
-If there is no C<:outer> PMC, this returns a NULL PMC. Conversely, you can
-set the outer sub:
-
-  $P0.'set_outer'($P1)
-
-=head3 Scope and HLLs
-
-As mentioned previously, X<High Level Languages;HLL> High Level Languages such
-as Perl, Python, and Ruby allow nested scopes, or blocks within blocks that can
-have their own lexical variables.  Even this construct is common in the C
-programming language:
-
-  {
-      int x = 0;
-      int y = 1;
-      {
-          int z = 2;
-          /* x, y, and z are all visible here */
-      }
-
-      /* only x and y are visible here */
-  }
-
-In the inner block, all three varaibles are visible.  The variable C<z> is only
-visible inside that block. The outer block has no knowledge of C<z>.  A very
-direct, naI<iuml>ve translation of this code to PIR might be:
-
-  .param int x
-  .param int y
-  .param int z
-  x = 0
-  y = 1
-  z = 2
-  ...
-
-This PIR code is similar, but the handling of the variable C<z> is different:
-C<z> is visible throughout the entire current subroutine, where it is not
-visible throughout the entire C function. To help approximate this effect, PIR
-supplies lexical subroutines to create nested lexical scopes.
-
-=head3 PIR Scoping
-
-Only one PIR structure supports scoping like this: the subroutine.N<... and
-objects that inherit from subroutines, such as methods, coroutines, and
-multisubs> There are no blocks in PIR that have their own scope besides
-subroutines. Fortunately, we can use these lexical subroutines to simulate this
-behavior that HLLs require:
-
-=begin PIR
-
-  .sub 'MyOuter'
-      .local int x,y
-      .lex 'x', x
-      .lex 'y', y
-      'MyInner'()
-      # only x and y are visible here
-  .end
-
-  .sub 'MyInner' :outer('MyOuter')
-      .local int z
-      .lex 'z', z
-      # x, y, and z are all "visible" here
-  .end
-
-=end PIR
-
-=for author
-
-This paragraph is unclear.
-
-=end for
-
-This example calls the variables in C<MyInner> "visible". This is because
-lexically-defined variables need to be accessed with the C<get_lex> and
-C<set_lex> opcodes. These two opcodes don't just access the value of a
-register, where the value is stored while it's being used, but they also make
-sure to interact with the C<LexPad> PMC that's storing the data. If the value
-isn't properly stored in the LexPad, then they won't be available in nested
-inner subroutines, or available from C<:outer> subroutines either.
-
-=head3 Lexical Variables
-
-=for author
-
-What's the point of this paragraph?
-
-=end for
-
-As we have seen above, we can declare a new subroutine to be a nested inner
-subroutine of an existing outer subroutine using the C<:outer> flag. The outer
-flag is used to specify the name of the outer subroutine. Where there may be
-multiple subroutines with the same name, we can use the C<:subid> flag on the
-outer subroutine to give it a different--and unique--name that the lexical
-subroutines can reference in their C<:outer> declarations. Within lexical
-subroutines, the C<.lex> command defines a local variable that follows these
-scoping rules.
-
-=head3 LexPad and LexInfo PMCs
-
-X<LexPad PMC>
-X<LexInfo PMC>
-Subs store information about lexical variables in two different PMCs: the
-LexPad PMC and the LexInfo PMC. They're not visible to PIR code; Parrot uses
-them internally to store information about lexical variables.
-
-I<LexInfo> PMCs store read-only information about the lexical variables used in
-a Sub.  Parrot creates them when it compiles a Sub.  Not all subroutines get a
-LexInfo PMC by default; only those that need it.  One way to identify such a
-Sub is its use of the C<.lex> directive, but this only works for languages
-which know the names of lexical variables at compile time. If that's not true
-of your language, declare the Sub with the C<:lex> attribute.
-
-I<LexPad> PMCs store run-time information about lexical variables.  This
-includes their current values and their type information. Parrot creates LexPad
-PMCs for Subs that already have a LexInfo PMC. As you can imagine, Parrot must
-create a new LexPad for each I<invocation> of a Sub, lest a recursive call
-overwrite previous lexical values.
-
-Call the C<get_lexinfo> method on a Subroutine PMC to access its associated
-LexInfo PMC:
-
-  $P0 = find_global "MySubroutine"
-  $P1 = $P0.'get_lexinfo'()
-
-Once you have the LexInfo PMC, you can inspect the lexicals it represents:
-
-  $I0 = elements $P1    # the number of lexical variables it holds
-  $P0 = $P1["name"]     # the entry for lexical variable "name"
-
-There's not much else you can do (though the PMC behaves like a Hash PMC, so
-you can iterate over its keys and values).
-
-There is no easy way to get a reference to the current LexPad PMC in a given
-subroutine, but they're not useful from PIR anyway.  Remember that subroutines
-themselves can be lexical; the lexical environment of a given variable can
-extend to multiple subroutines with their own LexPads. The opcodes C<find_lex>
-and C<store_lex> search through nested LexPads recursively to find the proper
-environment for the given variables.
-
-=head2 Compilation Units Revisited
-
-Z<CHP-4-SECT-1.1>
-
-X<Subroutine>
-A subroutine is a section of code that forms a single unit. The factorial
-calculation example had two separate subroutines: the C<main> subroutine and
-the C<fact> subroutine. Here is that algorithm in a single subroutine:
-
-=begin PIR
-
-  .sub 'main'
-      $I1 = 5           # counter
-      bsr fact
-      say $I0
-      $I1 = 6           # counter
-      bsr fact
-      say $I0
-      end
-
-  fact:
-      $I0 = 1           # product
-  L1:
-      $I0 = $I0 * $I1
-      dec $I1
-      if $I1 > 0 goto L1
-      ret
-  .end
-
-=end PIR
-
-The unit of code from the C<fact> label definition to C<ret> is a reusable
-routine, but is only usable from within the C<main> subroutine. There are
-several problems with this simple approach. In terms of the interface, the
-caller has to know to pass the argument to C<fact> in C<$I1> and to get the
-result from C<$I0>. This differs from Parrot's well-understood calling
-conventions.
-
-Another disadvantage of this approach is that C<main> and C<fact> share the
-same subroutine. Parrot processes them as one piece of code.  They share
-registers, and they'd share any LexInfo and LexPad PMCs, if any were needed by
-C<main>. The C<fact> routine is also not easily usable from outside the C<main>
-subroutine, so other parts of your code won't have access to it.
-
-=head2 NameSpaces, Methods, and VTABLES
-
-Z<CHP-4-SECT-2>
-
-X<PIR (Parrot intermediate representation);methods>
-X<methods;in PIR>
-X<classes;methods>
-X<. (dot);. (method call);instruction (PIR)>
-PIR provides syntax to simplify writing methods and method calls for
-object-oriented programming.  PIR allows you to define your own classes, and
-with those classes you can define method interfaces to them. Method calls
-follow the Parrot's calling conventions, including the various parameter
-configurations, lexical scoping, and other aspects already shown.
-
-Parrot supports several built-in classes, such as C<ResizablePMCArray> and
-C<Integer>, written in C and compiled with the rest of Parrot. You may also
-declare your own classes in PIR. Like other object oriented systems, Parrot
-classes provide their own I<namespaces> and support I<methods> and
-I<attributes>.
-
-=head3 NameSpaces
-
-Z<CHP-4-SECT-2.1>
-
-X<NameSpaces>
-X<.namespace>
-NameSpaces provide a categorization mechanism to avoid name collisions. This is
-most useful when producing encapsulated libraries or when building large
-systems.  Each namespace provides a separate location for function names and
-global variables.
-
-X<namespace collisions>
-X<namespace pollution>
-
-Without a namespace (or in a program that eschews namespaces), all subroutines
-and global variables would live in one big bag, running the risk of
-I<namespace collisions> thanks to I<namespace pollution>. You couldn't tell
-which subroutine performed which operation when two task contexts use the same
-word to mean two different things.
-
-NameSpaces are very effective at hiding private information as well as
-gathering similar things together.
-
-For example, the C<Math> namespace could store subroutines that manipulate
-numbers. The C<Images> namespace could store subroutines create and manipulate
-images. If your program must add two numbers together I<and> perform additive
-image composition, you can use the appropriate namespaced C<add> functions
-without conflict or confusion.  Within the C<Image> namespace you could have
-also have sub namespaces for C<jpeg> and C<MRI> and C<schematics>; each of
-these could have its own C<add> subroutine without getting into each other's
-way.
-
-Declare a namespace in PIR with the C<.namespace []> directive. The brackets
-are not optional, but the keys inside them are. For example:
-
-  .namespace [ ]               # The root namespace
-  .namespace [ "Foo" ]         # The namespace "Foo"
-  .namespace [ "Foo" ; "Bar" ] # NameSpace Foo::Bar
-  .namespace                   # WRONG! The [] are needed
-
-You may nest namespaces to arbitrary depth by separating name components with
-semicolons.  NameSpaces are PMC, so you can access them and manipulate them
-just like other data objects. Get the PMC for the root namespace using the
-C<get_root_namespace> opcode:
-
-  $P0 = get_root_namespace
-
-The current namespace may be different from the root namespace; retrieved it
-with the C<get_namespace> opcode:
-
-  $P0 = get_namespace             # get current namespace PMC
-  $P0 = get_namespace ["Foo"]     # get PMC for namespace "Foo"
-
-X<HLL namespaces>
-X<namespaces; HLL>
-Parrot arranges its namespaces in a hiarachy.  The root namespace is the root
-of the tree.  Beneath the root are HLL namespaces; hLL compiler gets its own
-HLL namespace where it can store its data during compilation and runtime. Each
-HLL namespace may itself be the root of a tree of namespaces.
-
-=head3 NameSpace PMC
-
-There are multiple ways to address a namespace in PIR, depending on the
-starting point of the lookup.  They may start at the root namespace:
-
-  # Get namespace "a/b/c" starting at the root namespace
-  $P0 = get_root_namespace ["a" ; "b" ; "c"]
-
-... or from the current HLL's namespace as a root:
-
-  # Get namespace "a/b/c" starting in the current HLL namespace.
-  $P0 = get_hll_namespace ["a" ; "b" ; "c"]
-
-... but this is identical to a root namespace lookup with the HLL as the first
-branch:
-
-  $P0 = get_root_namespace ["hll" ; "a" ; "b" ; "c"]
-
-... and, of course, relative to the current namespace without a root:
-
-  # Get namespace "a/b/c" starting in the current namespace
-  $P0 = get_namespace ["a" ; "b" ; "c"]
-
-Given a namespace PMC, retrieve global variables and subroutine PMCs with the
-C<get_global> opcode:
-
-  $P1 = get_global $S0            # Get global in current namespace
-  $P1 = get_global ["Foo"], $S0   # Get global in namespace "Foo"
-  $P1 = get_global $P0, $S0       # Get global in $P0 namespace PMC
-
-=head3 Operations on the NameSpace PMC
-
-You can perform other operations on the NameSpace PMC.  You can find methods
-and variables that are stored in the namespace or add new ones.
-
-For example, to add one namespace to another current namespace, use the
-C<add_namespace> method:
-
-  $P0 = get_namespace
-  $P0.'add_namespace'($P1)
-
-You can also find a namespace nested in a namespace with the C<find_namespace>
-method.  Note that this finds I<only> a namespace, where the C<find_global>
-opcode will find I<any> PMC stored in that namespace under the given name:
-
-  $P0 = get_namespace
-  $P1 = $P0.'find_namespace'("MyOtherNameSpace")
-
-You may also wish to create a namespace if it doesn't exist and find it
-otherwise.  That's the purpose of the C<make_namespace> method:
-
-  $P1 = $P0.'make_namespace'("MyNameSpace")
-
-To manipulate Sub PMCs in a namespace, use the C<add_sub> and C<find_sub>
-methods.  As with C<find_namespace>, C<find_sub> returns I<only> a Sub PMC and
-never any other kind of global symbol:
-
-  $P0.'add_sub'("MySub", $P2)
-  $P1 = $P0.'find_sub'("MySub")
-
-Similarly, the C<add_var> and C<find_var> methods work on PMCs of I<any> type:
-
-  $P0.'add_var'("MyVar", $P3)   # Add variable "MyVar" in $P3
-  $P1 = $P0.'find_var'("MyVar") # Find it
-
-You can get the name of a namespace with the C<get_name> method; this returns a
-ResizableStringArray of STRINGs:
-
-  $P3 = $P0.'get_name'()
-
-Request a namespace's parent namespace with the C<get_parent> method:
-
-  $P5 = $P0.'get_parent'()
-
-Find a class associated with a namespace with the C<get_class> method:
-
-  $P6 = $P0.'get_class'()
-
-=head3 Calling Methods
-
-Z<CHP-4-SECT-2.2>
-
-X<methods>
-Namespaces enable plenty of interesting behaviors, such as object oriented
-programming and method calls.  Methods resemble subroutines with one big
-change: they require an invocant (an object PMC passed as the C<self>
-parameter).
-
-The basic syntax for a method call resembles a subroutine call.  Previous
-examples have demonstrated it already.  A PIR method call takes a variable for
-the invocant PMC and a string with the name of the method:
-
-  object."methodname"(arguments)
-
-If you forget the quotes around the method's name, PIR will treat the method
-name as a named variable which contains the method's name:
-
-  .local string methname = "Foo"
-  object.methname()               # Same as object."Foo"()
-  object."Foo"()                  # Same
-
-The invocant can be a variable or register, and the method name can be a
-literal string, string variable, or method object PMC.
-
-=head3 Defining Methods
-
-Define a method like any other subroutine, respecting two changes. First, a
-method must be a member of a namespace (the namespace representing the class to
-which the method belongs). Second, they require the C<:method> flag.
-
-  .namespace [ "MyClass" ]
-
-  .sub 'MyMethod' :method
-    ...
-  .end
-
-Inside the method, access the invocant object through the C<self> parameter.
-C<self> isn't the only name you can call this value, however.  You can also use
-the C<:invocant> flag to define a new name for the invocant object:
-
-(See TT #483)
-
-=begin PIR
-
-  .sub 'MyMethod' :method
-    $S0 = self                    # Already defined as "self"
-    say $S0
-  .end
-
-  .sub 'MyMethod2' :method
-    .param pmc item :invocant     # "self" is now "item"
-    $S0 = item
-    say $S0
-  .end
-
-=end PIR
-
-This example defines two methods in the C<Foo> class. It calls one from the
-main body of the subroutine and the other from within the first method:
-
-=begin PIR
-
-  .sub 'main'
-    .local pmc class
-    .local pmc obj
-    newclass class, "Foo"       # create a new Foo class
-    new obj, "Foo"              # instantiate a Foo object
-    obj."meth"()                # call obj."meth" which is actually
-    say "done"                  # in the "Foo" namespace
-    end
-  .end
-
-  .namespace [ "Foo" ]          # start namespace "Foo"
-
-  .sub 'meth' :method           # define Foo::meth global
-     say "in meth"
-     $S0 = "other_meth"         # method names can be in a register too
-     self.$S0()                 # self is the invocant
-  .end
-
-  .sub 'other_meth' :method     # define another method
-     say "in other_meth"        # as earlier, Parrot provides a return
-  .end                          # statement
-
-=end PIR
-
-Each method call looks up the method name in the object's class namespace.  The
-C<.sub> directive automatically makes a symbol table entry for the subroutine
-in the current namespace.
-
-You can pass multiple arguments to a method and retrieve multiple return values
-just like a single line subroutine call:
-
-  (res1, res2) = obj."method"(arg1, arg2)
-
-=head3 VTABLEs
-
-PMCs all implement a common interface of functions called X<VTABLE> VTABLEs.
-Every PMC implements the same set of these interfaces, which perform very
-specific low-level tasks on the PMC. The term VTABLE was originally a shortened
-form of the name "virtual function table", although that name isn't used any
-more by the developers, or in any of the documentation.N<In fact, if you say
-"virtual function table" to one of the developers, they probably won't know
-what you are talking about.> The virtual functions in the VTABLE, called
-X<VTABLE interfaces> VTABLE interfaces, are similar to ordinary functions and
-methods in many respects. VTABLE interfaces are occasionally called "VTABLE
-functions", or "VTABLE methods" or even "VTABLE entries" in casual
-conversation. A quick comparison shows that VTABLE interfaces are not really
-subroutines or methods in the way that those terms have been used throughout
-the rest of Parrot. Like methods on an object, VTABLE interfaces are defined
-for a specific class of PMC, and can be invoked on any member of that class.
-Likewise, in a VTABLE interface declaration, the C<self> keyword is used to
-describe the object that it is invoked upon. That's where the similarities end,
-however. Unlike ordinary subroutines or methods, VTABLE methods cannot be
-invoked directly, they are also not inherited through class hierarchies like
-how methods are. With all this terminology discussion out of the way, we can
-start talking about what VTABLES are and how they are used in Parrot.
-
-VTABLE interfaces are the primary way that data in the PMC is accessed
-and modified. VTABLES also provide a way to invoke the PMC if it's a
-subroutine or subroutine-like PMC. VTABLE interfaces are not called
-directly from PIR code, but are instead called internally by Parrot to
-implement specific opcodes and behaviors. For instance, the C<invoke>
-opcode calls the C<invoke> VTABLE interface of the subroutine PMC,
-while the C<inc> opcode on a PMC calls the C<increment> VTABLE
-interface on that PMC. What VTABLE interface overrides do, in essence,
-is to allow the programmer to change the very way that Parrot accesses
-PMC data in the most fundamental way, and changes the very way that the
-opcodes act on that data.
-
-PMCs, as we will look at more closely in later chapters, are typically
-implemented using X<PMC Script> PMC Script, a layer of syntax and macros
-over ordinary C code. A X<PMC Compiler> PMC compiler program converts the
-PMC files into C code for compilation as part of the ordinary build
-process. However, VTABLE interfaces can be written I<and overwritten> in
-PIR using the C<:vtable> flag on a subroutine declaration. This technique
-is used most commonly when subclassing an existing PMC class in PIR code
-to create a new data type with custom access methods.
-
-VTABLE interfaces are declared with the C<:vtable> flag:
-
-  .sub 'set_integer' :vtable
-      #set the integer value of the PMC here
-  .end
-
-in which case the subroutine must have the same name as the VTABLE
-interface it is intended to implement. VTABLE interfaces all have very
-specific names, and you can't override one with just any arbitrary name.
-However, if you would like to name the function something different but
-still use it as a VTABLE interface, you could add an additional name
-parameter to the flag:
-
-  .sub 'MySetInteger' :vtable('set_integer')
-      #set the integer value of the PMC here
-  .end
-
-VTABLE interfaces are often given the C<:method> flag also, so that they can
-be used directly in PIR code as methods, in addition to being used by Parrot
-as VTABLE interfaces. This means we can have the following:
-
-  .namespace [ "MyClass" ]
-
-  .sub 'ToString' :vtable('get_string') :method
-      $S0 = "hello!"
-      .return($S0)
-  .end
-
-  .namespace [ "OtherClass" ]
-
-  .local pmc myclass = new "MyClass"
-  say myclass                 # say converts to string internally
-  $S0 = myclass               # Convert to a string, store in $S0
-  $S0 = myclass.'ToString'()  # The same
-
-Inside a VTABLE interface definition, the C<self> local variable contains
-the PMC on which the VTABLE interface is invoked, just like in a method
-declaration.
-
-=head2 Roles
-
-As we've seen above and in the previous chapter, Class PMCs and NameSpace
-PMCs work to keep classes and methods together in a logical way. There is
-another factor to add to this mix: The Role PMC.
-
-Roles are like classes, but don't stand on their own. They represent
-collections of methods and VTABLES that can be added into an existing class.
-Adding a role to a class is called I<composing> that role, and any class
-that has been composed with a role C<does> that role.
-
-Roles are created as PMCs and can be manipulated through opcodes and methods
-like other PMCs:
-
-  $P0 = new 'Role'
-  $P1 = get_global "MyRoleSub"
-  $P0.'add_method'("MyRoleSub", $P1)
-
-Once we've created a role and added methods to it, we can add that role to
-a class, or even to another role:
-
-  $P1 = new 'Role'
-  $P2 = new 'Class'
-  $P1.'add_role'($P0)
-  $P2.'add_role'($P0)
-  add_role $P2, $P0    # Same!
-
-Now that we have added the role, we can check whether we implement it:
-
-  $I0 = does $P2, $P0  # Yes
-
-We can get a list of roles from our Class PMC:
-
-  $P3 = $P2.'roles'()
-
-Roles are very useful for ensuring that related classes all implement a common
-interface.  
-
-=head2 Coroutines
-
-X<PIR;Coroutines>
-X<Coroutines>
-We've mentioned coroutines several times before, and we're finally going
-to explain what they are. Coroutines are similar to subroutines except
-that they have an internal notion of I<state>.N<And the cool new name!>.
-Coroutines, in addition to performing a normal C<.return> to return
-control flow back to the caller and destroy the lexical environment of
-the subroutine, may also perform a C<.yield> operation. C<.yield> returns
-a value to the caller like C<.return> can, but it does not destroy the
-lexical state of the coroutine. The next time the coroutine is called, it
-continues execution from the point of the last C<.yield>, not at the
-beginning of the coroutine.
-
-In a Coroutine, when we continue from a C<.yield>, the entire lexical
-environment is the same as it was when C<.yield> was called. This
-means that the parameter values don't change, even if we call the
-coroutine with different arguments later.
-
-=head3 Defining Coroutines
-
-Coroutines are defined like any ordinary subroutine. They do not require
-any special flag or any special syntax to mark them as being a
-coroutine. However, what sets them apart is the use of the C<.yield>
-directive. C<.yield> plays several roles:
-
-=over 4
-
-=item * Identifies coroutines
-
-When Parrot sees a yield, it knows to create a Coroutine PMC object
-instead of a Sub PMC.
-
-=item * Creates a continuation
-
-Continuations, as we have already seen, allow us to continue
-execution at the point of the continuation later. It's like a snapshot of
-the current execution environment. C<.yield> creates a continuation in
-the coroutine and stores the continuation object in the coroutine object
-or later resuming from the point of the C<.yield>.
-
-=item * Returns a value
-
-C<.yield> can return a valueN<or many values, or no values> to the caller.
-It is basically the same as a C<.return> in this regard.
-
-=back
-
-Here is a quick example of a simple coroutine:
-
-  .sub 'MyCoro'
-    .yield(1)
-    .yield(2)
-    .yield(3)
-    .return(4)
-  .end
-
-  .sub 'main' :main
-    $I0 = MyCoro()    # 1
-    $I0 = MyCoro()    # 2
-    $I0 = MyCoro()    # 3
-    $I0 = MyCoro()    # 4
-    $I0 = MyCoro()    # 1
-    $I0 = MyCoro()    # 2
-    $I0 = MyCoro()    # 3
-    $I0 = MyCoro()    # 4
-    $I0 = MyCoro()    # 1
-    $I0 = MyCoro()    # 2
-    $I0 = MyCoro()    # 3
-    $I0 = MyCoro()    # 4
-  .end
-
-This is obviously a contrived example, but it demonstrates how the coroutine
-stores it's state. The coroutine stores it's state when we reach a C<.yield>
-directive, and when the coroutine is called again it picks up where it last
-left off. Coroutines also handle parameters in a way that might not be
-intuitive. Here's an example of this:
-
-  .sub 'StoredConstant'
-    .param int x
-    .yield(x)
-    .yield(x)
-    .yield(x)
-  .end
-
-  .sub 'main' :main
-    $I0 = StoredConstant(5)       # $I0 = 5
-    $I0 = StoredConstant(6)       # $I0 = 5
-    $I0 = StoredConstant(7)       # $I0 = 5
-    $I0 = StoredConstant(8)       # $I0 = 8
-  .end
-
-Notice how even though we are calling the C<StoredConstant> coroutine with
-different arguments each time, the value of parameter C<x> doesn't change
-until the coroutine's state resets after the last C<.yield>. Remember that
-a continuation takes a snapshot of the current state, and the C<.yield>
-directive takes a continuation. The next time we call the coroutine, it
-invokes the continuation internally, and returns us to the exact same place in
-the exact same condition as we were when we called the C<.yield>. In order
-to reset the coroutine and enable it to take a new parameter, we must either
-execute a C<.return> directive or reach the end of the coroutine.
-
-=head2 Multiple Dispatch
-
-Multiple dispatch is when there are multiple subroutines in a single
-namespace with the same name. These functions must differ, however, in
-their parameter list, or "signature". All subs with the same name get
-put into a single PMC called a MultiSub. The MultiSub is like a list
-of subroutines. When the multisub is invoked, the MultiSub PMC object
-searches through the list of subroutines and searches for the one with
-the closest matching signature. The best match is the sub that gets
-invoked.
-
-=head3 Defining MultiSubs
-
-MultiSubs are subroutines with the C<:multi> flag applied to them.
-MultiSubs (also called "Multis") must all differ from one another in
-the number and/or type of arguments passed to the function. Having
-two multisubs with the same function signature could result in a
-parsing error, or the later function could overwrite the former one
-in the multi.
-
-Multisubs are defined like this:
-
-  .sub 'MyMulti' :multi
-      # does whatever a MyMulti does
-  .end
-
-Multis belong to a specific namespace. Functions in different namespaces with
-the same name do not conflict with each other.  It's only when multiple
-functions in a single namespace need to have the same name that a multi is
-used.
-
-Multisubs take a special designator called a I<multi signature>. The multi
-signature tells Parrot what particular combination of input parameters the
-multi accepts. Each multi will have a different signature, and Parrot will
-be able to dispatch to each one depending on the arguments passed. The
-multi signature is specified in the C<:multi> directive:
-
-  .sub 'Add' :multi(I, I)
-    .param int x
-    .param int y
-    .return(x + y)
-  .end
-
-  .sub 'Add' :multi(N, N)
-    .param num x
-    .param num y
-    .return(x + y)
-  .end
-
-  .sub 'Start' :main
-    $I0 = Add(1, 2)      # 3
-    $N0 = Add(3.14, 2.0) # 5.14
-    $S0 = Add("a", "b")  # ERROR! No (S, S) variant!
-  .end
-
-Multis can take I, N, S, and P types, but they can also use C<_> (underscore)
-to denote a wildcard, and a string that can be the name of a particular PMC
-type:
-
-  .sub 'Add' :multi(I, I)  # Two integers
-    ...
-
-  .sub 'Add' :multi(I, 'Float')  # An integer and Float PMC
-    ...
-
-                           # Two Integer PMCs
-  .sub 'Add' :multi('Integer', _)
-    ...
-
-When we call a multi PMC, Parrot will try to take the most specific
-best-match variant, and will fall back to more general variants if a perfect
-best-match cannot be found. So if we call C<'Add'(1, 2)>, Parrot will dispatch
-to the C<(I, I)> variant. If we call C<'Add'(1, "hi")>, Parrot will match the
-C<(I, _)> variant, since the string in the second argument doesn't match C<I>
-or C<'Float'>. Parrot can also choose to automatically promote one of the I,
-N, or S values to an Integer, Float, or String PMC.
-
-To make the decision about which multi variant to call, Parrot takes a
-I<Manhattan Distance> between the two. Parrot calculates the I<distance>
-between the multi signatures and the argument signature. Every difference
-counts as one step. A difference can be an autobox from a primitive type
-to a PMC, or the conversion from one primitive type to another, or the
-matching of an argument to a C<_> wildcard. After Parrot calculates the
-distance to each variant, it calls the function with the lowest distance.
-Notice that it's possible to define a variant that is impossible to call:
-for every potential combination of arguments there is a better match. This
-isn't necessarily a common occurrence, but it's something to watch out for
-in systems with a lot of multis and a limited number of data types in use.
-
-
-=head2 Classes and Objects
-
-It may seem more appropriate for a discussion of PIR's support for classes
-and objects to reside in its own chapter, instead of appearing in a generic
-chapter about PIR programming "basics". However, part of PIR's core
-functionality is its support for object-oriented programming. PIR doesn't
-use all the fancy syntax as other OO languages, and it doesn't even support
-all the features that most modern OO languages have. What PIR does have is
-support for some of the basic structures and abilities, the necessary subset
-to construct richer and higher-level object systems.
-
-=head2 PMCs as Classes
-
-PMCs aren't exactly "classes" in the way that this term is normally used in
-object-oriented programming languages. They are polymorphic data items that can
-be one of a large variety of predefined types. As we have seen briefly, and as
-we will see in more depth later, PMCs have a standard interface called the
-VTABLE interface. VTABLEs are a standard list of functions that all PMCs
-implement.N<Alternately, PMCs can choose not to implement each interface
-explicitly and instead let Parrot call the default implementations.>
-
-VTABLEs are very strict: There are a fixed number with fixed names and
-fixed argument lists. You can't just create any random VTABLE interface that
-you want to create, you can only make use of the ones that Parrot supplies
-and expects. To circumvent this limitation, PMCs may have METHODS in
-addition to VTABLEs. METHODs are arbitrary code functions that can be
-written in C, may have any name, and may implement any behavior.
-
-=head2 VTABLE Interfaces
-
-Internally, all operations on PMCs are performed by calling various VTABLE
-interfaces.
-
-=head2 Class and Object PMCs
-
-The details about various PMC classes are managed by the Class PMC. Class PMCs
-contain information about the class, available methods, the inheritance
-hierarchy of the class, and various other details. Classes can be created
-with the C<newclass> opcode:
-
-  $P0 = newclass "MyClass"
-
-Once we have created the class PMC, we can instantiate objects of that class
-using the C<new> opcode. The C<new> opcode takes either the class name or the
-Class PMC as an argument:
-
-  $P1 = new $P0        # $P0 is the Class PMC
-  $P2 = new "MyClass"  # Same
-
-The C<new> opcode can create two different types of PMC. The first type are
-the built-in core PMC classes. The built-in PMCs are written in C and cannot
-be extended from PIR without subclassing. However, you can also create
-user-defined PMC types in PIR. User-defined PMCs use the Object PMC type for
-instantiation. Object PMCs are used for all user-defined type and keep track
-of the methods and VTABLE override definitions. We're going to talk about
-methods and VTABLE overrides in the next chapter.
-
-=head2 Subclassing PMCs
-
-Existing built-in PMC types can be subclassed to associate additional data
-and methods with that PMC type. Subclassed PMC types act like their PMC
-base types, by sharing the same VTABLE methods and underlying data types.
-However, the subclass can define additional methods and attribute data
-storage. If necessary new VTABLE interfaces can be defined in PIR and old
-VTABLE methods can be overridden using PIR. We'll talk about defining
-methods and VTABLE interface overrides in the next chapter.
-
-Creating a new subclass of an existing PMC class is done using the
-C<subclass> keyword:
-
-  # create an anonymous subclass
-  $P0 = subclass 'ResizablePMCArray'
-
-  # create a subclass named "MyArray"
-  $P0 = subclass 'ResizablePMCArray', 'MyArray'
-
-This returns a C<Class> PMC which can be used to create and modify the
-class by adding attributes or creating objects of that class. You can also
-use the new class PMC to create additional subclasses:
-
-  $P0 = subclass 'ResizablePMCArray', 'MyArray'
-  $P1 = subclass $P0, 'MyOtherArray'
-
-Once you have created these classes, you can create them like normal with
-the C<new> keyword:
-
-  $P0 = new 'MyArray'
-  $P1 = new 'MyOtherArray'
-
-=head2 Attributes
-
-Classes and subclasses can be given attributes which are named data fields.
-Attributes are created with the C<addattribute> opcode, and can be set and
-retrieved with the C<setattribute> and C<getattribute> opcodes respectively:
-
-  # Create the new class with two attributes
-  $P0 = newclass 'MyClass'
-  addattribute $P0, 'First'
-  addattribute $P0, 'Second'
-
-  # Create a new item of type MyClass
-  $P1 = new 'MyClass'
-
-  # Set values to the attributes
-  setattribute $P1, 'First', 'First Value'
-  setattribute $P1, 'Second', 'Second Value'
-
-  # Get the attribute values
-  $S0 = getattribute $P1, 'First'
-  $S1 = getattribute $P1, 'Second'
-
-Those values added as attributes don't need to be strings, even though
-both of the ones in the example are. They can be integers, numbers
-or PMCs too.
-
-=head2 Input and Output
-
-Like almost everything else in Parrot, input and output are handled by PMCs.
-Using the C<print> opcode or the C<say> opcode like we've already seen in
-some examples does this internally without your knowledge. However, we can
-do it explicitly too. First we'll talk about basic I/O, and then we will talk
-about using PMC-based filehandles for more advanced operations.
-
-=head2 Basic I/O Opcodes
-
-We've seen C<print> and C<say>. These are carry-over artifacts from Perl, when
-Parrot was simply the VM backend to the Perl 6 language. C<print> prints
-the given string argument, or the stringified form of the argument, if it's
-not a string, to standard output. C<say> does the same thing but also appends
-a trailing newline to it. Another opcode worth mentioning is the C<printerr>
-opcode, which prints an argument to the standard error output instead.
-
-We can read values from the standard input using the C<read> and C<readline>
-ops. C<read> takes an integer value and returns a string with that many
-characters. C<readline> reads an entire line of input from the standard
-input, and returns the string without the trailing newline. Here is a simple
-echo program that reads in characters from the user and echos them to
-standard output:
-
-=begin PIR
-
-  .sub 'main'
-    loop_top:
-      $S0 = read 10
-      print $S0
-      goto loop_top
-  .end
-
-=end PIR
-
-=head2 Filehandles
-
-The ops we have seen so far are useful if all your I/O operations are limited
-to the standard streams. However, there are plenty of other places where
-you might want to get data from and send data to. Things like files, sockets,
-and databases all might need to have data sent to them. These things can be
-done by using a file handle.
-
-Filehandles are PMCs that describe a file and keep track of an I/O operations
-internal state. We can get Filehandles for the standard streams using dedicated
-opcodes:
-
-  $P0 = getstdin    # Standard input handle
-  $P1 = getstdout   # Standard output handle
-  $P2 = getstderr   # Standard error handle
-
-If we have a file, we can create a handle to it using the C<open> op:
-
-  $P0 = open "my/file/name.txt"
-
-We can also specify the exact mode that the file handle will be in:
-
-  $P0 = open "my/file/name.txt", "wa"
-
-The mode string at the end should be familiar to C programmers, because they
-are mostly the same values:
-
-  r  : read
-  w  : write
-  wa : append
-  p  : pipe
-
-So if we want a handle that we can read and write to, we write the mode string
-C<"rw">. If we want to be able to read and write to it, but we don't want
-write operations to overwrite the existing contents, we use C<"rwa"> instead.
-
-When we are done with a filehandle that we've created, we can shut it down
-with the C<close> op. Notice that we don't want to be closing any of the
-standard streams.
-
-  close $P0
-
-With a filehandle, we can perform all the same operations as we could earlier,
-but we pass the filehandle as an additional argument to tell the op where to
-write or read the data from.
-
-  print "hello"       # Write "hello!" to STDOUT
-
-  $P0 = getstdout
-  print $P0, "hello"  # Same, but more explicit
-
-  say $P0, " world!"  # say to STDOUT
-
-  $P1 = open "myfile.txt", "wa"
-  print $P1, "foo"    # Write "foo" to myfile.txt
-
-=head2 Filehandle PMCs
-
-Let's see a little example of a program that reads in data from a file, and
-prints it to STDOUT.
-
-=begin PIR
-
-  .sub 'main'
-    $P0 = getstdout
-    $P1 = open "myfile.txt", "r"
-    loop_top:
-      $S0 = readline $P1
-      print $P0, $S0
-      if $P1 goto loop_top
-    close $P1
-  .end
-
-=end PIR
-
-This example shows that treating a filehandle PMC like a boolean value
-returns whether or not we have reached the end of the file. A true return
-value means there is more file to read. A false return value means we are at
-the end. In addition to this behavior, Filehandle PMCs have a number of methods
-that can be used to perform various operations.
-
-=over 4
-
-=item C<$P0.'open'(STRING filename, STRING mode)>
-
-Opens the filehandle. Takes two optional strings: the name of the file to open
-and the open mode. If no filename is given, the previous filename associated
-with the filehandle is opened. If no mode is given, the previously-used mode
-is used.
-
-  $P0 = new 'Filehandle'
-  $P0.'open'("myfile.txt", "r")
-
-  $P0 = open "myfile.txt", "r"   # Same!
-
-The C<open> opcode internally creates a new filehandle PMC and calls the
-C<'open'()> method on it. So even though the above two code snippets act in
-an identical way, the later one is a little more concise to write. The caveat
-is that the C<open> opcode creates a new PMC for every call, while the
-C<'open'()> method call can reuse an existing filehandle PMC for a new file.
-
-=item C<$P0.'isatty'()>
-
-Returns a boolean value whether the filehandle is a TTY terminal
-
-=item C<$P0.'close'()>
-
-Closes the filehandle. Can be reopened with C<.'open'> later.
-
-  $P0.'close'()
-
-  close $P0   # Same
-
-The C<close> opcode calls the C<'close'()> method on the Filehandle PMC
-internally, so these two calls are equivalent.
-
-=item C<$P0.'is_closed'()>
-
-Returns true if the filehandle is closed, false if it is opened.
-
-=item C<$P0.'read'(INTVAL length)>
-
-Reads C<length> bytes from the filehandle.
-
-  $S0 = read $P0, 10
-
-  $P0.'read'(10)
-
-The two calls are equivalent, and the C<read> opcode calls the C<'read'()>
-method internally.
-
-=item C<$P0.'readline'()>
-
-Reads an entire line (up to a newline character or EOF) from the filehandle.
-
-=item C<$P0.'readline_interactive'(STRING prompt)>
-
-Displays the string C<prompt> and then reads a line of input.
-
-=item C<$P0.'readall'(STRING name)>
-
-Reads the entire file C<name> into a string. If the filehandle is closed,
-it will open the file given by C<name>, read the entire file, and then close
-the handle. If the filehandle is already open, C<name> should not be passed
-(it is an optional parameter).
-
-=item C<$P0.'flush'()>
-
-Flushes the buffer
-
-=item C<$P0.'print'(PMC to_print)>
-
-Prints the given value to the filehandle. The C<print> opcode uses the
-C<'print'()> method internally.
-
-  print "Hello"
-
-  $P0 = getstdout
-  print $P0, "Hello!"    # Same
-
-  $P0.'print'("Hello!")  # Same
-
-=item C<$P0.'puts'(STRING to_print)>
-
-Prints the given string value to the filehandle
-
-=item C<$P0.'buffer_type'(STRING new_type)>
-
-If C<new_type> is given, changes the buffer to the new type. If it is not,
-returns the current type. Acceptable types are:
-
-  unbuffered
-  line-buffered
-  full-buffered
-
-=item C<$P0.'buffer_size'(INTVAL size)>
-
-If C<size> is given, set the size of the buffer. If not, returns the size of
-the current buffer.
-
-=item C<$P0.'mode'()>
-
-Returns the current file access mode.
-
-=item C<$P0.'encoding'(STRING encoding)>
-
-Sets the filehandle's string encoding to C<encoding> if given, returns the
-current encoding otherwise.
-
-=item C<$P0.'eof'()>
-
-Returns true if the filehandle is at the end of the current file, false
-otherwise.
-
-=item C<$P0.'get_fd'()>
-
-Returns the integer file descriptor of the current file, but only on operating
-systems that use file descriptors. Returns C<-1> on systems that do not
-support this.
-
-=back
-
-=head2 Exceptions
-
-Parrot includes a robust exception mechanism that is not only used internally
-to implement a variety of control flow constructs, but is also available for
-use directly from PIR code. Exceptions, in as few words as possible, are
-error conditions in the program. Exceptions are I<thrown> when an error
-occurs, and they can be I<caught> by special routines called I<handlers>. This
-enables Parrot to recover from errors in a controlled way, instead of crashing
-and terminating the process entirely.
-
-Exceptions, like most other data objects in Parrot, are PMCs. They contain
-and provide access to a number of different bits of data about the error,
-such as the location where the error was thrown (including complete
-backtraces), any annotation information from the file, and other data.
-
-=head2 Throwing Exceptions
-
-Many exceptions are used internally in Parrot to indicate error conditions.
-Opcodes such as C<die> and C<warn> throw exceptions internally to do what they
-are supposed to do. Other opcodes such as C<div> throw exceptions only when
-an error occurs, such as an attempted division by zero.
-
-Exceptions can also be thrown manually using the C<throw> opcode. Here's an
-example:
-
-  $P0 = new 'Exception'
-  throw $P0
-
-This throws the exception object as an error. If there are any available
-handlers in scope, the interpreter will pass the exception object to the
-handler and continue execution there. If there are no handlers available,
-Parrot will exit.
-
-=head2 Exception Attributes
-
-Since Exceptions are PMC objects, they can contain a number of useful data
-items. One such data item is the message:
-
-  $P0 = new 'Exception'
-  $P1 = new 'String'
-  $P1 = "this is an error message for the exception"
-  $P0["message"] = $P1
-
-Another is the severity and the type:
-
-  $P0["severity"] = 1   # An integer value
-  $P0["type"] = 2       # Also an Integer
-
-Finally, there is a spot for additional data to be included:
-
-  $P0["payload"] = $P2  # Any arbitrary PMC
-
-=head2 Exception Handlers
-
-Exception handlers are labels in PIR code that can be jumped to when an
-exception is thrown. To list a label as an exception handler, the C<push_eh>
-opcode is used. All handlers exist on a stack. Pushing a new handler adds it
-to the top of the stack, and using the C<pop_eh> opcode pops the handler off
-the top of the stack.
-
-  push_eh my_handler
-    # something that might cause an error
-
-  my_handler:
-    # handle the error here
-
-=head3 Catching Exceptions
-
-The exception PMC that was thrown can be caught using the C<.get_results()>
-directive. This returns the Exception PMC object that was thrown from inside
-the handler:
-
-  my_handler:
-    .local pmc err
-    .get_results(err)
-
-With the exception PMC available, the various attributes of that PMC can be
-accessed and analyzed for additional information about the error.
-
-=head3 Exception Handler PMCs
-
-Like all other interesting data types in Parrot, exception handlers are a PMC
-type. When using the syntax above with C<push_eh LABEL>, the handler PMC
-is created internally by Parrot. However, you can create it explicitly too
-if you want:
-
-  $P0 = new 'ExceptionHandler'
-  set_addr $P0, my_handler
-  push_eh $P0
-  ...
-
-  my_handler:
-    ...
-
-=head2 Rethrowing and Exception Propagation
-
-Exception handlers are nested and are stored in a stack. This is because not
-all handlers are intended to handle all exceptions. If a handler cannot deal
-with a particular exception, it can C<rethrow> the exception to the next
-handler in the stack. Exceptions propagate through the handler stack until it
-reaches the default handler which causes Parrot to exit.
-
-=head2 Annotations
-
-Annotations are pieces of metadata that can be stored in a bytecode file to
-give some information about what the original source code looked like. This
-is especially important when dealing with high-level languages. We'll go into
-detail about annotations and their use in Chapter 10.
-
-Annotations are created using the C<.annotation> keyword. Annotations consist
-of a key/value pair, where the key is a string and the value is an integer,
-a number, or a string. Since annotations are stored compactly as constants in
-the compiled bytecode, PMCs cannot be used.
-
-  .annotation 'file', 'mysource.lang'
-  .annotation 'line', 42
-  .annotation 'compiletime', 0.3456
-
-Annotations exist, or are "in force" throughout the entire subroutine,
-or until they are redefined. Creating a new annotation with the same name as
-an old one overwrites it with the new value. The current hash of annotations
-can be retrieved with the C<annotations> opcode:
-
-  .annotation 'line', 1
-  $P0 = annotations # {'line' => 1}
-  .annotation 'line', 2
-  $P0 = annotations # {'line' => 2}
-
-Or, to retrieve a single annotation by name, you can write:
-
-  $I0 = annotations 'line'
-
-=head3 Annotations in Exceptions
-
-Exception objects contain information about the annotations that were in force
-when the exception was thrown. These can be retrieved with the
-C<'annotation'()>  method of the exception PMC object:
-
-  $I0 = $P0.'annotations'('line')  # only the 'line' annotation
-  $P1 = $P0.'annotations'()        # hash of all annotations
-
-Exceptions can also give out a backtrace to try and follow where the program
-was exactly when the exception was thrown:
-
-  $P1 = $P0.'backtrace'()
-
-The backtrace PMC is an array of hashes. Each element in the array corresponds
-to a function in the current call stack. Each hash has two elements:
-C<'annotation'> which is the hash of annotations that were in effect at that
-point, and C<'sub'> which is the Sub PMC of that function.
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/tt761_keys_revamp/docs/book/ch04_compiler_tools.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/book/ch04_compiler_tools.pod	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,273 +0,0 @@
-=pod
-
-=head1 Parrot Compiler Tools
-
-Z<CHP-4>
-
-The previous chapters demonstrated low-level Parrot programming in PIR.  That's
-fun, but Parrot's true power is to host programs written in high level
-languages such as Perl 6, Python, Ruby, Tcl, and PHP.
-
-Parrot's language neutrality was a conscious design decision.  Parrot and Perl
-6 hewed closely in the early days; it would have been easy for the two to
-overlap and intermingle.
-
-By keeping the two projects separate and encapsulated, the possibility arose to
-support many other dynamic languages equally well. This modular design also
-benefits designers of future languages.  Instead of having to reimplement
-low-level features such as garbage collection and dynamic data types, language
-designers and compiler implementers can leave these details of infrastructure
-to Parrot and focus on the syntax, capabilities, and libraries of their
-high-level languages instead.
-
-Parrot exposes a rich interface for these languages to use, offering several
-important features: a robust exceptions system, compilation into
-platform-independent bytecode, a clean extension and embedding interface,
-just-in-time compilation to machine code, native library interface mechanisms,
-garbage collection, support for objects and classes, and a robust concurrency
-model.  Designing a new language or implementing a new compiler for an old
-language is easier with all of these features designed, implemented, tested,
-and supported in a VM already.
-
-Language interoperability is a core goal for Parrot. Different languages are
-suited to different tasks; heated debates explode across the Internet about
-which language is right for which project.  There's rarely a perfect fit.
-Developers often settle for one particular language if only because it offers
-the fewest I<disadvantages>.  Parrot changes this game by allowing developers
-to combine multiple languages seamlessly within a single project.  Well-tested
-libraries written in one languages can interoperate with clean problem-domain
-expression in a second language, glued together by a third language which
-elegantly describes the entire system's architecture.  You can use the
-strengths of multiple language and mitigate their weaknesses.
-
-For language hosting and interoperability to work, languages developers need to
-write compilers that convert source code written in high level languages to
-bytecode.  This process is analogous to how a compiler such as GCC converts C
-or C++ into machine code -- though instead of targeting machine code for a
-specific hardware platform, compilers written in Parrot produce Parrot code
-which can run on any hardware platform that can run Parrot.
-
-Parrot includes a suite of compiler tools for every step of this conversion:
-lexical analysis, parsing, optimization, resource allocation, and code
-generation.  Instead of using traditional low-level languages -- such as the C
-produced by C<lex> and C<yacc> -- to write compilers, Parrot can use any
-language hosted on Parrot in its compiler process.  As a practical matter, the
-prevalent tool uses a subset of the Perl 6 programming language called I<Not
-Quite Perl>X<Not Quite Perl> (NQP) and an implementation of the Perl 6 Grammar
-Engine X<Perl 6 Grammar Engine> (PGE) to build compilers for Parrot.
-
-=begin notetip
-
-Yes, the Perl 6 compiler on Parrot is itself written in Perl 6.  This
-X<bootstrapping> I<bootstrapping> process is mind-boggling at first.
-
-=end notetip
-
-PGE and NQP are part of the Parrot Compiler Tools.  A<CHP-5> Chapter 5
-discusses PGE and A<CHP-6> Chapter 6 explains NQP.
-
-=head2 PCT Overview
-
-The X<Parrot Compiler Tools;PCT> Parrot Compiler Tools (PCT) enable the
-creation of high-level language compilers and runtimes.  Though the Perl 6
-development team originally created these tools to produce Rakudo (Perl 6 on
-Parrot), several other Parrot-hosted compilers use them to great effect.
-Writing a compiler using Perl 6 syntax and dynamic language tools is much
-easier than writing a compiler in C, C<lex>, and C<yacc>.
-
-PCT contains several classes that implement various parts of a compiler. HLL
-developers write language-specific subclasses to fill in the details their
-languages require.  The X<HLLCompiler> C<PCT::HLLCompiler> class specifies the
-compiler's interface and represents the object used to parse and execute code.
-The X<Parrot Compiler Tools;PCT::Grammar> C<PCT::Grammar> and X<Parrot Compiler
-Tools;PCT::Grammar::Actions> C<PCT::Grammar::Actions> classes represent the
-parser and syntax tree generators, respectively. Creating a new HLL compiler is
-as easy as subclassing these three entities with methods specific to your
-language.
-
-=head3 Grammars and Action Files
-
-A PCT-based compiler requires three basic files: the main entry point file, the
-grammar specification file, and the grammar actions file. In addition,
-compilers and the languages they implement often use large libaries of built-in
-routines to provide language-specific behaviors.
-
-=over 4
-
-=item * The main file
-
-The main file is (often) a PIR program which contains the C<:main> function
-that creates and executes the compiler object. This program instantiates a
-C<PCT::HLLCompiler> subclass, loads any necessary support libraries, and
-initializes any compiler- or languages-specific data.
-
-The main file tends to be short.  The guts of the compiler logic is in the
-grammar and actions files.  Runtime support and auxiliary functions often
-appear in other files, by convention.  This separation of concerns tends to
-make compilers easier to maintain.
-
-=item * A grammar file
-
-The high-level language's grammar appears in a F<.pg> file.  This file
-subclasses C<PCT::Grammar> class and implements all of the necessary rules --
-written using PGE -- to parse the languages.
-
-=item * An actions file
-
-Actions contains methods -- written in NQP -- on the C<PCT::Grammar:Actions>
-object which receive parse data from the grammar rules and construct an
-X<Abstract Syntax Tree;Parrot Abstract Syntax Tree;AST;PAST> Abstract Syntax
-Tree (AST).N<The Parrot version of an AST is, of course, the Parrot Abstract
-Syntax Tree, or PAST.>
-
-=back
-
-PCT's workflow is customizable, but simple.  The compiler passes the source
-code of the HLL into the grammar engine.  The grammer engine parses this code
-and returns a X<PGE;Match Object> special Match object which represents a
-parsed version of the code.  The compiler then passes this match object to the
-action methods, which convert it in stages into PAST.  The compiler finally
-converts this PAST into PIR code, which it can save to a file, convert to
-bytecode, or execute directly.
-
-=head3 C<mk_language_shell.pl>
-
-The only way creating a new language compiler could be easier is if these files
-created themselves. PCT includes a tool to do just that:
-C<mk_language_shell.pl>.  This program automatically creates a new directory in
-F<languages/> for your new language, the necessary three files, starter files
-for libraries, a F<Makefile> to automate the build process, and a basic test
-harness to demonstrate that your language works as expects.
-
-These generated files are all stubs which will require extensive editing to
-implement a full language, but they are a well-understood and working starting
-point.  With this single command you can create a working compiler.  It's up to
-you to fill the details.
-
-C<mk_language_shell.pl> prefers to run from within a working Parrot repository.
-It requires a single argument, the name of the new project to create.  There
-are no hard-and-fast rules about names, but the Parrot developers reccomend
-that Parrot-based implementations of existing languages use unique names.
-
-Consider the names of Perl 5 distributions: Active Perl and Strawberry Perl.
-Python implementations are IronPython (running on the CLR) and Jython (running
-on the JVM).  The Ruby-on-Parrot compiler isn't just "Ruby": it's Cardinal.
-The Tcl compiler on Parrot is Partcl.
-
-An entirely new language has no such constraints.
-
-From the Parrot directory, invoke C<mk_language_shell.pl> like:
-
-  $ B<cd languages/>
-  $ B<perl ../tools/build/mk_language_shell.pl <project name>>
-
-=head3 Parsing Fundamentals
-
-An important part of a compiler is the parser and lexical analyzer.  The
-lexical analyzer converts the HLL input file into individual tokens. A token
-may consist of an individual punctuation ("+"), an identifier ("myVar"), a
-keyword ("while"), or any other artifact that stands on its own as a single
-unit.  The parser attempts to match a stream of these input tokens against a
-given pattern, or grammar. The matching process orders the input tokens into an
-abstract syntax tree which the other portions of the compiler can process.
-
-X<top-down parser>
-X<bottom-up parser>
-X<parsers; top-down>
-X<parsers; bottom-up>
-Parsers come in top-down and bottom-up varieties. Top-down parsers start with a
-top-level rule which represents the entire input. It attempts to match various
-combination of subrules until it has consumed the entire input.  Bottom-down
-parsers start with individual tokens from the lexical analyzer and attempt to
-combine them together into larger and larger patterns until they produce a
-top-level token.
-
-PGE is a top-down parser, although it also contains a bottom-up I<operator
-precedence> parser to make processing token clusters such as mathematical
-expressions more efficient.
-
-=head2 Driver Programs
-
-The driver program for the new compiler must create instances of the various
-necessary classes that run the parser. It must also include the standard
-function libraries, create global variables, and handle commandline options.
-PCT provides several useful command-line options, but driver programs may need
-to override several behaviors.
-
-PCT programs can run in two ways.  An interactive mode runs one statement at a
-time in the console.  A file mode loads and runs an entire file at once.  A
-driver program may specificy information about the interactive prompt and
-environment, as well as help and error messages.
-
-=head3 C<HLLCompiler> class
-
-The C<HLLCompiler> class implements a compiler object. This object contains
-references to language-specific parser grammar and actions files, as well as
-the steps involved in the compilation process.  The stub compiler created by
-C<mk_language_shell.pl> might resemble:
-
-  .sub 'onload' :anon :load :init
-      load_bytecode 'PCT.pbc'
-      $P0 = get_hll_global ['PCT'], 'HLLCompiler'
-      $P1 = $P0.'new'()
-      $P1.'language'('MyCompiler')
-      $P1.'parsegrammar'('MyCompiler::Grammar')
-      $P1.'parseactions'('MyCompiler::Grammar::Actions')
-  .end
-
-  .sub 'main' :main
-      .param pmc args
-      $P0 = compreg 'MyCompiler'
-      $P1 = $P0.'command_line'(args)
-  .end
-
-The C<:onload> function creates the driver object as an instance of
-C<HLLCompiler>, sets the necessary options, and registers the compiler with
-Parrot. The C<:main> function drives parsing and execution begin. It calls the
-C<compreg> opcode to retrieve the registered compiler object for the language
-"MyCompiler" and invokes that compiler object using the options received from
-the commandline.
-
-The C<compreg> opcode hides some of Parrot's magic; you can use it multiple
-times in a program to compile and run different languages. You can create
-multiple instances of a compiler object for a single language (such as for
-runtime C<eval>) or you can create compiler objects for multiple languages for
-easy interoperability. The Rakudo Perl 6 C<eval> function uses this mechanism
-to allow runtime eval of code snippets in other languages:
-
-  eval("puts 'Konnichiwa'", :lang<Ruby>);
-
-=head3 C<HLLCompiler> methods
-
-The previous example showed the use of several HLLCompiler methods:
-C<language>, C<parsegrammar>, and C<parseactions>.  These three methods are the
-bare minimum interface any PCT-based compiler should provide.  The C<language>
-method takes a string argument that is the name of the compiler. The
-HLLCompiler object uses this name to register the compiler object with Parrot.
-The C<parsegrammar> method creates a reference to the grammar file that you
-write with PGE. The C<parseactions> method takes the class name of the NQP file
-used to create the AST-generator for the compiler.
-
-If your compiler needs additional features, there are several other available
-methods:
-
-=over 4
-
-=item * C<commandline_prompt>
-
-The C<commandline_prompt> method allows you to specify a custom prompt to
-display to users in interactive mode.
-
-=item * C<commandline_banner>
-
-The C<commandline_banner> method allows you to specify a banner message that
-displays at the beginning of interactive mode.
-
-=back
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/tt761_keys_revamp/docs/book/ch05_pge.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/book/ch05_pge.pod	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,1558 +0,0 @@
-=pod
-
-=head1 Grammar Engine
-
-X<Parrot Grammar Engine>
-X<PGE (Parrot Grammar Engine)>
-The Parrot Grammar Engine (PGE) is a parser generator, one of the key
-components of the Parrot Compiler Toolkit. It reads grammar files written in
-the PGE rules format and generates parser modules written in PIR code. PGE
-rules provide the full power of I<recursive descent parsing> and I<operator
-precedence parsing>. Fortunately, you don't need to know what those terms
-mean in order to make good use of PGE. We'll introduce the necessary
-concepts as we talk about various features in this chapter.
-
-=head2 Grammars
-
-The ultimate goal of a parser is to match patterns in a source language and
-convert them to an internal data structure for later manipulations. As a
-programmer, you're probably already familiar with some of these types of
-patterns: function declarations, function calls, statements, and assignments.
-Each of these different concepts have a particular form called a I<syntax>.
-In C for example, the syntax to define a function looks something like this:
-
-  <return_type> <function_name> ( <arguments> ) { <function_body> }
-
-Things that fit this pattern, so long as all the sub-patterns use the proper
-syntax also, are valid subroutines in C. Similarly, we can use a slightly
-different pattern to create a subroutine:
-
-  sub <function_name> { <function_body> }
-
-A grammar is a collection of rules like the ones above that specify all the
-acceptable patterns in a language. Grammars group together these rules in
-much the same way that a groups together related data fields and methods
-N<In languages like Perl 6 for instance, a grammar is just a special kind
-of class and a rule is just a special kind of method.>. Each rule defines
-a pattern for matching one unit of text, and can be made up of various other
-rules which are called recursively to make a complete match.
-
-A rule can contain regular expressions to match patterns of characters:
-
-  rule id { \d+ }
-
-A rule can also contain patterns of references to other rules:
-
-  rule record { <id> <name> <phone> }
-
-A grammar contains a group of rules that work together to match the entire
-language:
-
-  grammar Contacts;
-
-  rule name { 'John' | 'Bob ' | 'Fred' }
-
-  rule id   { \d+ }
-
-  rule record { <id> <name> }
-
-  ...
-
-=head3 Rules and Tokens
-
-X<rule>
-X<token>
-There are two different kinds of rules: C<rule>, which we saw above, and
-C<token>. A C<rule> performs smart whitespace matching between the various
-pieces of the pattern. The C<record> rule given previously would match
-"6355 John" or "6355      John" but not "6355John".
-
-A C<token> matches whitespace only if you specifically request it. To get the
-same effect with a token, add the C<\s> (match a space character) and C<+>
-(match the preceding atom -- the space character, in this case -- one or more
-times) pattern to the rule:
-
-  token record { <id> \s+ <name> }
-
-=head3 The Start Rule
-
-X<top>
-X<top-down parser>
-A recursive descent parser is what's called a I<top-down parser>. It starts
-at the highest-level rule, called C<TOP>, and works its way down through
-individual rules to match an entire string or file. Real Perl 6 allows any
-name for the top-level rule, but PCT expects a rule called C<TOP>. If PCT
-was as fully-featured as Perl 6, people would use it instead! Here's an
-example of a TOP rule:
-
-  rule TOP { <record> }
-
-This rule matches a single C<record> pattern in a string or file. Once the
-parser has succeeded in matching the entire string or file passed to the
-start rule, it returns a parse tree. If it cannot match the entire input
-with the rules provided, it can either return a partial match, or it can
-throw a parse error.
-
-=head3 Testing a Grammar
-
-Let's do a small example grammar. Save this example to a file called
-F<Contacts.pg>:
-
-  grammar Contacts is PGE::Grammar;
-
-  rule  TOP    { <record> }
-  rule  record { <id> <name> }
-  token name   { 'John' | 'Bob ' | 'Fred' }
-  token id     { \d+ }
-
-Then compile the grammar:
-
-  $ B<parrot Perl6Grammar.pbc --output=Contacts.pir Contacts.pg>
-
-=for author
-
-Assume an installed Parrot for all examples?  Anyone working from the source
-tree should be able to mangle paths appropriately.
-
-=end for
-
-The path to F<parrot> and to the F<Perl6Grammar.pbc> file will vary on
-different systems. If you compiled Parrot from source, it will be:
-
-  $ B<./parrot runtime/parrot/library/PGE/Perl6Grammar.pbc \>
-        B<--output=Contacts.pir Contacts.pg>
-
-Next, create a small PIR script to run your grammar. Save it as
-F<grammar_test.pir>:
-
-=begin PIR
-
-  .sub main :main
-      load_bytecode 'PGE.pbc'        # load some required modules
-      load_bytecode 'dumper.pbc'
-      load_bytecode 'PGE/Dumper.pbc'
-
-      load_bytecode 'Contacts.pir'   # load your grammar
-
-      .local string source
-      source  = "3 John"
-
-      .local pmc top, grammar, match
-      top     = get_hll_global ['Contacts'], 'TOP'
-      grammar = get_class 'Contacts'
-      match   = top(source, 'grammar' => grammar)
-
-      _dumper(match, "match")
-  .end
-
-=end PIR
-
-Run the test script:
-
-  $ B<parrot grammar_test.pir>
-
-It will print out a text representation of the raw parse tree stored in the
-C<match> variable:
-
-  "match" => PMC 'Contacts' => "3 John" @ 0 {
-      <record> => PMC 'Contacts' => "3 John" @ 0 {
-          <id> => PMC 'Contacts' => "3" @ 0
-          <name> => PMC 'Contacts' => "John" @ 2
-      }
-  }
-
-Each node in the tree corresponds to a rule in the grammar.  The top-level
-match variable contains one child named C<record>, which contains two children
-named C<id> and C<name>.  C<id> contains the number 3, and C<name> contains the
-string "John". This is exactly what the simple grammar should have matched.
-
-=head2 Rule Syntax
-
-Every language has a set of basic components (words or parts of words) and
-syntax conventions for combining them. The "words" in rules are literal
-characters or symbols, some X<metacharacters> metacharacters (or metasymbols),
-and X<rules;escape sequences>X<escape sequences, rules> escape sequences, while
-the combining syntax includes other metacharacters, X<quantifiers, rules>
-X<rules;quantifiers> quantifiers, bracketing characters, and assertions.
-
-=head3 Metacharacters
-
-The C<.> metacharacter matches any single character, even a newline character.
-The C<^> and C<$> metacharacters are zero-width matches which represent the
-beginning and end of a string. They each have doubled alternates C<^^> and
-C<$$> that match at the beginning and end of every (newline-delimited) line
-within a string.
-
-The C<|>, C<&>, C<\>, C<#>, and C<:=> metacharacters are all syntax structure
-elements. C<|> alternates between two options. C<&> matches two patterns
-simultaneously (the patterns must be the same length). C<\> turns literal
-characters into metacharacters (producing escape sequences). C<#> starts a
-comment which proceeds until the end of the line. You can start a comment at
-any point on any line in a rule. C<:=> binds a hypothetical variable to the
-result of a subrule or grouped pattern (see L<Hypothetical Variables>).
-
-The metacharacters C<()>, C<[]>, C<{}> and C<E<lt>E<gt>> are bracketing pairs.
-Bracketing pairs must always be balanced within the rule; to use a literal
-character, escape it with a C<\>.  The C<()> and C<[]> pairs group patterns as
-a single atom. They often capture a result, mark the boundaries of an
-alternation, or mark a group of patterns with a quantifier. Parentheses C<()>
-capture, but square brackets C<[]> do not. The C<{}> brackets define a section
-of code (a closure) within a rule. These closures are always a successful
-zero-width match. The C<E<lt>...E<gt>> brackets mark assertions, which handle a
-variety of constructs including character classes and user-defined quantifiers
-(see L<Assertions>).
-
-Table 7-2 summarizes the basic metacharacters.
-
-=begin table picture Metacharacters
-
-Z<CHP-7-TABLE-2>
-
-=headrow
-
-=row
-
-=cell Symbol
-
-=cell Meaning
-
-=bodyrows
-
-=row
-
-=cell C<.>
-
-=cell Match any single character, including a newline.
-X<. (dot);. match single character (rules)>
-
-=row
-
-=cell C<^>
-
-=cell Match the beginning of a string.
-X<^ (caret);^ beginning of string (rules)>
-
-=row
-
-=cell C<$>
-
-=cell Match the end of a string.
-X<$ (dollar sign);$ end of string (rules)>
-
-=row
-
-=cell C<^^>
-
-=cell Match the beginning of a line within the string.
-X<^ (caret);^^ beginning of line (rules)>
-
-=row
-
-=cell C<$$>
-
-=cell Match the end of a line within the string.
-X<$ (dollar sign);$$ end of line (rules)>
-
-=row
-
-=cell C<|>
-
-=cell Match alternate patterns (OR).
-
-=row
-
-=cell C<&>
-
-=cell Match multiple patterns (AND).
-
-=row
-
-=cell C<\>
-
-=cell Escape a metacharacter to get a literal character, or escape a
-literal character to get a metacharacter.
-X<\ (backslash);\ escape sequences (rules)>
-X<\ (backslash);\ to escape metacharacters (rules)>
-
-=row
-
-=cell C<#>
-
-=cell Mark a comment (to the end of the line).
-
-=row
-
-=cell C<:=>
-
-=cell Bind the result of a match to a hypothetical variable.
-X<: (colon);:= (binding);in rules>
-
-=row
-
-=cell C<(...)>
-
-=cell Group patterns and capture the result.
-
-=row
-
-=cell C<[...]>
-
-=cell Group patterns without capturing.
-
-=row
-
-=cell C<{...}>
-
-=cell Execute a closure (Perl 6 code) within a rule.
-
-=row
-
-=cell C<E<lt>...E<gt>>
-
-=cell Match an assertion.
-
-=end table
-
-=head3 Escape Sequences
-
-Z<CHP-7-SECT-2.2>
-
-X<escape sequences, rules>
-X<rules;escape sequences>
-X<\ (backslash);\ escape sequences (rules)>
-
-Escape sequences are literal characters acting as metacharacters.  A preceding
-backslash (C<\>) identifies them as escapes. Some escape sequences represent
-single characters that are difficult to represent literally, such as C<\t> for
-tab, or C<\x[...]> to specify a character by its hexadecimal number.  Some
-represent limited character classes, such as C<\d> for digits or C<\w> for word
-characters. Some represent zero-width positions in a match, such as C<\b> for a
-word boundary.
-
-X<variable interpolation in rules>
-X<rules;variable interpolation>
-If you've used Perl 5 regexps, you may remember the C<\Q> escape sequence which
-treats everything until the following C<\E> sequence as literal text,
-containing no escape sequences.  Because ordinary variables now interpolate as
-literal strings by default, the C<\Q> escape sequence is rarely needed.
-
-A<CHP-7-TABLE-3>Table 7-3 shows the escape sequences for rules.
-
-=begin table picture Escape sequences
-
-Z<CHP-7-TABLE-3>
-
-=headrow
-
-=row
-
-=cell Escape
-
-=cell Meaning
-
-=bodyrows
-
-=row
-
-=cell C<\0[...]>
-
-=cell Match a character given in octal (brackets optional).
-
-=row
-
-=cell C<\b>
-
-=cell Match a word boundary.
-
-=row
-
-=cell C<\B>
-
-=cell Match when not on a word boundary.
-
-=row
-
-=cell C<\c[...]>
-
-=cell Match a named character or control character.
-
-=row
-
-=cell C<\C[...]>
-
-=cell Match any character except the bracketed named or control character.
-
-=row
-
-=cell C<\d>
-
-=cell Match a digit.
-
-=row
-
-=cell C<\D>
-
-=cell Match a non-digit.
-
-=row
-
-=cell C<\e>
-
-=cell Match an escape character.
-
-=row
-
-=cell C<\E>
-
-=cell Match anything but an escape character.
-
-=row
-
-=cell C<\f>
-
-=cell Match the form feed character.
-
-=row
-
-=cell C<\F>
-
-=cell Match anything but a form feed.
-
-=row
-
-=cell C<\n>
-
-=cell Match a (logical) newline.
-
-=row
-
-=cell C<\N>
-
-=cell Match anything but a (logical) newline.
-
-=row
-
-=cell C<\h>
-
-=cell Match horizontal whitespace.
-
-=row
-
-=cell C<\H>
-
-=cell Match anything but horizontal whitespace.
-
-=row
-
-=cell C<\L[...]>
-
-=cell Everything within the brackets is lowercase.
-
-=row
-
-=cell C<\Q[...]>
-
-=cell All metacharacters within the brackets match as literal characters.
-
-=row
-
-=cell C<\r>
-
-=cell Match a return.
-
-=row
-
-=cell C<\R>
-
-=cell Match anything but a return.
-
-=row
-
-=cell C<\s>
-
-=cell Match any whitespace character.
-
-=row
-
-=cell C<\S>
-
-=cell Match anything but whitespace.
-
-=row
-
-=cell C<\t>
-
-=cell Match a tab.
-
-=row
-
-=cell C<\T>
-
-=cell Match anything but a tab.
-
-=row
-
-=cell C<\U[...]>
-
-=cell Everything within the brackets is uppercase.
-
-=row
-
-=cell C<\v>
-
-=cell Match vertical whitespace.
-
-=row
-
-=cell C<\V>
-
-=cell Match anything but vertical whitespace.
-
-=row
-
-=cell C<\w>
-
-=cell Match a word character (Unicode alphanumeric characters plus the
-underscore C<_>).
-
-=row
-
-=cell C<\W>
-
-=cell Match anything but a word character.
-
-=row
-
-=cell C<\x[...]>
-
-=cell Match a character given in hexadecimal (brackets optional).
-
-=row
-
-=cell C<\X[...]>
-
-=cell Match anything but the character given in hexadecimal (brackets
-optional).
-
-=end table
-
-=head3 Quantifiers
-
-Z<CHP-7-SECT-2.3>
-
-Quantifiers specify the number of times an atom (a single character,
-metacharacter, escape sequence, grouped pattern, assertion, etc) will match.
-
-X<. (dot);.. (range);quantifier (rules)>
-X<. (dot);... (infinite range);quantifier (rules)>
-The numeric quantifiers use assertion syntax. A single number (C<E<lt>3E<gt>>)
-requires exactly that many matches. A numeric range quantifier
-(C<E<lt>3C<..>5E<gt>>) succeeds if the number of matches is between the minimum
-and maximum numbers, inclusive. A range with three trailing dots
-(C<E<lt>2...E<gt>>) is shorthand for C<E<lt>R<n>..InfE<gt>>; it matches as many
-times as possible.
-
-Each quantifier has a minimal alternate form -- marked with a trailing C<?> --
-which matches the shortest possible sequence first.  That is, given the string
-C<aaaaaa>, C<aE<lt>3C<..>5E<gt>> will match C<aaaaa> and C<aE<lt>3C<..>5E<gt>?>
-will match C<aaa>.
-
-A<CHP-7-TABLE-4>Table 7-4 shows the built-in
-X<quantifiers, rules> X<rules;quantifiers> quantifiers.
-
-=begin table picture Quantifiers
-
-Z<CHP-7-TABLE-4>
-
-=headrow
-
-=row
-
-=cell Maximal
-
-=cell Minimal
-
-=cell Meaning
-
-=bodyrows
-
-=row
-
-=cell C<*>
-
-=cell C<*?>
-
-=cell Match 0 or more times.
-
-=row
-
-=cell C<+>
-
-=cell C<+?>
-
-=cell Match 1 or more times.
-
-=row
-
-=cell C<?>
-
-=cell C<??>
-
-=cell Match 0 or 1 times.
-
-=row
-
-=cell C<E<lt>>R<n>C<E<gt>>
-
-=cell C<E<lt>>R<n>C<E<gt>?>
-
-=cell Match exactly R<n> times.
-
-=row
-
-=cell C<E<lt>>R<n>C<..>R<m>C<E<gt>>
-
-=cell C<E<lt>>R<n>C<..>R<m>C<E<gt>?>
-
-=cell Match at least R<n> and no more than R<m> times.
-
-=row
-
-=cell C<E<lt>>R<n>C<...E<gt>>
-
-=cell C<E<lt>>R<n>C<...E<gt>?>
-
-=cell Match at least R<n> times.
-
-=end table
-
-=head3 Assertions
-
-Z<CHP-7-SECT-2.4>
-
-X<assertions, rules>
-X<rules;assertions>
-An assertion states that some condition or state is true. The match fails when
-that assertion is false.
-
-X<variable interpolation in rules>
-X<rules;variable interpolation>
-
-Assertions match named and anonymous rules, arrays or hashes containing
-anonymous rules, and subroutines or closures that return anonymous rules.
-
-To interpolate a variable in assertion rules, enclose it in assertion
-delimiters.
-A bare scalar in a pattern
-interpolates as a literal string, while a scalar variable in assertion
-brackets interpolates as an anonymous rule. A bare array in a pattern
-matches as a series of alternate literal strings, while an array in
-assertion brackets interpolates as a series of alternate anonymous
-rules.
-
-A bare hash in a pattern matches a word (C<\w+>) if and only if that word is
-one of its keysN<The effect is similar to matching the keys as a series of
-alternates, but it prefers to match the longest possible key, instead of the
-first potential match.>, while a hash in assertion brackets also matches the
-associated value as an anonymous rule.
-
-X<fail keyword>
-A bare closure in a pattern always matches (unless it calls C<fail>), but a
-closure in assertion brackets C<E<lt>{...}E<gt>> must return an anonymous rule
-to match.
-
-An assertion with parentheses C<E<lt>(...)E<gt>> resembles a bare closure in a
-pattern in that it allows you to include Perl code within a rule.
-C<E<lt>(...)E<gt>> evaluates the return value of the closure in boolean
-context. The match succeeds or fails based on that return value.
-
-Assertions match character classes, both named and enumerated. A named rule
-character class is often more accurate than an enumerated character class. The
-common C<E<lt>[a-zA-Z]E<gt>> idiom matches ASCII alphabetic characters, but the
-more comprehensive built-in rule C<E<lt>alphaE<gt>> matches the full set of
-Unicode alphabetic characters.
-
-A<CHP-7-TABLE-5>Table 7-5 shows the syntax of assertions.
-
-=begin table picture Assertions
-
-Z<CHP-7-TABLE-5>
-
-=headrow
-
-=row
-
-=cell Syntax
-
-=cell Meaning
-
-=bodyrows
-
-=row
-
-=cell C<E<lt>...E<gt>>
-
-=cell Generic assertion delimiter.
-
-=row
-
-=cell C<E<lt>!...E<gt>>
-
-=cell Negate any assertion.
-
-=row
-
-=cell C<E<lt>>R<name>C<E<gt>>
-
-=cell Match a named rule or character class.
-
-=row
-
-=cell C<E<lt>[...]E<gt>>
-
-=cell Match an enumerated character class.
-
-=row
-
-=cell C<E<lt>-...E<gt>>
-
-=cell Complement a character class (named or enumerated).
-
-=row
-
-=cell C<E<lt>"..."E<gt>>
-
-=cell Match a literal string (interpolated at match time).
-
-=row
-
-=cell C<E<lt>'...'E<gt>>
-
-=cell Match a literal string (not interpolated).
-
-=row
-
-=cell C<E<lt>(...)E<gt>>
-
-=cell Boolean assertion. Execute a closure and match if it returns a true
-result.
-
-=row
-
-=cell C<E<lt>$scalarE<gt>>
-
-=cell Match an anonymous rule.
-
-=row
-
-=cell C<E<lt>@arrayE<gt>>
-
-=cell Match a series of anonymous rules as alternates.
-
-=row
-
-=cell C<E<lt>%hashE<gt>>
-
-=cell Match a key from the hash, then its value (as an anonymous rule).
-
-=row
-
-=cell C<E<lt>E<amp>sub()E<gt>>
-
-=cell Match an anonymous rule returned by a sub.
-
-=row
-
-=cell C<E<lt>{>R<code>C<}E<gt>>
-
-=cell Match an anonymous rule returned by a closure.
-
-=row
-
-=cell C<E<lt>.E<gt>>
-
-=cell Match any logical grapheme, including combining character sequences.
-
-=end table
-
-=head3 Modifiers
-
-Z<CHP-7-SECT-2.5>
-
-X<modifiers>
-X<: (colon);: modifier delimiter in rules>
-Modifiers alter the meaning of a pattern. The standard position for modifiers
-is at the beginning of the rule, right after the C<m>, C<s>, or C<rx>, or after
-the name in a named rule. Modifiers cannot attach to the outside of a bare
-C</.../>. For example:
-
-  m:i/marvin/ # case insensitive
-  rule names :i { marvin | ford | arthur }
-
-You may group single-character modifiers, but you must separate longer
-modifiers by colons:
-
-  m:wig/ zaphod /                        # OK
-  m:words:ignorecase:globally / zaphod / # OK
-  m:wordsignorecaseglobally / zaphod /   # Not OK
-
-Most modifiers can also appear inside the rule when attached to rule or
-grouping delimiters. Internal modifiers are lexically scoped to their enclosing
-delimiters, so can alter subpatterns:
-
-  m/:w I saw [:i zaphod] / # only 'zaphod' is case insensitive
-
-The repetition modifiers (C<:R<N>x>, C<:R<N>th>, C<:once>, C<:globally>, and
-C<:exhaustive>) and the continue modifier (C<:cont>) alter the return value of
-the rule as a whole, so you cannot use them lexically inside a rule.
-
-The C<:R<N>x> modifier matches the rule a specific number of times. If the
-modifier expects more matches than the string has, the match fails.  Its
-alternate form (C<:x(R<N>)>) can take a variable in place of the number.
-
-The C<:once> modifier on a rule only allows it to match once. The rule will not
-match again until the you call the C<.reset> method on the rule object.
-
-The C<:globally> modifier matches as many times as possible. The C<:exhaustive>
-modifier also matches as many times as possible, in as many different ways as
-possible.
-
-The C<:R<N>th> modifier preserves one result from a particular counted match.
-If the rule matches fewer times than the modifier expects, the match fails. It
-has several alternate forms. One form, C<:th(R<N>)>, takes a variable in place
-of the number. The other forms -- C<:R<N>st>, C<:R<N>nd>, and C<:R<N>rd> --
-allow you to write more naturally C<:1st>, C<:2nd>, C<:3rd>.  The other way is
-valid as well; choose whichever is most comfortable.
-
-By default, rules ignore literal whitespace within the pattern.  The C<:w>
-modifier makes rules sensitive to literal whitespace, but in an intelligent
-way. Any cluster of literal whitespace acts like an explicit C<\s+> when it
-separates two identifiers and C<\s*> everywhere else.
-
-I<No> modifiers exist to treat the matched string as a single line or multiple
-lines.  Instead, use the "beginning of string" and "end of string" or
-"beginning of line" and "end of line" metacharacters.
-
-A<CHP-7-TABLE-6>Table 7-6 lists the available modifiers.
-
-=begin table picture Modifiers
-
-Z<CHP-7-TABLE-6>
-
-=headrow
-
-=row
-
-=cell Short
-
-=cell Long
-
-=cell Meaning
-
-=bodyrows
-
-=row
-
-=cell C<:i>
-
-=cell C<:ignorecase>
-
-=cell Case-insensitive match.
-
-=row
-
-=cell C<:I>
-
-=cell
-
-=cell Case-sensitive match (on by default).
-
-=row
-
-=cell C<:c>
-
-=cell C<:cont>
-
-=cell Continue where the previous match on the string left off.
-
-=row
-
-=cell C<:w>
-
-=cell C<:words>
-
-=cell Literal whitespace in the pattern matches as C<\s+>
-or C<\s*>.
-
-=row
-
-=cell C<:W>
-
-=cell
-
-=cell Turn off intelligent whitespace matching (return to default).
-
-=row
-
-=cell
-
-=cell :R<N>C<x>/C<:x(>R<N>C<)>
-
-=cell Match the pattern R<N> times.
-
-=row
-
-=cell
-
-=cell C<:>R<N>C<th>/C<:nth(>R<N>C<)>
-
-=cell Match the R<N>th occurrence of a pattern.
-
-=row
-
-=cell
-
-=cell C<:once>
-
-=cell Match the pattern once and only once.
-
-=row
-
-=cell C<:g>
-
-=cell C<:globally>
-
-=cell Match the pattern as many times as possible without overlapping
-possibilities.
-
-=row
-
-=cell C<:e>
-
-=cell C<:exhaustive>
-
-=cell Match every possible occurrence of a pattern, including overlapping
-possibilities.
-
-=row
-
-=cell
-
-=cell C<:u0>
-
-=cell . is a byte.
-
-=row
-
-=cell
-
-=cell C<:u1>
-
-=cell . is a Unicode codepoint.
-
-=row
-
-=cell
-
-=cell C<:u2>
-
-=cell . is a Unicode grapheme.
-
-=row
-
-=cell
-
-=cell C<:u3>
-
-=cell . is language dependent.
-
-=row
-
-=cell
-
-=cell C<:p5>
-
-=cell The pattern uses Perl 5 regex syntax.
-
-=end table
-
-=head3 Built-in Rules
-
-Z<CHP-7-SECT-3>
-
-X<rules;built-in>
-PGE provides several named rules, including a complete set of X<POSIX-style
-classes> POSIX-style classes, and X<Unicode property classes> Unicode property
-classes. The list isn't fully defined yet, but A<CHP-7-TABLE-7>Table 7-7 shows
-a few you're likely to see.
-
-The C<E<lt>nullE<gt>> rule matches a zero-width string (it always matches) and
-C<E<lt>priorE<gt>> matches whatever the most recent successful rule matched.
-These replace the two behaviors of X</ (slash);// invalid null pattern>
-X<invalid null pattern //> the Perl 5 null pattern C<//>, which is no longer
-valid syntax for rules.
-
-=begin table picture Built-in rules
-
-Z<CHP-7-TABLE-7>
-
-=headrow
-
-=row
-
-=cell Rule
-
-=cell Meaning
-
-=bodyrows
-
-=row
-
-=cell C<E<lt>alphaE<gt>>
-
-=cell Match a Unicode alphabetic character.
-
-=row
-
-=cell C<E<lt>digitE<gt>>
-
-=cell Match a Unicode digit.
-
-=row
-
-=cell C<E<lt>spE<gt>>
-
-=cell Match a single space character (the same as C<\s>).
-
-=row
-
-=cell C<E<lt>wsE<gt>>
-
-=cell Match any whitespace (the same as C<\s+>).
-
-=row
-
-=cell C<E<lt>nullE<gt>>
-
-=cell Match the null string.
-
-=row
-
-=cell C<E<lt>priorE<gt>>
-
-=cell Match the same thing as the previous match.
-
-=row
-
-=cell C<E<lt>before ...E<gt>>
-
-=cell Zero-width lookahead. Assert that the current position I<precedes> a
-pattern.
-
-=row
-
-=cell C<E<lt>after ...E<gt>>
-
-=cell Zero-width lookbehind. Assert that the current position I<follows> a
-pattern.
-
-=row
-
-=cell C<E<lt>prop ...E<gt>>
-
-=cell Match any character with the named property.
-
-=row
-
-=cell C<E<lt>replace(...)E<gt>>
-
-=cell Replace everything matched so far in the rule or subrule with the
-given string (under consideration).
-
-=end table
-
-=head3 Backtracking Control
-
-Z<CHP-7-SECT-4>
-
-X<backtracking controls>
-X<fail keyword>
-Whenever part of the pattern fails to match, PGE performs backtracking --
-backing up to the previous point at which the match could succeed and trying
-again.  You can explicitly trigger backtracking by calling the C<fail> function
-within a closure. A<CHP-7-TABLE-8>Table 7-8 displays metacharacters and
-built-in rules relevant to backtracking.
-
-=for author
-
-This could use an example.
-
-=end for
-
-=begin table picture Backtracking controls
-
-Z<CHP-7-TABLE-8>
-
-=headrow
-
-=row
-
-=cell Operator
-
-=cell Meaning
-
-=bodyrows
-
-=row
-
-=cell C<:>
-
-=cell Don't retry the previous atom.  Instead, fail to the next earlier atom.
-X<: (colon);: fail to atom before last (rules)>
-X<backtracking controls;: fail to atom before last>
-
-=row
-
-=cell C<::>
-
-=cell Don't backtrack over this point. Instead fail out of the closest
-enclosing group (C<(...)>, C<[...]>, or the rule delimiters).
-X<: (colon);:: fail out of group (rules)>
-X<backtracking controls;: fail out of group>
-
-=row
-
-=cell C<:::>
-
-=cell Don't backtrack over this point.  Instead, fail out of the current rule
-or subrule.
-X<: (colon);::: fail out of rule (rules)>
-X<backtracking controls;: fail out of rule>
-
-=row
-
-=cell C<E<lt>commitE<gt>>
-
-=cell Don't backtrack over this point. Instead, fail out of the entire match
-(even from within a subrule).
-
-=row
-
-=cell C<E<lt>cutE<gt>>
-
-=cell Like C<E<lt>commitE<gt>>, but also cuts the string matched. The current
-matching position at this point becomes the new beginning of the string.
-
-=end table
-
-=head3 Calling Actions
-
-Once the parser has matched the entire input N<a source code file, or a line of
-input at the terminal in interactive mode> the parse has succeeded.  The
-generated AST is now available to the code generator for conversion into PIR.
-
-=for author
-
-Please review.  The forward declaration is awkward here, but a little bit of
-explanation might ameliorate this.
-
-=end for
-
-This AST gets built up by actions -- code snippets attached to rules and
-tokens.  To call an action, insert the C<{*}> token into the rule. When PGE
-encounters C<{*}>, it will call the associated action method with the current
-match object as an argument.
-
-The best way to demonstrate this is by example.  Sprinkle the C<persons_name>
-rule liberally with action calls:
-
- rule persons_name {
-    {*} <first_name> {*} <last_name> {*}
- }
-
-The first call to the action method contains an empty match object because the
-parser hasn't matched anything yet.  The second call contains only the first
-name of the match. The third and final call contains both the matched first and
-last name.
-
-If the match fails halfway through, PGE will still call the actions that have
-succeeded; it will not call the actions after the failure.  If you try to match
-the string "Leia", PGE will call the first two action methods.  When the rule
-tries to match the last name, it fails, and PGE will not call the third action
-method.
-
-=head3 Alternations and Keys
-
-In addition to sub-rules, groups, and quantifiers, you can also express
-either-or alternations between options. The vertical bar token (C<|>)
-distinguishes between options where only one may match:
-
- rule hero {
-    ['Luke' | 'Leia'] 'Skywalker'
- }
-
-This rule will match either "Luke Skywalker" or "Leia Skywalker" but won't
-match "Luke Leia Skywalker"N<nor anything else.>.  Given alternations and
-action methods, it's often important to distinguish which alternation matched:
-
- rule hero {
-    [
-      'Luke' {*}    #= Luke
-    | 'Leia' {*}    #= Leia
-    ]
-    'Skywalker'
- }
-
-This is the same rule, except now it passes two arguments to its action method:
-the match object and the name of the person who matched.
-
-=head3 Warning: Left Recursion
-
-If you've worked with parsers before, you may have seen this coming.  If not,
-don't fear.  Like functions in ordinary procedural or functional languages, the
-methods in the PGE parser grammar can call themselves recursively.  Consider
-some rules derived in part from the grammar for the C programming language:
-
- rule if_statement {
-    'if' <condition> '{' <statement>* '}' <else_block>?
- }
-
- rule statement {
-    <if_statement> | <expression>
- }
-
- rule else_block {
-    'else' '{' <statements>* '}'
- }
-
-An C<if_statement> can contain a list of C<statement>s, and that each statement
-may itself be an C<if_statement>.  This is I<recursion> X<Recursion>; it's one
-of the reasons PGE is a "Recursive descent" parser.
-
-Consider the more direct example of a comma-separated list of integer digits
-which form a list.  A recursive definition might be:
-
- rule list {
-     <list> ',' <digit> | <digit>
- }
-
-If there is only one digit, the second option in the alternation matches.  If
-there are multiple digits, recursion will match them through the first
-alternation.
-
-That's the intention.  The results are insidious.
-
-The recursive descent parser enters the C<list> rule. Its first option is to
-enter the list rule again, so it does.  Recursive descent is a X<depth-first
-algorithm> depth-first algorithm; PGE will continue to descend down a
-particular path until it finds a successful match or a match failure. In this
-case, it matches C<list>, then it matches C<list> again, then it matches
-C<list> again, and so on.  This rule forms an infinite loop -- a pattern called
-X<left recursion> I<left recursion>.  The problem is that the left-most item of
-the left-most alternation is itself a recursion.
-
-The rule above does not recurse infinitely when rewritten as:
-
- rule list {
-    <digit> | <list> ',' <digit>
- }
-
-... or even:
-
- rule list {
-    <digit> ',' <list> | <digit>
- }
-
-Both options ensure that the left-most item in the rule is recursive.
-
-Left recursion may be trickier.  It's not immediately obvious in this grammar:
-
- rule term {
-    <expression> '*' <term> | <digit>
- }
-
- rule expression {
-    <term> '+' <expression> | <term>
- }
-
-Even this common, limited subset of mathematical equations has the same
-problem.  To match a C<term>, the parser first tries to match an C<expression>,
-which in turn matches a C<term> and then an C<expression> ....
-
-Again, the solution is simple.  Rewrite at least one of the rules so that the
-first condition it tries to match is not itself a recursive situation.
-
-=head3 Operator Precedence Parser
-
-Recursive descent parsing can be inefficient where statements have lots of
-little tokens and many possible options to match.  For example, mathematical
-expressions are very open-ended, with many valid forms which are difficult to
-anticipate.  Consider the expression:
-
- a + b * c + d
-
-A recursive descent parser will undergo significant trial and error to parse
-this statement.  Recursive descent parsing is not ideal for these situations.
-Instead, a type of bottom-up parser called an I<operator precedence> X<Parser,
-Operator precedence> parser is much better.
-
-=for author
-
-Is this a categorization of all opps or just PGE's opp?
-
-=end for
-
-Operator precedence parsers work similarly to more versatile bottom-up parsers
-such as Lex or Yacc, but are optimized for use with expressions and equations.
-Equations have two subtypes, I<terms> and I<operators>. Operators themselves
-have several subtypes, including prefix (C<-a>), postfix (C<i++>), infix (C<x +
-y>), circumfix (C<[z]>), postcircumfix (C<a[b]>), and list (C<1, 2, 3>). Each
-operator gets its own precedence number that specifies how closely it binds to
-the terms. The previous example should parse as:
-
- a + (b * c) + d
-
-... because the C<*> operator has a higher precedence -- binding more tightly
-to its terms -- than the C<+> operator.
-
-Within a grammar, switch from the top-down recursive descent parser to the
-bottom-up operator precedence parser with an C<optable> X<Parser, optable>
-rule:
-
- rule expression is optable { ... }
-
-The C<...> ellipsis isn't an editorial shortcut, it's the Perl 6 operator to to
-define a function signature. The C<...> indicates that this is just a
-signature; the actual implementation is elsewhere.  In this case, that location
-in the definition of the optable.
-
-=head3 Protofunction Definitions
-
-X<Protofunctions>
-
-Protofunctions define operators in the optable in the same way that rules and
-tokens make up the grammar. A proto declares a rule, defined elsewhere, which
-other code may override dynamically.  In this case, PCT takes information from
-the proto declaration and fills in the details. The "dynamic overriding"
-implies that a high-level language itself itself can modify its own grammar at
-run time, by overriding the proto definitions for its operator table. Some
-languages call this process X<operator overloading> I<operator overloading>.
-
-A proto definition resembles:
-
- 'proto' <proto_name> [ 'is' <property> ] '{' '...' '}'
-
-The name of the operator, noted as C<< <proto_name> >>, contains both a
-location part and an identifier part. The location is the type of the operator,
-such as infix, postfix, prefix, circumfix, and postcircumfix. The name of the
-operator is the symbol used for the operator in any of the quotes that Perl 6
-understands:
-
- proto infix:<+>                  # a + b
- proto postfix:'--'               # i--
- proto circumfix:«<>»             # <x>
-
-The C<is> X<Parser, is> keyword defines a property of the rule. Examples
-include:
-
- is precedence(1)     # Specifies an exact precedence
- is equiv('+')        # Has the same precedence as the "+" operator
- is assoc('right')    # Right associative. May also be "left" or "list"
- is pirop('add')      # Operands are passed to the PIR operator "and"
- is subname('mySub')  # Operands are passed to the function "mySub"
- is pasttype('if')    # Operands are passed as children to an "if" PAST node in
-                      # the parse tree
- is parsed(&myRule)   # The token is parsed and identified using the rule
-                      # "myRule" from the top-down parser
-
-=for author
-
-Please review.
-
-=end for
-
-Protofunction definitions are function signatures; you can override them with
-multimethod dispatch. This means that you can write functions I<with the same
-name> as the rule to implement the behavior of the operator.  Here's a proto:
-
- rule infix:"+" { ... }
-
-... and its corresponding PIR rule:
-
-=begin PIR
-
- .sub 'infix:+'
-    .param pmc a
-    .param pmc b
-    .local pmc c
-    c = a + b
-    .return(c)
- .end
-
-=end PIR
-
-You may ask "Why have an C<is subname()> property, if you can define all
-operators as subroutines?" Using the C<is subname()> property allows PCT to
-call a subroutine of a different name then the operator.  This is a good idea
-if there is already a built-in function in the language that duplicates the
-functionality of the operator.  There is no sense in duplicating behavior.
-
-The great thing about protos being overloadable is that you can specify
-different functions to call with different signatures:
-
-=begin PIR
-
- .sub 'infix:+' :multi('Integer', 'Integer')
-    #...
- .end
-
- .sub 'infix:+' :multi('CLispRatio', 'Number')
-    #...
- .end
-
- .sub 'infix:+' :multi('Perl6Double', 'PythonInteger')
-    #...
- .end
-
-=end PIR
-
-This list can be a bit intimidating, and it's hard to imagine that it would be
-necessary to write up a new function to handle addition between every
-conceivable pair of operands. Fortunately, this is rarely the case in Parrot,
-because all these data types support common the VTABLE interface. For most data
-types Parrot already has basic arithmetic operations built in, and it's only
-necessary to override for those data types with special needs.
-
-=head3 Hypothetical Variables
-
-Z<CHP-7-SECT-5>
-
-X<variables;hypothetical>
-X<hypothetical variables>
-X<rules;captures>
-Hypothetical variables are a powerful way of building up data structures from
-within a match. Ordinary captures with C<()> store the result of the captures
-in C<$1>, C<$2>, etc. PGE stores values in these variables if the match is
-successful, but throws them away if the match fails.  The numbered capture
-variables are accessible outside the match, but only within the immediate
-surrounding lexical scope:
-
-  "Zaphod Beeblebrox" ~~ m:w/ (\w+) (\w+) /;
-
-  print $1; # prints Zaphod
-
-You can also capture into any user-defined variable with the binding operator
-C<:=> -- I<if> you have declared these variables in a lexical scope enclosing
-the rule:
-
-  my $person;
-  "Zaphod's just this guy." ~~ / ^ $person := (\w+) /;
-  print $person; # prints Zaphod
-
-You may capture repeated matches into an array:
-
-  my @words;
-  "feefifofum" ~~ / @words := (f<-[f]>+)* /;
-  # @words contains ("fee", "fi", "fo", "fum")
-
-You may capture pairs of repeated matches into a hash:
-
-  my %customers;
-  $records ~~ m:w/ %customers := [ E<lt>idE<gt> = E<lt>nameE<gt> \n]* /;
-
-If you don't need the captured value outside the rule, use a C<$?> variable
-instead. These are only directly accessible within the rule:
-
-  "Zaphod saw Zaphod" ~~ m:w/ $?name := (\w+) \w+ $?name/;
-
-A match of a named rule stores the result in a C<$?> variable with the same
-name as the rule. These variables are also accessible only within the rule:
-
-  "Zaphod saw Zaphod" ~~ m:w/ E<lt>nameE<gt> \w+ $?name /;
-
-=for author
-
-This next paragraph feels out of place; is there more?
-
-=end for
-
-When a rule matches a sequence of input tokens, PCT calls an associated method
-within NQP to convert that match into an AST node, which it inserts into the
-I<parse tree>.
-
-=head3 Basic Rules
-
-Consider the simple example rule:
-
- rule persons_name {
-    <first_name> <last_name>
- }
-
-... and two example tokens:
-
- token first_name { <alpha>+ }
- token last_name  { <alpha>+ }
-
-The special token C<< <alpha> >> is a built-in construct that only accepts
-upper case and lower case letters. The C<+> after the C<< <alpha> >> tag is a
-short way of saying "one or more". The rule will match names like C<Darth
-Vader>N<It also matches many strings that I<aren't> real names>, but won't
-match something like C<C 3P0>.
-
-This rule I<will> match C<Jar Jar Binks>, but not as you might expect: way you
-would expect: It would match the first "Jar" as C<< <first_name> >>, the second
-"Jar" as C<< <last_name> >>, and ignore "Binks"N<You should ignore the whole
-thing.>.
-
-=for author
-
-The rest seems vestigial.  An example like this should precede the rest of the
-chapter.  There are forward references, but it's a decent overview for people
-who haven't used similar systems before -- if you avoid going out in the weeds.
-
-=end for
-
-this example shows another new construct, the square brackets. Square
-brackets are ways to group things together. The star at the end means
-that we take all the things inside the brackets zero or more times.
-This is similar to the plus, except the plus matches one or more times.
-Notice, however, that the above rule always matches a comma at the end,
-so we would need to have something like:
-
- Darth Vader, Luke Skywalker,
-
-Instead of something more natural like:
-
- Darth Vader, Luke Skywalker
-
-We can modify the rule a little bit so that it always ends with a name
-instead of a comma:
-
- rule TOP {
-    [ <persons_name> ',' ]* <persons_name>
- }
-
-Now we don't need a trailing comma, but at the same time we can't match
-an empty file because it always expects to have at least one name at the
-end. If we still want to match empty files successfully, we need to make
-the whole rule optional:
-
- rule TOP {
-    [ [ <persons_name> ',' ]* <persons_name> ]?
- }
-
-We've grouped the whole rule together in another set of brackets, and
-put a "?" question mark at the end. The question mark means zero or
-one of the prior item.
-
-The symbols "*" (zero or more), "+" (one or more) and "?" are called
-I<quantifiers>, and allow an item in the rule to match a variable
-number of times. These aren't the only quantifiers, but they are the
-most common. We will talk about other quantifiers later on.
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/tt761_keys_revamp/docs/book/ch06_nqp.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/book/ch06_nqp.pod	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,219 +0,0 @@
-=pod
-
-=head1 Grammar Actions
-
-The job of the grammar is to match input patterns from the source language.
-These patterns then need to get converted to nodes in the abstract syntax
-tree for manipulation in other stages of the compiler. We've already seen
-one example of a subroutine structure that takes a match and produces a
-tree node: Protofunctions. Protofunction signatures aren't the only way to
-apply functions to rules matched by a parser.  They are limited and are
-slightly primitive, but effective for handling operators.  There is an
-easier and more powerful way to write subroutines to convert match objects
-into parse tree nodes, using a language that's almost, but Not Quite Perl.
-
-X<NQP>
-X<Not Quite Perl>
-NQP (Not Quite Perl) is a small language which offers a limited subset of
-Perl 6's syntax and semantics. Though it originated as a bootstrapping tool
-for the Rakudo Perl 6 compiler, several other Parrot-based compilers use it
-as well.  It has become a permanent member of PCT, and therefore a permanent
-part of the Parrot code base. 
-
-NQP represets almost the smallest subset of the Perl 6 language necessary to
-implement parser transformations, plus a few syntactic convenience features
-that developers have requested. NQP's Perl 6 subset shows its Perl 5 roots,
-so existing Perl 5 programmers should find much of it familiar and should be
-able to leverage their existing skills for writing compilers.
-
-In PGE, at the time of a match the grammar we can invoke an action using the
-special <code>{*}</code> symbol. In general, these action methods are
-written in NQP, although it is possible for them to be written in PIR N<In
-fact, this is how the NQP compiler itself is written>. We won't discuss the
-PIR case here because it's uncommon and needlessly difficult. NQP is the
-standard and preferred choice for this.
-
-=head2 NQP Basics
-
-X<sigils>
-X<scalar>
-Like all flavors and versions of Perl, NQP uses special prefix symbols called
-I<sigils> to distinguish variable types. The C<$> sigil represents scalars,
-C<@> arrays, and C<%> for hashes.  A scalar is any single value which can
-interchangeably contain given a string value, an integer value, or an object
-reference. Simple NQP assignments are:
-
- $scalar := "This is a string"
- $x      := 123
- $pi     := 3.1415      # rounding
-
-X<bind operator>
-X<operators; binding>
-X<:=>
-The C<:=> I<bind> operator performs reference assignment in NQP. Reference
-assignment makes one variable into an alias for another. This means that
-the two variables are just different names for the same storage location,
-and changes to one will change both. It's important to remember that a bind
-is not a copy!
-
-NQP has hashes and arrays just like other flavors of Perl and various
-dynamic languages. NQP does not have a notion of hash and array context,
-but otherwise it works the way you would expect. Arrays have the C<@> sigil,
-and hashes have the C<%> sigil. Here are some examples:
-
-  @ary[0] := 1;
-  @ary[1] := "foo";
-  ...
-
-  %hsh{'bar'} := 2;
-  %hsh{'baz'} := "parrot";
-  ...
-
-There is also a nice shorthand way to index hashes, using angle brackets:
-
-  %hsh<bar> := "parrot";
-
-It's also possible to assign a list in I<scalar context>:
-
- $array_but_a_scalar := (1, 2, 3, 4)
-
-Or you could write a new function in PIR to create a new array from a variadic
-argument list:
-
- @my_array := create_new_array(1, 2, 3, 4)
-
-... which calls the PIR function:
-
-=begin PIR
-
- .namespace []
-
- .sub 'create_new_array'
-     .param pmc elems :slurpy
-     .return(elems)
- .end
-
-=end PIR
-
-=head3 Calling Actions From Rules
-
-=for editor
-
-Needs a link to that section.
-
-=end for
-
-As mentioned in the chapter on grammar rules, the funny little C<{*}> symbol
-calls an action. The action in question is an NQP method with the same name as
-the rule that calls it. NQP rules can have two different signatures:
-
- method name ($/)      { ... }
- method name($/, $key) { ... }
-
-Where does the key come from?  Consider this grammar:
-
- rule cavepeople {
-      'Fred'  {*}    #= Caveman
-    | 'Wilma' {*}    #= Cavewoman
-    | 'Dino'  {*}    #= Dinosaur
- }
-
-The C<cavepeople> rule demonstrates the result:
-
- method cavepeople($/, $key) {
-    if $key eq 'Caveman' {
-        say "We've found a caveman!";
-    } elsif $key eq 'Cavewoman' {
-        say "We've found a cavewoman!";
-    } elsif $key eq 'Dinosaur' {
-        say "A dinosaur isn't a caveperson at all!";
-    }
- }
-
-The key is a string that contains whatever any text following the C<#=> symbol.
-Without a C<#=> following the rule invocation, there's no C<$key> to use in the
-method.  If you attempt to use one without the other, the NQP compiler will die
-with error messages about mismatched argument/parameter numbers.
-
-=head3 The Match Object C<$/>
-
-X<match object>
-X<$/>
-The match object C<$/> it's a data structure that's all business: it's both a
-hash and an array. Because it's a special variable used pervasively in PCT, it
-has a special shortcut syntax:
-
- $/{'Match_item'}   is the same as $<Match_item>
- $/[0]              is the same as $[0]
-
-Each key in the match object's hash is the name of a matched rule.  Given a
-file containing "C<X + 5>" and a rule:
-
- rule introductions {
-    <variable> <operator> <number>
- }
-
-The resulting match object will contain the key/value pairs:
-
- "variable" => "x"
- "operator" => "+"
- "number"   => "5"
-
-When the match contains multiple values with the same name, or when rules have
-quantifiers such as C<*> or C<+>, the values in the hash may be arrays.  Given
-the input "A A A B B" and the rule:
-
- rule letters {
-    <vowel>* <consonant>*
- }
-
-The match object will contain the pairs:
-
- "vowel"     => ["A", "A", "A"]
- "consonant" => ["B", "B"]
-
-X<$( ) operator>
-
-Use the C<$( )> operator to count the number of matches in each group (by
-casting it to a scalar):
-
- $($<vowel>) == 3
-
-=head3 Inline PIR
-
-=for author
-
-Needs expansion.
-
-=end for
-
-X<{{ }}>
-X<double curly brackets>
-Sometimes NQP isn't quite flexible enough to handle transforms appropriately.
-In a PGE rule, the C<{{ }}> double curly brackets demarcate inline-PIR mode.
-PGE will execute any PIR code in those brackets. You can access C<$/> directly
-in the grammar without having to jump into NQP.
-
-=head3 PAST Nodes
-
-X<PAST>
-X<PAST nodes>
-NQP's job is to make abstract syntax trees.  These trees are all objects -- and
-as such, instances of PAST nodes.  Each PAST class represents a unique program
-construct.  These constructs are common and simple, but combine to represent
-complicated programming structures.
-
-=head3 Making Trees
-
-Every action has the ability to create a PAST node that represents that action,
-as well as any children of that node. Calling C<make> on that node adds it into
-the growing PAST tree that PCT maintains. Once the C<TOP> rule matches
-successfully and returns, PCT optimizes and converts that tree into PIR and PBC
-for execution.
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/tt761_keys_revamp/docs/book/ch07_dynpmcs.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/book/ch07_dynpmcs.pod	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,237 +0,0 @@
-=pod
-
-=head1 Dynamic C-level Objects
-
-Z<CHP-11>
-
-PMCs are one of the four fundamental data types in Parrot, and definitely one
-of the most useful. A PMC can contain a single scalar value (integer, floating
-point number, string), an array of values, a subroutine, a namespace, or an
-entire list of other data types as well. PMCs are the basis for all higher
-order data types in Parrot, and are flexible enough to be used for any
-purpose that an HLL needs.
-
-All the common PMC types are included in the Parrot repository and built directly
-into libparrot and the parrot executable. However, the system is not rigid; new
-PMC types can be defined externally and loaded into Parrot at a later time. In
-this way, HLLs and libraries and applications can add new data types to Parrot
-at the C code level, which helps to ensure speed and efficiency. PMCs loaded
-this way are called X<dynamic PMCs;dynpmcs> Dynamic PMCs or I<dynpmcs>.
-
-=head2 PIR Classes
-
-It's worth a quick diversion here to talk about the difference between a pure
-PIR class object, and a PMC. Even though classes written in PIR can inherit from
-an existing PMC type, they aren't all their own type of PMC. In fact, classes
-written in PIR are all of the Object PMC type. In order to add a new fundamental
-PMC type to Parrot, it needs to be written in C N<well, a superset of C anyway>
-and it needs to be compiled using the X<PMC compiler> PMC compiler.
-
-=head2 Writing PMCs
-
-In the strictest sense, PMCs are written in C and are compiled by your local
-C compiler into machine code for linking with libparrot or the parrot
-executable. However, Parrot's build process makes use of a special PMC compiler
-program that converts PMCs defined in a special C-like script to ordinary
-C code. The PMC compiler adds all the necessary boiler plate code and installs
-the PMC type into Parrot for use. The PMC script is like a macro superset
-N<although the functionality is a little bit more involved then is available
-in the normal C preprocessor> over the C language. All valid C is valid in
-PMC scripts, but there are also a few additions that help to make common tasks
-a little easier.
-
-The PMC script was born of conflicting necessities. The internals of Parrot
-are all written according to the ISO C89 standard for maximum portability.
-However, PIR and languages that are built on top of Parrot are typically
-object-oriented (or have some OO capabilities). PMCs are like classes,
-they have data and methods, and they can inherit from parent PMCs.
-
-C is low-level and portable, which is desirable. But Parrot needed some
-support for OO features that C doesn't have, and the C preprocessor
-can't support directly. To support the necessary features, and to make
-the task of writing PMCs just a little bit easier, the Parrot developers
-created a PMC compiler program that takes a special PMC script and converts
-it into standard ISO C89.
-
-=head3 PMC Files
-
-PMC files have a C<.pmc> file extension. They're written in a C-like
-language with a few additions to help with creating PMCs. PMC files do
-not natively allow POD documentation, so all such documentation must be
-enclosed in C</* */> comments. All PMC files that ship with Parrot
-include significant file-level and function-level documentation to help
-explain how the PMCs operate.
-
-=head3 C<pmclass> Definitions
-
-A PMC file can contain a single PMC class definition and any other helper
-functions or data structure definitions that are needed to support the
-PMC. To define a PMC class in the PMC file, you use the C<pmclass>
-statement. Everything outside the C<pmclass> definition will be ignored by
-the PMC compiler and passed through verbatim into the generated C<.c> file.
-Inside the C<pmclass> definition are going to be all the VTABLE and METHOD
-declarations for the PMC.
-
-A standard definition can contain a number of parts. Here's a pseudo-grammar
-for them:
-
-  pmclass CLASSNAME [extends PARENT]? [provides INTERFACE] [FLAGS]* {
-      /* Attributes defined here */
-
-      /* VTABLE and METHODs defined here. */
-
-  }
-
-The C<extends> keyword is optional, but allows us to specify that this
-PMC class is a subtype of the given type. If we have an C<extends>
-in the definition, we can use the C<SUPER> keyword throughout the PMC
-file to refer to the parent type.
-
-The C<FLAGS> are a series of flags that can be specified to determine
-how the PMC behaves and how it's constructed internally. The C<need_ext>
-flag assigns a special C<PMC_EXT> data structure to the PMC structure
-internally. C<PMC_EXT> is necessary to handle data sharing between threads
-or interpreters, storing attributes in the PMC, and a few other uses as
-well. The C<singleton> flag means that there can only be one instantiated
-object of this class. The C<is_ro> and C<has_ro> flags indicate that the
-PMC class is read-only or that it contains read-only data, respectively.
-The C<is_shared> flag indicates that the PMC is intended to be shared
-between multiple interpreters, and therefore special synchronization
-logic should be applied. The C<abstract> flag indicates that the PMC
-class cannot be instantiated directly, but can be inherited from by a
-non-abstract PMC class.
-
-The C<provides> keyword is used to show that the PMC provides certain
-standard interfaces. For instance, you can specify C<provides array>
-and then Parrot will enable us to write things like C<$P0[2]> in PIR
-code to access the PMC using integer indices. C<provides hash> means
-that we can use string and PMC keys to access values in the PMC. These
-C<provides> each correspond to a series of VTABLE interfaces that the
-PMC must provide, or must inherit. Without the necessary VTABLE
-interfaces available, Parrot may try to perform illegal operations and
-things will go badly. We'll talk about all the available C<provides>
-interfaces and the VTABLE interfaces that they must define.
-
-=head3 Attributes
-
-PMCs can be given a custom set of data field attributes using the C<ATTR>
-keyword. ATTR allows the PMC to be extended to contain custom data
-structures that are automatically managed by Parrot's memory subsystem.
-Here's an example:
-
-  pmclass Foo {
-    ATTR INTVAL bar;
-    ATTR PMC baz;
-
-    ...
-  }
-
-The attributes are stored in a custom data structure that can be accessed
-using a macro with the same name as the PMC, but all upper-case:
-
-  Parrot_Foo_Attributes * attrs = PARROT_FOO(SELF);
-  attrs->bar = 7;                 /* it's an INTVAL */
-  attrs->baz = pmc_new( ... )     /* it's a PMC */
-
-Notice how the type name of the attributes structure is C<Parrot_>,
-followed by the name of the PMC with the same capitalization as is used
-in the C<pmclass> definition, followed by C<_Attributes>. The macro to
-return this structure is C<PARROT_> followed by the name of the PMC in
-all caps.
-
-=head3 C<INTERP>, C<SUPER> and C<SELF>
-
-The PMC compiler enables us to use a few pre-defined variable names
-throughout the file to make things easier. The C<INTERP> keyword always
-contains a reference to the current interpreter structure. This keyword is
-included by default in all VTABLE interfaces and all PMC methods. It is not
-automatically included in any extra helper functions that you define in
-the PMC file.
-
-Here's an example of a VTABLE interface function:
-
-  VTABLE Foo(INVAR PMC, INVAR INTVAL)
-  {
-      ...
-  }
-
-The PMC compiler will convert this to the following C function definition:
-
-  void Foo(PARROT_INTERP, PMC *self, PMC *arg_1, INTVAL arg_2)
-  {
-      ...
-  }
-
-The C<interp> and C<self> variables are provided in all VTABLE interfaces,
-even though you don't have to define them explicitly in the PMC file.
-
-If the C<pmclass> definition uses the C<extends> keyword, a reference to
-a member of the parent class is also contained in the C<SUPER> variable.
-The C<SUPER()> function calls the VTABLE interface from the parent class.
-
-  VTABLE destroy()
-  {
-      SUPER(); /* Call the parent PMC's VTABLE */
-  }
-
-The PMC compiler also allows the use of "method syntax" for the C<SELF> and
-C<SUPER> variables:
-
-  SUPER.clone()   /* Call the clone VTABLE interface on SUPER */
-  SELF.destroy()  /* Call the destroy VTABLE interface on SELF */
-
-Or, you can call the VTABLE interfaces more directly:
-
-  VTABLE_clone(INTERP, SUPER)
-  VTABLE_destroy(INTERP, SELF)
-
-=head3 PMC Compiler
-
-The PMC compiler is a small program written in Perl 5 that's part of the
-normal Parrot build process. It converts all C<.pmc> files to C<.c> files
-for final compilation. The long-term goal for Parrot is to not be dependent
-on Perl 5 for configuration and building, but for now Perl 5 is required
-when building Parrot.
-
-=head2 VTABLE Function Definitions
-
-=head3 VTABLE Functions Parameters
-
-VTABLE functions are defined just like ordinary C functions, almost. Here's
-a normal definition for a VTABLE method:
-
-  VTABLE VTABLENAME (PARAMETERS) {
-    /* ordinary C here, almost */
-  }
-
-You can't just name your VTABLE functions anything you want. There is a
-predefined list of VTABLE function names, and you must name it exactly
-the same as the one you are trying to implement. The PARAMETERS list
-is pretty particular as well: Each VTABLE function type has a specific
-parameter list that must be implemented exactly or else the compiler
-will throw a warning.
-
-=head2 Methods
-
-VTABLES are standard, but they're rigid. They need to have the exact name
-that Parrot expects, and they need to have the exact function signature
-that Parrot expects too. VTABLES are responsible for the low-level basic
-access operations that all data types need to implement. However, to get
-more out of your PMCs, we need a more flexible want to interact with them.
-
-Enter methods, which are ways to extend the functionality of your PMC
-in ways that the PMC needs. Methods allow the developer to add all sorts
-of arbitrary functionality to a PMC that the VTABLE functions themselves
-cannot define.
-
-=head2 Dynpmcs
-
-=head3 Loading dynpmcs
-
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/tt761_keys_revamp/docs/book/ch08_dynops.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/book/ch08_dynops.pod	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,266 +0,0 @@
-=pod
-
-=head1 Dynamic Opcodes
-
-Z<CHP-12>
-
-The smallest executable component is not the compilation unit or even the
-subroutine, but is actually the I<opcode>. Opcodes in Parrot, like opcodes in
-other machines (both virtual and physical), are individual instructions that
-implement low-level operations in the machine. In the world of
-microprocessors, the word "opcode" typically refers to the numeric identifier
-for each instructions. The human-readable word used in the associated assembly
-language is called the "mnemonic". An assembler, among other tasks, is
-responsible for converting mnemonics into opcodes for execution. In Parrot,
-instead of referring to an instruction by different names depending on what
-form it's in, we just call them all "opcodes".
-
-=head2 Opcodes
-
-Opcodes are the smallest logical execution element in Parrot. An
-individual opcode corresponds, in an abstract kind of way, with a single
-machine code instruction for a particular hardware processor
-architecture. Parrot is a pretty high-level virtual machine, and even though
-its opcodes represent the smallest bits of executable code in Parrot, they
-are hardly small or low-level by themselves. In fact, some Parrot opcodes
-implement some complex operations and algorithms. Other opcodes are more
-traditional, performing basic arithmetic and data manipulating operations.
-
-Parrot comes with about 1,200 opcodes total in a basic install. It also has a
-facility for dynamically loading additional opcode libraries, called
-C<dynops>, as needed.
-
-=head3 Opcode naming
-
-To the PIR and PASM programmers, opcodes appear to be polymorphic. That
-is, some opcodes appear to have multiple allowable argument formats. This is
-just an illusion, however. Parrot opcodes are not polymorphic, although
-certain features enable them to appear that way to the PIR programmer.
-Different argument list formats are detected during parsing and mapped to
-separate, unique opcode names.
-
-During the Parrot build process, opcode definitions called "ops files" are
-translated into C code prior to compilation. This translation process renames
-all ops to use unique names depending on their argument lists. An op "foo"
-that takes two PMCs and returns an integer would be renamed to C<foo_i_p_p>.
-Another op named "foo" that takes one floating point number and returns a
-string would be renamed to C<foo_s_n>. So, when we call the opcode "foo" from
-our PIR program, the PIR compiler will look at the list of arguments and
-call the appropriate opcode to handle it.
-
-=head2 Writing Opcodes
-
-Writing Opcodes, like writing PMCs, is done in a C-like language which is
-later compiled into C code by the X<opcode compiler> opcode compiler. The
-opcode script represents a thin overlay on top of ordinary C code: All
-valid C code is valid opcode script. There are a few neat additions that
-make writing opcodes easier. The C<INTERP> keyword, for instance, contains
-a reference to the current interpreter structure. C<INTERP> is always
-available when writing opcodes, even though it isn't defined anywhere.
-Opcodes are all defined with the C<op> keyword.
-
-Opcodes are written in files with the C<.ops> extension. The core
-operation files are stored in the C<src/ops/> directory.
-
-=head3 Opcode Parameters
-
-Each opcode can take any fixed number of input and output arguments. These
-arguments can be any of the four primary data types--INTVALs, PMCs, NUMBERS
-and STRINGs--but can also be one of several other types of values including
-LABELs, KEYs and INTKEYs.
-
-Each parameter can be an input, an output or both, using the C<in>, C<out>,
-and C<inout> keywords respectively. Here is an example:
-
-  op Foo (out INT, in NUM)
-
-This opcode could be called like this:
-
-  $I0 = Foo $N0     # in PIR syntax
-  Foo I0, N0        # in PASM syntax
-
-When Parrot parses through the file and sees the C<Foo> operation, it
-converts it to the real name C<Foo_i_n>. The real name of an opcode
-is its name followed by an underscore-separated ordered list of
-the parameters to that opcode. This is how Parrot appears to use
-polymorphism: It translates the overloaded opcode common names into
-longer unique names depending on the parameter list of that opcode. Here
-is a list of some of the variants of the C<add> opcode:
-
-  add_i_i      # $I0 += $I1
-  add_n_n      # $N0 += $N1
-  add_p_p      # $P0 += $P1
-  add_i_i_i    # $I0 = $I1 + $I2
-  add_p_p_i    # $P0 = $P1 + $I0
-  add_p_p_n    # $P0 = $P1 + $N0
-
-This isn't a complete list, but you should get the picture. Each different
-combination of parameters translates to a different unique operation, and
-each operation is remarkably simple to implement. In some cases, Parrot
-can even use its multi-method dispatch system to call opcodes which are
-heavily overloaded, or for which there is no exact fit but the parameters
-could be coerced into different types to complete the operation. For
-instance, attempting to add a STRING to a PMC might coerce the string into
-a numerical PMC type first, and then dispatch to the C<add_p_p_n> opcode.
-This is just an example, and the exact mechanisms may change as more opcodes
-are added or old ones are deleted.
-
-Parameters can be one of the following types:
-
-=over 4
-
-=item * INT
-
-A normal integer type, such as one of the I registers
-
-=item * NUM
-
-A floating point number, like is used in the N registers
-
-=item * STR
-
-A string, such as in a S register
-
-=item * PMC
-
-A PMC value, like a P register
-
-=item * KEY
-
-A key value. Something like C<[5 ; "Foo" ; 6 ; "Bar"]>. These are the same
-as indexes that we use in PMC aggregates.
-
-=item * INTKEY
-
-A basic key value that uses only integer values C<[1 ; 2 ; 3 ]>.
-
-=item * LABEL
-
-A label value, which represents a named statement in PIR or PASM code.
-
-=back
-
-In addition to these types, you need to specify the direction that data is
-moving through that parameter:
-
-=over 4
-
-=item * in
-
-The parameter is an input, and should be initialized before calling the op.
-
-=item * out
-
-The parameter is an output
-
-=item * inout
-
-The parameter is an input and an output. It should be initialized before
-calling the op, and it's value will change after the op executes.
-
-=item * invar
-
-The parameter is a reference type like a String or PMC, and it's internals
-might change in the call.
-
-=back
-
-=head3 Opcode Control Flow
-
-Some opcodes have the ability to alter control flow of the program they
-are in. There are a number of control behaviors that can be implemented,
-such as an unconditional jump in the C<goto> opcode, or a subroutine
-call in the C<call> code, or the conditional behavior implemented by C<if>.
-
-At the end of each opcode you can call a C<goto> operation to jump to the
-next opcode to execute. If no C<goto> is performed, control flow will
-continue like normal to the next operation in the program. In this way,
-opcodes can easily manipulate control flow. Opcode script provides a
-number of keywords to alter control flow:
-
-=over 4
-
-=item * NEXT()
-
-The keyword C<NEXT> contains the address of the next opcode in memory. At the
-end of a normal op you don't need to call C<goto NEXT()> because moving to the
-next opcode in the program is the default behavior of Parrot N<You can do
-this if you really want to, but it really wouldn't help you any>. The C<NEXT>
-keyword is frequently used in places like the C<invoke> opcode to create a
-continuation to the next opcode to return to after the subroutine returns.
-
-=item * ADDRESS()
-
-Jumps execution to the given address.
-
-  ADDRESS(x);
-
-Here, C<x> should be an C<opcode_t *> value of the opcode to jump to.
-
-=item * OFFSET()
-
-Jumps to the address given as an offset from the current address.
-
-  OFFSET(x)
-
-Here, C<x> is an offset in C<size_t> units that represents how far forward
-(positive) or how far backwards (negative) to jump to.
-
-=item * POP()
-
-C<POP> pops the next opcode address off the control stack. To put an address
-onto the control stack, use the C<PUSH> keyword instead. C<PUSH> takes a single
-C<opcode_t *> argument to store, and C<POP> returns a single C<opcode_ *>
-value.
-
-=back
-
-=head2 The Opcode Compiler
-
-As we've seen in our discussions above, ops have a number of transformations
-to go through before they can be become C code and compiled into Parrot.
-The various special variables like C<$1>, C<INTERP> and C<ADDRESS> need to be
-converted to normal variable values. Also, each runcore requires the ops be
-compiled into various formats: The slow and fast cores need the ops to be
-compiled into individual subroutines. The switch core needs all the ops to be
-compiled into a single function using a large C<switch> statement. The
-computed goto cores require the ops be compiled into a large function with a
-large array of label addresses.
-
-Parrot's opcode compiler is a tool that's tasked with taking raw opcode files
-with a C<.ops> extension and converting them into several different formats,
-all of which need to be syntactically correct C code for compilation.
-
-=head2 Dynops
-
-Parrot has about 1200 built-in opcodes. These represent operations which are
-sufficiently simple and fundamental, but at the same time are very common.
-However, these do not represent all the possible operations that some
-programmers are going to want to use. Of course, not all of those 1200 ops
-are unique, many of them are overloaded variants of one another. As an example
-there are about 36 variants of the C<set> opcode, to account for all the
-different types of values you may want to set to all the various kinds of
-registers. The number of unique operations therefore is much smaller then 1200.
-
-This is where I<dynops> come in. Dynops are dynamically-loadable libraries of
-ops that can be written and compiled separately from Parrot and loaded in at
-runtime. dynops, along with dynpmcs and runtime libraries are some of the
-primary ways that Parrot can be extended.
-
-Parrot ships with a small number of example dynops libraries in the file
-L<src/dynoplibs/>. These are small libraries of mostly nonsensical but
-demonstrative opcodes that can be used as an example to follow.
-
-Dynops can be written in a C<.ops> file like the normal built-in ops are.
-The ops file should use C<#include "parrot/extend.h"> in addition to any
-other libraries the ops need. They can be compiled into C using the opcode
-compiler, then compiled into a shared library using a normal C compiler. Once
-compiled, the dynops can be loaded into Parrot using the .loadlib directive.
-
-=cut
-
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/tt761_keys_revamp/docs/book/ch10_opcode_reference.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/book/ch10_opcode_reference.pod	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,2953 +0,0 @@
-=pod
-
-=head1 Instruction Reference
-
-Z<CHP-10>
-
-This chapter contains a condensed reference to the Parrot virtual
-machine's native instruction set, generally called opcodes. All opcodes
-are valid in both PIR and PASM, and correspond to the bytecode
-instructions.
-
-For complete details on each opcode and the latest changes, read the
-documentation in F<docs/ops/>, or look at all the C<.ops> files in the
-F<ops/> directory.
-
-We've followed a few conventions. C<DEST> is always the register where
-the result of the operation is stored. Sometimes the original value of
-C<DEST> is one of the source values. C<VAL> indicates that the actual
-value might be a literal integer, float, or string, or a register
-containing an integer, float, string, or PMC. See the F<.ops> files
-for the combinations allowed with a particular operation.
-
-=head3 abs
-
-X<abs opcode (PASM)>
-
-  abs R<DEST>
-  abs R<DEST>, R<VAL>
-
-Return the absolute value of a number. If R<VAL> is left out, R<DEST>
-gets the absolute value of itself.
-
-I<Arguments: IR or NR or IR, I or IR, N or NR, I or NR, N>
-
-=head3 acos
-
-X<acos opcode (PASM)>
-
-  acos R<DEST>, R<VAL>
-
-The arc cosine of R<VAL> in radians.
-
-I<Arguments: NR, N or NR, I>
-
-=head3 add
-
-X<add opcode (PASM)>
-
-  add R<DEST>, R<VAL>
-  add R<DEST>, R<VAL>, R<VAL>
-
-Add two values and return the sum. If only one R<VAL>, add R<VAL> to
-R<DEST>.
-
-I<Arguments: IR, I or NR, I or NR, N or P, I or P, N or P, P or IR, I, I
-or NR, N, I or NR, N, N or P, P, I or P, P, N or P, P, P>
-
-=head3 addattribute
-
-X<addattribute opcode (PASM)>
-
-  addattribute R<CLASS>, R<ATTR>
-
-Add the attribute name R<ATTR> to class R<CLASS>.
-
-I<Arguments: P, S>
-
-=head3 addparent
-
-X<addparent opcode (PASM)>
-
-  addparent R<CLASS1>, R<CLASS2>
-
-Add class R<CLASS2> to the list of parent classes for R<CLASS1>.
-
-I<Arguments: P, P>
-
-=head3 and
-
-X<and opcode (PASM)>
-
-  and R<DEST>, R<VAL1>, R<VAL2>
-
-Logical AND. Return R<VAL1> if it's false; otherwise, return R<VAL2>.
-
-I<Arguments: IR, I, I or P, P, P>
-
-=head3 asec
-
-X<asec opcode (PASM)>
-
-  asec R<DEST>, R<VAL>
-
-The arc secant of R<VAL> in radians.
-
-I<Arguments: NR, I or NR, N>
-
-=head3 asin
-
-X<asin opcode (PASM)>
-
-  asin R<DEST>, R<VAL>
-
-The arc sine of R<VAL> in radians.
-
-I<Arguments: NR, I or NR, N>
-
-=head3 assign
-
-X<assign opcode (PASM)>
-
-  assign R<DEST>, R<VAL>
-
-Assign a value to a PMC.
-
-I<Arguments: SR, S or P, I or P, N or P, S or P, P>
-
-=head3 atan
-
-X<atan opcode (PASM)>
-
-  atan R<DEST>, R<VAL>
-  atan R<DEST>, R<VAL1>, R<VAL2>
-
-The arc tangent of R<VAL1> / R<VAL2> in radians (sign significant). If
-R<VAL2> is omitted, then just the arc tangent of R<VAL>.
-
-I<Arguments: NR, I or NR, N or NR, I, I or NR, I, N or NR, N, I or NR,
-N, N>
-
-=head3 band
-
-X<band opcode (PASM)>
-
-  band R<DEST>, R<VAL>
-  band R<DEST>, R<VAL>, R<VAL>
-
-Bitwise AND on two values. If only one R<VAL>, bitwise AND on R<DEST>
-and R<VAL>.
-
-I<Arguments: IR, I or P, I or P, P or IR, I, I or P, P, I or P, P, P>
-
-=head3 bands
-
-X<bands opcode (PASM)>
-
-  bands R<DEST>, R<VAL>
-  bands R<DEST>, R<VAL>, R<VAL>
-
-Bitwise AND on two strings. If only one R<VAL>, bitwise AND on R<DEST>
-and R<VAL>.
-
-I<Arguments: SR, S or P, S or P, P or SR, S, S or P, P, S or P, P, P>
-
-=head3 bnot
-
-X<bnot opcode (PASM)>
-
-  bnot R<DEST>, R<VAL>
-
-Bitwise NOT on R<VAL>.
-
-I<Arguments: IR, I or P, P>
-
-=head3 bnots
-
-X<bnots opcode (PASM)>
-
-  bnots R<DEST>, R<VAL>
-
-Bitwise NOT on string R<VAL>.
-
-I<Arguments: SR, S or P, P>
-
-=head3 bor
-
-X<bor opcode (PASM)>
-
-  bor R<DEST>, R<VAL>, R<VAL>
-
-Bitwise OR on two values. If only one R<VAL>, bitwise OR on R<DEST>
-and R<VAL>.
-
-I<Arguments: IR, I or P, I or P, P or IR, I, I or P, P, I or P, P, P>
-
-=head3 bors
-
-X<bors opcode (PASM)>
-
-  bors R<DEST>, R<VAL>, R<VAL>
-
-Bitwise OR on two strings. If only one R<VAL>, bitwise OR on R<DEST>
-and R<VAL>.
-
-I<Arguments: SR, S or P, S or P, P or SR, S, S or P, P, S or P, P, P>
-
-=head3 bounds
-
-X<bounds opcode (PASM)>
-
-  bounds R<INT>
-
-Toggle bytecode bounds checking in the interpreter (0 for off, any other
-value for on).
-
-I<Arguments: I>
-
-=head3 branch
-
-X<branch opcode (PASM)>
-
-  branch R<LABEL>
-
-Branch to a label. The label is calculated as a relative offset.
-
-I<Arguments: I>
-
-=head3 branch_cs
-
-X<branch_cs opcode (PASM)>
-
-  branch_cs R<FIXUP_ENTRY>
-
-Intersegment branch to the location of the given fixup table entry.
-
-I<Arguments: S>
-
-=head3 bsr
-
-X<bsr opcode (PASM)>
-
-  bsr R<LABEL>
-
-Branch to a label, like C<branch>, but also push the current location
-onto the call stack so C<ret> can return to it.
-
-I<Arguments: I>
-
-=head3 bxor
-
-X<bxor opcode (PASM)>
-
-  bxor R<DEST>, R<VAL>
-  bxor R<DEST>, R<VAL>, R<VAL>
-
-Bitwise XOR on two values. If only one R<VAL>, bitwise XOR on R<DEST>
-and R<VAL>.
-
-I<Arguments: IR, I or P, I or P, P or IR, I, I or P, P, I or P, P, P>
-
-=head3 bxors
-
-X<bxors opcode (PASM)>
-
-  bxors R<DEST>, R<VAL>
-  bxors R<DEST>, R<VAL>, R<VAL>
-
-Bitwise XOR on two strings. If only one R<VAL>, bitwise XOR on R<DEST>
-and R<VAL>.
-
-I<Arguments: SR, S or P, S or P, P or SR, S, S or P, P, S or P, P, P>
-
-=head3 callmethod
-
-X<callmethod opcode (PASM)>
-
-  callmethod
-  callmethod R<METHODNAME>
-
-Call the method named R<METHODNAME> on the object stored in C<P2>
-according to the Parrot Calling Conventions. If no method name, pull the
-name from C<S0>.
-
-I<Arguments: S>
-
-=head3 callmethodcc
-
-X<callmethodcc opcode (PASM)>
-
-  callmethodcc
-  callmethodcc R<METHODNAME>
-
-Call the method named R<METHODNAME> on the object stored in C<P2>
-according to the Parrot Calling Conventions. If no method name, pull the
-name from C<S0>. Also create a return continuation and store it in
-C<P1>.
-
-I<Arguments: S>
-
-=head3 can
-
-X<can opcode (PASM)>
-
-  can R<DEST>, R<OBJECT>, R<METHODNAME>
-
-Return a true value if R<OBJECT> I<can> do the R<METHODNAME> method,
-otherwise return a false value.
-
-I<Arguments: IR, P, S>
-
-=head3 ceil
-
-X<ceil opcode (PASM)>
-
-  ceil R<DEST>
-  ceil R<DEST>, R<VAL>
-
-Set R<DEST> to the smallest integral value less than or equal to R<VAL>
-(if present) or itself (if not).
-
-I<Arguments: NR or IR, N or NR, N>
-
-=head3 checkevents
-
-X<checkevents opcode (PASM)>
-
-  checkevents
-
-Check the interpreter's task queue for unhandled events and run the associated
-event handlers.
-
-=head3 chopn
-
-X<chopn opcode (PASM)>
-
-  chopn R<DEST>, R<VAL1>
-  chopn R<DEST>, R<VAL1>, R<VAL2>
-
-Remove R<VAL2> number of characters from string R<VAL1>. If no
-R<VAL2>, remove R<VAL> number of characters from string R<DEST>.
-
-I<Arguments: SR, I or SR, S, I>
-
-=head3 chr
-
-X<chr opcode (PASM)>
-
-  chr R<DEST>, R<INT>
-
-Return the character represented by the given number.
-
-I<Arguments: SR, I>
-
-=head3 class
-
-X<class opcode (PASM)>
-
-  class R<CLASS>, R<OBJECT>
-
-Return the R<CLASS> of the given R<OBJECT>.
-
-I<Arguments: P, P>
-
-=head3 clear_eh
-
-X<clear_eh>
-
-  clear_eh
-
-Clear the most recent exception handler.
-
-See also: C<set_eh>, C<throw>.
-
-=head3 clearX
-
-X<cleari opcode (PASM)>
-X<clearn opcode (PASM)>
-X<clearp opcode (PASM)>
-X<clears opcode (PASM)>
-
-  cleari
-  clearn
-  clearp
-  clears
-
-Clear all registers of the given type ("i" = integer, "n" = float, "p"
-= PMC, "s" = string). Integer and float registers clear to zero; string
-and PMC registers clear to NULL.
-
-=head3 clone
-
-X<clone opcode (PASM)>
-
-  clone R<DEST>, R<VAL>
-
-Clone (deep copy) a string or PMC and return the result.
-
-I<Arguments: SR, S or P, P>
-
-=head3 close
-
-X<close opcode (PASM)>
-
-  close R<DEST>
-
-Close the filehandle in the given register.
-
-I<Arguments: P>
-
-=head3 cmod
-
-X<cmod opcode (PASM)>
-
-  cmod R<DEST>, R<VAL1>, R<VAL2>
-
-C's built-in mod operator.
-
-See also C<mod>.
-
-I<Arguments: IR, I, I or NR, N, N or P, P, I or P, P, N or P, P, P>
-
-=head3 cmp
-
-X<cmp (comparison);opcode (PASM)>
-
-  cmp R<DEST>, R<VAL1>, R<VAL2>
-
-Set R<DEST> to 1 if R<VAL1> is greater then R<VAL2>, to -1 if it's less then
-R<VAL2> or to zero if both are equal. If R<VAL1> and R<VAL2> are both PMCs,
-then the type of comparison depends on R<VAL1>.
-
-I<Arguments: IR, I, I or IR, N, N or IR, S, S or IR, P, I or IR, P, N
-IR, P, S or IR, P, P>
-
-=head3 cmp_num
-
-X<cmp_num opcode (PASM)>
-
-  cmp_num R<DEST>, R<VAL1>, R<VAL2>
-
-Like C<cmp>, but forces numeric comparison.
-
-I<Arguments: IR, P, P>
-
-=head3 cmp_str
-
-X<cmp_str opcode (PASM)>
-
-  cmp_str R<DEST>, R<VAL1>, R<VAL2>
-
-Like C<cmp>, but forces string comparison.
-
-I<Arguments: IR, P, P>
-
-=head3 cmp_pmc
-
-X<cmp_pmc opcode (PASM)>
-
-  cmp_pmc R<DEST>, R<VAL1>, R<VAL2>
-
-Like C<cmp>, but places a PMC in R<DEST>.  This opcode is useful for avoiding
-semipredicate problems in HLLs where two PMCs are not always comparable.
-
-I<Arguments: P, P, P>
-
-=head3 collect
-
-X<collect opcode (PASM)>
-
-  collect
-
-Trigger a garbage collection (GC) run.
-
-=head3 collectoff
-
-X<collectoff opcode (PASM)>
-
-  collectoff
-
-Disable garbage collection runs (nestable).
-
-=head3 collecton
-
-X<collecton opcode (PASM)>
-
-  collecton
-
-Re-enable garbage collection runs.
-
-=head3 compile
-
-X<compile opcode (PASM)>
-
-  compile R<DEST>, R<COMPILER>, R<SOURCE>
-
-Compile a string of source code with a given compiler PMC and store
-the result.
-
-I<Arguments: P, P, S>
-
-=head3 compreg
-
-X<compreg opcode (PASM)>
-
-  compreg R<DEST>, R<TYPE>
-
-Return a compiler PMC for a particular type of source code.
-
-I<Arguments: P, S>
-
-  compreg R<TYPE>, R<SUB>
-
-Register R<SUB> as a compiler for language R<TYPE>.
-
-I<Arguments: S, P>
-
-=head3 concat
-
-X<concat opcode (PASM)>
-
-  concat R<DEST>, R<VAL>
-  concat R<DEST>, R<VAL>, R<VAL>
-
-Concatenate two strings. If only one R<VAL>, concatenate R<VAL> onto
-R<DEST>.
-
-I<Arguments: SR, S or SR, S, S or P, P, S or P, P, P>
-
-=head3 cos
-
-X<cos opcode (PASM)>
-
-  cos R<DEST>, R<VAL>
-
-The cosine of R<VAL> in radians.
-
-I<Arguments: NR, I or NR, N>
-
-=head3 cosh
-
-X<cosh opcode (PASM)>
-
-  cosh R<DEST>, R<VAL>
-
-The hyperbolic cosine of R<VAL> in radians.
-
-I<Arguments: NR, I or NR, N>
-
-=head3 debug
-
-X<debug opcode (PASM)>
-
-  debug R<FLAG>
-
-Toggle debugging in the interpreter (0 for off, any other value for on).
-
-I<Arguments: I>
-
-=head3 dec
-
-X<dec opcode (PASM)>
-
-  dec R<DEST>
-
-Decrement a value by 1.
-
-I<Arguments: I or N or P>
-
-=head3 decodelocaltime
-
-X<decodelocaltime opcode (PASM)>
-
-  decodelocaltime R<DEST>, R<VAL>
-
-Set R<DEST> to a new array which represents the decoded time of the
-given epoch-seconds value shifted to local time.
-
-I<Arguments: P, I>
-
-=head3 decodetime
-
-X<decodetime opcode (PASM)>
-
-  decodetime R<DEST>, R<VAL>
-
-Set R<DEST> to a new array which represents the decoded time of the
-given epoch-seconds value.
-
-I<Arguments: P, I>
-
-=head3 defined
-
-X<defined opcode (PASM)>
-
-  defined R<DEST>, R<PMC>
-  defined R<DEST>, R<PMC>[R<KEY>]
-
-Test a keyed PMC value for definedness. If no R<KEY>, test a PMC for
-definedness.
-
-I<Arguments: IR, P>
-
-=head3 delete
-
-X<delete opcode (PASM)>
-
-  delete R<DEST>[R<KEY>]
-
-Delete a keyed value from an aggregate PMC.
-
-I<Arguments: P>
-
-=head3 delprop
-
-X<delprop opcode (PASM)>
-
-  delprop R<PMC>, R<NAME>
-
-Delete a named property from a PMC.
-
-I<Arguments: P, S>
-
-See also: C<setprop> and C<getprop>.
-
-=head3 deref
-
-X<deref opcode (PASM)>
-
-  deref R<DEST>, R<REF>
-
-Set R<DEST> to the PMC that R<REF> refers to.
-
-I<Arguments: P, P>
-
-=head3 die_hard
-
-X<die_hard opcode (PASM)>
-
-  die_hard R<LEVEL>, R<ERROR>
-
-Die at a given level of severity, and with the given error code.
-
-I<Arguments: I, I>
-
-See also: C<exit>.
-
-=head3 div
-
-X<div opcode (PASM)>
-
-  div R<DEST>, R<VAL>
-  div R<DEST>, R<VAL1>, R<VAL2>
-
-Divide R<VAL1> by R<VAL2>. If R<VAL2> is left out, divide R<DEST> by
-R<VAL>.
-
-I<Arguments: IR, I or NR, I or NR, N or P, I or P, N or P, P or IR, I, I
-or NR, N, I or NR, N, N or P, P, I or P, P, N or P, P, P>
-
-=head3 dlfunc
-
-X<dlfunc opcode (PASM)>
-
-  dlfunc R<DEST>, R<LIBRARY>, R<SYMBOL>, R<SIGNATURE>
-
-Look up a symbol in a dynamic link library PMC and create a subroutine
-PMC for that symbol with the given signature.
-
-I<Arguments: P, P, S, S>
-
-=head3 dlvar
-
-X<dlvar opcode (PASM)>
-
-  dlvar R<DEST>, R<LIBRARY>, R<SYMBOL>
-
-Look up a symbol in a dynamic link library PMC and create a
-PMC for that symbol.
-
-I<Arguments: P, P, S>
-
-=head3 does
-
-X<does opcode (PASM)>
-
-  does R<DEST>, R<OBJECT>, R<VAL>
-
-Return a true value if R<OBJECT> I<does> provide the interface R<VAL>,
-otherwise return a false value.
-
-I<Arguments: I, P, S>
-
-=head3 downcase
-
-X<downcase opcode (PASM)>
-
-  downcase R<DEST>
-  downcase R<DEST>, R<VAL>
-
-Create a copy of the string in R<VAL> with all characters converted to
-lower case, and store it in R<DEST>. If R<VAL> is omitted, convert and
-replace the string in R<DEST>.
-
-I<Arguments: S or S, S>
-
-See also: C<upcase>, C<titlecase>.
-
-=head3 end
-
-X<end opcode (PASM)>
-
-  end
-
-End execution within the current code segment or halt the interpreter
-if in the main code segment.
-
-=head3 enternative
-
-X<enternative opcode (PASM)>
-
-  enternative
-
-Run the C<run_native> C function.
-
-=head3 eq
-
-X<eq opcode (PASM)>
-
-  eq R<VAL>, R<VAL>, R<LABEL>
-
-Jump to a label if the two values are equal.
-
-I<Arguments: I, I, IC or N, N, IC or S, S, IC or P, I, IC or P, N, IC
-or P, S, IC or P, P, IC>
-
-=head3 eq_addr
-
-X<eq_addr opcode (PASM)>
-
-  eq_addr R<VAL1>, R<VAL2>, R<LABEL>
-
-Jump to a label if R<VAL1> and R<VAL2> point to the same string or PMC.
-Note that this op compares the addresses of the two strings or PMCs,
-not simply their values.
-
-I<Arguments: S, S, IC or P, P, IC>
-
-=head3 eq_num
-
-X<eq_num opcode (PASM)>
-
-  eq_num R<VAL>, R<VAL>, R<LABEL>
-
-Jump to a label if the two values are numerically equal.
-
-I<Arguments: P, P, IC>
-
-=head3 eq_str
-
-X<eq_str opcode (PASM)>
-
-  eq_str R<VAL>, R<VAL>, R<LABEL>
-
-Jump to a label if the two strings are equal.
-
-I<Arguments: P, P, IC>
-
-=head3 err
-
-X<err opcode (PASM)>
-
-  err R<DEST>
-  err R<DEST>, R<CODE>
-
-Return the system error code to an integer destination or the system
-error message to a string destination. The two-argument version returns
-the system error message for a given code.
-
-I<Arguments: IR or SR or SR, I>
-
-=head3 errorsoff
-
-X<errorsoff opcode (PASM)>
-
-  errorsoff R<VAL>
-
-Turn off errors of type R<VAL>.
-
-I<Arguments: I>
-
-=head3 errorson
-
-X<errorson opcode (PASM)>
-
-  errorson R<VAL>
-
-Turn on errors of type R<VAL>.
-
-I<Arguments: I>
-
-=head3 exchange
-
-X<exchange opcode (PASM)>
-
-  exchange R<REG>, R<REG>
-
-Exchange the contents of two registers.
-
-I<Arguments: IR, IR or NR, NR or SR, SR or P, P>
-
-=head3 exists
-
-X<exists opcode (PASM)>
-
-  exists R<DEST>, R<PMC>[R<KEY>]
-
-Test a PMC key for existence.
-
-I<Arguments: IR, P>
-
-=head3 exit
-
-X<exit opcode (PASM)>
-
-  exit R<STATUS>
-
-Exit the interpreter with a given R<STATUS>. (For extended exit status,
-throw an exception with severity C<EXCEPT_exit>.)
-
-I<Arguments: I>
-
-See also: C<throw>, C<die_hard>.
-
-=head3 exp
-
-X<exp opcode (PASM)>
-
-  exp R<DEST>, R<VAL>
-
-Base of the natural logarithm, I<e>, to the power of R<VAL>.
-
-I<Arguments: NR, I or NR, N>
-
-=head3 exsec
-
-X<exsec opcode (PASM)>
-
-  exsec R<DEST>, R<VAL>
-
-The exsecant of R<VAL> in radians.
-
-I<Arguments: NR, N>
-
-=head3 fact
-
-X<fact opcode (PASM)>
-
-  fact R<DEST>, R<INT>
-
-Return the factorial of R<INT>.
-
-I<Arguments: IR, I or NR, I>
-
-=head3 fdopen
-
-X<fdopen opcode (PASM)>
-
-  fdopen R<DEST>, R<INT>, R<MODE>
-
-Get a FileHandle object for handle R<INT> with open mode R<MODE>.
-
-I<Arguments: P, I, S>
-
-=head3 find_chartype
-
-X<find_chartype opcode (PASM)>
-
-  find_chartype R<DEST>, R<NAME>
-
-Find the chartype named R<NAME> and return its number in R<DEST>.
-
-I<Arguments: IR, S>
-
-=head3 find_encoding
-
-X<strings;encoding>
-X<find_encoding opcode (PASM)>
-
-  find_encoding R<DEST>, R<NAME>
-
-Find the encoding named R<NAME> and return its number in R<DEST>.
-
-I<Arguments: IR, S>
-
-=head3 find_global
-
-X<find_global opcode (PASM)>
-
-  find_global R<DEST>, R<NAME>
-
-Return a global variable with the given name.
-
-I<Arguments: P, S>
-
-  find_global R<DEST>, R<NAMESPACE>, R<NAME>
-
-Return a global variable with the given name from the given namespace.
-
-I<Arguments: P, S, S or P, P, S>
-
-See also: C<store_global>.
-
-=head3 find_lex
-
-X<find_lex opcode (PASM)>
-
-  find_lex R<DEST>, R<NAME>
-  find_lex R<DEST>, R<DEPTH>, R<NAME>
-  find_lex R<DEST>, R<DEPTH>, R<POSITION>
-
-Return the lexical variable of the given name from a lexical
-scratchpad. If R<DEPTH> is provided, only return a variable from the
-scratchpad at that depth. A find by position returns the variable at a
-particular position in the scratchpad.
-
-I<Arguments: P, S or P, I, S or P, I, I>
-
-See also: C<store_lex>.
-
-=head3 find_method
-
-X<find_method opcode (PASM)>
-
-  find_method R<DEST>, R<PMC>, R<NAME>
-
-Look up a method by name in a PMC's vtable. Return a method PMC.
-
-I<Arguments: P, P, S>
-
-=head3 find_type
-
-X<find_type opcode (PASM)>
-
-  find_type R<DEST>, R<NAME>
-
-Find the integer identifier for a PMC type or native Parrot datatype by name.
-
-I<Arguments: IR, S>
-
-See also: C<typeof>.
-
-=head3 findclass
-
-X<findclass opcode (PASM)>
-
-  findclass R<DEST>, R<NAME>
-
-Return 1 if the class R<NAME> exists, and 0 otherwise.
-
-I<Arguments: IR, S>
-
-See also: C<typeof>.
-
-=head3 floor
-
-X<floor opcode (PASM)>
-
-  floor R<DEST>
-  floor R<DEST>, R<VAL>
-
-Return the largest integral value less than or equal to R<VAL> (if
-present) or itself (if not).
-
-I<Arguments: NR or IR, N or NR, N>
-
-=head3 foldup
-
-X<foldup opcode (PASM)>
-
-  foldup R<DEST>
-  foldup R<DEST>, R<SKIP>
-
-Return a new array holding all passed subroutine parameters. R<SKIP>
-defines an optional offset.
-
-I<Arguments: P or P, I>
-
-=head3 freeze
-
-X<freeze opcode (PASM)>
-
-  freeze R<DEST>, R<VAL>
-
-Create a frozen image R<DEST> from PMC R<VAL>.
-
-I<Arguments: SR, P>
-
-See also: C<thaw>.
-
-=head3 gc_debug
-
-X<gc_debug opcode (PASM)>
-
-  gc_debug R<INT>
-
-Toggle garbage collection debugging in the interpreter (0 for off, any
-other value for on).
-
-I<Arguments: I>
-
-=head3 gcd
-
-X<gcd opcode (PASM)>
-
-  gcd R<DEST>, R<VAL>, R<VAL>
-
-Return the greatest common divisor of two values.
-
-I<Arguments: IR, I, I or IR, N, N>
-
-=head3 ge
-
-X<ge (greater than or equal);opcode (PASM)>
-
-  ge R<VAL1>, R<VAL2>, R<LABEL>
-
-Jump to a label if R<VAL1> is greater than or equal to R<VAL2>.
-
-I<Arguments: I, I, IC or N, N, IC or S, S, IC or P, I, IC or P, N, IC
-or P, S, IC or P, P, IC>
-
-=head3 ge_num
-
-X<ge_num opcode (PASM)>
-
-  ge_num R<VAL1>, R<VAL2>, R<LABEL>
-
-Jump to a label if R<VAL1> is numerically greater than or equal to R<VAL2>.
-
-I<Arguments: P, P, IC>
-
-=head3 ge_str
-
-X<ge_str opcode (PASM)>
-
-  ge_str R<VAL1>, R<VAL2>, R<LABEL>
-
-Jump to a label if R<VAL1> is stringwise greater than or equal to R<VAL2>.
-
-I<Arguments: P, P, IC>
-
-=head3 get_addr
-
-X<get_addr opcode (PASM)>
-
-  get_addr R<DEST>, R<SUB>
-
-Get the absolute address of a subroutine PMC.
-
-I<Arguments: IR, P>
-
-See also: C<set_addr>.
-
-=head3 getattribute
-
-X<getattribute opcode (PASM)>
-
-  getattribute R<DEST>, R<OBJECT>, R<OFFS>
-
-Get a reference to attribute number R<OFFS> from object R<OBJECT>.
-
-I<Arguments: P, P, I>
-
-See also: C<setattribute>, C<classoffset>.
-
-=head3 get_class
-
-X<get_class opcode (PASM)>
-
-  get_class R<DEST>, R<NAME>
-
-Return the class PMC of the given name.
-
-I<Arguments: P, S>
-
-=head3 getfile
-
-X<getfile opcode (PASM)>
-
-  getfile R<DEST>
-
-Return the name of the current file.
-
-I<Arguments: SR>
-
-=head3 getinterp
-
-X<getinterp opcode (PASM)>
-
-  getinterp R<DEST>
-
-Get a PMC representing the current interpreter.
-
-I<Arguments: P>
-
-=head3 getline
-
-X<getline opcode (PASM)>
-
-  getline R<DEST>
-
-Return the current line number.
-
-I<Arguments: IR>
-
-=head3 getpackage
-
-X<getpackage opcode (PASM)>
-
-  getpackage R<DEST>
-
-Return the current package name.
-
-I<Arguments: SR>
-
-=head3 getprop
-
-X<getprop opcode (PASM)>
-
-  getprop R<DEST>, R<NAME>, R<PMC>
-
-Return the value of a named property on a PMC.
-
-I<Arguments: P, S, P>
-
-See also: C<setprop> and C<prophash>.
-
-=head3 getstd*
-
-X<getstderr opcode (PASM)>
-X<getstdin opcode (PASM)>
-X<getstdout opcode (PASM)>
-
-  getstderr R<DEST>
-  getstdin R<DEST>
-  getstdout R<DEST>
-
-Get a FileHandle object for the given standard handle.
-
-I<Arguments: P>
-
-=head3 gmtime
-
-X<gmtime opcode (PASM)>
-
-  gmtime R<DEST>, R<VAL>
-
-Take the integer, which represents GMT epoch-seconds, and turn it into a
-formatted string.
-
-I<Arguments: SR, I>
-
-See also: C<localtime>.
-
-=head3 gt
-
-X<gt opcode (PASM)>
-
-  gt R<VAL1>, R<VAL2>, R<LABEL>
-
-Jump to a label if R<VAL1> is greater than R<VAL2>.
-
-I<Arguments: I, I, IC or N, N, IC or S, S, IC or P, I, IC or P, N, IC or
-P, S, IC or P, P, IC>
-
-=head3 gt_num
-
-X<gt_num opcode (PASM)>
-
-  gt_num R<VAL1>, R<VAL2>, R<LABEL>
-
-Jump to a label if R<VAL1> is numerically greater than R<VAL2>.
-
-I<Arguments: P, P, IC>
-
-=head3 gt_str
-
-X<gt_str opcode (PASM)>
-
-  gt_str R<VAL1>, R<VAL2>, R<LABEL>
-
-Jump to a label if R<VAL1> is stringwise greater than R<VAL2>.
-
-I<Arguments: P, P, IC>
-
-=head3 hav
-
-X<hav opcode (PASM)>
-
-  hav R<DEST>, R<VAL>
-
-The haversine of R<VAL> in radians.
-
-I<Arguments: NR, N>
-
-=head3 if
-
-X<if (conditional);opcode (PASM)>
-
-  if R<CONDITION>, R<LABEL>
-
-Jump to a label if the condition is a true value.
-
-I<Arguments: I, IC or N, IC or S, IC or P, IC>
-
-=head3 inc
-
-X<inc opcode (PASM)>
-
-  inc R<DEST>
-
-Increment a value by one.
-
-I<Arguments: IR or NR or P>
-
-=head3 index
-
-X<index opcode (PASM)>
-
-  index R<DEST>, R<STRING>, R<SEARCH>
-  index R<DEST>, R<STRING>, R<SEARCH>, R<POS>
-
-Return the position of the first occurrence of the string R<SEARCH> in
-the string R<STRING>, starting at the position R<POS>. If the starting
-position is unspecified, start at the beginning of the string.
-
-I<Arguments: IR, S, S or IR, S, S, I>
-
-=head3 interpinfo
-
-X<interpinfo opcode (PASM)>
-
-  interpinfo R<DEST>, R<FLAG>
-
-Return information about the interpreter. An integer flag selects
-which information to return, as listed in
-Table 10-1.
-
-=begin table picture Interpinfo flags
-
-Z<CHP-10-TABLE-1>
-
-=headrow
-
-=row
-
-=cell Flag
-
-=cell Returns
-
-=bodyrows
-
-=row
-
-=cell C<1>
-
-=cell Allocated memory, in bytes.
-
-=row
-
-=cell C<2>
-
-=cell Number of GC mark runs performed.
-
-=row
-
-=cell C<3>
-
-=cell Number of GC runs performed.
-
-=row
-
-=cell C<4>
-
-=cell Number of active PMCs.
-
-=row
-
-=cell C<5>
-
-=cell Number of active buffers.
-
-=row
-
-=cell C<6>
-
-=cell Number of allocated PMCs.
-
-=row
-
-=cell C<7>
-
-=cell Number of allocated buffers.
-
-=row
-
-=cell C<8>
-
-=cell Number of new PMC or buffer headers allocated since last mark run.
-
-=row
-
-=cell C<9>
-
-=cell Number of memory blocks allocated since last GC run.
-
-=row
-
-=cell C<10>
-
-=cell Amount of memory copied during GC runs, in bytes.
-
-=end table
-
-I<Arguments: IR, I>
-
-=head3 invoke
-
-X<invoke opcode (PASM)>
-
-  invoke
-  invoke R<SUB>
-
-Call a subroutine, coroutine, or continuation stored in a PMC. If no
-PMC register is specified, it calls the subroutine in C<P0> and uses
-the standard calling conventions.  Otherwise, no calling convention is
-defined. Also C<yield> from a coroutine.
-
-I<Arguments: P>
-
-=head3 invokecc
-
-X<invokecc opcode (PASM)>
-
-  invokecc
-  invokecc R<SUB>
-
-Call a subroutine like C<invoke>, but also generate a return
-continuation in C<P1>.
-
-I<Arguments: P>
-
-See also: C<updatecc>.
-
-=head3 isa
-
-X<isa opcode (PASM)>
-
-  isa R<DEST>, R<OBJECT>, R<CLASS>
-
-Return a true value if R<OBJECT> I<isa> member of class R<CLASS>, or of
-one of its subclasses, otherwise return a false value.
-
-I<Arguments: IR, P, S>
-
-=head3 isnull
-
-X<isnull opcode (PASM)>
-
-  isnull R<VAL>, R<LABEL>
-
-Jump to R<LABEL> if the given PMC is a NULL PMC.
-
-I<Arguments: P, IC>
-
-=head3 join
-
-X<join opcode (PASM)>
-
-  join R<DEST>, R<DELIM>, R<ARRAY>
-
-Create a new string by joining all elements from array with the given
-delimiter.
-
-I<Arguments: SR, S, P>
-
-=head3 jsr
-
-X<jsr opcode (PASM)>
-
-  jsr R<ADDRESS>
-
-Jump to an address, like C<jump>, but also push the current location
-onto the call stack so C<ret> can return to it.
-
-I<Arguments: I>
-
-=head3 jump
-
-X<jump opcode (PASM)>
-
-  jump R<ADDRESS>
-
-Jump to a specified absolute address.
-
-I<Arguments: I>
-
-See also: C<set_addr>.
-
-=head3 lcm
-
-X<lcm opcode (PASM)>
-
-  lcm R<DEST>, R<VAL>, R<VAL>
-
-Return the least common multiple of two values.
-
-I<Arguments: IR, I, I or NR, I, I>
-
-=head3 le
-
-X<le (less than or equal);opcode (PASM)>
-
-  le R<VAL1>, R<VAL2>, R<LABEL>
-
-Jump to a label if R<VAL1> is less than or equal to R<VAL2>.
-
-I<Arguments: I, I, IC or N, N, IC or S, S, IC or P, I, IC or P, N, IC or
-P, S, IC or P, P, IC>
-
-=head3 le_num
-
-X<le_num opcode (PASM)>
-
-  le_num R<VAL1>, R<VAL2>, R<LABEL>
-
-Jump to a label if R<VAL1> is numerically less than or equal to R<VAL2>.
-
-I<Arguments: P, P, IC>
-
-=head3 le_str
-
-X<le_str opcode (PASM)>
-
-  le_str R<VAL1>, R<VAL2>, R<LABEL>
-
-Jump to a label if R<VAL1> is stringwise less than or equal to R<VAL2>.
-
-I<Arguments: P, P, IC>
-
-=head3 length
-
-X<length opcode (PASM)>
-
-  length R<DEST>, R<STRING>
-
-Return the character length of a string.
-
-I<Arguments: IR, S>
-
-=head3 ln
-
-X<ln opcode (PASM)>
-
-  ln R<DEST>, R<VAL>
-
-The natural logarithm of R<VAL>.
-
-I<Arguments: NR, I or NR, N>
-
-=head3 load_bytecode
-
-X<load_bytecode>
-
-  load_bytecode R<FILE>
-
-Load Parrot bytecode from a file.
-
-I<Arguments: S>
-
-=head3 loadlib
-
-X<loadlib opcode (PASM)>
-
-  loadlib R<DEST>, R<LIBRARY>
-
-Load a dynamic link library by name and store it in a PMC.
-
-I<Arguments: P, S>
-
-See also: C<dlfunc>.
-
-=head3 localtime
-
-X<localtime opcode (PASM)>
-
-  localtime R<DEST>, R<VAL>
-
-Take the integer, which represents GMT epoch-seconds, and turn it into a
-formatted string after adjusting to localtime.
-
-I<Arguments: SR, I>
-
-See also: C<gmtime>.
-
-=head3 log10
-
-X<log10 opcode (PASM)>
-
-  log10 R<DEST>, R<VAL>
-
-The base 10 logarithm of R<VAL>.
-
-I<Arguments: NR, I or NR, N>
-
-=head3 log2
-
-X<log2 opcode (PASM)>
-
-  log2 R<DEST>, R<VAL>
-
-The base 2 logarithm of R<VAL>.
-
-I<Arguments: NR, I or NR, N>
-
-=head3 lsr
-
-X<lsr opcode (PASM)>
-
-  lsr R<DEST>, R<BITS>
-  lsr R<DEST>, R<VAL>, R<BITS>
-
-Logically shift a value right by a given number of bits.
-
-I<Arguments: IR, I or IR, I, I>
-
-=head3 lt
-
-X<lt (less than);opcode (PASM)>
-
-  lt R<VAL1>, R<VAL2>, R<LABEL>
-
-Jump to a label if R<VAL1> is less than R<VAL2>.
-
-I<Arguments: I, I, IC or N, N, IC or S, S, IC or P, I, IC or P, N, IC or
-P, S, IC or P, P, IC>
-
-=head3 lt_num
-
-X<lt_num opcode (PASM)>
-
-  lt_num R<VAL1>, R<VAL2>, R<LABEL>
-
-Jump to a label if R<VAL1> is numerically less than R<VAL2>.
-
-I<Arguments: P, P, IC>
-
-=head3 lt_str
-
-X<lt_str opcode (PASM)>
-
-  lt_str R<VAL1>, R<VAL2>, R<LABEL>
-
-Jump to a label if R<VAL1> is stringwise less than R<VAL2>.
-
-I<Arguments: P, P, IC>
-
-=head3 mod
-
-X<mod opcode (PASM)>
-
-  mod R<DEST>, R<VAL>
-  mod R<DEST>, R<VAL1>, R<VAL2>
-
-Divide R<VAL1> by R<VAL2> and return the remainder. If R<VAL2> is omitted,
-divide R<DEST> by R<VAL>.  The operation is defined as:
-
-  x mod y = x - y * floor(x / y)
-
-I<Arguments: P, I or IR, I, I or NR, N, N or P, P, I or P, P, N>
-
-See also: C<cmod>.
-
-=head3 mul
-
-X<mul opcode (PASM)>
-
-  mul R<DEST>, R<VAL>
-  mul R<DEST>, R<VAL>, R<VAL>
-
-Multiply two values and return the result. If only one R<VAL>,
-multiply R<DEST> by R<VAL>.
-
-I<Arguments: IR, I or NR, I or NR, N or P, I or P, N or P, P or IR, I,
-I or NR, N, I or NR, N, N or P, P, I or P, P, N or P, P, P>
-
-=head3 ne
-
-X<ne (not equal);opcode (PASM)>
-
-  ne R<VAL>, R<VAL>, R<LABEL>
-
-Jump to a label if the two values are not equal.
-
-I<Arguments: I, I, IC or N, N, IC or S, S, IC or P, I, IC or P, N, IC or
-P, S, IC or P, P, IC>
-
-=head3 ne_addr
-
-X<ne_addr opcode (PASM)>
-
-  ne_addr R<VAL>, R<VAL>, R<LABEL>
-
-Jump to a label if R<VAL1> and R<VAL2> do not point to the same string
-or PMC.
-
-I<Arguments: S, S, IC or P, P, IC>
-
-=head3 ne_num
-
-X<ne_num opcode (PASM)>
-
-  ne_num R<VAL>, R<VAL>, R<LABEL>
-
-Jump to a label if the two values are numerically different.
-
-I<Arguments: P, P, IC>
-
-=head3 ne_str
-
-X<ne_str opcode (PASM)>
-
-  ne_str R<VAL>, R<VAL>, R<LABEL>
-
-Jump to a label if the two strings are not equal.
-
-I<Arguments: P, P, IC>
-
-=head3 needs_destroy
-
-X<needs_destroy opcode (PASM)>
-
-  needs_destroy R<PMC>
-
-Mark the PMC as requiring timely destruction.
-
-I<Arguments: P>
-
-See also: C<sweep>.
-
-=head3 neg
-
-X<neg opcode (PASM)>
-
-  neg R<DEST>
-  neg R<DEST>, R<VAL>
-
-Return the negative of a number. If there is no R<VAL>, R<DEST> is the
-negative of itself.
-
-I<Arguments: IR or NR or P or IR, I or NR, N or P, P>
-
-=head3 new
-
-X<new opcode (PASM)>
-
-  new R<DEST>, R<TYPE>
-  new R<DEST>, R<TYPE>, R<INITIALIZE>
-  new R<DEST>, R<TYPE>, R<INITIALIZE>, R<PROPS>
-
-Create a new PMC of type R<TYPE>. R<INITIALIZE> is an array PMC
-containing initialization data for the new PMC. R<PROPS> is a property hash.
-
-I<Arguments: P, I or P, I, P or P, I, P, P>
-
-  new R<DEST>
-  new R<DEST>, R<LENGTH>
-  new R<DEST>, R<LENGTH>, R<ENCODING>
-  new R<DEST>, R<LENGTH>, R<ENCODING>, R<TYPE>
-
-Allocate a new empty string with a given R<LENGTH>, R<ENCODING>, and
-R<TYPE>.
-
-I<Arguments: SR or SR, I or SR, I, I or SR, I, I, I>
-
-=head3 new_callback
-
-X<new_callback opcode (PASM)>
-
-  new_callback R<DEST>, R<SUB>, R<DATA>, R<SIG>
-
-Create a callback stub R<DEST> for a PASM subroutine R<SUB> with user
-data R<DATA> and function signature R<SIG>.
-
-I<Arguments: P, P, P, S>
-
-=head3 new_pad
-
-X<new_pad opcode (PASM)>
-
-  new_pad R<DEPTH>
-  new_pad R<DEST>, R<DEPTH>
-
-Create a new lexical scratchpad. If a destination PMC is provided,
-store the pad in the PMC, otherwise push it onto the pad stack.
-R<DEPTH> specifies the static nesting depth for the pad (lower static
-depths are copied from the current static nesting).
-
-I<Arguments: I or P, I>
-
-=head3 newclass
-
-X<newclass opcode (PASM)>
-
-  newclass R<DEST>, R<NAME>
-
-Create a new class with the given name.
-
-I<Arguments: P, S>
-
-=head3 newsub
-
-X<newsub opcode (PASM)>
-
-  newsub R<DEST>, R<CLASS>, R<LABEL>
-
-Generate a new subroutine object of the given R<CLASS>, located at the
-given R<LABEL>, and store the object in the destination PMC.
-
-I<Arguments: P, I, IC>
-
-  newsub R<CLASS>, R<RETCLASS>, R<LABEL>, R<RETADDR>
-
-Generate a new subroutine object of the given R<CLASS>, located at the
-given R<LABEL>, and store the object in C<P0>. Also generate a return
-continuation of class R<RETCLASS> with the return address R<RETADDR> and
-store it in C<P1>.
-
-I<Arguments: I, I, IC, IC>
-
-=head3 noop
-
-X<noop opcode (PASM)>
-
-  noop
-
-Do nothing.
-
-=head3 not
-
-X<not opcode (PASM)>
-
-  not R<DEST>, R<VAL>
-
-Logical NOT. True if R<VAL> is false.
-
-I<Arguments: IR, I or P, P>
-
-=head3 null
-
-X<null opcode (PASM)>
-
-  null R<DEST>
-
-Set R<DEST> (which must be a register) to 0, 0.0 or a NULL pointer,
-depending on its type.
-
-I<Arguments: IR or NR or SR or P>
-
-=head3 open
-
-X<open opcode (PASM)>
-
-  open R<DEST>, R<FILENAME>
-  open R<DEST>, R<FILENAME>, R<MODE>
-
-Open a file in the specified mode ("r", "w", etc.) and return
-a filehandle. Without the mode it defaults to read/write.
-
-I<Arguments: P, S, S or P, S>
-
-=head3 or
-
-X<or opcode (PASM)>
-
-  or R<DEST>, R<VAL1>, R<VAL2>
-
-Logical OR. Return R<VAL1> if it's true; otherwise, return R<VAL2>.
-
-I<Arguments: IR, I, I or P, P, P>
-
-=head3 ord
-
-X<ord opcode (PASM)>
-
-  ord R<DEST>, R<STRING>
-  ord R<DEST>, R<STRING>, R<POS>
-
-Return the character at position R<POS> in R<STRING>. If R<POS> isn't
-specified, return the 0th character.
-
-I<Arguments: IR, S or IR, S, I>
-
-=head3 peek
-
-X<peek opcode (PASM)>
-
-  peek R<DEST>
-  peek R<DEST>, R<PIO>
-
-Read the next byte from the given FileHandle object or from C<stdin> but
-don't remove it.
-
-I<Arguments: SR or SR, P>
-
-=head3 peek_pad
-
-X<peek_pad opcode (PASM)>
-
-  peek_pad R<DEST>
-
-Store the current lexical scope pad in a PMC.
-
-I<Arguments: P>
-
-=head3 pin
-
-X<pin opcode (PASM)>
-
-  pin R<DEST>
-
-Make the string in R<DEST> immobile. This prevents the garbage collector
-from moving it to a different location in memory (which it otherwise may
-choose to do).
-
-I<Arguments: SR>
-
-See also: C<unpin>.
-
-=head3 pop
-
-X<pop opcode (PASM)>
-
-  pop R<DEST>, R<PMC>
-
-Pop the last entry off an aggregate PMC and return it.
-
-I<Arguments: IR, P or NR, P or SR, P or P, P>
-
-=head3 pop_pad
-
-X<pop_pad opcode (PASM)>
-
-  pop_pad
-
-Pop the current lexical scope pad off the lexical scope stack.
-
-See also: C<peek_pad>.
-
-=head3 popX
-
-X<popi opcode (PASM)>
-X<popn opcode (PASM)>
-X<popp opcode (PASM)>
-X<pops opcode (PASM)>
-
-  popi
-  popn
-  popp
-  pops
-
-Restore all the registers of one type from the stack ("i" = integer,
-"n" = float, "p" = PMC, "s" = string).
-
-  popbottomi
-  popbottomn
-  popbottomp
-  popbottoms
-
-Restore registers in the range 0..15.
-
-  poptopi
-  poptopn
-  poptopp
-  poptops
-
-Restore registers in the range 16..31.
-
-See also: C<push>R<X>.
-
-=head3 pow
-
-X<pow opcode (PASM)>
-
-  pow R<DEST>, R<VAL1>, R<VAL2>
-
-Return R<VAL1> raised to the power of R<VAL2>.
-
-I<Arguments: NR, I, I or NR, I, N or NR, N, I or NR, N, N>
-
-=head3 print
-
-X<print opcode (PASM)>
-
-  print R<VAL>
-  print R<IO>, R<VAL>
-
-Print a value to an I/O object or file descriptor. If no R<IO> is
-given, print the value to standard output.
-
-I<Arguments: I or N or S or P or P, I or P, N or P, S or P, P>
-
-=head3 printerr
-
-X<printerr opcode (PASM)>
-
-  printerr R<VAL>
-
-Print a value to C<stderr>.
-
-I<Arguments: I or N or S or P>
-
-=head3 profile
-
-X<profile opcode (PASM)>
-
-  profile R<INT>
-
-Toggle profiling in the interpreter (0 for off, any other value for on).
-
-I<Arguments: I>
-
-=head3 prophash
-
-X<prophash opcode (PASM)>
-
-  prophash R<DEST>, R<PMC>
-
-Return a hash containing all the properties from a PMC.
-
-I<Arguments: P, P>
-
-See also: C<getprop>.
-
-=head3 push
-
-X<push opcode (PASM)>
-
-  push R<PMC>, R<VAL>
-
-Push a value onto the end of an aggregate PMC.
-
-I<Arguments: P, I or P, N or P, S or P, P>
-
-=head3 push_pad
-
-X<push_pad opcode (PASM)>
-
-  push_pad R<PAD>
-
-Push a scratchpad stored in a PMC onto the lexical scope stack.
-
-I<Arguments: P>
-
-=head3 pushX
-
-X<pushi opcode (PASM)>
-X<pushn opcode (PASM)>
-X<pushp opcode (PASM)>
-X<pushs opcode (PASM)>
-
-  pushi
-  pushn
-  pushp
-  pushs
-
-Save all the registers of one type to the stack ("i" = integer, "n" =
-float, "p" = PMC, "s" = string). Restore with C<pop>R<X>.
-
-  pushbottomi
-  pushbottomn
-  pushbottomp
-  pushbottoms
-
-Push registers 0..15.
-
-  pushtopi
-  pushtopn
-  pushtopp
-  pushtops
-
-Push registers 16..31.
-
-=head3 read
-
-X<read opcode (PASM)>
-
-  read R<DEST>, R<BYTES>
-  read R<DEST>, R<IO>, R<BYTES>
-
-Read the specified number of bytes from a Parrot I/O object. Read from
-C<stdin> if no R<IO> is provided.
-
-I<Arguments: SR, I or SR, P, I>
-
-=head3 readline
-
-X<readline opcode (PASM)>
-
-  readline R<DEST>, R<IO>
-
-Read a line from a Parrot I/O object.
-
-I<Arguments: SR, P>
-
-=head3 register
-
-X<register opcode (PASM)>
-
-  register R<PMC>
-
-Register the given PMC in the interpreter's root set, so that it's
-visible during the mark phase.
-
-I<Arguments: P>
-
-See also: C<unregister>.
-
-=head3 removeparent
-
-X<removeparent opcode (PASM)>
-
-  removeparent R<CLASS1>, R<CLASS2>
-
-Remove R<CLASS2> from class C<CLASS1>'s list of parents.
-
-I<Arguments: P, P>
-
-=head3 repeat
-
-X<repeat opcode (PASM)>
-
-  repeat R<DEST>, R<VAL>, R<REPEAT>
-
-Repeat a string R<REPEAT> number of times.
-
-I<Arguments: SR, S, I or P, P, I or P, P, P>
-
-=head3 restoretop
-
-X<restoretop opcode (PASM)>
-
-  restoretop
-
-Restore registers 16..31. Does a C<pop>R<X> for every type.
-
-See also: C<savetop>.
-
-=head3 ret
-
-X<ret opcode (PASM)>
-
-  ret
-
-Pop a location off the top of the call stack, and go there.
-Often used with C<bsr> and C<jsr>.
-
-=head3 rethrow
-
-X<rethrow opcode (PASM)>
-
-  rethrow R<EXCEPTION>
-
-Rethrow an exception. Only valid inside an exception handler.
-
-I<Arguments: P>
-
-See also: C<throw>
-
-=head3 runinterp
-
-X<runinterp opcode (PASM)>
-
-  runinterp R<INTERPRETER>, R<OFFSET>
-
-Use an interpreter stored in PMC to run code starting at a given
-offset.
-
-I<Arguments: P, I>
-
-See also: C<newinterp>.
-
-=head3 say
-
-X<say opcode (PASM)>
-
-  say R<VAL>
-
-Print a value to C<stdout> with a trailing newline.
-
-I<Arguments: I or N or S or P>
-
-=head3 sec
-
-X<sec opcode (PASM)>
-
-  sec R<DEST>, R<VAL>
-
-The secant of R<VAL> in radians.
-
-I<Arguments: NR, I or NR, N>
-
-=head3 sech
-
-X<sech opcode (PASM)>
-
-  sech R<DEST>, R<VAL>
-
-The hyperbolic secant of R<VAL> in radians.
-
-I<Arguments: NR, I or NR, N>
-
-=head3 seek
-
-X<seek opcode (PASM)>
-
-  seek R<DEST>, R<IO>, R<OFFSET>, R<STARTFLAG>
-  seek R<DEST>, R<IO>, R<UPPER32>, R<LOWER32>, R<STARTFLAG>
-
-Set the file position of a Parrot I/O object to a given offset from a
-starting position (STARTFLAG: 0 is the beginning of the file, 1 is
-current the position, 2 is the end of the file).  R<DEST> is the
-success or failure of the seek.
-
-64-bit C<seek> combines R<UPPER32> and R<LOWER32> to get one 64-bit
-R<OFFSET>.
-
-I<Arguments: P, I, I or P, I, I, I>
-
-=head3 set
-
-X<set opcode (PASM)>
-
-  set R<DEST>, R<VAL>
-
-Set a register to a value.
-
-I<Arguments: IR, I or IR, N or IR, S or IR, P or NR, I or NR, N or NR,
-S or NR, P or SR, I or SR, N or SR, S or SR, P or P, I or P, N or P, S
-or P, P>
-
-  set R<DEST[KEY]>, R<VAL>
-
-A keyed set operation on a PMC.
-
-I<Arguments: P, I or P, N or P, S or P, P>
-
-  set R<DEST>, R<PMC[KEY]>
-
-A keyed get operation on a PMC.
-
-I<Arguments: I, P or N, P or S, P or P, P>
-
-=head3 setX_ind
-
-X<seti_ind opcode (PASM)>
-X<setn_ind opcode (PASM)>
-X<sets_ind opcode (PASM)>
-X<setp_ind opcode (PASM)>
-
-  seti_ind R<REG>, R<VAL>
-  setn_ind R<REG>, R<VAL>
-  sets_ind R<REG>, R<VAL>
-  setp_ind R<REG>, R<VAL>
-
-Set register number R<REG> of the specified type to R<VAL>. Bypasses
-the register allocator, so use with care.
-
-I<Arguments: I, I or I, S or I, N or I, P>
-
-=head3 set_addr
-
-X<set_addr opcode (PASM)>
-
-  set_addr R<DEST>, R<LABEL>
-
-Return the current address plus the offset to R<LABEL>. Often used to
-calculate absolute addresses for C<jump> or C<jsr>.
-
-I<Arguments: IR, IC>
-
-  set_addr R<SUB>, R<LABEL>
-
-Set the subroutine address pointing to the given label.
-
-I<Arguments: P, I>
-
-=head3 set_chartype
-
-X<set_chartype opcode (PASM)>
-
-  set_chartype R<STRING>, R<CHARTYPE>
-
-Set the chartype of a string.
-
-I<Arguments: S, I>
-
-=head3 set_eh
-
-X<set_eh opcode (PASM)>
-
-  set_eh R<HANDLER>
-
-Push an exception handler on the control stack.
-
-I<Arguments: P>
-
-See also: C<clear_eh>, C<throw>.
-
-=head3 set_encoding
-
-X<set_encoding opcode (PASM)>
-X<strings;encoding>
-
-  set_encoding R<STRING>, R<ENCODING>
-
-Set the encoding of a string.
-
-I<Arguments: S, I>
-
-=head3 setattribute
-
-X<setattribute opcode (PASM)>
-
-  setattribute R<OBJECT>, R<OFFSET>, R<ATTRIBUTE>
-
-Set the given attribute at R<OFFSET> for object R<OBJECT>.
-
-I<Arguments: P, I, P>
-
-See also: C<getattribute>, C<classoffset>.
-
-=head3 setprop
-
-X<setprop opcode (PASM)>
-
-  setprop R<PMC>, R<NAME>, R<VALUE>
-
-Set the value of a named property on a PMC.
-
-I<Arguments: P, S, P>
-
-See also: C<getprop> and C<delprop>.
-
-=head3 setstd*
-
-X<setstderr opcode (PASM)>
-X<setstdin  opcode (PASM)>
-X<setstdout opcode (PASM)>
-
-  setstderr R<DEST>
-  setstdin  R<DEST>
-  setstdout R<DEST>
-
-Set a FileHandle object for the given standard handle.
-
-I<Arguments: P>
-
-=head3 shift
-
-X<shift opcode (PASM)>
-
-  shift R<DEST>, R<PMC>
-
-Shift a value off the front of an aggregate PMC.
-
-I<Arguments: IR, P or NR, P or SR, P or P, P>
-
-=head3 shl
-
-X<shl opcode (PASM)>
-
-  shl R<DEST>, R<VAL>, R<BITS>
-
-Bitwise shift a value left by a given number of bits.
-
-I<Arguments: IR, I or P, I or P, P or IR, I, I or P, P, I or P, P, P>
-
-=head3 shr
-
-X<shr opcode (PASM)>
-
-  shr R<DEST>, R<VAL>, R<BITS>
-
-Bitwise shift a value right by a given number of bits.
-
-I<Arguments: IR, I or P, I or P, P or IR, I, I or P, P, I or P, P, P>
-
-=head3 sin
-
-X<sin opcode (PASM)>
-
-  sin R<DEST>, R<VAL>
-
-The sine of R<VAL> in radians.
-
-I<Arguments: NR, I or NR, N>
-
-=head3 singleton
-
-X<singleton opcode (PASM)>
-
-  singleton R<DEST>
-
-Take the given object and put it into its own singleton class.
-
-I<Arguments: P>
-
-=head3 sinh
-
-X<sinh opcode (PASM)>
-
-  sinh R<DEST>, R<VAL>
-
-The hyperbolic sine of R<VAL> in radians.
-
-I<Arguments: NR, I or NR, N>
-
-=head3 sizeof
-
-X<sizeof opcode (PASM)>
-
-  sizeof R<DEST>, R<TYPE>
-
-Set R<DEST> to the size in bytes of the given natural type.
-
-I<Arguments: IR, I>
-
-=head3 sleep
-
-X<sleep opcode (PASM)>
-
-  sleep R<SECONDS>
-
-Sleep for the given number of seconds.
-
-I<Arguments: I or N>
-
-=head3 spawnw
-
-X<spawnw opcode (PASM)>
-
-  spawnw R<DEST>, R<COMMAND>
-
-Spawn a subprocess to run the given R<COMMAND>, wait for it to finish,
-and return the result.
-
-I<Arguments: IR, S>
-
-=head3 splice
-
-X<splice opcode (PASM)>
-
-  splice R<DEST>, R<REPLACE>, R<OFFSET>, R<COUNT>
-
-Starting at R<OFFSET>, replace R<COUNT> number of values in the
-destination PMC with values provided in the R<REPLACE> PMC.
-
-I<Arguments: P, P, I, I>
-
-=head3 sprintf
-
-X<sprintf opcode (PASM)>
-
-  sprintf R<DEST>, R<FORMAT>, R<ARGS>
-
-Format arguments in an aggregate PMC, using format string R<FORMAT>.
-
-I<Arguments: SR, S, P or P, P, P>
-
-=head3 stat
-
-X<stat opcode (PASM)>
-
-  stat R<DEST>, R<VAL>, R<VAL>
-
-Stat the VAL1 file and return stat element VAL2, as listed in
-Table 10-2.
-
-I<Arguments: IR, S, I or IR, I, I>
-
-=begin table picture Stat arguments
-
-Z<CHP-10-TABLE-2>
-
-=headrow
-
-=row
-
-=cell Flag
-
-=cell Flagname
-
-=cell Returns
-
-=bodyrows
-
-=row
-
-=cell C<0>
-
-=cell EXISTS
-
-=cell Does the file exist?
-
-=row
-
-=cell C<1>
-
-=cell FILESIZE
-
-=cell Size of file, in bytes
-
-=row
-
-=cell C<2>
-
-=cell ISDIR
-
-=cell Is the file a directory?
-
-=row
-
-=cell C<3>
-
-=cell ISDEV
-
-=cell Is the file a device?
-
-=row
-
-=cell C<4>
-
-=cell CREATETIME
-
-=cell Time file was created
-
-=row
-
-=cell C<5>
-
-=cell ACCESSTIME
-
-=cell Time file was last accessed
-
-=row
-
-=cell C<6>
-
-=cell MODIFYTIME
-
-=cell Time file data was changed
-
-=row
-
-=cell C<7>
-
-=cell CHANGETIME
-
-=cell Time file metadata was changed
-
-=row
-
-=cell C<8>
-
-=cell BACKUPTIME
-
-=cell Time of last backup
-
-=row
-
-=cell C<9>
-
-=cell UID
-
-=cell ID of file owner
-
-=row
-
-=cell C<10>
-
-=cell GID
-
-=cell ID of file group
-
-=end table
-
-=head3 store_global
-
-X<store_global opcode (PASM)>
-
-  store_global R<NAME>, R<OBJECT>
-  store_global R<NAME>, R<NAMESPACE>, R<OBJECT>
-
-Store a global variable as a named symbol.
-
-I<Arguments: S, P or S, S, P or P, S, P>
-
-See also: C<find_global>.
-
-=head3 store_lex
-
-X<store_lex opcode (PASM)>
-
-  store_lex R<NAME>, R<OBJECT>
-  store_lex R<DEPTH>, R<NAME>, R<OBJECT>
-  store_lex R<DEPTH>, R<POSITION>, R<OBJECT>
-
-Store an object as a lexical variable with a given name. If the symbol
-doesn't exist, it will be created in the lexical scratchpad at the
-specified depth (a negative depth counts back from the current scope).
-If R<DEPTH> isn't provided, the symbol must already exist. If a
-position is provided instead of a name, the symbol will be stored at
-the given position in the scratchpad.
-
-I<Arguments: S, P or I, I, P or I, S, P>
-
-See also: C<find_lex>.
-
-=head3 string_chartype
-
-X<string_chartype opcode (PASM)>
-
-  string_chartype R<DEST>, R<STRING>
-
-Return the chartype of the string.
-
-I<Arguments: IR, S>
-
-=head3 string_encoding
-
-X<string_encoding opcode (PASM)>
-X<strings;encoding>
-
-  string_encoding R<DEST>, R<STRING>
-
-Return the encoding of the string.
-
-I<Arguments: IR, S>
-
-=head3 stringinfo
-
-X<stringinfo opcode (PASM)>
-
-  stringinfo R<DEST>, R<STRING>, R<FLAG>
-
-Return information about a string. An integer flag selects which
-information to return, as listed in Table 10-3.
-
-=begin table picture Stringinfo arguments
-
-Z<CHP-10-TABLE-3>
-
-=headrow
-
-=row
-
-=cell Flag
-
-=cell Returns
-
-=bodyrows
-
-=row
-
-=cell C<1>
-
-=cell Location of string buffer header.
-
-=row
-
-=cell C<2>
-
-=cell Location of start of string memory.
-
-=row
-
-=cell C<3>
-
-=cell Allocated length, in bytes.
-
-=row
-
-=cell C<4>
-
-=cell String flags.
-
-=row
-
-=cell C<5>
-
-=cell Length of string buffer currently used, in bytes.
-
-=row
-
-=cell C<6>
-
-=cell String length, in characters.
-
-=end table
-
-I<Arguments: IR, S, I>
-
-=head3 sub
-
-X<sub opcode (PASM)>
-
-  sub R<DEST>, R<VAL>
-  sub R<DEST>, R<VAL1>, R<VAL2>
-
-Subtract R<VAL2> from R<VAL1>. If no R<VAL2>, subtract R<VAL> from
-R<DEST>.
-
-I<Arguments: IR, I or NR, I or NR, N or P, I or P, N or P, P or IR, I,
-I or NR, N, I or NR, N, N or P, P, I or P, P, N or P, P, P>
-
-=head3 subclass
-
-X<subclass opcode (PASM)>
-
-  subclass R<DEST>, R<CLASS>
-  subclass R<DEST>, R<CLASS>, R<NAME>
-
-Create a subclass of R<CLASS>. Without R<NAME> an anonymous subclass is
-created.
-
-I<Arguments: P, S or P, P or P, S, S or P, P, S>
-
-=head3 substr
-
-X<substr opcode (PASM)>
-
-  substr R<DEST>, R<STRING>, R<OFFSET>
-  substr R<DEST>, R<STRING>, R<OFFSET>, R<LENGTH>
-
-Return a substring of R<STRING>, beginning at R<OFFSET> and with length
-R<LENGTH>.
-
-I<Arguments: SR, S, I or SR, S, I, I or SR, P, I, I>
-
-  substr R<DEST>, R<STRING>, R<OFFSET>, R<LENGTH>, R<REPLACE>
-
-If R<REPLACE> is given, use it to replace the returned substring in
-R<STRING>.
-
-I<Arguments: SR, S, I, I, S>
-
-  substr R<DEST>, R<OFFSET>, R<LENGTH>, R<REPLACE>
-
-If R<STRING> is omitted, operate on the string in R<DEST>.
-
-I<Arguments: SR, I, I, S>
-
-
-=head3 substr_r
-
-X<substr_r opcode (PASM)>
-
-  substr_r R<DEST>, R<STRING>, R<OFFSET>, R<LENGTH>
-
-Acts like C<substr>, but reuses the destination string instead of
-creating a new string. Deprecated.
-
-I<Arguments: SR, S, I, I>
-
-=head3 sweep
-
-X<sweep opcode (PASM)>
-
-  sweep R<LAZY>
-
-Trigger a GC mark run. If R<LAZY> is set to 1, only objects that need timely
-destruction may be destroyed.
-
-I<Arguments: IC>
-
-=head3 sweepoff
-
-X<sweepoff opcode (PASM)>
-
-  sweepoff
-
-Disable GC mark runs (nestable).
-
-=head3 sweepon
-
-X<sweepon opcode (PASM)>
-
-  sweepon
-
-Re-enable GC mark runs.
-
-=head3 sysinfo
-
-X<sysinfo opcode (PASM)>
-
-  sysinfo R<DEST>, R<ITEM>
-
-Return OS-specific details given by C<ITEM>.
-
-I<Arguments: IR, I or SR, I>
-
-=head3 tan
-
-X<tan opcode (PASM)>
-
-  tan R<DEST>, R<VAL>
-
-The tangent of R<VAL> in radians.
-
-I<Arguments: NR, I or NR, N>
-
-=head3 tanh
-
-X<tanh opcode (PASM)>
-
-  tanh R<DEST>, R<VAL>
-
-The hyperbolic tangent of R<VAL> in radians.
-
-I<Arguments: NR, I or NR, N>
-
-=head3 tell
-
-X<tell opcode (PASM)>
-
-  tell R<DEST>, R<PIO>
-  tell R<UPPER32>, R<LOWER32>, R<PIO>
-
-Return the file position of the given FileHandle object.
-
-I<Arguments: IR, P or IR, I, P>
-
-See also: C<seek>.
-
-=head3 thaw
-
-X<thaw opcode (PASM)>
-
-  thaw R<DEST>, R<STR>
-
-Create a new PMC representing the frozen image.
-
-I<Arguments: P, S>
-
-See also: C<freeze>.
-
-=head3 throw
-
-X<throw opcode (PASM)>
-
-  throw R<EXCEPTION>
-
-Throw an exception.
-
-I<Arguments: P>
-
-See also: C<rethrow>, C<set_eh>, C<clear_eh>
-
-=head3 time
-
-X<time opcode (PASM)>
-
-  time R<DEST>
-
-Return the current system time.
-
-I<Arguments: IR or NR>
-
-=head3 titlecase
-
-X<titlecase opcode (PASM)>
-
-  titlecase R<DEST>
-  titlecase R<DEST>, R<VAL>
-
-Create a copy of the string in R<VAL> with all characters converted to
-title case, and store it in R<DEST>. If R<VAL> is omitted, convert and
-replace the string in R<DEST>.
-
-I<Arguments: SR or SR, S>
-
-See also: C<upcase>, C<downcase>.
-
-=head3 trace
-
-X<trace opcode (PASM)>
-
-  trace R<INT>
-
-Toggle tracing in the interpreter (0 for off, any other value for on).
-
-I<Arguments: I>
-
-=head3 transcode
-
-X<transcode opcode (PASM)>
-
-  transcode R<DEST>, R<ENCODING>
-  transcode R<DEST>, R<SOURCE>, R<ENCODING>
-  transcode R<DEST>, R<SOURCE>, R<ENCODING>, R<CHARTYPE>
-
-Transcode a string to the given R<CHARTYPE> and R<ENCODING>. If
-R<CHARTYPE> is omitted, it is assumed to be the same as the original.
-
-I<Arguments: SR, I or SR, S, I or SR, S, I, I>
-
-=head3 typeof
-
-X<typeof opcode (PASM)>
-
-  typeof R<DEST>, R<VAL>
-  typeof R<DEST>, R<PMC[KEY]>
-
-Return the type of a PMC or Parrot data type, either its class name (to a
-string destination) or integer identifier (to an integer destination).
-
-I<Arguments: IR, P or SR, I or SR, P>
-
-=head3 unless
-
-X<unless (conditional);opcode (PASM)>
-
-  unless R<CONDITION>, R<LABEL>
-
-Jump to a label unless the condition is a true value.
-
-I<Arguments: I, IC or N, IC or S, IC or P, IC>
-
-=head3 unpin
-
-X<unpin opcode (PASM)>
-
-  unpin R<DEST>
-
-Make the string in R<DEST> movable again. This is the default, so
-C<unpin> is a no-op unless the string has been pinned with C<pin>.
-
-See also: C<pin>.
-
-I<Arguments: SR>
-
-=head3 unregister
-
-X<unregister opcode (PASM)>
-
-  unregister R<PMC>
-
-Remove one reference to PMC from the root set registry.
-
-I<Arguments: P>
-
-See also: C<register>.
-
-=head3 unshift
-
-X<unshift opcode (PASM)>
-
-  unshift R<DEST>, R<VAL>
-
-Unshift a value onto the front of an aggregate PMC.
-
-I<Arguments: P, I or P, N or P, S or P, P>
-
-=head3 upcase
-
-X<upcase opcode (PASM)>
-
-  upcase R<DEST>
-  upcase R<DEST>, R<VAL>
-
-Create a copy of the string in R<VAL> with all characters converted to
-upper case, and store it in R<DEST>. If R<VAL> is omitted, convert and
-replace the string in R<DEST>.
-
-I<Arguments: SR or SR, S>
-
-See also: C<downcase>, C<titlecase>.
-
-=head3 updatecc
-
-X<updatecc>
-
-  updatecc
-
-Update the state of a return continuation stored in C<P1>. Used when
-context information changes after the return continuation is created
-but before it's invoked.
-
-See also: C<invokecc>.
-
-I<Arguments: IR, I>
-
-=head3 vers
-
-X<vers opcode (PASM)>
-
-  vers R<DEST>, R<VAL>
-
-The versine of R<VAL> in radians.
-
-I<Arguments: NR, N>
-
-=head3 warningsoff
-
-X<warningsoff opcode (PASM)>
-
-  warningsoff R<CATEGORY>
-
-Turn off a particular category of warnings by category number. Turning
-off one category will not affect the status of other warnings
-categories. See C<warningson> for the list of categories.
-
-I<Arguments: I>
-
-=head3 warningson
-
-X<warningson opcode (PASM)>
-
-  warningson R<CATEGORY>
-
-Turn on a particular category of warnings by category number. The
-default is all warnings off. Turning on one category will not turn off
-other categories. Combine category numbers with a bitwise OR to turn on
-more than one at a time. If you include F<warnings.pasm>, the category
-numbers are available by name as:
-
-  .PARROT_WARNINGS_ALL_FLAG
-  .PARROT_WARNINGS_UNDEF_FLAG
-  .PARROT_WARNINGS_IO_FLAG
-  .PARROT_WARNINGS_PLATFORM_FLAG
-
-I<Arguments: I>
-
-=head3 xor
-
-X<xor opcode (PASM)>
-
-  xor R<DEST>, R<VAL1>, R<VAL2>
-
-Logical XOR. If R<VAL1> is true and R<VAL2> is false, return R<VAL1>.
-If R<VAL1> is false and R<VAL2> is true, return R<VAL2>. Otherwise,
-return a false value.
-
-I<Arguments: IR, I, I or P, P, P>
-
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/tt761_keys_revamp/docs/book/ch11_directive_reference.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/book/ch11_directive_reference.pod	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,227 +0,0 @@
-=pod
-
-=head1 Directive Reference
-
-Z<CHP-13-SECT-2>
-
-X<PIR (Parrot intermediate representation);quick reference;directives>
-This is a summary of PIR directives. Directives are preprocessed by the
-Parrot interpreter. Since PIR and PASM run on the same interpreter, many
-of the directives listed here are also valid in PASM code.
-
-
-=head3 .arg
-
-X<.arg directive>
-
-  .arg R<VAL>
-
-pass a value to a subroutine according to PCC.
-
-=head3 .const
-
-X<.const directive>
-
-  .const R<TYPE>R<NAME> = R<VALUE>
-
-Define a named constant.
-
-=head3 .macro_const
-
-X<.macro_const directive>
-
-  .macro_const R<NAME>R<VALUE>
-
-Define a named macro that expands to a given value. Macros are called
-as directives, i.e. .R<NAME> (PASM code only).
-
-=head3 .emit
-
-X<.emit directive>
-
-  .emit
-
-Define a compilation unit of PASM code. Always paired with C<.eom>.
-
-=head3 .end
-
-X<.end directive>
-
-  .end
-
-End a compilation unit. Always paired with C<.sub>.
-
-=head3 .endm
-
-X<.endm directive>
-
-  .endm
-
-End a macro definition. Always paired with C<.macro>.
-
-=head3 .eom
-
-X<.eom directive>
-
-  .eom
-
-End a compilation unit of PASM code. Always paired with C<.emit>.
-
-=head3 .flatten_arg
-
-X<.flatten_arg directive>
-
-  .flatten_arg R<PArray>
-
-Flatten the passed array PMC and provide args for PCC calls.
-
-=head3 .globalconst
-
-X<.globalconst directive>
-
-  .globalconst R<TYPE>R<NAME> = R<VALUE>
-
-Define a named, file visible constant.
-
-=head3 .include
-
-X<.include directive>
-
-  .include " R<FILENAME> "
-
-Include the contents of an external file by inserting it in place.
-
-=head3 .invocant
-
-X<.invocant directive>
-
-  .invocant R<OBJ>
-
-Set the invocant for a method call.
-
-=head3 .local
-
-X<.local directive>
-
-  .local R<TYPE>R<NAME>
-
-Define a local named variable.
-
-=head3 .macro
-
-X<.macro directive>
-
-  .macro R<NAME> (R<PARAMS>)
-
-Define a named macro with a list of parameters. The macro is called as
-.R<NAME>(R<arg1>,R<arg2>,...).  Always paired with C<.endm>.
-
-=head3 .meth_call
-
-X<.meth_call directive>
-
-  .meth_call R<SUB>
-  .meth_call R<SUB>, R<RETCONT>
-
-Create a method call.
-
-=head3 .namespace
-
-X<.namespace directive>
-
-  .namespace R< [ "namespace" ] >
-
-Define a namespace.
-
-=head3 .nci_call
-
-X<.nci_call directive>
-
-  .nci_call R<SUB>
-
-Create an NCI call.
-
-=head3 .param
-
-X<.param directive>
-
-  .param R<DEST>
-  .param R<TYPE>R<NAME>
-
-Define a subroutine parameter.
-
-=head3 .begin_call
-
-X<.begin_call directive>
-
-Start a call sequence. Always paired with C<.end_call>
-
-=head3 .begin_return
-
-X<.begin_return directive>
-
-Start a return sequence. Always paired with C<.end_return>
-
-=head3 .begin_yield
-
-X<.begin_yield directive>
-
-Start a return of a coroutine sequence. Always paired with C<.end_yield>
-
-=head3 .call
-
-X<.call directive>
-
-  .call R<SUB>
-  .call R<SUB>, R<RETCONT>
-
-Create a subroutine call.
-
-=head3 .pcc_sub
-
-X<.pcc_sub directive>
-
-  .pcc_sub R<_LABEL>
-
-Create a symbol entry for subroutine at the _LABEL. This directive is
-for PASM code only.
-
-=head3 .result
-
-X<.result directive>
-
-  .result R<DEST>
-
-Get a return value according to PCC.
-
-=head3 .return
-
-X<.return directive>
-
-  .return R<VAL>
-
-Return a value to the calling subroutine according to PCC.
-
-=head3 .sub
-
-X<.sub directive>
-
-  .sub R<NAME>
-
-Define a compilation unit. Always paired with C<.end>. Names begin
-with "C<_>" by convention.
-
-=head3 .sym
-
-X<.sym directive>
-
-  .sym R<TYPE> R<NAME>
-
-Same as C<.local>.
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/tt761_keys_revamp/docs/book/ch12_operator_reference.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/book/ch12_operator_reference.pod	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,299 +0,0 @@
-=pod
-
-=head1 PIR Operator Reference
-
-Z<CHP-13-SECT-3>
-
-X<PIR (Parrot intermediate representation);quick reference;instructions>
-This section is a quick reference to PIR instructions. For more details
-and the latest changes, see F<imcc/docs/syntax.pod> or dive into the
-source code in F<imcc/imcc.l> and F<imcc/imcc.y>.
-
-=head3 =
-
-X<= (equal sign);= (assignment);instruction (PIR)>
-
-  R<DEST> = R<VAL>
-
-Assign a value to a particular register, temporary register, or named
-variable.
-
-=head3 +, +=
-
-X<+ (plus sign);+ (addition);instruction (PIR)>
-X<+ (plus sign);+= (addition assignment);instruction (PIR)>
-
-  R<DEST> = R<VAL> + R<VAL>
-  R<DEST> += R<VAL>
-
-Add two numbers or PMCs.
-
-=head3 -, -=
-
-X<- (hyphen);- (subtraction);instruction (PIR)>
-X<- (hyphen);-= (subtraction assignment);instruction (PIR)>
-X<- (hyphen);- (negation);instruction (PIR)>
-
-  R<DEST> = R<VAL1> - R<VAL2>
-  R<DEST> -= R<VAL1>
-  R<DEST> = - R<VAL>
-
-Subtract R<VAL1> from R<VAL2>. The unary "C<->" negates a number.
-
-=head3 *, *=
-
-X<* (asterisk);* (multiplication);instruction (PIR)>
-X<* (asterisk);*= (multiplication assignment);instruction (PIR)>
-
-  R<DEST> = R<VAL> * R<VAL>
-  R<DEST> *= R<VAL>
-
-Multiply two numbers or PMCs.
-
-=head3 /, /=
-
-X</ (slash);/ (division);instruction (PIR)>
-X</ (slash);/= (division assignment);instruction (PIR)>
-
-  R<DEST> = R<VAL1> / R<VAL2>
-  R<DEST> /= R<VAL1>
-
-Divide R<VAL1> by R<VAL2>.
-
-=head3 **
-
-X<* (asterisk);** (exponentiation);instruction (PIR)>
-
-  R<DEST> = R<VAL1> ** R<VAL2>
-
-Raise R<VAL1> to the power of R<VAL2>.
-
-=head3 %, %=
-
-X<% (percent sign);% (modulus);instruction (PIR)>
-X<% (percent sign);%= (modulus assignment);instruction (PIR)>
-
-  R<DEST> = R<VAL1> % R<VAL2>
-  R<DEST> %= R<VAL1>
-
-Divide R<VAL1> by R<VAL2> and return the (C<mod>) remainder.
-
-=head3 ., .=
-
-X<. (dot);. (concatenation) instruction (PIR)>
-X<. (dot);.= (concatenation assignment) instruction (PIR)>
-
-  R<DEST> = R<VAL> . R<VAL>
-  R<DEST> .= R<VAL>
-
-Concatenate two strings. The concat operator must be surrounded by
-whitespace.
-
-=head3 E<lt>
-
-X<E<lt> (left angle bracket);E<lt> (less than);instruction (PIR)>
-
-  if R<VAL1> E<lt> R<VAL2> goto R<LABEL>
-
-Conditionally branch to a label if R<VAL1> is less than R<VAL2>.
-
-=head3 E<lt>=
-
-X<E<lt> (left angle bracket);E<lt>= (less than or equal);instruction (PIR)>
-
-  if R<VAL1> E<lt>= R<VAL2> goto R<LABEL>
-
-Conditionally branch to a label if R<VAL1> is less than or equal to
-R<VAL2>.
-
-=head3 E<gt>
-
-X<E<gt> (right angle bracket);E<gt> (greater than);instruction (PIR)>
-
-  if R<VAL1> E<gt> R<VAL2> goto R<LABEL>
-
-Conditionally branch to a label if R<VAL1> is greater than R<VAL2>.
-
-=head3 E<gt>=
-
-X<E<gt> (right angle bracket);E<gt>= (greater than or equal);instruction (PIR)>
-
-  if R<VAL1> E<gt>= R<VAL2> goto R<LABEL>
-
-Conditionally branch to a label if R<VAL1> is greater than or equal to
-R<VAL2>.
-
-=head3 ==
-
-X<= (equal sign);== (equality);instruction (PIR)>
-
-  if R<VAL1> == R<VAL2> goto R<LABEL>
-
-Conditionally branch to a label if R<VAL1> is equal to R<VAL2>.
-
-=head3 !=
-
-X<! (bang);!= (not equal);instruction (PIR)>
-
-  if R<VAL1> != R<VAL2> goto R<LABEL>
-
-Conditionally branch to a label if R<VAL1> is not equal to R<VAL2>.
-
-=head3 &&
-
-X<& (ampersand);&& (logical AND);instruction (PIR)>
-
-  R<DEST> = R<VAL1> && R<VAL2>
-
-Logical AND. Return R<VAL1> if it's false, otherwise return R<VAL2>.
-
-=head3 ||
-
-X<| (pipe);|| (logical OR);instruction (PIR)>
-
-  R<DEST> = R<VAL1> || R<VAL2>
-
-Logical OR. Return R<VAL1> if it's true, otherwise return R<VAL2>.
-
-=head3 ~~
-
-X<~ (tilde);~~ (logical XOR) instruction (PIR)>
-
-  R<DEST> = R<VAL1> ~~ R<VAL2>
-
-Logical XOR. If R<VAL1> is true and R<VAL2> is false, return R<VAL1>.
-If R<VAL1> is false and R<VAL2> is true, return R<VAL2>. Otherwise,
-return a false value.
-
-=head3 !
-
-X<! (bang);! (not);instruction (PIR)>
-
-  R<DEST> = ! R<VAL>
-
-Logical NOT. Return a true value if R<VAL> is false.
-
-=head3 &, &=
-
-X<& (ampersand);& (bitwise AND) instruction (PIR)>
-X<& (ampersand);&= (bitwise AND assignment) instruction (PIR)>
-
-  R<DEST> = R<VAL> & R<VAL>
-  R<DEST> &= R<VAL>
-
-Bitwise AND on two values.
-
-=head3 |, |=
-
-X<| (pipe);| (bitwise AND) instruction (PIR)>
-X<| (pipe);|= (bitwise AND assignment) instruction (PIR)>
-
-  R<DEST> = R<VAL> | R<VAL>
-  R<DEST> |= R<VAL>
-
-Bitwise OR on two values.
-
-=head3 ~, ~=
-
-X<~ (tilde);~ (bitwise XOR) instruction (PIR)>
-X<~ (tilde);~= (bitwise XOR assignment) instruction (PIR)>
-
-  R<DEST> = R<VAL> ~ R<VAL>
-  R<DEST> ~= R<VAL>
-  R<DEST> = ~ R<VAL>
-
-Bitwise XOR on two values. The unary form is a bitwise NOT on a value.
-
-=head3 E<lt>E<lt>, E<lt>E<lt>=
-
-X<E<lt> (left angle bracket);E<lt>E<lt> (bitwise left shift);instruction (PIR)>
-X<E<lt> (left angle bracket);E<lt>E<lt>= (bitwise left shift assignment);instruction (PIR)>
-
-  R<DEST> = R<VAL1> E<lt>E<lt> R<VAL2>
-  R<DEST> E<lt>E<lt>= R<VAL2>
-
-Bitwise shift R<VAL1> left by R<VAL2> number of bits.
-
-=head3 E<gt>E<gt>, E<gt>E<gt>=
-
-X<E<gt> (right angle bracket);E<gt>E<gt> (bitwise right shift);instruction (PIR)>
-X<E<gt> (right angle bracket);E<gt>E<gt>= (bitwise right shift assignment);instruction (PIR)>
-
-  R<DEST> = R<VAL1> E<gt>E<gt> R<VAL2>
-  R<DEST> E<gt>E<gt>= R<VAL2>
-
-Bitwise shift R<VAL1> right by R<VAL2> number of bits.
-
-=head3 E<gt>E<gt>E<gt>, E<gt>E<gt>E<gt>=
-
-X<E<gt> (right angle bracket);E<gt>E<gt>E<gt> (logical right shift) instruction (PIR)>
-X<E<gt> (right angle bracket);E<gt>E<gt>E<gt>= (logical right shift assignment) instruction (PIR)>
-
-  R<DEST> = R<VAL1> E<gt>E<gt>E<gt> R<VAL2>
-  R<DEST> E<gt>E<gt>E<gt>= R<VAL2>
-
-Logically shift R<VAL1> right by R<VAL2> number of bits.
-
-=head3 [  ]
-
-X<[] (brackets);indexed access to PMC (PIR)>
-
-  R<DEST> = R<PMC> [ R<KEY> ]
-  R<PMC> [ R<KEY> ] = R<VAL>
-
-Indexed access to a PMC and indexed assignment to a PMC.
-
-  DEST = STRING [ OFFSET ]
-  STRING [ OFFSET ]  = VAL
-
-Access a one-character substring on a string, starting at a particular
-offset, or assign to that substring.
-
-=head3 call
-
-X<call instruction (PIR)>
-
-  call R<NAME>
-
-Call the named subroutine (a C<.sub> label).
-
-=head3 global
-
-X<global instruction (PIR)>
-
-  R<DEST> = global R<NAME>
-  global R<NAME> = R<VAL>
-
-Access a global variable for read or write.
-
-=head3 goto
-
-X<goto command (PIR)>
-
-  goto R<NAME>
-
-Jump to the named identifier (label or subroutine name).
-
-=head3 if
-
-X<if (conditional);instruction (PIR)>
-
-  if R<EXPR> goto R<NAME>
-
-If the value or expression evaluates as true, jump to the named
-identifier.
-
-=head3 unless
-
-X<unless (conditional);instruction (PIR)>
-
-  unless R<VAL> goto R<NAME>
-
-Unless the value evaluates as true, jump to the named identifier.
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Copied and modified: branches/tt761_keys_revamp/docs/book/draft/README (from r39858, branches/tt761_keys_revamp/docs/book/README)
==============================================================================

Copied and modified: branches/tt761_keys_revamp/docs/book/draft/appa_glossary.pod (from r39858, branches/tt761_keys_revamp/docs/book/appa_glossary.pod)
==============================================================================

Copied and modified: branches/tt761_keys_revamp/docs/book/draft/appb_patch_submission.pod (from r39858, branches/tt761_keys_revamp/docs/book/appb_patch_submission.pod)
==============================================================================

Copied and modified: branches/tt761_keys_revamp/docs/book/draft/appc_command_line_options.pod (from r39858, branches/tt761_keys_revamp/docs/book/appc_command_line_options.pod)
==============================================================================

Copied and modified: branches/tt761_keys_revamp/docs/book/draft/appd_build_options.pod (from r39858, branches/tt761_keys_revamp/docs/book/appd_build_options.pod)
==============================================================================

Copied and modified: branches/tt761_keys_revamp/docs/book/draft/appe_source_code.pod (from r39858, branches/tt761_keys_revamp/docs/book/appe_source_code.pod)
==============================================================================

Copied and modified: branches/tt761_keys_revamp/docs/book/draft/ch01_introduction.pod (from r39858, branches/tt761_keys_revamp/docs/book/ch01_introduction.pod)
==============================================================================

Copied and modified: branches/tt761_keys_revamp/docs/book/draft/ch02_getting_started.pod (from r39858, branches/tt761_keys_revamp/docs/book/ch02_getting_started.pod)
==============================================================================

Copied and modified: branches/tt761_keys_revamp/docs/book/draft/ch04_compiler_tools.pod (from r39858, branches/tt761_keys_revamp/docs/book/ch04_compiler_tools.pod)
==============================================================================

Copied and modified: branches/tt761_keys_revamp/docs/book/draft/ch05_pge.pod (from r39858, branches/tt761_keys_revamp/docs/book/ch05_pge.pod)
==============================================================================

Copied and modified: branches/tt761_keys_revamp/docs/book/draft/ch06_nqp.pod (from r39858, branches/tt761_keys_revamp/docs/book/ch06_nqp.pod)
==============================================================================
--- branches/tt761_keys_revamp/docs/book/ch06_nqp.pod	Wed Jul  1 22:38:36 2009	(r39858, copy source)
+++ branches/tt761_keys_revamp/docs/book/draft/ch06_nqp.pod	Sat Jul  4 21:38:28 2009	(r39884)
@@ -20,7 +20,7 @@
 as well.  It has become a permanent member of PCT, and therefore a permanent
 part of the Parrot code base. 
 
-NQP represets almost the smallest subset of the Perl 6 language necessary to
+NQP represents almost the smallest subset of the Perl 6 language necessary to
 implement parser transformations, plus a few syntactic convenience features
 that developers have requested. NQP's Perl 6 subset shows its Perl 5 roots,
 so existing Perl 5 programmers should find much of it familiar and should be

Copied and modified: branches/tt761_keys_revamp/docs/book/draft/ch07_dynpmcs.pod (from r39858, branches/tt761_keys_revamp/docs/book/ch07_dynpmcs.pod)
==============================================================================

Copied and modified: branches/tt761_keys_revamp/docs/book/draft/ch08_dynops.pod (from r39858, branches/tt761_keys_revamp/docs/book/ch08_dynops.pod)
==============================================================================

Copied and modified: branches/tt761_keys_revamp/docs/book/draft/ch10_opcode_reference.pod (from r39858, branches/tt761_keys_revamp/docs/book/ch10_opcode_reference.pod)
==============================================================================

Copied and modified: branches/tt761_keys_revamp/docs/book/draft/ch11_directive_reference.pod (from r39858, branches/tt761_keys_revamp/docs/book/ch11_directive_reference.pod)
==============================================================================

Copied and modified: branches/tt761_keys_revamp/docs/book/draft/ch12_operator_reference.pod (from r39858, branches/tt761_keys_revamp/docs/book/ch12_operator_reference.pod)
==============================================================================

Added: branches/tt761_keys_revamp/docs/book/pir/ch01_introduction.pod
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/tt761_keys_revamp/docs/book/pir/ch01_introduction.pod	Sat Jul  4 21:38:28 2009	(r39884)
@@ -0,0 +1,114 @@
+=pod
+
+=head1 Introduction
+
+Parrot is a language-neutral virtual machine for dynamic languages such as
+Ruby, Python, PHP, and Perl. It hosts a powerful suite of compiler tools
+tailored to dynamic languages and a next generation regular expression engine.
+Its architecture differs from virtual machines such as the JVM or CLR, with
+optimizations for dynamic languages, the use of registers instead of stacks,
+and pervasive continuations used for all flow control.
+
+The name "Parrot" was inspired by Monty Python's Parrot sketch. As an April
+Fools' Day joke in 2001, Simon Cozens published "Programming Parrot", a
+fictional interview between Guido van Rossum and Larry Wall detailing their
+plans to merge Python and Perl into a new language called Parrot
+(U<http://www.perl.com/pub/a/2001/04/01/parrot.htm>).
+
+Parrot Intermediate Representation (PIR) is Parrot's native low-level language.
+PIR is fundamentally an assembly language, but it has some higher-level
+features such as operator syntax, syntactic sugar for subroutine and method
+calls, automatic register allocation, and more friendly conditional syntax.
+Parrot libraries -- including most of Parrot's compiler tools -- are often
+written in PIR.  Even so, PIR is more rigid and "close to the machine" than
+some higher-level languages like C, which makes it a good window into the inner
+workings of the virtual machine.
+
+=head2 Parrot Resources
+
+X<www.parrot.org website>
+The starting point for all things related to Parrot is the main website
+U<http://www.parrot.org/>. The site lists additional resources, well as recent
+news and information about the project.
+
+The Parrot Foundation holds the copyright over Parrot and helps support its
+development and community.
+
+=head3 Documentation
+
+X<docs.parrot.org website>
+X<online documentation (docs.parrot.org)>
+Parrot includes extensive documentation in the distribution. The full
+documentation for the latest release is available online at
+U<http://docs.parrot.org/>.
+
+=head3 Mailing Lists
+
+X<parrot-dev mailing list>
+X<mailing lists>
+
+The primary mailing list for Parrot is I<parrot-dev>.N<parrot-dev at lists.parrot.org>  If
+you're interested in developing Parrot, the I<parrot-commits> and
+I<parrot-tickets> lists are useful.  More information on the Parrot mailing
+lists, as well as subscription options, is available on the mailing list
+info page 
+U<http://lists.parrot.org/mailman/listinfo>.
+
+The archives for I<parrot-dev> are available on Google Groups at
+U<http://groups.google.com/group/parrot-dev> and as NNTP at
+U<nntp://news.gmane.org/gmane.comp.compilers.parrot.devel>.
+
+=head3 IRC
+
+X<#parrot (IRC channel)>
+X<IRC channel (#parrot)>
+
+Parrot developers and users congregate on IRC at C<#parrot> on the
+U<irc://irc.parrot.org> server. It's a good place to ask questions or discuss
+Parrot in real time.
+
+=head3 Issue Tracking & Wiki
+
+X<trac.parrot.org website>
+X<issue tracking (trac.parrot.org)>
+
+Parrot developers track bugs, feature requests, and roadmap tasks at
+U<https://trac.parrot.org/>, the open source Trac issue tracker. Users
+can submit new tickets and track the status of existing tickets.  The
+site also includes a wiki used in project development, a source code
+browser, and the project roadmap.
+
+=head2 Parrot Development
+
+X<development cycles>
+
+Parrot's first release occurred in September 2001.  The 1.0 release took place
+on March 17, 2009.  2009. The Parrot project makes releases on the third
+Tuesday of each month. Two releases a year E<mdash> occuring every January and
+July E<mdash> are "supported" releases intended for production use.  The other
+ten releases are development releases intended for language implementers and
+testers.
+
+Development proceeds in cycles around releases. Activity just before a release
+focuses on closing tickets, fixing bugs, reviewing documentation, and preparing
+for the release. Immediately after the release, larger changes occur: merging
+branches, adding large features, or removing deprecated features. This allows
+developers to ensure that changes have sufficient testing time before the next
+release.  These regular releases also encourage feedback from casual users and
+testers.
+
+=head2 Licensing
+
+X<license>
+
+The Parrot foundation supports the Parrot development community and holds
+trademarks and copyrights to Parrot.  The project is available under the
+Artistic License 2.0, allowing free use in commercial and open source/free
+software contexts.
+
+=cut
+
+# Local variables:
+#   c-file-style: "parrot"
+# End:
+# vim: expandtab shiftwidth=4:

Added: branches/tt761_keys_revamp/docs/book/pir/ch02_getting_started.pod
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/tt761_keys_revamp/docs/book/pir/ch02_getting_started.pod	Sat Jul  4 21:38:28 2009	(r39884)
@@ -0,0 +1,78 @@
+=pod
+
+=head1 Getting Started
+
+The simplest way to install Parrot is to use a pre-compiled binary for your
+operating system or distribution. Packages are available for many systems,
+including Debian, Ubuntu, Fedora, Mandriva, FreeBSD, Cygwin, and MacPorts. The
+Parrot website lists all known packages.N<U<http://www.parrot.org/download>> A
+binary installer for Windows is also available from the Parrot Win32
+project on SourceForge.N<U<http://parrotwin32.sourceforge.net/>> 
+If packages aren't available on your system, you can download a source
+tarball for the latest supported
+release from U<http://www.parrot.org/release/supported>.
+
+You need a C compiler and a make utility to build Parrot from source code --
+usually C<gcc> and C<make>, but Parrot can build with standard compiler
+toolchains on different operating systems.  Perl 5.8 is also a prerequiste for
+configuring and building Parrot.
+
+X<compiling>
+If you have these dependencies installed, build the core virtual machine and
+compiler toolkit and run the standard test suite with the commands:
+
+  $ perl Configure.pl
+  $ make
+  $ make test
+
+X<installation>
+By default, Parrot installs to directories F<bin/>, F<lib/>, and
+F<include/> under F</usr/local>. If you have privileges to
+write to these directories, install Parrot with:
+
+  $ make install
+
+To install Parrot in a different location, use the C<--prefix> option to
+F<Configure.pl>:
+
+    $ perl Configure.pl --prefix=/home/me/parrot
+
+Setting the prefix to F</home/me/parrot> installs the Parrot executable
+in F</home/me/parrot/bin/parrot>.
+
+If you intend to develop a language on Parrot, install the Parrot
+developer tools as well:
+
+  $ make install-dev
+
+X<.pir files>
+Once you've installed Parrot, create a test file called
+F<news.pir>.N<Files containing PIR code use the F<.pir> extension.>
+
+=begin PIR
+
+  .sub 'news'
+    say "Here is the news for Parrots."
+  .end
+
+=end PIR
+
+Now run this file with:
+
+  $ parrot news.pir
+
+which will print:
+
+  Here is the news for Parrots.
+
+=cut
+
+X<tutorial>
+The Parrot source distribution includes copious examples in its F<examples/>
+directory.  In particular, a PIR tutorial is available in
+F<examples/tutorial/>.
+
+# Local variables:
+#   c-file-style: "parrot"
+# End:
+# vim: expandtab shiftwidth=4:

Added: branches/tt761_keys_revamp/docs/book/pir/ch03_basic_syntax.pod
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/tt761_keys_revamp/docs/book/pir/ch03_basic_syntax.pod	Sat Jul  4 21:38:28 2009	(r39884)
@@ -0,0 +1,314 @@
+=pod
+
+=head1 Basic Syntax
+
+Z<CHP-3>
+
+X<PIR syntax>
+PIR has a relatively simple syntax. Every line is a comment, a label, a
+statement, or a directive. Each statement or directive stands on its own
+line. There is no end-of-line symbol (such as a semicolon in C).
+
+=head2 Comments
+
+X<comments>
+A comment begins with the C<#> symbol, and continues until the end of the line.
+Comments can stand alone on a line or follow a statement or directive.
+
+=begin PIR
+
+    # This is a regular comment. The PIR
+    # interpreter ignores this.
+
+=end PIR
+
+X<Pod documentation>
+PIR also treats inline documentation in Pod format as a comment. An
+equals sign as the first character of a line marks the start of a Pod
+block.  A C<=cut> marker signals the end of a Pod block.
+
+  =head2
+
+  This is Pod documentation, and is treated like a
+  comment. The PIR interpreter ignores this.
+
+  =cut
+
+=head2 Labels
+
+X<labels>
+A label attaches a name to a line of code so other statements can refer to it.
+Labels can contain letters, numbers, and underscores. By convention, labels use
+all capital letters to stand out from the rest of the source code. It's fine to
+put a label on the same line as a statement or directive:
+
+=begin PIR_FRAGMENT
+
+    GREET: say "'Allo, 'allo, 'allo."
+
+=end PIR_FRAGMENT
+
+Labels on separate lines improve readability, especially when outdented:
+
+=begin PIR_FRAGMENT
+
+  GREET:
+    say "'Allo, 'allo, 'allo."
+
+=end PIR_FRAGMENT
+
+=head2 Statements
+
+Z<CHP-3-SECT-1>
+
+X<statements>X<opcodes>
+A statement is either an opcode or syntactic sugar for one or more opcodes. An
+opcode is a native instruction for the virtual machine; it consists of the name
+of the instruction followed by zero or more arguments.
+
+=begin PIR_FRAGMENT
+
+  say "Norwegian Blue"
+
+=end PIR_FRAGMENT
+
+PIR also provides higher-level constructs, including symbolic operators:
+
+=begin PIR_FRAGMENT
+
+  $I1 = 2 + 5
+
+=end PIR_FRAGMENT
+
+X<operators>
+These special statement forms are just syntactic sugar for regular opcodes. The
+C<+> symbol corresponds to the C<add> opcode, the C<-> symbol to the C<sub>
+opcode, and so on. The previous example is equivalent to:
+
+=begin PIR_FRAGMENT
+
+  add $I1, 2, 5
+
+=end PIR_FRAGMENT
+
+=head2 Directives
+
+X<directives>
+Directives resemble opcodes, but they begin with a period (C<.>).  Some
+directives specify actions that occur at compile time. Other directives
+represent complex operations that require the generation of multiple
+instructions.  The C<.local> directive, for example, declares a named variable.
+
+=begin PIR_FRAGMENT
+
+  .local string hello
+
+=end PIR_FRAGMENT
+
+=head2 Literals
+
+X<literals>
+Integers and floating point numbers are numeric literals. They can be positive
+or negative.
+
+=begin PIR_FRAGMENT
+
+  $I0 = 42       # positive
+  $I1 = -1       # negative
+
+=end PIR_FRAGMENT
+
+X<integers>
+Integer literals can also be binary, octal, or hexadecimal:
+
+=begin PIR_FRAGMENT
+
+  $I1 = 0b01010  # binary
+  $I2 = 0o72     # octal
+  $I3 = 0xA5     # hexadecimal
+
+=end PIR_FRAGMENT
+
+X<numbers (floating-point)>
+Floating point number literals have a decimal point and can use scientific
+notation:
+
+=begin PIR_FRAGMENT
+
+  $N0 = 3.14
+  $N2 = -1.2e+4
+
+=end PIR_FRAGMENT
+
+X<strings>
+String literals are enclosed in single or double-quotes.N<See the
+section on L<Strings> in Chapter 4 for an explanation of the differences
+between the quoting types.>
+
+=begin PIR_FRAGMENT
+
+  $S0 = "This is a valid literal string"
+  $S1 = 'This is also a valid literal string'
+
+=end PIR_FRAGMENT
+
+=head2 Variables
+
+X<variables>
+PIR variables can store four different kinds of valuesE<mdash>integers,
+numbers (floating point), strings, and objects. Parrot's objects are
+called PMCs, for "I<P>olyI<M>orphic I<C>ontainer".
+
+The simplest kind of variable is a register variable. The name of a register
+variable always starts with a dollar sign (C<$>), followed by a single
+character which specifies the type of the variable -- integer (C<I>), number
+(C<N>), string (C<S>), or PMC (C<P>) -- and ends with a unique number. You need
+not predeclare register variables:
+
+=begin PIR_FRAGMENT
+
+  $S0 = "Who's a pretty boy, then?"
+  say $S0
+
+=end PIR_FRAGMENT
+
+X<named variables>
+PIR also has named variables; the C<.local>
+directive declares them. As with register variables, there are four valid types:
+C<int>, C<num>, C<string>, and C<pmc>. You I<must> declare named variables; 
+otherwise they behave exactly the same as register variables.
+
+=begin PIR_FRAGMENT
+
+  .local string hello
+  hello = "'Allo, 'allo, 'allo."
+  say hello
+
+=end PIR_FRAGMENT
+
+=head2 Constants
+
+X<constants>
+The C<.const> directive declares a named constant. Named constants are similar
+to named variables, but the values set in the declaration may never change.
+Like C<.local>, C<.const> takes a type and a name. It also requires a literal
+argument to set the value of the constant.
+
+=begin PIR_FRAGMENT
+
+  .const int    frog = 4                       # integer
+  .const string name = "Superintendent Parrot" # string
+  .const num    pi   = 3.14159                 # floating point
+
+=end PIR_FRAGMENT
+
+You may use a named constant anywhere you may use a literal, but you must
+declare the named constant beforehand.  This example declares a named string
+constant C<hello> and prints the value:
+
+=begin PIR_FRAGMENT
+
+  .const string hello = "Hello, Polly."
+  say hello
+
+=end PIR_FRAGMENT
+
+=head2 Keys
+
+X<keys>
+A key is a special kind of constant used for accessing elements in complex
+variables (such as an array). A key is either an integer or a string; and it's
+always enclosed in square brackets (C<[> and C<]>).  You do not have to declare
+literal keys.  This code example stores the string "foo" in $P0 as element 5,
+and then retreives it.
+
+=begin PIR_FRAGMENT
+
+  $P0[5] = "foo"
+  $S1    = $P0[5]
+
+=end PIR_FRAGMENT
+
+PIR supports multi-part keys.  Use a semicolon to separate each part.
+
+=begin PIR_FRAGMENT
+
+  $P0['my';'key'] = 472
+  $I1             = $P0['my';'key']
+
+=end PIR_FRAGMENT
+
+=head2 Control Structures
+
+X<control structures>X<goto instruction>
+Rather than providing a pre-packaged set of control structures like C<if> and
+C<while>, PIR gives you the building blocks to construct your own.N<PIR has
+many advanced features, but at heart it B<is> an assembly language.> The most
+basic of these building blocks is C<goto>, which jumps to a named label.N<This
+is not your father's C<goto>. It can only jump inside a subroutine, and only to
+a named label.> In this code example, the C<say> statement will run immediately
+after the C<goto> statement:
+
+=begin PIR_FRAGMENT
+
+    goto GREET
+      # ... some skipped code ...
+  GREET:
+    say "'Allo, 'allo, 'allo."
+
+=end PIR_FRAGMENT
+
+X<conditional branch>
+Variations on the basic C<goto> check whether a particular condition is
+true or false before jumping:
+
+=begin PIR_FRAGMENT
+
+  if $I0 > 5 goto GREET
+
+=end PIR_FRAGMENT
+
+You can construct any traditional control structure from PIR's built-in control structures.
+
+=head2 Subroutines
+
+X<subroutines>
+A PIR subroutine starts with the C<.sub> directive and ends with the C<.end>
+directive. Parameter declarations use the C<.param> directive; they resemble
+named variable declarations. This example declares a subroutine named
+C<greeting>, that takes a single string parameter named C<hello>:
+
+=begin PIR
+
+  .sub 'greeting'
+      .param string hello
+      say hello
+  .end
+
+=end PIR
+
+=head2 That's All Folks
+
+You now know everything you need to know about PIR. Everything else you
+read or learn about PIR will use one of these fundamental language
+structures. The rest is vocabulary.
+
+=begin sidebar Parrot Assembly Language
+
+Parrot Assembly Language (PASM) is another low-level language native to the
+virtual machine. PASM is a pure assembly language, with none of the syntactic
+sugar that makes PIR friendly for library development.  PASM's primary purpose
+is to act as a plain English reprepresention of the bytecode format. Its
+typical use is for debugging, rather than for writing libraries. Use PIR or a
+higher-level language for development tasks.
+
+PASM files use the F<.pasm> file extension.
+
+=end sidebar
+
+=cut
+
+# Local variables:
+#   c-file-style: "parrot"
+# End:
+# vim: expandtab shiftwidth=4:

Added: branches/tt761_keys_revamp/docs/book/pir/ch04_variables.pod
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/tt761_keys_revamp/docs/book/pir/ch04_variables.pod	Sat Jul  4 21:38:28 2009	(r39884)
@@ -0,0 +1,1826 @@
+=pod
+
+=head1 Variables
+
+Parrot is a register-based virtual machine. It has four typed register sets --
+integers, floating-point numbers, strings, and objects.  All variables in PIR
+are one of these four types. When you work with register variables or named
+variables, you're actually working directly with register storage locations in
+the virtual machine.
+
+If you've ever worked with an assembly language before, you may immediately
+jump to the conclusion that C<$I0> is the zeroth integer register in the
+register set, but Parrot is a bit smarter than that. The number of a register
+variable does not necessarily correspond to the register used internally;
+Parrot's compiler maps registers as appropriate for speed and memory
+considerations. The only guarantee Parrot gives you is that you'll always get
+the same storage location when you use C<$I0> in the same subroutine.
+
+=head2 Assignment
+
+X<assignment>
+X<= operator>
+The most basic operation on a variable is assignment using the C<=>
+operator:
+
+=begin PIR_FRAGMENT
+
+  $I0 = 42        # set integer variable to the value 42
+  $N3 = 3.14159   # set number variable to approximation of pi
+  $I1 = $I0       # set $I1 to the value of $I0
+
+=end PIR_FRAGMENT
+
+X<exchange opcode>
+The C<exchange> opcode swaps the contents of two variables of the same type.
+This example sets C<$I0> to the value of C<$I1> and sets C<$I1> to the value
+of C<$I0>.
+
+=begin PIR_FRAGMENT
+
+  exchange $I0, $I1
+
+=end PIR_FRAGMENT
+
+X<null opcode>
+The C<null> opcode sets an integer or number variable to a zero value,
+and undefines a string or object.
+
+=begin PIR_FRAGMENT
+
+  null $I0  # 0
+  null $N0  # 0.0
+  null $S0  # NULL
+  null $P0  # PMCNULL
+
+=end PIR_FRAGMENT
+
+=head2 Working with Numbers
+
+X<integers>X<numbers (floating-point)>
+PIR has an extensive set of instructions that work with integers,
+floating-point numbers, and numeric PMCs. Many of these instructions
+have a variant that modifies the result in place:
+
+=begin PIR_FRAGMENT
+
+  $I0 = $I1 + $I2
+  $I0 += $I1
+
+=end PIR_FRAGMENT
+
+X<+ operator>
+The first form of C<+> stores the sum of the two arguments in the result
+variable, C<$I0>. The second variant, C<+=>, adds the single argument to
+C<$I0> and stores the sum back in C<$I0>.
+
+The arguments can be Parrot literals, variables, or constants.  If the
+result is an integer type, like C<$I0>, the arguments must also be
+integers. A number result, like C<$N0>, usually requires number
+arguments, but many numeric instructions also allow the final argument to
+be an integer. Instructions with a PMC result may accept an integer,
+floating-point, or PMC final argument:
+
+=begin PIR_FRAGMENT
+
+  $P0 = $P1 * $P2
+  $P0 = $P1 * $I2
+  $P0 = $P1 * $N2
+  $P0 *= $P1
+  $P0 *= $I1
+  $P0 *= $N1
+
+=end PIR_FRAGMENT
+
+=head3 Unary numeric opcodes
+
+X<unary numeric opcodes>
+Unary opcodes have a single argument.  They either return a result or
+modify the argument in place. Some of the most common unary numeric
+opcodes are C<inc> (increment)X<inc opcode>, C<dec> (decrement)X<dec
+opcode>, C<abs> (absolute value)X<abs opcode>, C<neg> (negate)X<neg
+opcode>, and C<fact> (factorial)X<fact opcode>:
+
+=begin PIR_FRAGMENT
+
+  $N0 = abs -5.0  # the absolute value of -5.0 is 5.0
+  $I1 = fact  5   # the factorial of 5 is 120
+  inc $I1         # 120 incremented by 1 is 121
+
+=end PIR_FRAGMENT
+
+=head3 Binary numeric opcodes
+
+X<binary numeric opcodes>
+
+Binary opcodes have two arguments and a result.  Parrot provides
+addition (C<+>X<+ operator> or C<add>X<add opcode>), subtraction
+(C<->X<- operator> or C<sub>X<sub opcode>), multiplication (C<*>X<*
+operator> or C<mul>X<mul opcode>), division (C</>X</ operator> or
+C<div>X<div opcode>), modulus (C<%>X<% operator> or C<mod>X<mod
+opcode>), and exponent (C<pow>X<pow opcode>) opcodes, as well as
+C<gcd>X<gcd opcode> (greatest common divisor) and C<lcm>X<lcm opcode>
+(least common multiple).
+
+=begin PIR_FRAGMENT
+
+  $I0 = 12 / 5
+  $I0 = 12 % 5
+
+=end PIR_FRAGMENT
+
+=head3 Floating-point operations
+
+The most common floating-point operations are C<ln>X<ln opcode> (natural
+log), C<log2>X<log2 opcode> (log base 2), C<log10>X<log10 opcode> (log
+base 10), and C<exp>X<exp opcode> (I<e>G<x>), as well as a full set of
+trigonometric opcodes such as C<sin>X<sin opcode> (sine), C<cos>X<cos
+opcode> (cosine), C<tan>X<tan opcode> (tangent), C<sec>X<sec opcode>
+(secant), C<cosh>X<cosh opcode> (hyperbolic cosine), C<tanh>X<tanh
+opcode> (hyperbolic tangent), C<sech>X<sech opcode> (hyperbolic secant),
+C<asin>X<asin opcode> (arc sine), C<acos>X<acos opcode> (arc cosine),
+C<atan>C<atan opcode> (arc tangent), C<asec>X<asec opcode> (arc secant),
+C<exsec>X<exsec opcode> (exsecant), C<hav>X<hav opcode> (haversine), and
+C<vers>X<vers opcode> (versine).  All angle arguments for the
+X<trigonometric opcodes> trigonometric opcodes are in radians:
+
+=begin PIR_FRAGMENT
+
+  $N0 = sin $N1
+  $N0 = exp 2
+
+=end PIR_FRAGMENT
+
+The majority of the floating-point operations have a single argument and a
+single result. The arguments can generally be either an integer or number, but
+many of these opcodes require the result to be a number.
+
+=head3 Logical and Bitwise Operations
+
+X<logical opcodes>
+The logical opcodes evaluate the truth of their arguments.  They are most
+useful to make decisions for control flow.  Integers and numeric PMCs
+support logical are false if they're 0 and true otherwise. Strings are
+false if they're the empty string or a single character "0", and true
+otherwise. PMCs are true when their C<get_bool>X<get_bool vtable
+function> vtable function returns a nonzero value.
+
+The C<and>X<and opcode> opcode returns the first argument if
+it's false and the second argument otherwise:
+
+=begin PIR_FRAGMENT
+
+  $I0 = and 0, 1  # returns 0
+  $I0 = and 1, 2  # returns 2
+
+=end PIR_FRAGMENT
+
+The C<or>X<or opcode> opcode returns the first argument if
+it's true and the second argument otherwise:
+
+=begin PIR_FRAGMENT
+
+  $I0 = or 1, 0  # returns 1
+  $I0 = or 0, 2  # returns 2
+
+  $P0 = or $P1, $P2
+
+=end PIR_FRAGMENT
+
+Both C<and> and C<or> are short-circuiting ops. If they can determine what
+value to return from the first argument, they'll never evaluate the third.
+This is significant only for PMCs, as they might have side effects on
+evaluation.
+
+The C<xor>X<xor opcode> opcode returns the first argument if it is the only
+true value, returns the second argument if it is the only true value, and
+returns false if both values are true or both are false:
+
+=begin PIR_FRAGMENT
+
+  $I0 = xor 1, 0  # returns 1
+  $I0 = xor 0, 1  # returns 1
+  $I0 = xor 1, 1  # returns 0
+  $I0 = xor 0, 0  # returns 0
+
+=end PIR_FRAGMENT
+
+The C<not>X<not opcode> opcode returns a true value when the argument is false
+and a false value if the argument is true:
+
+=begin PIR_FRAGMENT
+
+  $I0 = not $I1
+  $P0 = not $P1
+
+=end PIR_FRAGMENT
+
+X<bitwise opcodes>
+The bitwise opcodes operate on their values a single bit at a time.
+C<band>X<band opcode>, C<bor>X<bor opcode>, and C<bxor>X<bxor opcode> return a
+value that is the logical AND, OR, or XOR of each bit in the source arguments.
+They each take two arguments.
+
+=begin PIR_FRAGMENT
+
+  $I0 = bor $I1, $I2
+  $P0 = bxor $P1, $I2
+
+=end PIR_FRAGMENT
+
+C<band>, C<bor>, and C<bxor> also have variants that modify the result
+in place.
+
+=begin PIR_FRAGMENT
+
+  $I0 = band $I1
+  $P0 = bor $P1
+
+=end PIR_FRAGMENT
+
+C<bnot>X<bnot opcode> is the logical NOT of each bit in the source argument.
+
+=begin PIR_FRAGMENT
+
+  $I0 = bnot $I1
+
+=end PIR_FRAGMENT
+
+X<shl opcode>
+X<shr opcode>
+X<lsr opcode>
+The logical and arithmetic shift operations shift their values by a specified
+number of bits:
+
+=begin PIR_FRAGMENT
+
+  $I0 = shl $I1, $I2        # shift $I1 left by count $I2
+  $I0 = shr $I1, $I2        # arithmetic shift right
+  $P0 = lsr $P1, $P2        # logical shift right
+
+=end PIR_FRAGMENT
+
+=head2 Working with Strings
+
+X<strings>
+Parrot strings are buffers of variable-sized data. The most common use of
+strings is to store text data. Strings can also hold binary or other
+non-textual data, though this is rare.N<In general, a custom PMC is more
+useful.> Parrot strings are flexible and powerful, to handle the complexity of
+human-readable (and computer-representable) text data.  String operations work
+with string literals, variables, and constants, and with string-like PMCs.
+
+=head3 Escape Sequences
+
+X<string escapes>
+X<escape sequences>
+
+Strings in double-quotes allow escape sequences using backslashes. Strings in
+single-quotes only allow escapes for nested quotes:
+
+  $S0 = "This string is \n on two lines"
+  $S0 = 'This is a \n one-line string with a slash in it'
+
+Table 4.1 shows the escape sequences Parrot supports in double-quoted
+strings.
+
+=begin table String Escapes
+
+=headrow
+
+=row
+
+=cell Escape
+
+=cell Meaning
+
+=bodyrows
+
+=row
+
+=cell C<\a>
+
+=cell An ASCII alarm character
+
+=row
+
+=cell C<\b>
+
+=cell An ASCII backspace character
+
+=row
+
+=cell C<\t>
+
+=cell A tab
+
+=row
+
+=cell C<\n>
+
+=cell A newline
+
+=row
+
+=cell C<\v>
+
+=cell A vertical tab
+
+=row
+
+=cell C<\f>
+
+=cell A form feed
+
+=row
+
+=cell C<\r>
+
+=cell A carriage return
+
+=row
+
+=cell C<\e>
+
+=cell An escape
+
+=row
+
+=cell C<\\>
+
+=cell A backslash
+
+=row
+
+=cell C<\">
+
+=cell A quote
+
+=row
+
+=cell C<\x>R<NN>
+
+=cell A character represented by 1-2 hexadecimal digits
+
+=row
+
+=cell C<\x{>R<NNNNNNNN>C<}>
+
+=cell A character represented by 1-8 hexadecimal digits
+
+=row
+
+=cell C<\o>R<NNN>
+
+=cell A character represented by 1-3 octal digits
+
+=row
+
+=cell C<\u>R<NNNN>
+
+=cell A character represented by 4 hexadecimal digits
+
+=row
+
+=cell C<\U>R<NNNNNNNN>
+
+=cell A character represented by 8 hexadecimal digits
+
+=row
+
+=cell C<\c>R<X>
+
+=cell A control character R<X>
+
+=end table
+
+=head3 Heredocs
+
+X<heredocs>
+If you need more flexibility in defining a string, use a heredoc string
+literal. The C<E<lt>E<lt>> operator starts a heredoc.  The string terminator
+immediately follows. All text until the terminator is part of the string. The
+terminator must appear on its own line, must appear at the beginning of the
+line, and may not have any trailing whitespace.
+
+  $S2 = << "End_Token"
+  This is a multi-line string literal. Notice that
+  it doesn't use quotation marks.
+  End_Token
+
+=head3 Concatenating strings
+
+X<. operator>
+X<strings;concatenation>
+
+Use the C<.> operator to concatenate strings. The following example
+concatenates the string "cd" onto the string "ab" and stores the result in
+C<$S1>.
+
+=begin PIR_FRAGMENT
+
+  $S0 = "ab"
+  $S1 = $S0 . "cd"  # concatenates $S0 with "cd"
+  say $S1           # prints "abcd"
+
+=end PIR_FRAGMENT
+
+X<.= operator>
+Concatenation has a C<.=> variant to modify the result in place. In the
+next example, the C<.=> operation appends "xy" onto the string "abcd" in
+C<$S1>.
+
+=begin PIR_FRAGMENT
+
+  $S1 .= "xy"       # appends "xy" to $S1
+  say $S1           # prints "abcdxy"
+
+=end PIR_FRAGMENT
+
+=head3 Repeating strings
+
+X<repeat opcode>
+The C<repeat> opcode repeats a string a specified number of times:
+
+=begin PIR_FRAGMENT
+
+  $S0 = "a"
+  $S1 = repeat $S0, 5
+  say $S1              # prints "aaaaa"
+
+=end PIR_FRAGMENT
+
+In this example, C<repeat> generates a new string with "a" repeated five
+times and stores it in C<$S1>.
+
+=head3 Length of a string
+
+X<length opcode>
+The C<length> opcode returns the length of a string in characters. This won't
+be the same as the length in I<bytes> for multibyte encoded strings:
+
+=begin PIR_FRAGMENT
+
+  $S0 = "abcd"
+  $I0 = length $S0                # the length is 4
+  say $I0
+
+=end PIR_FRAGMENT
+
+C<length> has no equivalent for PMC strings.
+
+=head3 Substrings
+
+The simplest version of the C<substr>X<substr opcode> opcode takes three
+arguments: a source string, an offset position, and a length. It returns a
+substring of the original string, starting from the offset position (0 is the
+first character) and spanning the length:
+
+=begin PIR_FRAGMENT
+
+  $S0 = substr "abcde", 1, 2        # $S0 is "bc"
+
+=end PIR_FRAGMENT
+
+This example extracts a two-character string from "abcde" at a one-character
+offset from the beginning of the string (starting with the second character).
+It generates a new string, "bc", in the destination register C<$S0>.
+
+When the offset position is negative, it counts backward from the end of the
+string. Thus an offset of -1 starts at the last character of the string.
+
+C<substr> also has a four-argument form, where the fourth argument is a string
+used to replace the substring. This variant modifies the source string and
+returns the removed substring.
+
+This example above replaces the substring "bc" in C<$S1> with the string "XYZ",
+and returns "bc" in C<$S0>:
+
+=begin PIR_FRAGMENT
+
+  $S1 = "abcde"
+  $S0 = substr $S1, 1, 2, "XYZ"
+  say $S0                        # prints "bc"
+  say $S1                        # prints "aXYZde"
+
+=end PIR_FRAGMENT
+
+When the offset position in a replacing C<substr> is one character beyond the
+original string length, C<substr> appends the replacement string just like the
+concatenation operator. If the replacement string is an empty string, the
+opcode removes the characters from the original string.
+
+If you don't need to capture the replaced string, an optimized version of
+C<substr> performs a replace without returning the removed substring:
+
+=begin PIR_FRAGMENT
+
+  $S1 = "abcde"
+  $S1 = substr 1, 2, "XYZ"
+  say $S1                        # prints "aXYZde"
+
+=end PIR_FRAGMENT
+
+=head3 Converting characters
+
+The C<chr>X<chr opcode> opcode takes an integer value and returns the
+corresponding character in the ASCII character set as a one-character string.
+The C<ord>X<ord opcode> opcode takes a single character string and returns the
+integer value of the character at the first position in the string. The integer
+value of the character will differ depending on the current encoding of the
+string:
+
+=begin PIR_FRAGMENT
+
+  $S0 = chr 65              # $S0 is "A"
+  $I0 = ord $S0             # $I0 is 65, if $S0 is ASCII/UTF-8
+
+=end PIR_FRAGMENT
+
+C<ord> has a two-argument variant that takes a character offset to select
+a single character from a multicharacter string. The offset must be within
+the length of the string:
+
+=begin PIR_FRAGMENT
+
+  $I0 = ord "ABC", 2        # $I0 is 67
+
+=end PIR_FRAGMENT
+
+A negative offset counts backward from the end of the string, so -1 is
+the last character.
+
+=begin PIR_FRAGMENT
+
+  $I0 = ord "ABC", -1       # $I0 is 67
+
+=end PIR_FRAGMENT
+
+=head3 Formatting strings
+
+X<strings;formatting>
+
+The C<sprintf>X<sprintf opcode> opcode generates a formatted string from a
+series of values. It takes two arguments: a string specifying the format, and
+an array PMC containing the values to be formatted. The format string and the
+result can be either strings or PMCs:
+
+=begin PIR_FRAGMENT
+
+  $S0 = sprintf $S1, $P2
+  $P0 = sprintf $P1, $P2
+
+=end PIR_FRAGMENT
+
+The format string is similar to C's C<sprintf> function with extensions for
+Parrot data types. Each format field in the string starts with a C<%> and ends
+with a character specifying the output format. Table 4.2 lists the available
+output format characters.
+
+=begin table Format characters
+
+=headrow
+
+=row
+
+=cell Format
+
+=cell Meaning
+
+=bodyrows
+
+=row
+
+=cell C<%c>
+
+=cell A single character.
+
+=row
+
+=cell C<%d>
+
+=cell A decimal integer.
+
+=row
+
+=cell C<%i>
+
+=cell A decimal integer.
+
+=row
+
+=cell C<%u>
+
+=cell An unsigned integer.
+
+=row
+
+=cell C<%o>
+
+=cell An octal integer.
+
+=row
+
+=cell C<%x>
+
+=cell A hex integer, preceded by 0x (when # is specified).
+
+=row
+
+=cell C<%X>
+
+=cell A hex integer with a capital X (when # is specified).
+
+=row
+
+=cell C<%b>
+
+=cell A binary integer, preceded by 0b (when # is specified).
+
+=row
+
+=cell C<%B>
+
+=cell A binary integer with a capital B (when # is specified).
+
+=row
+
+=cell C<%p>
+
+=cell A pointer address in hex.
+
+=row
+
+=cell C<%f>
+
+=cell A floating-point number.
+
+=row
+
+=cell C<%e>
+
+=cell A floating-point number in scientific notation (displayed with a
+lowercase "e").
+
+=row
+
+=cell C<%E>
+
+=cell The same as C<%e>, but displayed with an uppercase E.
+
+=row
+
+=cell C<%g>
+
+=cell The same as C<%e> or C<%f>, whichever fits best.
+
+=row
+
+=cell C<%G>
+
+=cell The same as C<%g>, but displayed with an uppercase E.
+
+=row
+
+=cell C<%s>
+
+=cell A string.
+
+=end table
+
+Each format field supports several specifier options: R<flags>, R<width>,
+R<precision>, and R<size>.  Table 4.3 lists the format flags.
+
+=begin table Format flags
+
+=headrow
+
+=row
+
+=cell Flag
+
+=cell Meaning
+
+=bodyrows
+
+=row
+
+=cell 0
+
+=cell Pad with zeros.
+
+=row
+
+=cell E<lt>spaceE<gt>
+
+=cell Pad with spaces.
+
+=row
+
+=cell C<+>
+
+=cell Prefix numbers with a sign.
+
+=row
+
+=cell C<->
+
+=cell Align left.
+
+=row
+
+=cell C<#>
+
+=cell Prefix a leading 0 for octal, 0x for hex, or force a decimal point.
+
+=end table
+
+The R<width> is a number defining the minimum width of the output from
+a field. The R<precision> is the maximum width for strings or
+integers, and the number of decimal places for floating-point fields.
+If either R<width> or R<precision> is an asterisk (C<*>), it takes its
+value from the next argument in the PMC.
+
+The R<size> modifier defines the type of the argument the field takes.
+Table 4.4 lists the size flags. The values in the aggregate PMC must
+have a type compatible with the specified R<size>.
+
+=begin table Size flags
+
+=headrow
+
+=row
+
+=cell Character
+
+=cell Meaning
+
+=bodyrows
+
+=row
+
+=cell C<h>
+
+=cell short integer or single-precision float
+
+=row
+
+=cell C<l>
+
+=cell long
+
+=row
+
+=cell C<H>
+
+=cell huge value (long long or long double)
+
+=row
+
+=cell C<v>
+
+=cell Parrot INTVAL or FLOATVAL
+
+=row
+
+=cell C<O>
+
+=cell opcode_t pointer
+
+=row
+
+=cell C<P>
+
+=cell C<PMC>
+
+=row
+
+=cell C<S>
+
+=cell String
+
+=end table
+
+
+=begin PIR_FRAGMENT
+
+  $S0 = sprintf "int %#Px num %+2.3Pf\n", $P2
+  say $S0       # prints "int 0x2a num +10.000"
+
+=end PIR_FRAGMENT
+
+The format string of this C<sprintf> example has two format fields. The first,
+C<%#Px>, extracts a PMC argument (C<P>) from the aggregate C<$P2> and formats
+it as a hexadecimal integer (C<x>) with a leading 0x (C<#>). The second format
+field, C<%+2.3Pf>, takes a PMC argument (C<P>) and formats it as a
+floating-point number (C<f>) with a minimum of two whole digits and a maximum
+of three decimal places (C<2.3>) and a leading sign (C<+>).
+
+
+The test files F<t/op/string.t> and F<t/op/sprintf.t> have many more
+examples of format strings.
+
+=head3 Joining strings
+
+The C<join>X<join opcode> opcode joins the elements of an array PMC into
+a single string. The first argument separates the individual elements of
+the PMC in the final string result.
+
+=begin PIR_FRAGMENT
+
+  $P0 = new "Array"
+  push $P0, "hi"
+  push $P0, 0
+  push $P0, 1
+  push $P0, 0
+  push $P0, "parrot"
+  $S0 = join "__", $P0
+  say $S0                # prints "hi__0__1__0__parrot"
+
+=end PIR_FRAGMENT
+
+This example builds a C<Array> in C<$P0> with the values C<"hi">, C<0>, C<1>,
+C<0>, and C<"parrot">. It then joins those values (separated by the string
+C<"__">) into a single string stored in C<$S0>.
+
+=head3 Splitting strings
+
+Splitting a string yields a new array containing the resulting substrings of
+the original string.
+
+This example splits the string "abc" into individual characters and stores them
+in an array in C<$P0>. It then prints out the first and third elements of the
+array.
+
+=begin PIR_FRAGMENT
+
+  $P0 = split "", "abc"
+  $P1 = $P0[0]
+  say $P1                # 'a'
+  $P1 = $P0[2]
+  say $P1                # 'c'
+
+=end PIR_FRAGMENT
+
+=head3 Testing for substrings
+
+The C<index>X<index opcode> opcode searches for a substring
+within a string. If it finds the substring, it returns the position
+where the substring was found as a character offset from the beginning
+of the string. If it fails to find the substring, it returns -1:
+
+=begin PIR_FRAGMENT
+
+  $I0 = index "Beeblebrox", "eb"
+  say $I0                           # prints 2
+  $I0 = index "Beeblebrox", "Ford"
+  say $I0                           # prints -1
+
+=end PIR_FRAGMENT
+
+C<index> also has a three-argument version, where the final argument
+defines an offset position for starting the search.
+
+=begin PIR_FRAGMENT
+
+  $I0 = index "Beeblebrox", "eb", 3
+  say $I0                           # prints 5
+
+=end PIR_FRAGMENT
+
+This example finds the second "eb" in "Beeblebrox" instead of the first,
+because the search skips the first three characters in the string.
+
+=head3 Bitwise Operations
+
+The numeric bitwise opcodes also have string variants for AND, OR, and XOR:
+C<bors>X<bors opcode>, C<bands>X<bands opcode>, and C<bxors>X<bxors opcode>.
+These take string or string-like PMC arguments and perform the logical
+operation on each byte of the strings to produce the result string.
+
+=begin PIR_FRAGMENT
+
+  $S0 = bors $S1
+  $P0 = bands $P1
+  $S0 = bors $S1, $S2
+  $P0 = bxors $P1, $S2
+
+=end PIR_FRAGMENT
+
+The bitwise string opcodes produce meaningful results only when used with
+simple ASCII strings, because Parrot performs bitwise operations per byte.
+
+=head3 Copy-On-Write
+
+Strings use copy-on-write (COW)X<copy-on-write>X<COW (copy-on-write)>
+optimizations. A call to C<$S1 = $S0> doesn't immediately make a copy of
+C<$S0>, it only makes both variables point to the same string. Parrot
+doesn't make a copy of the string until one of two strings is modified.
+
+=begin PIR_FRAGMENT
+
+  $S0 = "Ford"
+  $S1 = $S0
+  $S1 = "Zaphod"
+  say $S0                # prints "Ford"
+  say $S1                # prints "Zaphod"
+
+=end PIR_FRAGMENT
+
+Modifying one of the two variables causes Parrot to create a new string.  This
+example preserves the existing value in C<$S0> and assigns the new value to the
+new string in C<$S1>. The benefit of copy-on-write is avoiding the cost of
+copying strings until the copies are necessary.
+
+=head3 Encodings and Charsets
+
+X<charset>
+X<ASCII character set>
+X<encoding>
+Years ago, strings only needed to support the ASCII character set (or
+charset), a mapping of 128 bit patterns to symbols and English-language
+characters. This worked as long as everyone using a computer read and
+wrote English and only used a small handful of punctuation symbols. In
+other words, it was woefully insufficient. A modern string system must
+manage charsets in order to make sense out of all the string data in the
+world. A modern string system must also handle different encodings --
+ways to represent various charsets in memory and on disk.
+
+Every string in Parrot has an associated encoding and character set. The default
+charset is 8-bit ASCII, which is almost universally supported.  Double-quoted
+string constants can have an optional prefix specifying the string's encoding
+and charset.N<As you might suspect, single-quoted strings do not support this.>
+Parrot tracks information about encoding and charset internally, and
+automatically converts strings when necessary to preserve these
+characteristics. Strings constants may have prefixes of the form C<encoding:charset:>.
+
+=begin PIR_FRAGMENT
+
+  $S0 = utf8:unicode:"Hello UTF-8 Unicode World!"
+  $S1 = utf16:unicode:"Hello UTF-16 Unicode World!"
+  $S2 = ascii:"This is 8-bit ASCII"
+  $S3 = binary:"This is raw, unformatted binary data"
+
+=end PIR_FRAGMENT
+
+X<ISO 8859-1 character set>
+X<Latin 1 character set>
+X<UCS-2 encoding>
+X<UTF-8 encoding>
+X<UTF-16 encoding>
+Parrot supports the character sets C<ascii>, C<binary>, C<iso-8859-1>
+(Latin 1), and C<unicode> and the encodings C<fixed_8>, C<ucs2>,
+C<utf8>, and C<utf18>.
+
+The C<binary:> charset treats the string as a buffer of raw unformatted
+binary data. It isn't really a string per se, because binary data
+contains no readable characters. This exists to support libraries which
+manipulate binary data that doesn't easily fit into any other primitive
+data type.
+
+When Parrot operates on two strings (as in concatenation or comparison), they
+must both use the same character set and encoding. Parrot will automatically
+upgrade one or both of the strings to the next highest compatible format as
+necessary. ASCII strings will automatically upgrade to UTF-8 strings if needed,
+and UTF-8 will upgrade to UTF-16.  All of these conversions happen inside
+Parrot, so the programmer doesn't need to worry about the details.
+
+=head2 Working with PMCs
+
+X<Polymorphic Containers (PMCs)>
+X<PMCs (Polymorphic Containers)>
+Polymorphic Containers (PMCs) are the basis for complex data types and
+object-oriented behavior in Parrot. In PIR, any variable that isn't a
+low-level integer, number, or string is a PMC. PMC variables act much
+like the low-level variables, but you have to instantiate a new PMC
+object before you use it. The C<new> opcode creates a new PMC object of
+the specified type.
+
+=begin PIR_FRAGMENT
+
+  $P0 = new 'String'
+  $P0 = "That's a bollard and not a parrot"
+  say $P0
+
+=end PIR_FRAGMENT
+
+This example creates a C<String> object, stores it in the PMC register
+variable C<$P0>, assigns it the value "That's a bollard and not a
+parrot", and prints it.
+
+Every PMC has a type that indicates what data it can store and what
+behavior it supports. The C<typeof>X<typeof opcode> opcode reports the
+type of a PMC.  When the result is a string variable, C<typeof> returns
+the name of the type:
+
+=begin PIR_FRAGMENT
+
+  $P0 = new "String"
+  $S0 = typeof $P0               # $S0 is "String"
+  say $S0                        # prints "String"
+
+=end PIR_FRAGMENT
+
+When the result is a PMC variable, C<typeof> returns the C<Class> PMC
+for that object type.
+
+=head3 Scalars
+
+X<scalar PMCs>
+X<PMCs (Polymorphic Containers);scalar>
+In most of the examples shown so far, PMCs duplicate the behavior of integers,
+numbers, and strings. Parrot provides a set of PMCs for this exact purpose.
+C<Integer>, C<Number>, and C<String> are thin overlays on Parrot's low-level
+integers, numbers, and strings.
+
+A previous example showed a string literal assigned to a PMC variable of type
+C<String>. Direct assignment of a literal to a PMC works for all the low-level
+types and their PMC equivalents:
+
+=begin PIR_FRAGMENT
+
+  $P0 = new 'Integer'
+  $P0 = 5
+
+  $P1 = new 'String'
+  $P1 = "5 birds"
+
+  $P2 = new 'Number'
+  $P2 = 3.14
+
+=end PIR_FRAGMENT
+
+X<boxing>
+
+You may also assign non-constant low-level integer, number, or string registers
+directly to a PMC. The PMC handles the conversion from the low-level type to
+its own internal storage.N<This conversion of a simpler type to a more complex
+type is "boxing".>
+
+=begin PIR_FRAGMENT
+
+  $I0 = 5
+  $P0 = new 'Integer'
+  $P0 = $I0
+
+  $S1 = "5 birds"
+  $P1 = new 'String'
+  $P1 = $S1
+
+  $N2 = 3.14
+  $P2 = new 'Number'
+  $P2 = $N2
+
+=end PIR_FRAGMENT
+
+The C<box> opcode is a handy shortcut to create the appropriate PMC
+object from an integer, number, or string literal or variable.
+
+=begin PIR_FRAGMENT
+
+  $P0 = box 3    # $P0 is an "Integer"
+
+  $P1 = box $S1  # $P1 is a "String"
+
+  $P2 = box 3.14 # $P2 is a "Number"
+
+=end PIR_FRAGMENT
+
+X<unboxing>
+In the reverse situation, when assigning a PMC to an integer, number, or
+string variable, the PMC also has the ability to convert its value to
+the low-level type.N<The reverse of "boxing" is "unboxing".>
+
+=begin PIR_FRAGMENT
+
+  $P0 = box 5
+  $S0 = $P0           # the string "5"
+  $N0 = $P0           # the number 5.0
+  $I0 = $P0           # the integer 5
+
+  $P1 = box "5 birds"
+  $S1 = $P1           # the string "5 birds"
+  $I1 = $P1           # the integer 5
+  $N1 = $P1           # the number 5.0
+
+  $P2 = box 3.14
+  $S2 = $P2           # the string "3.14"
+  $I2 = $P2           # the integer 3
+  $N2 = $P2           # the number 3.14
+
+=end PIR_FRAGMENT
+
+This example creates C<Integer>X<Integer PMC>, C<Number>X<Number PMC>,
+and C<String>X<String PMC> PMCs, and shows the effect of assigning each
+one back to a low-level type.
+
+Converting a string to an integer or number only makes sense when the contents
+of the string are a number. The C<String> PMC will attempt to extract a number
+from the beginning of the string, but otherwise will return a false value.
+
+=begin sidebar Type Conversions
+
+X<type conversions>
+Parrot also handles conversions between the low-level types where
+possible, converting integers to strings (C<$S0 = $I1>),
+numbers to strings (C<$S0 = $N1>), numbers to integers (C<$I0 = $N1>),
+integers to numbers (C<$N0 = $I1>), and even strings to integers or
+numbers (C<$I0 = $S1> and C<$N0 = $S1>).
+
+=end sidebar
+
+=head3 Aggregates
+
+X<aggregate PMCs>
+X<PMCs (Polymorphic Containers);aggregate>
+PMCs can define complex types that hold multiple values, commonly called
+aggregates. Two basic aggregate types are ordered arrays and associative
+arrays. The primary difference between these is that ordered arrays use integer
+keys for indexes and associative arrays use string keys.
+
+Aggregate PMCs support the use of numeric or string keys.  PIR also offers a
+extensive set of operations for manipulating aggregate data types.
+
+=head4 Ordered Arrays
+
+X<arrays>
+X<ordered arrays>
+Parrot provides several ordered array PMCs, differentiated by whether
+the array should store booleans, integers, numbers, strings, or other
+PMCs, and whether the array should maintain a fixed size or dynamically
+resize for the number of elements it stores.
+
+The core array types are C<FixedPMCArray>, C<ResizablePMCArray>,
+C<FixedIntegerArray>, C<ResizableIntegerArray>, C<FixedFloatArray>,
+C<ResizableFloatArray>, C<FixedStringArray>, C<ResizableStringArray>,
+C<FixedBooleanArray>, and C<ResizableBooleanArray>. The array
+types that start with "Fixed" have a fixed size and do not allow
+elements to be added outside their allocated size. The "Resizable"
+variants automatically extend themselves as more elements are
+added.N<With some additional overhead for checking array bounds and
+reallocating array memory.> The array types that include "String",
+"Integer", or "Boolean" in the name use alternate packing methods for
+greater memory efficiency.
+
+Parrot's core ordered array PMCs all have zero-based integer keys. Extracting
+or inserting an element into the array uses PIR's standard key syntax, with the
+key in square brackets after the variable name. An lvalue key sets the value
+for that key.  An rvalue key extracts the value for that key in the aggregate
+to use as the argument value:
+
+=begin PIR_FRAGMENT
+
+  $P0    = new "ResizablePMCArray" # create a new array object
+  $P0[0] = 10                      # set first element to 10
+  $P0[1] = $I31                    # set second element to $I31
+  $I0    = $P0[0]                  # get the first element
+
+=end PIR_FRAGMENT
+
+Setting the array to an integer value directly (without a key) sets the number
+of elements of the array.  Assigning an array directly to an integer retrieves
+the number of elements of the array.
+
+=begin PIR_FRAGMENT
+
+  $P0 = 2    # set array size
+  $I1 = $P0  # get array size
+
+=end PIR_FRAGMENT
+
+This is equivalent to using the C<elements> opcode to retrieve the number of
+items currently in an array:
+
+=begin PIR_FRAGMENT
+
+  elements $I0, $P0 # get element count
+
+=end PIR_FRAGMENT
+
+Some other useful instructions for working with ordered arrays are
+C<push>, C<pop>, C<shift>, and C<unshift>, to add or remove elements.
+C<push> and C<pop> work on the end of the array, the highest numbered
+index. C<shift> and C<unshift> work on the start of the array, adding or
+removing the zeroth element, and renumbering all the following elements.
+
+=begin PIR_FRAGMENT
+
+  push $P0, 'banana' # add to end
+  $S0 = pop $P0      # fetch from end
+
+  unshift $P0, 74    # add to start
+  $I0 = shift $P0    # fetch from start
+
+=end PIR_FRAGMENT
+
+=head4 Associative Arrays
+
+X<associative arrays>
+X<hashes>
+X<dictionaries>
+An associative array is an unordered aggregate that uses string keys to
+identify elements.  You may know them as "hash tables", "hashes", "maps", or
+"dictionaries". Parrot provides one core associative array PMC, called C<Hash>.
+String keys work very much like integer keys.  An lvalue key sets the value of
+an element, and an rvalue key extracts the value of an element. The string in
+the key must always be in single or double quotes.
+
+=begin PIR_FRAGMENT
+
+  new $P1, "Hash"          # create a new associative array
+  $P1["key"] = 10          # set key and value
+  $I0        = $P1["key"]  # get value for key
+
+=end PIR_FRAGMENT
+
+Assigning a C<Hash>X<Hash PMC> PMC (without a key) to an integer result
+fetches the number of elements in the hash.N<You may not set a C<Hash>
+PMC directly to an integer value.>
+
+=begin PIR_FRAGMENT
+
+  $I1 = $P1         # number of entries
+
+=end PIR_FRAGMENT
+
+The C<exists>X<exists opcode> opcode tests whether a keyed value exists in an
+aggregate. It returns 1 if it finds the key in the aggregate and 0 otherwise.
+It doesn't care if the value itself is true or false, only that an entry exists
+for that key:
+
+=begin PIR_FRAGMENT
+
+  new $P0, "Hash"
+  $P0["key"] = 0
+  exists $I0, $P0["key"] # does a value exist at "key"?
+  say $I0                # prints 1
+
+=end PIR_FRAGMENT
+
+The C<delete>X<delete opcode> opcode removes an element from an associative
+array:
+
+=begin PIR_FRAGMENT
+
+  delete $P0["key"]
+
+=end PIR_FRAGMENT
+
+=head4 Iterators
+
+X<iterators>
+X<PMCs (Polymorphic Containers); iterators>
+An iterator extracts values from an aggregate PMC one at a time.  Iterators are
+most useful in loops which perform an action on every element in an aggregate.
+The C<iter> opcode creates a new iterator from an aggregate PMC. It takes one
+argument, the PMC over which to iterate:
+
+=begin PIR_FRAGMENT
+
+  $P1 = iter $P2
+
+=end PIR_FRAGMENT
+
+Alternatively, you can also create an iterator by creating a new
+C<Iterator>X<Iterator PMC> PMC, passing the aggregate PMC as an
+initialization parameter to C<new>:
+
+=begin PIR_FRAGMENT
+
+  $P1 = new "Iterator", $P2
+
+=end PIR_FRAGMENT
+
+The C<shift>X<shift opcode> opcode extracts the next value from the iterator.
+
+=begin PIR_FRAGMENT
+
+      $P5 = shift $P1
+
+=end PIR_FRAGMENT
+
+Evaluating the iterator PMC as a boolean returns whether the iterator has
+reached the end of the aggregate:
+
+=begin PIR_FRAGMENT
+
+      if $P1 goto iter_repeat
+
+=end PIR_FRAGMENT
+
+Parrot provides predefined constants for working with iterators.
+C<.ITERATE_FROM_START> and C<.ITERATE_FROM_END> constants select whether an
+ordered array iterator starts from the beginning or end of the array.  These
+two constants have no effect on associative array iterators, as their elements
+are unordered.
+
+Load the iterator constants with the C<.include>X<.include directive>
+directive to include the file F<iterator.pasm>. To use them, set the
+iterator PMC to the value of the constant:
+
+=begin PIR_FRAGMENT
+
+      .include "iterator.pasm"
+
+      # ...
+
+      $P1 = .ITERATE_FROM_START
+
+=end PIR_FRAGMENT
+
+With all of those separate pieces in one place, this example loads the iterator
+constants, creates an ordered array of "a", "b", "c", creates an iterator from
+that array, and then loops over the iterator using a conditional C<goto> to
+checks the boolean value of the iterator and another unconditional C<goto>:
+
+=begin PIR_FRAGMENT
+
+      .include "iterator.pasm"
+      $P2 = new "ResizablePMCArray"
+      push $P2, "a"
+      push $P2, "b"
+      push $P2, "c"
+
+      $P1 = iter $P2
+      $P1 = .ITERATE_FROM_START
+
+  iter_loop:
+      unless $P1 goto iter_end
+      $P5 = shift $P1
+      say $P5                        # prints "a", "b", "c"
+      goto iter_loop
+  iter_end:
+
+=end PIR_FRAGMENT
+
+Associative array iterators work similarly to ordered array iterators.  When
+iterating over associative arrays, the C<shift> opcode extracts keys instead of
+values. The key looks up the value in the original hash PMC.
+
+=begin PIR_FRAGMENT
+
+      $P2      = new "Hash"
+      $P2["a"] = 10
+      $P2["b"] = 20
+      $P2["c"] = 30
+
+      $P1      = iter $P2
+
+  iter_loop:
+      unless $P1 goto iter_end
+      $S5 = shift $P1          # the key "a", "b", or "c"
+      $I9 = $P2[$S5]           # the value 10, 20, or 30
+      say $I9
+      goto iter_loop
+  iter_end:
+
+=end PIR_FRAGMENT
+
+This example creates an associative array C<$P2> that contains three
+keys "a", "b", and "c", assigning them the values 10, 20, and 30. It
+creates an iterator (C<$P1>) from the associative array using the
+C<iter> opcode, and then starts a loop over the iterator. At the start
+of each loop, the C<unless> instruction checks whether the iterator has
+any more elements. If there are no more elements, C<goto> jumps to the
+end of the loop, marked by the label C<iter_end>. If there are more
+elements, the C<shift> opcode extracts the next key. Keyed assignment
+stores the integer value of the element indexed by the key in C<$I9>.
+After printing the integer value, C<goto> jumps back to the start of the
+loop, marked by C<iter_loop>.
+
+=head4 Multi-level Keys
+
+X<keys>
+X<multi-level keys>
+Aggregates can hold any data type, including other aggregates.
+Accessing elements deep within nested data structures is a common
+operation, so PIR provides a way to do it in a single instruction.
+Complex keys specify a series of nested data structures, with each
+individual key separated by a semicolon.
+
+=begin PIR_FRAGMENT
+
+  $P0           = new "Hash"
+  $P1           = new "ResizablePMCArray"
+  $P1[2]        = 42
+  $P0["answer"] = $P1
+
+  $I1 = 2
+  $I0 = $P0["answer";$I1]
+  say $I0
+
+=end PIR_FRAGMENT
+
+This example builds up a data structure of an associative array
+containing an ordered array. The complex key C<["answer"; $I1]>
+retrieves an element of the array within the hash. You can also set a
+value using a complex key:
+
+=begin PIR_FRAGMENT
+
+  $P0["answer";0] = 5
+
+=end PIR_FRAGMENT
+
+The individual keys are integer or string literals, or variables with
+integer or string values.
+
+=head3 Copying and Cloning
+
+X<PMCs (Polymorphic Containers); copying vs. cloning>
+PMC registers don't directly store the data for a PMC, they only store a
+pointer to the structure that stores the data. As a result, the C<=>
+operator doesn't copy the entire PMC, it only copies the pointer to the
+PMC data. If you later modify the copy of the variable, it will also
+modify the original.
+
+=begin PIR_FRAGMENT
+
+  $P0 = new "String"
+  $P0 = "Ford"
+  $P1 = $P0
+  $P1 = "Zaphod"
+  say $P0                # prints "Zaphod"
+  say $P1                # prints "Zaphod"
+
+=end PIR_FRAGMENT
+
+In this example, C<$P0> and C<$P1> are both pointers to the same
+internal data structure.  Setting C<$P1> to the string literal
+"Zaphod", it overwrites the previous value "Ford". Both C<$P0> and
+C<$P1> refer to the C<String> PMC "Zaphod".
+
+The C<clone> X<clone opcode> opcode makes a deep copy of a PMC, instead
+of copying the pointer like C<=>X<= operator> does.
+
+=begin PIR_FRAGMENT
+
+  $P0 = new "String"
+  $P0 = "Ford"
+  $P1 = clone $P0
+  $P0 = "Zaphod"
+  say $P0        # prints "Zaphod"
+  say $P1        # prints "Ford"
+
+=end PIR_FRAGMENT
+
+This example creates an identical, independent clone of the PMC in
+C<$P0> and puts it in C<$P1>. Later changes to C<$P0> have no effect on
+the PMC in C<$P1>.N<With low-level strings, the copies created by
+C<clone> are copy-on-writeX<copy-on-write> exactly the same as the copy
+created by C<=>.>
+
+To assign the I<value> of one PMC to another PMC that already exists, use the
+C<assign>X<assign opcode> opcode:
+
+=begin PIR_FRAGMENT
+
+  $P0 = new "Integer"
+  $P1 = new "Integer"
+  $P0 = 42
+  assign $P1, $P0    # note: $P1 must exist already
+  inc $P0
+  say $P0            # prints 43
+  say $P1            # prints 42
+
+=end PIR_FRAGMENT
+
+This example creates two C<Integer> PMCs, C<$P1> and C<$P2>, and gives the
+first one the value 42. It then uses C<assign> to pass the same integer value
+on to C<$P1>. Though C<$P0> increments, C<$P1> doesn't change. The result for
+C<assign> must have an existing object of the right type in it, because
+C<assign> neither creates a new duplicate object (as does C<clone>) or reuses
+the source object (as does C<=>).
+
+=head3 Properties
+
+X<properties>
+X<PMCs (Polymorphic Containers); properties>
+
+PMCs can have additional values attached to them as "properties" of the
+PMC. Most properties hold extra metadata about the PMC.
+
+The C<setprop>X<setprop opcode> opcode sets the value of a named property on a
+PMC. It takes three arguments: the PMC on which to set a property, the name of
+the property, and a PMC containing the value of the property.
+
+=begin PIR_FRAGMENT
+
+  setprop $P0, "name", $P1
+
+=end PIR_FRAGMENT
+
+The C<getprop>X<getprop opcode> opcode returns the value of a property.  It
+takes two arguments: the name of the property and the PMC from which to
+retrieve the property value.
+
+=begin PIR_FRAGMENT
+
+  $P2 = getprop "name", $P0
+
+=end PIR_FRAGMENT
+
+This example creates a C<String> object in C<$P0> and an C<Integer> object with
+the value 1 in C<$P1>. C<setprop> sets a property named "eric" on the object in
+C<$P0> and gives the property the value of C<$P1>. C<getprop> retrieves the
+value of the property "eric" on C<$P0> and stores it in C<$P2>.
+
+=begin PIR_FRAGMENT
+
+  $P0 = new "String"
+  $P0 = "Half-a-Bee"
+  $P1 = new "Integer"
+  $P1 = 1
+
+  setprop $P0, "eric", $P1  # set a property on $P0
+  $P2 = getprop "eric", $P0 # retrieve a property from $P0
+
+  say $P2                   # prints 1
+
+=end PIR_FRAGMENT
+
+Parrot stores PMC properties in an associative array where the name of the
+property is the key.
+
+C<delprop>X<delprop opcode> deletes a property from a PMC.
+
+=begin PIR_FRAGMENT
+
+  delprop $P1, "constant" # delete property
+
+=end PIR_FRAGMENT
+
+You can fetch a complete hash of all properties on a PMC with
+C<prophash>X<prophash opcode>:
+
+=begin PIR_FRAGMENT
+
+  $P0 = prophash $P1 # set $P0 to the property hash of $P1
+
+=end PIR_FRAGMENT
+
+Fetching the value of a non-existent property returns an C<Undef> PMC.
+
+=head3 Vtable Functions
+
+X<vtable functions>
+You may have noticed that a simple operation sometimes has a different effect
+on different PMCs. Assigning a low-level integer value to a C<Integer> PMC sets
+its integer value of the PMC, but assigning that same integer to an ordered
+array sets the size of the array.
+
+Every PMC defines a standard set of low-level operations called vtable
+functions. When you perform an assignment like:
+
+   $P0 = 5
+
+... Parrot calls the C<set_integer_native> vtable function on the PMC referred
+to by register C<$P0>.
+
+X<polymorphic substitution>
+Parrot has a fixed set of vtable functions, so that any PMC can stand in for
+any other PMC; they're polymorphic.N<Hence the name "Polymorphic Container".>
+Every PMC defines some behavior for every vtable function. The default behavior
+is to throw an exception reporting that the PMC doesn't implement that vtable
+function. The full set of vtable functions for a PMC defines the PMC's basic
+interface, but PMCs may also define methods to extend their behavior beyond the
+vtable set.
+
+=head2 Namespaces
+
+X<namespaces>
+X<global variables>
+Parrot performs operations on variables stored in small register sets local to
+each subroutine. For more complex tasks,N<...and for most high-level languages
+that Parrot supports.> it's also useful to have variables that live beyond the
+scope of a single subroutine. These variables may be global to the entire
+program or restricted to a particular library. Parrot stores long-lived
+variables in a hierarchy of namespaces.
+
+The opcodes C<set_global>X<set_global opcode> and
+C<get_global>X<get_global opcode> store and fetch a variable in a
+namespace:
+
+=begin PIR_FRAGMENT
+
+  $P0 = new "String"
+  $P0 = "buzz, buzz"
+  set_global "bee", $P0
+  # ...
+  $P1 = get_global "bee"
+  say $P1                        # prints "buzz, buzz"
+
+=end PIR_FRAGMENT
+
+The first two statements in this example create a C<String> PMC in
+C<$P0> and assign it a value. In the third statement, C<set_global>
+stores that PMC as the named global variable C<bee>.  At some later
+point in the program, C<get_global> retrieves the global variable by
+name, and stores it in C<$P1> to print.
+
+Namespaces can only store PMC variables.  Parrot boxes all primitive integer,
+number, or string values into the corresponding PMCs before storing them in a
+namespace.
+
+The name of every variable stored in a particular namespace must be
+unique. You can't have store both an C<Integer> PMC and an array PMC
+both named "bee", stored in the same namespace.N<You may wonder why
+anyone would want to do this. We wonder the same thing, but Perl 5 does
+it all the time. The Perl 6 implementation on Parrot includes type
+sigils in the names of the variables it stores in namespaces so each
+name is unique, e.g. C<$bee>, C<@bee>....>
+
+=head3 Namespace Hierarchy
+
+X<hierarchical namespaces>
+X<namespaces; hierarchy>
+
+A single global namespace would be far too limiting for most languages or
+applications. The risk of accidental collisions -- where two libraries try to
+use the same name for some variable -- would be quite high for larger code
+bases. Parrot maintains a collection of namespaces arranged as a tree, with the
+C<parrot> namespace as the root.  Every namespace you declare is a child of the
+C<parrot> namespace (or a child of a child....).
+
+The C<set_global> and C<get_global> opcodes both have alternate forms that take
+a key name to access a variable in a particular namespace within the tree. This
+code example stores a variable as C<bill> in the Duck namespace and retrieves
+it again:
+
+=begin PIR_FRAGMENT
+
+  set_global ["Duck"], "bill", $P0
+  $P1 = get_global ["Duck"], "bill"
+
+=end PIR_FRAGMENT
+
+The key name for the namespace can have multiple levels, which correspond to
+levels in the namespace hierarchy. This example stores a variable as C<bill> in
+the Electric namespace under the General namespace in the hierarchy.
+
+=begin PIR_FRAGMENT
+
+  set_global ["General";"Electric"], "bill", $P0
+  $P1 = get_global ["General";"Electric"], "bill"
+
+=end PIR_FRAGMENT
+
+X<root namespace>
+X<namespaces; root>
+
+The C<set_global> and C<get_global> opcode operate on the currently selected
+namespace. The default top-level namespace is the "root" namespace. The
+C<.namespace>X<.namespace directive> directive allows you to declare any
+namespace for subsequent code.  If you select the General Electric
+namespace, then store or retrieve the C<bill> variable without
+specifying a namespace, you will work with the General Electric bill,
+not the Duck bill.
+
+  .namespace ["General";"Electric"]
+  #...
+  set_global "bill", $P0
+  $P1 = get_global "bill"
+
+Passing an empty key to the C<.namespace> directive resets the selected
+namespace to the root namespace. The brackets are required even when the
+key is empty.
+
+  .namespace [ ]
+
+When you need to be absolutely sure you're working with the root namespace
+regardless of what namespace is currently active, use the
+C<set_root_global>X<set_root_global opcode> and
+C<get_root_global>X<get_root_global opcode> opcodes instead of
+C<set_global> and C<get_global>. This example sets and retrieves the
+variable C<bill> in the Dollar namespace, which is directly under the
+root namespace:
+
+=begin PIR_FRAGMENT
+
+  set_root_global ["Dollar"], "bill", $P0
+  $P1 = get_root_global ["Dollar"], "bill"
+
+=end PIR_FRAGMENT
+
+X<HLL namespaces>
+X<namespaces; hll>
+To prevent further collisions, each high-level language running on
+Parrot operates within its own virtual namespace root. The default
+virtual root is C<parrot>, and the C<.HLL>X<.HLL directive> directive
+(for I<H>igh-I<L>evel I<L>anguage) selects an alternate virtual root for
+a particular high-level language:
+
+  .HLL 'ruby'
+
+The C<set_hll_global>X<set_hll_global opcode> and
+C<get_hll_global>X<get_hll_global opcode> opcodes are like
+C<set_root_global> and C<get_root_global>, except they always operate on
+the virtual root for the currently selected HLL. This example stores and
+retrieves a C<bill> variable in the Euro namespace, under the Dutch HLL
+namespace root:
+
+  .HLL 'Dutch'
+  #...
+  set_hll_global ["Euro"], "bill", $P0
+  $P1 = get_hll_global ["Euro"], "bill"
+
+=head3 NameSpace PMC
+
+X<NameSpace PMC>
+Namespaces are just PMCs. They implement the standard vtable functions
+and a few extra methods. The C<get_namespace>X<get_namespace opcode>
+opcode retrieves the currently selected namespace as a PMC object:
+
+  $P0 = get_namespace
+
+The C<get_root_namespace>X<get_root_namespace opcode> opcode retrieves
+the namespace object for the root namespace.  The
+C<get_hll_namespace>X<get_hll_namespace opcode> opcode retrieves the
+virtual root for the currently selected HLL.
+
+  $P0 = get_root_namespace
+  $P0 = get_hll_namespace
+
+Each of these three opcodes can take a key argument to retrieve a namespace
+under the currenly selected namespace, root namespace, or HLL root namespace:
+
+  $P0 = get_namespace ["Duck"]
+  $P0 = get_root_namespace ["General";"Electric"]
+  $P0 = get_hll_namespace ["Euro"]
+
+Once you have a namespace object you can use it to retrieve variables from the
+namespace instead of using a keyed lookup. This example first looks up the Euro
+namespace in the currently selected HLL, then retrieves the C<bill> variable
+from that namespace:
+
+  $P0 = get_hll_namespace ["Euro"]
+  $P1 = get_global $P0, "bill"
+
+Namespaces also provide a set of methods to provide more complex
+behavior than the standard vtable functions allow. The
+C<get_name>X<get_name method> method returns the name of the namespace
+as a C<ResizableStringArray>:
+
+  $P3 = $P0.'get_name'()
+
+The C<get_parent>X<get_parent method> method retrieves a namespace
+object for the parent namespace that contains this one:
+
+  $P5 = $P0.'get_parent'()
+
+The C<get_class>X<get_class method> method retrieves any Class PMC
+associated with the namespace:
+
+  $P6 = $P0.'get_class'()
+
+The C<add_var>X<add_var method> and C<find_var>X<find_var method>
+methods store and retrieve variables in a namespace in a
+language-neutral way:
+
+  $P0.'add_var'("bee", $P3)
+  $P1 = $P0.'find_var'("bee")
+
+The C<find_namespace>X<find_namespace method> method looks up a
+namespace, just like the C<get_namespace> opcode:
+
+  $P1 = $P0.'find_namespace'("Duck")
+
+The C<add_namespace>C<add_namespace method> method adds a new namespace
+as a child of the namespace object:
+
+  $P0.'add_namespace'($P1)
+
+The C<make_namespace>X<make_namespace method> method looks up a
+namespace as a child of the namespace object and returns it. If the
+requested namespace doesn't exist, C<make_namespace> creates a new one
+and adds it under that name:
+
+  $P1 = $P0.'make_namespace'("Duck")
+
+=head3 Aliasing
+
+X<aliasing>
+Just like regular assignment, the various operations to store a variable in a
+namespace only store a pointer to the PMC. If you modify the local PMC after
+storing in a namespace, those changes will also appear in the stored global. To
+store a true copy of the PMC, C<clone> it before you store it.
+
+Leaving the global variable as an alias for a local variable has its advantages.
+If you retrieve a stored global into a register and modify it:
+
+=begin PIR_FRAGMENT
+
+  $P1 = get_global "feather"
+  inc $P1
+
+=end PIR_FRAGMENT
+
+... you modify the value of the stored global, so you don't need to call
+C<set_global> again.
+
+=cut
+
+# Local variables:
+#   c-file-style: "parrot"
+# End:
+# vim: expandtab shiftwidth=4:

Added: branches/tt761_keys_revamp/docs/book/pir/ch05_control_structures.pod
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/tt761_keys_revamp/docs/book/pir/ch05_control_structures.pod	Sat Jul  4 21:38:28 2009	(r39884)
@@ -0,0 +1,343 @@
+=pod
+
+=head1 Control Structures
+
+The semantics of control structures in high-level languages vary broadly.
+Rather than dictating one particular set of semantics for control structures,
+or attempting to provide multiple implementations of common control structures
+to fit the semantics of all major target languages, PIR provides a simple set
+of conditional and unconditional branch instructions.N<In fact, all control
+structures in all languages ultimately compile down to conditional and
+unconditional branches, so you're just getting a peek into the inner workings
+of your software.>
+
+=head2 Conditionals and Unconditionals
+
+X<goto instruction>
+X<unconditional branch>
+An unconditional branch always jumps to a specified label.  PIR has only
+one unconditional branch instruction, C<goto>. In this example, the
+first C<print> statement never runs because the C<goto> always skips
+over it to the label C<skip_all_that>:
+
+=begin PIR_FRAGMENT
+
+      goto skip_all_that
+      say "never printed"
+
+  skip_all_that:
+      say "after branch"
+
+=end PIR_FRAGMENT
+
+X<conditional branch>
+A conditional branch jumps to a specified label only when a particular
+condition is true. The condition may be as simple as checking the truth of a
+particular variable or as complex as a comparison operation.
+
+In this example, the C<if/goto>X<if instruction> skips to the label
+C<maybe_skip> only if the value stored in C<$I0> is true. If C<$I0> is
+false, it will print "might be printed" and then print "after branch":
+
+=begin PIR_FRAGMENT
+
+      if $I0 goto maybe_skip
+      say "might be printed"
+  maybe_skip:
+      say "after branch"
+
+=end PIR_FRAGMENT
+
+=head3 Boolean Truth
+
+X<boolean truth>
+Parrot's C<if> and C<unless> instructions evaluate a variable as a boolean to
+decide whether to jump. In PIR, an integer is false if it's 0 and true if it's
+any non-zero value. A number is false if it's 0.0 and true otherwise. A string
+is false if it's the empty string (C<"">) or a string containing only a zero
+(C<"0">), and true otherwise. Evaluating a PMC as a boolean calls the vtable
+function C<get_bool>X<get_bool vtable function> to check if it's true or
+false, so each PMC is free to determine what its boolean value should
+be.
+
+=head3 Comparisons
+
+X<comparison operators>
+In addition to a simple check for the truth of a variable, PIR provides a
+collection of comparison operations for conditional branches.  These jump when
+the comparison is true.
+
+This example compares C<$I0> to C<$I1> and jumps to the label C<success>
+if C<$I0> is less than C<$I1>:
+
+=begin PIR_FRAGMENT
+
+      if $I0 < $I1 goto success
+      say "comparison false"
+  success:
+      say "comparison true"
+
+=end PIR_FRAGMENT
+
+The full set of comparison operators in PIR are C<==> (equal), C<!=>
+(not equal), C<E<lt>> (less than), C<E<lt>=> (less than or equal),
+C<E<gt>> (greater than), and C<E<gt>=> (greater than or equal).
+
+=head3 Complex Conditions
+
+PIR disallows nested expressions.  You cannot embed a statement within another
+statement.  If you have a more complex condition than a simple truth test or
+comparison, you must build up your condition with a series of instructions that
+produce a final, single truth value.
+
+This example performs two operations, addition and multiplication, then
+uses C<and>X<and opcode> to check if the results of both operations were
+true.  The C<and> opcode stores a boolean value (0 or 1) in the integer
+variable C<$I2>; the code uses this value in an ordinary truth test:
+
+=begin PIR_FRAGMENT
+
+    $I0 = 4 + 5
+    $I1 = 63 * 0
+    $I2 = and $I0, $I1
+
+    if $I2 goto true
+    say "maybe printed"
+  true:
+
+=end PIR_FRAGMENT
+
+=head2 If/Else Construct
+
+C<if control structure>
+High-level languages often use the keywords I<if> and I<else> for simple
+conditional control structures. These control structures perform an action when
+a condition is true and skip the action when the condition is false. PIR's
+C<if> instruction can build up simple conditionals.
+
+This example checks the truth of the condition C<$I0>. If C<$I0> is true, it
+jumps to the C<do_it> label, and runs the body of the conditional construct. If
+C<$I0> is false, it continues on to the next statement, a C<goto> instruction
+that skips over the body of the conditional to the label C<dont_do_it>:
+
+=begin PIR_FRAGMENT
+
+    if $I0 goto do_it
+    goto dont_do_it
+  do_it:
+    say "in the body of the if"
+  dont_do_it:
+
+=end PIR_FRAGMENT
+
+The control flow of this example may seem backwards.  In a high-level language,
+I<if> often means I<"if the condition is true, run the next few lines of
+code">.  In an assembly language, it's often more straightforward to write
+I<"if the condition is true, B<skip> the next few lines of code">. Because of
+the reversed logic, you may find it easier to build a simple conditional
+construct using the C<unless>X<unless instruction> instruction instead
+of C<if>.
+
+=begin PIR_FRAGMENT
+
+    unless $I0 goto dont_do_it
+    say "in the body of the if"
+  dont_do_it:
+
+=end PIR_FRAGMENT
+
+This example produces the same output as the previous example, but the logic is
+simpler.  When C<$I0> is true, C<unless> does nothing and the body of the
+conditional runs. When C<$I0> is false, C<unless> skips over the body of the
+conditional by jumping to C<dont_do_it>.
+
+C<else control structure>
+An I<if/else> control structure is easier to build using the C<if> instruction
+than C<unless>.  To build an I<if/else>, insert the body of the else right
+after the first C<if> instruction.
+
+This example checks if C<$I0> is true.  If so, it jumps to the label C<true>
+and runs the body of the I<if> construct. If C<$I0> is false, the C<if>
+instruction does nothing, and the code continues to the body of the I<else>
+construct. When the body of the else has finished, the C<goto> jumps to the end
+of the I<if/else> control structure by skipping over the body of the I<if>
+construct:
+
+    if $I0 goto true
+    say "in the body of the else"
+    goto done
+  true:
+    say "in the body of the if"
+  done:
+
+=head2 Switch Construct
+
+X<switch control structure>
+A I<switch> control structure selects one action from a list of possible
+actions by comparing a single variable to a series of values until it finds one
+that matches. The simplest way to achieve this in PIR is with a series of
+C<unless> instructions:
+
+=begin PIR_FRAGMENT
+
+    $S0 = 'a'
+
+  option1:
+    unless $S0 == 'a' goto option2
+    say "matched: a"
+    goto end_of_switch
+
+  option2:
+    unless $S0 == 'b' goto default
+    say "matched: b"
+    goto end_of_switch
+
+  default:
+    say "I don't understand"
+
+  end_of_switch:
+
+=end PIR_FRAGMENT
+
+This example uses C<$S0> as the I<case> of the switch construct. It
+compares that case against the first value C<a>.  If they match, it prints
+the string "matched: a", then jumps to the end of the switch at the
+label C<end_of_switch>. If the first case doesn't match C<a>, the
+C<goto> jumps to the label C<option2> to check the second option.
+The second option compares the case against the value C<b>.  If they
+match, it prints the string "matched: b", then jumps to the end of the
+switch. If the case doesn't match the second option, the C<goto>
+goes on to the default case, prints "I don't understand", and continues
+to the end of the switch.
+
+=head2 Do-While Loop
+
+A I<do-while>X<do-while loop> loop runs the body of the loop once, then
+checks a condition at the end to decide whether to repeat it.  A single
+conditional branch can build this style of loop:
+
+=begin PIR_FRAGMENT
+
+    $I0 = 0                 # counter
+
+  redo:                     # start of loop
+    inc $I0
+    say $I0
+    if $I0 < 10 goto redo   # end of loop
+
+=end PIR_FRAGMENT
+
+This example prints the numbers 1 to 10. The first time through, it executes
+all statements up to the C<if> instruction.  If the condition evaluates as true
+(C<$I0> is less than 10), it jumps to the C<redo> label and runs the loop body
+again. The loop ends when the condition evaluates as false.
+
+Here's a slightly more complex example that calculates the factorial C<5!>:
+
+=begin PIR_FRAGMENT
+
+      .local int product, counter
+
+      product = 1
+      counter = 5
+
+  redo:                         # start of loop
+      product *= counter
+      dec counter
+      if counter > 0 goto redo  # end of loop
+
+      say product
+
+=end PIR_FRAGMENT
+
+Each time through the loop it multiplies C<product> by the current value of the
+C<counter>, decrements the counter, and jumps to the start of the loop. The
+loop ends when C<counter> has counted down to 0.
+
+=head2 While Loop
+
+X<while loop>
+A I<while> loop tests the condition at the start of the loop instead of
+at the end. This style of loop needs a conditional branch combined with
+an unconditional branch.  This example also calculates a factorial, but
+with a I<while> loop:
+
+=begin PIR_FRAGMENT
+
+      .local int product, counter
+      product = 1
+      counter = 5
+
+  redo:                         # start of loop
+      if counter <= 0 goto end_loop
+      product *= counter
+      dec counter
+      goto redo
+  end_loop:                     # end of loop
+
+      say product
+
+=end PIR_FRAGMENT
+
+This code tests the counter C<counter> at the start of the loop to see if it's
+less than or equal to 0, then multiplies the current product by the counter and
+decrements the counter. At the end of the loop, it unconditionally jumps back
+to the start of the loop and tests the condition again.  The loop ends when the
+counter C<counter> reaches 0 and the C<if> jumps to the C<end_loop> label. If
+the counter is a negative number or zero before the loop starts the first time,
+the body of the loop will never execute.
+
+=head2 For Loop
+
+X<for loop>
+A I<for> loop is a counter-controlled loop with three declared components: a
+starting value, a condition to determine when to stop, and an operation to step
+the counter to the next iteration. A I<for> loop in C looks something like:
+
+  for (i = 1; i <= 10; i++) {
+    ...
+  }
+
+where C<i> is the counter, C<i = 1> sets the start value, C<<i <= 10>> checks
+the stop condition, and C<i++> steps to the next iteration.  A I<for> loop in
+PIR requires one conditional branch and two unconditional branches.
+
+=begin PIR_FRAGMENT
+
+  loop_init:
+    .local int counter
+    counter = 1
+
+  loop_test:
+    if counter <= 10 goto loop_body
+    goto loop_end
+
+  loop_body:
+    say counter
+
+  loop_continue:
+    inc counter
+    goto loop_test
+
+  loop_end:
+
+=end PIR_FRAGMENT
+
+The first time through the loop, this example sets the initial value of the
+counter in C<loop_init>. It then goes on to test that the loop condition is met
+in C<loop_test>. If the condition is true (C<counter> is less than or equal to
+10) it jumps to C<loop_body> and executes the body of the loop. If the the
+condition is false, it will jump straight to C<loop_end> and the loop will end.
+The body of the loop prints the current counter then goes on to
+C<loop_continue>, which increments the counter and jumps back up to
+C<loop_test> to continue on to the next iteration. Each iteration through the
+loop tests the condition and increments the counter, ending the loop when the
+condition is false. If the condition is false on the very first iteration, the
+body of the loop will never run.
+
+=cut
+
+# Local variables:
+#   c-file-style: "parrot"
+# End:
+# vim: expandtab shiftwidth=4:

Added: branches/tt761_keys_revamp/docs/book/pir/ch06_subroutines.pod
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/tt761_keys_revamp/docs/book/pir/ch06_subroutines.pod	Sat Jul  4 21:38:28 2009	(r39884)
@@ -0,0 +1,1300 @@
+=pod
+
+=head1 Subroutines
+
+X<subroutines>
+Subroutines in PIR are roughly equivalent to the subroutines or methods
+of a high-level language. They're the most basic building block of code
+reuse in PIR. Each high-level language has different syntax and
+semantics for defining and calling subroutines, so Parrot's subroutines
+need to be flexible enough to handle a broad array of behaviors.
+
+A subroutine declaration starts with the C<.sub>X<.sub directive>
+directive and ends with the C<.end>X<.end directive> directive. This
+example defines a subroutine named C<hello> that prints a string "Hello,
+Polly.":
+
+=begin PIR
+
+  .sub 'hello'
+      say "Hello, Polly."
+  .end
+
+=end PIR
+
+The quotes around the subroutine name are optional as long as the name of the
+subroutine uses only plain alphanumeric ASCII characters.  You must use quotes
+if the subroutine name uses Unicode characters, characters from some other
+character set or encoding, or is otherwise an invalid PIR identifier.
+
+A subroutine call consists of the name of the subroutine to call followed by a
+list of (zero or more) arguments in parentheses.  You may precede the call with
+a list of (zero or more) return values.  This example calls the subroutine
+C<fact> with two arguments and assigns the result to C<$I0>:
+
+  $I0 = 'fact'(count, product)
+
+=head2 Modifiers
+
+X<modifiers>
+X<subroutines; modifiers>
+A modifier is an annotation to a basic subroutine declarationN<or parameter
+declaration> that selects an optional feature. Modifiers all start with a colon
+(C<:>).  A subroutine can have multiple modifiers.
+
+When you execute a PIR file as a program, Parrot normally runs the first
+subroutine it encounters, but you can mark any subroutine as the first
+one to run with the C<:main>X<:main subroutine modifier> modifier:
+
+=begin PIR
+
+  .sub 'first'
+      say "Polly want a cracker?"
+  .end
+
+  .sub 'second' :main
+      say "Hello, Polly."
+  .end
+
+=end PIR
+
+This code prints "Hello, Polly." but not "Polly want a cracker?".  The C<first>
+subroutine is first in the source code, but C<second> has the C<:main> modifier.
+Parrot will never call C<first> in this program. If you remove the C<:main>
+modifier, the code will print "Polly want a cracker?" instead.
+
+The C<:load>X<:load subroutine modifier> modifier tells Parrot to run
+the subroutine when it loads the current file as a library.  The
+C<:init>X<:init subroutine modifier> modifier tells Parrot to run the
+subroutine only when it executes the file as a program (and I<not> as a
+library).  The C<:immediate>X<:immediate subroutine modifier> modifier
+tells Parrot to run the subroutine as soon as it gets compiled. The
+C<:postcomp>X<:postcomp subroutine modifier> modifier also runs the
+subroutine right after compilation, but only if the subroutine was
+declared in the main program file (when I<not> loaded as a library).
+
+By default, Parrot stores all subroutines in the namespace currently
+active at the point of their declaration. The C<:anon>X<:anon subroutine
+modifier> modifier tells Parrot not to store the subroutine in the
+namespace. The C<:nsentry>X:nsentry subroutine modifier> modifier stores
+the subroutine in the currenly active namespace with a different name.
+For example, Parrot will store this subroutine in the current namespace
+as C<bar>, not C<foo>:
+
+=begin PIR
+
+  .sub 'foo' :nsentry('bar')
+    #...
+  .end
+
+=end PIR
+
+Chapter 7 on I<"Classes and Objects"> explains other subroutine modifiers.
+
+=head2 Parameters and Arguments
+
+X<subroutines; parameters>
+X<.param directive>
+The C<.param> directive defines the parameters for the subroutine and
+creates local named variables for them (similar to C<.local>):
+
+=begin PIR_FRAGMENT
+
+  .param int c
+
+=end PIR_FRAGMENT
+
+X<.return directive>
+The C<.return> directive returns control flow to the calling subroutine.  To
+return results, pass them as arguments to C<.return>.
+
+=begin PIR_FRAGMENT
+
+  .return($P0)
+
+=end PIR_FRAGMENT
+
+This example implements the factorial algorithm using two subroutines, C<main>
+and C<fact>:
+
+=begin PIR
+
+  # factorial.pir
+  .sub 'main' :main
+     .local int count
+     .local int product
+     count   = 5
+     product = 1
+
+     $I0 = 'fact'(count, product)
+
+     say $I0
+  .end
+
+  .sub 'fact'
+     .param int c
+     .param int p
+
+  loop:
+     if c <= 1 goto fin
+     p = c * p
+     dec c
+     branch loop
+  fin:
+     .return (p)
+  .end
+
+=end PIR
+
+This example defines two local named variables, C<count> and C<product>,
+and assigns them the values 1 and 5. It calls the C<fact> subroutine
+with both variables as arguments. The C<fact> subroutine uses the
+C<.param> directive to retrieve these parameters and the C<.return>
+directive to return the result.  The final printed result is 120.
+
+=head3 Positional Parameters
+
+X<positional parameters>
+The default way of matching the arguments passed in a subroutine call to
+the parameters defined in the subroutine's declaration is by position.
+If you declare three parameters -- an integer, a number, and a string:
+
+=begin PIR
+
+  .sub 'foo'
+    .param int a
+    .param num b
+    .param string c
+    # ...
+  .end
+
+=end PIR
+
+... then calls to this subroutine must also pass three arguments -- an integer,
+a number, and a string:
+
+=begin PIR_FRAGMENT
+
+  'foo'(32, 5.9, "bar")
+
+=end PIR_FRAGMENT
+
+Parrot will assign each argument to the corresponding parameter in order from
+first to last.  Changing the order of the arguments or leaving one out is an
+error.
+
+=head3 Named Parameters
+
+X<named parameters>
+Named parameters are an alternative to positional parameters. Instead of
+passing parameters by their position in the string, Parrot assigns
+arguments to parameters by their name.  Consequencly you may pass named
+parameters in any order.  Declare named parameters with with the
+C<:named>X<:named parameter modifier> modifier.
+
+This example declares two named parameters in the subroutine C<shoutout>
+-- C<name> and C<years> -- each declared with the C<:named> modifier and
+followed by the name to use when pass arguments. The string name can
+match the parameter name (as with the C<name> parameter), but it can
+also be different (as with the C<years> parameter):
+
+=begin PIR
+
+ .sub 'shoutout'
+    .param string name :named("name")
+    .param string years :named("age")
+    $S0  = "Hello " . name
+    $S1  = "You are " . years
+    $S1 .= " years old"
+    say $S0
+    say $S1
+ .end
+
+=end PIR
+
+Pass named arguments to a subroutine as a series of name/value pairs, with the
+elements of each pair separated by an arrow C<< => >>.
+
+=begin PIR
+
+ .sub 'main' :main
+    'shoutout'("age" => 42, "name" => "Bob")
+ .end
+
+=end PIR
+
+The order of the arguments does not matter:
+
+=begin PIR
+
+ .sub 'main' :main
+    'shoutout'("name" => "Bob", "age" => 42)
+ .end
+
+=end PIR
+
+=head3 Optional Parameters
+
+X<optional parameters>
+Another alternative to the required positional parameters is optional
+parameters.  Some parameters are unnecessary for certain calls.
+Parameters marked with the C<:optional>X<:optional parameter modifier>
+modifier do not produce errors about invalid parameter counts if they
+are not present.  A subroutine with optional parameters should
+gracefully handle the missing argument, either by providing a default
+value or by performing an alternate action that doesn't need that value.
+
+Checking the value of the optional parameter isn't enough to know
+whether the call passed such an argument, because the user might have
+passed a null or false value intentionally. PIR also provides an
+C<:opt_flag>X<:opt_flag parameter modifier> modifier for a boolean check
+whether the caller passed an argument:
+
+=begin PIR_FRAGMENT
+
+  .param string name     :optional
+  .param int    has_name :opt_flag
+
+=end PIR_FRAGMENT
+
+When an integer parameter with the C<:opt_flag> modifier immediately follows an
+C<:optional> parameter, it will be true if the caller passed the argument and
+false otherwise.
+
+This example demonstrates how to provide a default value for an optional
+parameter:
+
+=begin PIR_FRAGMENT
+
+    .param string name     :optional
+    .param int    has_name :opt_flag
+
+    if has_name goto we_have_a_name
+    name = "default value"
+  we_have_a_name:
+
+=end PIR_FRAGMENT
+
+When the C<has_name> parameter is true, the C<if> control statement jumps to
+the C<we_have_a_name> label, leaving the C<name> parameter unmodified. When
+C<has_name> is false (when the caller passed no argument for C<name>) the C<if>
+statement does nothing.  The next line sets the C<name> parameter to a default
+value.
+
+The C<:opt_flag> parameter never takes an argument from the passed-in
+argument list.  It's purely for bookkeeping within the subroutine.
+
+Optional parameters can be positional or named parameters. Optional parameters
+must appear at the end of the list of positional parameters after all the
+required parameters.  An optional parameter must immediately
+precede its C<:opt_flag> parameter whether it's named or positional:
+
+=begin PIR
+
+  .sub 'question'
+    .param int value     :named("answer") :optional
+    .param int has_value :opt_flag
+    #...
+  .end
+
+=end PIR
+
+You can call this subroutine with a named argument or with no argument:
+
+=begin PIR_FRAGMENT
+
+  'question'("answer" => 42)
+  'question'()
+
+=end PIR_FRAGMENT
+
+=head3 Aggregating Parameters
+
+X<aggregating parameters>
+X<:slurpy parameter modifier>
+Another alternative to a sequence of positional parameters is an
+aggregating parameter which bundles a list of arguments into a single
+parameter. The C<:slurpy> modifier creates a single array parameter
+containing all the provided arguments:
+
+=begin PIR_FRAGMENT
+
+  .param pmc args :slurpy
+  $P0 = args[0]           # first argument
+  $P1 = args[1]           # second argument
+
+=end PIR_FRAGMENT
+
+As an aggregating parameter will consume all subsequent parameters, you may use
+an aggregating parameter with other positional parameters only after all other
+positional parameters:
+
+=begin PIR_FRAGMENT
+
+  .param string first
+  .param int second
+  .param pmc the_rest :slurpy
+
+  $P0 = the_rest[0]           # third argument
+  $P1 = the_rest[1]           # fourth argument
+
+=end PIR_FRAGMENT
+
+When you combine C<:named> and C<:slurpy> on a parameter, the result is a
+single associative array containing the named arguments passed into the
+subroutine call:
+
+=begin PIR_FRAGMENT
+
+  .param pmc all_named :slurpy :named
+
+  $P0 = all_named['name']             # 'name' => 'Bob'
+  $P1 = all_named['age']              # 'age'  => 42
+
+=end PIR_FRAGMENT
+
+=head3 Flattening Arguments
+
+X<flattening arguments>
+X<:flat argument modifier>
+A flattening argument breaks up a single argument to fill multiple parameters.
+It's the complement of an aggregating parameter.  The C<:flat> modifier splits
+arguments (and return values) into a flattened list.  Passing an array PMC to a
+subroutine with C<:flat>:
+
+=begin PIR_FRAGMENT
+
+  $P0 = new "ResizablePMCArray"
+  $P0[0] = "Bob"
+  $P0[1] = 42
+  'foo'($P0 :flat)
+
+=end PIR_FRAGMENT
+
+... allows the elements of that array to fill the required parameters:
+
+=begin PIR_FRAGMENT
+
+  .param string name  # Bob
+  .param int age      # 42
+
+=end PIR_FRAGMENT
+
+=head3 Arguments on the Command Line
+
+X<command-line arguments>
+
+Arguments passed to a PIR program on the command line are available to the
+C<:main> subroutine of that program as strings in a C<ResizableStringArray>
+PMC.  If you call a program F<args.pir>, passing it three arguments:
+
+  $ parrot args.pir foo bar baz
+
+... they will be accesible at index 1, 2, and 3 of the PMC parameter.N<Index 0
+is unused.>
+
+=begin PIR
+
+  .sub 'main' :main
+    .param pmc all_args
+    $S1 = all_args[1]   # foo
+    $S2 = all_args[2]   # bar
+    $S3 = all_args[3]   # baz
+    # ...
+  .end
+
+=end PIR
+
+Because C<all_args> is a C<ResizableStringArray> PMC, you can loop over the
+results, access them individually, or even modify them.
+
+=head2 Compiling and Loading Libraries
+
+X<libraries>
+In addition to running PIR files on the command-line, you can also load a
+library of pre-compiled bytecode directly into your PIR source file.  The
+C<load_bytecode>X<load_bytecode opcode> opcode takes a single argument: the
+name of the bytecode file to load. If you create a file named F<foo_file.pir>
+containing a single subroutine:
+
+=begin PIR
+
+  # foo_file.pir
+  .sub 'foo_sub'              # .sub stores a global sub
+     say "in foo_sub"
+  .end
+
+=end PIR
+
+... and compile it to bytecode using the C<-o> command-line switchX<-o
+command-line switch>:
+
+  $ parrot -o foo_file.pbc foo_file.pir
+
+... you can then load the compiled bytecode into F<main.pir> and directly
+call the subroutine defined in F<foo_file.pir>:
+
+=begin PIR
+
+  # main.pir
+  .sub 'main' :main
+    load_bytecode "foo_file.pbc"    # compiled foo_file.pir
+    foo_sub()
+  .end
+
+=end PIR
+
+The C<load_bytecode> opcode also works with source files, as long as Parrot has
+a compiler registered for that type of file:
+
+=begin PIR
+
+  # main2.pir
+  .sub 'main' :main
+    load_bytecode "foo_file.pir"  # PIR source code
+    foo_sub()
+  .end
+
+=end PIR
+
+=head2 Sub PMC
+
+X<Sub PMC>
+Subroutines are a PMC type in Parrot. You can store them in PMC registers and
+manipulate them just as you do with other PMCs.  Parrot stores subroutines in
+namespaces; retrieve them with the C<get_global>X<get_global opcode> opcode:
+
+=begin PIR_FRAGMENT
+
+  $P0 = get_global "my_sub"
+
+=end PIR_FRAGMENT
+
+To find a subroutine in a different namespace, first look up the appropriate
+the namespace object, then use that as the first parameter to C<get_global>:
+
+=begin PIR_FRAGMENT
+
+  $P0 = get_namespace ["My";"Namespace"]
+  $P1 = get_global $P0, "my_sub"
+
+=end PIR_FRAGMENT
+
+You can invoke a Sub object directly:
+
+=begin PIR_FRAGMENT
+
+  $P0(1, 2, 3)
+
+=end PIR_FRAGMENT
+
+You can get or even I<change> its name:
+
+=begin PIR_FRAGMENT
+
+  $S0 = $P0               # Get the current name
+  $P0 = "my_new_sub"      # Set a new name
+
+=end PIR_FRAGMENT
+
+X<inspect opcode>
+You can get a hash of the complete metadata for the subroutine:
+
+=begin PIR_FRAGMENT
+
+  $P1 = inspect $P0
+
+=end PIR_FRAGMENT
+
+... which contains the fields:
+
+=over 4
+
+=item * pos_required
+
+The number of required positional parameters
+
+=item * pos_optional
+
+The number of optional positional parameters
+
+=item * named_required
+
+The number of required named parameters
+
+=item * named_optional
+
+The number of optional named parameters
+
+=item * pos_slurpy
+
+True if the sub has an aggregating parameter for positional args
+
+=item * named_slurpy
+
+True if the sub has an aggregating parameter for named args
+
+=back
+
+Instead of fetching the entire inspection hash, you can also request
+individual pieces of metadata:
+
+=begin PIR_FRAGMENT
+
+  $P0 = inspect $P0, "pos_required"
+
+=end PIR_FRAGMENT
+
+The C<arity>X<arity method> method on the sub object returns the total
+number of defined parameters of all varieties:
+
+=begin PIR_FRAGMENT
+
+  $I0 = $P0.'arity'()
+
+=end PIR_FRAGMENT
+
+The C<get_namespace>X<get_namespace method> method on the sub object
+fetches the namespace PMC which contains the Sub:
+
+=begin PIR_FRAGMENT
+
+  $P1 = $P0.'get_namespace'()
+
+=end PIR_FRAGMENT
+
+=head2 Evaluating a Code String
+
+X<code strings, evaluating>
+One way of producing a code object during a running program is by compiling a
+code string. In this case, it's a X<bytecode segment object> bytecode
+segment object.
+
+The first step is to fetch a compiler object for the target language:
+
+=begin PIR_FRAGMENT
+
+  $P1 = compreg "PIR"
+
+=end PIR_FRAGMENT
+
+Parrot registers a compiler for PIR by default, so it's always
+available. The following example fetches a compiler object for PIR and
+places it in the named variable C<compiler>. It then generates a code
+object from a string by calling C<compiler> as a subroutine and places
+the resulting bytecode segment object into the named variable
+C<generated> and then invokes it as a subroutine:
+
+=begin PIR_FRAGMENT
+
+  .local pmc compiler, generated
+  .local string source
+  source    = ".sub foo\n$S1 = 'in eval'\nprint $S1\n.end"
+  compiler  = compreg "PIR"                
+  generated = compiler(source)
+  generated()
+  say "back again"
+
+=end PIR_FRAGMENT
+
+You can register a compiler or assembler for any language inside the
+Parrot core and use it to compile and invoke code from that language.
+
+In the following example, the C<compreg> opcode registers the
+subroutine-like object C<$P10> as a compiler for the language
+"MyLanguage":
+
+=begin PIR_FRAGMENT
+
+  compreg "MyLanguage", $P10
+
+=end PIR_FRAGMENT
+
+=head2 Lexicals
+
+X<lexical variables>
+X<scope>
+Variables stored in a namespace are global variables.  They're accessible from
+anywhere in the program if you specify the right namespace path. High-level
+languages also have lexical variables which are only accessible from the local
+section of code (or I<scope>) where they appear, or in a section of code
+embedded within that scope.N<A scope is roughly equivalent to a block in
+C.> In PIR, the section of code between a C<.sub> and a C<.end> defines
+a scope for lexical variables.
+
+While Parrot stores global variables in namespaces, it stores lexical variables
+in lexical padsN<Think of a pad like a box to hold a collection of lexical variables.>.
+Each lexical scope has its own pad. The C<store_lex> opcode stores a lexical variable
+in the current pad.  The C<find_lex> opcode retrieves a variable from the current pad:
+
+=begin PIR_FRAGMENT
+
+  $P0 = new "Integer"       # create a variable
+  $P0 = 10                  # assign value to it
+  store_lex "foo", $P0      # store with lexical name "foo"
+  # ...
+  $P1 = find_lex "foo"      # get the lexical "foo" into $P1
+  say $P1                   # prints 10
+
+=end PIR_FRAGMENT
+
+The C<.lex>X<.lex directive> directive defines a local variable that
+follows these scoping rules:
+
+=begin PIR_FRAGMENT
+
+      .local int foo
+      .lex 'foo', foo
+
+=end PIR_FRAGMENT
+
+=head3 LexPad and LexInfo PMCs
+
+X<LexPad PMC>
+X<LexInfo PMC>
+Parrot uses two different PMCs to store information about a subroutine's
+lexical variables: the C<LexPad> PMC and the C<LexInfo> PMC.  Neither of these
+PMC types are usable directly from PIR code; Parrot uses them internally to
+store information about lexical variables.
+
+C<LexInfo> PMCs store information about lexical variables at compile time.
+Parrot generates this read-only information during compilation to represent
+what it knows about lexical variables. Not all subroutines get a C<LexInfo> PMC
+by default; subroutines need to indicate to Parrot that they require a
+C<LexInfo> PMC. One way to do this is with the C<.lex> directive.  Of course,
+the C<.lex> directive only works for languages that know the names of there
+lexical variables at compile time. Languages where this information is not
+available can mark the subroutine with C<:lex> instead.
+
+C<LexPad> PMCs store run-time information about lexical variables.  This
+includes their current values and type information. Parrot creates a new
+C<LexPad> PMC for subs that have a C<LexInfo> PMC already. It does so
+for each invocation of the subroutine, which allows for recursive
+subroutine calls without overwriting lexical variables.
+
+The C<get_lexinfo>X<get_lexinfo method> method on a sub retrieves its
+associated C<LexInfo> PMC:
+
+=begin PIR_FRAGMENT
+
+  $P0 = get_global "MySubroutine"
+  $P1 = $P0.'get_lexinfo'()
+
+=end PIR_FRAGMENT
+
+The C<LexInfo> PMC supports a few introspection operations. The
+C<elements> opcode retrieves the number of elements it contains.  String
+key access operations retrieve entries from the C<LexInfo> PMC as if it
+were an associative array.
+
+=begin PIR_FRAGMENT
+
+  $I0 = elements $P1    # number of lexical variables
+  $P0 = $P1["name"]     # lexical variable "name"
+
+=end PIR_FRAGMENT
+
+There is no easy way to retrieve the current C<LexPad> PMC in a given
+subroutine, but they are of limited use in PIR.
+
+=head3 Nested Scopes
+
+X<nested lexical scopes>
+PIR has no separate syntax for blocks or lexical scopes; subroutines
+define lexical scopes in PIR. Because PIR disallows nested
+C<.sub>/C<.end> declarations, it needs a way to identify which lexical
+scopes are the parents of inner lexical scopes. The C<:outer>X<:outer
+subroutine modifier> modifier declares a subroutine as a nested inner
+lexical scope of another existing subroutine. The modifier takes one
+argument, the name of the outer subroutine:
+
+=begin PIR
+
+  .sub 'foo'
+    # defines lexical variables
+  .end
+
+  .sub 'bar' :outer('foo')
+    # can access foo's lexical variables
+  .end
+
+=end PIR
+
+Sometimes a name alone isn't sufficient to uniquely identify the outer
+subroutine. The C<:subid>X<:subid subroutine modifier> modifier allows
+the outer subroutine to declare a truly unique name usable with
+C<:outer>:
+
+=begin PIR
+
+  .sub 'foo' :subid('barsouter')
+    # defines lexical variables
+  .end
+
+  .sub 'bar' :outer('barsouter')
+    # can access foo's lexical variables
+  .end
+
+=end PIR
+
+The C<get_outer>X<get_outer method> method on a C<Sub> PMC retrieves its
+C<:outer> sub.
+
+=begin PIR_FRAGMENT
+
+  $P1 = $P0.'get_outer'()
+
+=end PIR_FRAGMENT
+
+If there is no C<:outer> sub, this will return a null PMC. The
+C<set_outer> method on a C<Sub> object sets the C<:outer> sub:
+
+=begin PIR_FRAGMENT
+
+  $P0.'set_outer'($P1)
+
+=end PIR_FRAGMENT
+
+=head3 Scope and Visibility
+
+High-level languages such as Perl, Python, and Ruby allow nested scopes,
+or blocks within blocks that have their own lexical variables.  This
+construct is common even in C:
+
+  {
+      int x = 0;
+      int y = 1;
+      {
+          int z = 2;
+          /* x, y, and z are all visible here */
+      }
+
+      /* only x and y are visible here */
+  }
+
+In the inner block, all three variables are visible.  The variable C<z>
+is only visible inside that block. The outer block has no knowledge of
+C<z>.  A naE<iuml>ve translation of this code to PIR might be:
+
+=begin PIR_FRAGMENT
+
+  .param int x
+  .param int y
+  .param int z
+  x = 0
+  y = 1
+  z = 2
+  #...
+
+=end PIR_FRAGMENT
+
+This PIR code is similar, but the handling of the variable C<z> is different:
+C<z> is visible throughout the entire current subroutine.  It was not visible
+throughout the entire C function. A more accurate translation of the C scopes
+uses C<:outer> PIR subroutines instead:
+
+=begin PIR
+
+  .sub 'MyOuter'
+      .local pmc x, y
+      .lex 'x', x
+      .lex 'y', y
+      x = new 'Integer'
+      x = 10
+      'MyInner'()
+      # only x and y are visible here
+      say y                             # prints 20
+  .end
+
+  .sub 'MyInner' :outer('MyOuter')
+      .local pmc x, new_y, z
+      .lex 'z', z
+      find_lex x, 'x'
+      say x                            # prints 10
+      new_y = new 'Integer'
+      new_y = 20
+      store_lex 'y', new_y
+  .end
+
+=end PIR
+
+The C<find_lex> and C<store_lex> opcodes don't just access the value of a
+variable directly in the scope where it's declared, they interact with
+the C<LexPad> PMC to find lexical variables within outer lexical scopes.
+All lexical variables from an outer lexical scope are visible from the
+inner lexical scope.
+
+Note that you can only store PMCs -- not primitive types -- as lexicals.
+
+=head2 Multiple Dispatch
+
+X<multiple dispatch>
+X<subroutines; signatures>
+Multiple dispatch subroutines (or I<multis>) have several variants with the
+same name but different sets of parameters. The set of parameters for a
+subroutine is its I<signature>. When a multi is called, the dispatch operation
+compares the arguments passed in to the signatures of all the variants and
+invokes the subroutine with the best match.
+
+Parrot stores all multiple dispatch subs with the same name in a
+namespace within a single PMC called a C<MultiSub>X<MultiSub PMC>. The
+C<MultiSub> is an invokable list of subroutines. When a multiple
+dispatch sub is called, the C<MultiSub> PMC searches its list of
+variants for the best matching candidate.
+
+The C<:multi>X<:multi subroutine modifier> modifier on a C<.sub>
+declares a C<MultiSub>:
+
+=begin PIR
+
+  .sub 'MyMulti' :multi()
+      # does whatever a MyMulti does
+  .end
+
+=end PIR
+
+Each variant in a C<MultiSub> must have a unique type or number of parameters
+declared, so the dispatcher can calculate a best match. If you had two variants
+that both took four integer parameters, the dispatcher would never be able to
+decide which one to call when it received four integer arguments.
+
+X<multi signature>
+The C<:multi> modifier takes one or more arguments defining the I<multi
+signature>. The multi signature tells Parrot what particular combination
+of input parameters the multi accepts:
+
+=begin PIR
+
+  .sub 'Add' :multi(I, I)
+    .param int x
+    .param int y
+     $I0 = x + y
+    .return($I0)
+  .end
+
+  .sub 'Add' :multi(N, N)
+    .param num x
+    .param num y
+    $N0 = x + y
+    .return($N0)
+  .end
+
+  .sub 'Start' :main
+    $I0 = Add(1, 2)      # 3
+    $N0 = Add(3.14, 2.0) # 5.14
+    $S0 = Add("a", "b")  # ERROR! No (S, S) variant!
+  .end
+
+=end PIR
+
+Multis can take I, N, S, and P types, but they can also use C<_> (underscore)
+to denote a wildcard, and a string which names a PMC type:
+
+=begin PIR
+
+  .sub 'Add' :multi(I, I)          # two integers
+    #...
+  .end
+
+  .sub 'Add' :multi(I, 'Float')    # integer and Float PMC
+    #...
+  .end
+
+  .sub 'Add' :multi('Integer', _)  # Integer PMC and wildcard
+    #...
+  .end
+
+=end PIR
+
+When you call a C<MultiSub>, Parrot will try to take the most specific
+best-match variant, but will fall back to more general variants if it
+cannot find a perfect match.  If you call C<Add> with C<(1, 2)>, Parrot will
+dispatch to the C<(I, I)> variant. If you call it with C<(1, "hi")>, Parrot
+will match the C<(I, _)> variant, as the string in the second argument
+doesn't match C<I> or C<Float>.  Parrot can also promote one of the I,
+N, or S values to an Integer, Float, or String PMC.
+
+X<Manhattan Distance>
+To make the decision about which multi variant to call, Parrot
+calculates the I<Manhattan Distance> between the argument signature and
+the parameter signature of each variant.  Every difference between each
+element counts as one step. A difference can be a promotion from a
+primitive type to a PMC, the conversion from one primitive type to
+another, or the matching of an argument to a C<_> wildcard. After Parrot
+calculates the distance to each variant, it calls the one with the
+lowest distance.  Notice that it's possible to define a variant that is
+impossible to call: for every potential combination of arguments there
+is a better match. This is uncommon, but possible in systems with many
+multis and a limited number of data types.
+
+=head2 Continuations
+
+X<continuations>
+X<subroutines; continuations>
+Continuations are subroutines that take snapshots of control flow. They are
+frozen images of the current execution state of the VM. Once you have a
+continuation, you can invoke it to return to the point where the continuation
+was first created. It's like a magical timewarp that allows the developer to
+arbitrarily move control flow back to any previous point in the program.
+
+Continuations are like any other PMC; create one with the C<new> opcode:
+
+=begin PIR_FRAGMENT
+
+  $P0 = new 'Continuation'
+
+=end PIR_FRAGMENT
+
+The new continuation starts in an undefined state. If you attempt to invoke a
+new continuation without initializing it, Parrot will throw an exception.  To
+prepare the continuation for use, assign it a destination label with the
+C<set_addr>X<set_addr opcode> opcode:
+
+=begin PIR_FRAGMENT
+
+    $P0 = new 'Continuation'
+    set_addr $P0, my_label
+
+  my_label:
+    # ...
+
+=end PIR_FRAGMENT
+
+To jump to the continuation's stored label and return the context to the state
+it was in I<at the point of its creation>, invoke the continuation:
+
+=begin PIR_FRAGMENT
+
+  $P0()
+
+=end PIR_FRAGMENT
+
+Even though you can use the subroutine call notation C<$P0()> to invoke
+the continuation, you cannot pass arguments or obtain return values.
+
+=head3 Continuation Passing Style
+
+X<continuation passing style (CPS)>
+X<CPS (continuation passing style)>
+Parrot uses continuations internally for control flow. When Parrot
+invokes a subroutine, it creates a continuation representing the current
+point in the program.  It passes this continuation as an invisible
+parameter to the subroutine call.  To return from that subroutine, Parrot
+invokes the continuation to return to the point of creation of that
+continuation.  If you have a continuation, you can invoke it to return
+to its point of creation any time you want.
+
+This type of flow control -- invoking continuations instead of
+performing bare jumps -- is called Continuation Passing Style (CPS).
+
+=head3 Tailcalls
+
+Many subroutines set up and call another subroutine and then return the
+result of the second call directly. This is a X<tailcall> tailcall, and is an
+important opportunity for optimization.  Here's a contrived example in
+pseudocode:
+
+  call add_two(5)
+
+  subroutine add_two(value)
+    value = add_one(value)
+    return add_one(value)
+
+In this example, the subroutine C<add_two> makes two calls to C<add_one>. The
+second call to C<add_one> is the return value. C<add_one> gets called; its
+result gets returned to the caller of C<add_two>.  Nothing in C<add_two> uses
+that return value directly.
+
+A simple optimization is available for this type of code.  The second call to
+C<add_one> can return to the same place that C<add_two> returns; it's perfectly
+safe and correct to use the same return continuation that C<add_two> uses. The
+two subroutine calls can share a return continuation.
+
+X<.tailcall directive>
+PIR provides the C<.tailcall> directive to identify similar situations.  Use it
+in place of the C<.return> directive. C<.tailcall> performs this optimization
+by reusing the return continuation of the parent subroutine to make the
+tailcall:
+
+=begin PIR
+
+  .sub 'main' :main
+      .local int value
+      value = add_two(5)
+      say value
+  .end
+
+  .sub 'add_two'
+      .param int value
+      .local int val2
+      val2 = add_one(value)
+      .tailcall add_one(val2)
+  .end
+
+  .sub 'add_one'
+      .param int a
+      .local int b
+      b = a + 1
+      .return (b)
+  .end
+
+=end PIR
+
+This example prints the correct value C<7>.
+
+=head2 Coroutines
+
+X<coroutines>
+X<subroutines; coroutines>
+Coroutines are similar to subroutines except that they have an internal
+notion of I<state>.  In addition to performing a normal C<.return> to
+return control flow back to the caller and destroy the execution
+environment of the subroutine, coroutines may also perform a C<.yield>
+operation.  C<.yield> returns a value to the caller like C<.return> can,
+but it does not destroy the execution state of the coroutine. The next
+call to the coroutine continues execution from the point of the last
+C<.yield>, not at the beginning of the coroutine.
+
+Inside a coroutine continuing from a C<.yield>, the entire execution
+environment is the same as it was when the coroutine C<.yield>ed. This
+means that the parameter values don't change, even if the next
+invocation of the coroutine had different arguments passed in.
+
+Coroutines look like ordinary subroutines. They do not require any
+special modifier or any special syntax to mark them as being a
+coroutine. What sets them apart is the use of the C<.yield>X<.yield
+directive> directive. C<.yield> plays several roles:
+
+=over 4
+
+=item * Identifies coroutines
+
+When Parrot sees a C<.yield>, it knows to create a Coroutine PMC object instead
+of a C<Sub> PMC.
+
+=item * Creates a continuation
+
+C<.yield> creates a continuation in the coroutine and stores the continuation
+object in the coroutine object for later resuming from the point of the
+C<.yield>.
+
+=item * Returns a value
+
+C<.yield> can return a value N<... or many values, or no values.> to the caller.
+It is basically the same as a C<.return> in this regard.
+
+=back
+
+Here is a simple coroutine example:
+
+=begin PIR
+
+  .sub 'MyCoro'
+    .yield(1)
+    .yield(2)
+    .yield(3)
+    .return(4)
+  .end
+
+  .sub 'main' :main
+    $I0 = MyCoro()    # 1
+    $I0 = MyCoro()    # 2
+    $I0 = MyCoro()    # 3
+    $I0 = MyCoro()    # 4
+    $I0 = MyCoro()    # 1
+    $I0 = MyCoro()    # 2
+    $I0 = MyCoro()    # 3
+    $I0 = MyCoro()    # 4
+    $I0 = MyCoro()    # 1
+    $I0 = MyCoro()    # 2
+    $I0 = MyCoro()    # 3
+    $I0 = MyCoro()    # 4
+  .end
+
+=end PIR
+
+This contrived example demonstrates how the coroutine stores its state. When
+Parrot encounters the C<.yield>, the coroutine stores its current execution
+environment.  At the next call to the coroutine, it picks up where it left off.
+
+=head2 Native Call Interface
+
+The X<NCI (native call interface)> Native Call Interface (NCI) is a
+special version of the Parrot calling conventions for calling functions
+in shared C libraries with a known signature.  This is a simplified
+version of the first test in F<t/pmc/nci.t>:
+
+=begin PIR_FRAGMENT
+
+    .local pmc library
+    library = loadlib "libnci_test"         # library object
+    say "loaded"
+
+    .local pmc ddfunc
+    ddfunc = dlfunc library, "nci_dd", "dd" # function object
+    say "dlfunced"
+
+    .local num result
+    result = ddfunc( 4.0 )                  # call the function
+
+    ne result, 8.0, nok_1
+    say "ok 1"
+    end
+  nok_1:
+    say "not ok 1"
+
+    #...
+
+=end PIR_FRAGMENT
+
+This example shows two new opcodes: C<loadlib> and C<dlfunc>. The
+C<loadlib>X<loadlib opcode> opcode obtains a handle for a shared library. It
+searches for the shared library in the current directory, in
+F<runtime/parrot/dynext>, and in a few other configured directories. It also
+tries to load the provided filename unaltered and with appended extensions like
+F<.so> or F<.dll>. Which extensions it tries depends on the operating
+system Parrot is running on.
+
+The C<dlfunc>X<dlfunc opcode> opcode gets a function object from a previously
+loaded library (second argument) of a specified name (third argument) with a
+known function signature (fourth argument). The function signature is a string
+where the first character is the return value and the rest of the parameters
+are the function parameters. Table 6-1 lists the characters used in NCI
+function signatures.
+
+=begin table Function signature letters
+
+Z<CHP-6-TABLE-1>
+
+=headrow
+
+=row
+
+=cell Character
+
+=cell Register
+
+=cell C type
+
+=bodyrows
+
+=row
+
+=cell C<v>
+
+=cell -
+
+=cell void (no return value)
+
+=row
+
+=cell C<c>
+
+=cell C<I>
+
+=cell char
+
+=row
+
+=cell C<s>
+
+=cell C<I>
+
+=cell short
+
+=row
+
+=cell C<i>
+
+=cell C<I>
+
+=cell int
+
+=row
+
+=cell C<l>
+
+=cell C<I>
+
+=cell long
+
+=row
+
+=cell C<f>
+
+=cell C<N>
+
+=cell float
+
+=row
+
+=cell C<d>
+
+=cell C<N>
+
+=cell double
+
+=row
+
+=cell C<t>
+
+=cell C<S>
+
+=cell char *
+
+=row
+
+=cell C<p>
+
+=cell C<P>
+
+=cell void * (or other pointer)
+
+=row
+
+=cell C<I>
+
+=cell -
+
+=cell Parrot_Interp *interpreter
+
+=row
+
+=cell C<C>
+
+=cell -
+
+=cell a callback function pointer
+
+=row
+
+=cell C<D>
+
+=cell -
+
+=cell a callback function pointer
+
+=row
+
+=cell C<Y>
+
+=cell C<P>
+
+=cell the subroutine C<C> or C<D> calls into
+
+=row
+
+=cell C<Z>
+
+=cell C<P>
+
+=cell the argument for C<Y>
+
+=end table
+
+=cut
+
+# Local variables:
+#   c-file-style: "parrot"
+# End:
+# vim: expandtab shiftwidth=4:

Added: branches/tt761_keys_revamp/docs/book/pir/ch07_objects.pod
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/tt761_keys_revamp/docs/book/pir/ch07_objects.pod	Sat Jul  4 21:38:28 2009	(r39884)
@@ -0,0 +1,450 @@
+=pod
+
+=head1 Classes and Objects
+
+Many of Parrot's core classes -- such as C<Integer>, C<String>, or
+C<ResizablePMCArray> -- are written in C, but you can also write your
+own classes in PIR.  PIR doesn't have the shiny syntax of high-level
+object-oriented languages, but it provides the necessary features to
+construct well-behaved objects every bit as powerful as those of
+high-level object systems.
+
+X<objects>
+Parrot developers often use the word "PMCs" to refer to the objects defined in
+C classes and "objects" to refer to the objects defined in PIR. In truth, all
+PMCs are objects and all objects are PMCs, so the distinction is a community
+tradition with no official meaning.
+
+=head2 Class Declaration
+
+X<classes>
+The C<newclass>X<newclass opcode> opcode defines a new class. It takes a
+single argument, the name of the class to define.
+
+=begin PIR_FRAGMENT
+
+    $P0 = newclass 'Foo'
+
+=end PIR_FRAGMENT
+
+Just as with Parrot's core classes, the C<new>X<new opcode> opcode
+instantiates a new object of a named class.
+
+=begin PIR_FRAGMENT
+
+  $P1 = new 'Foo'
+
+=end PIR_FRAGMENT
+
+In addition to a string name for the class, C<new> can also instantiate
+an object from a class object or from a keyed namespace name.
+
+=begin PIR_FRAGMENT
+
+  $P0 = newclass 'Foo'
+  $P1 = new $P0
+
+  $P2 = new ['Bar';'Baz']
+
+=end PIR_FRAGMENT
+
+=head2 Attributes
+
+X<attributes>
+X<classes;attributes>
+The C<addattribute> opcode defines a named attribute -- or I<instance variable> -- in the class:
+
+=begin PIR_FRAGMENT
+
+  $P0 = newclass 'Foo'
+  addattribute $P0, 'bar'
+
+=end PIR_FRAGMENT
+
+The C<setattribute>X<setattribute> opcode sets the value of a declared
+attribute.  You must declare an attribute before you may set it.  The value of
+an attribute is always a PMC, never an integer, number, or string.N<Though it
+can be an C<Integer>, C<Number>, or C<String> PMC.>
+
+=begin PIR_FRAGMENT
+
+    $P6 = box 42
+    setattribute $P1, 'bar', $P6
+
+=end PIR_FRAGMENT
+
+The C<getattribute>X<getattribute opcode> opcode fetches the value of a
+named attribute. It takes an object and an attribute name as arguments
+and returns the attribute PMC:
+
+=begin PIR_FRAGMENT
+
+    $P10 = getattribute $P1, 'bar'
+
+=end PIR_FRAGMENT
+
+Because PMCs are containers, you may modify an object's attribute by retrieving
+the attribute PMC and modifying its value.  You don't need to call
+C<setattribute> for the change to stick:
+
+=begin PIR_FRAGMENT
+
+    $P10 = getattribute $P1, 'bar'
+    $P10 = 5
+
+=end PIR_FRAGMENT
+
+=head2 Methods
+
+X<methods>
+X<classes;methods>
+X<subroutines;methods>
+Methods in PIR are subroutines stored in the class object. Define a method with
+the C<.sub> directive and the C<:method>X<:method subroutine modifier> modifier:
+
+=begin PIR
+
+  .sub half :method
+    $P0 = getattribute self, 'bar'
+    $P1 = $P0 / 2
+    .return($P1)
+  .end
+
+=end PIR
+
+This method returns the integer value of the C<bar> attribute of the object
+divided by two. Notice that the code never declares the named variable C<self>.
+Methods always make the invocant object -- the object on which the method was
+invoked -- available in a local variable called C<self>X<self variable>.
+
+The C<:method> modifier adds the subroutine to the class object
+associated with the currently selected namespace, so every class
+definition file must contain a C<.namespace>X<.namespace directive>
+declaration. Class files for languages may also contain an C<.HLL>X<.HLL
+directive> declaration to associate the namespace with the appropriate
+high-level language:
+
+=begin PIR
+
+  .HLL 'php'
+  .namespace [ 'Foo' ]
+
+=end PIR
+
+Method calls in PIR use a period (C<.>) to separate the object from the method
+name. The method name is either a literal string in quotes or a string
+variable. The method call looks up the method in the invocant object using the
+string name:
+
+=begin PIR_FRAGMENT
+
+    $P0 = $P1.'half'()
+
+    $S2 = 'double'
+    $P0 = $P1.$S2()
+
+=end PIR_FRAGMENT
+
+You can also pass a method object to the method call instead of looking it up
+by string name:
+
+=begin PIR_FRAGMENT
+
+    $P2 = get_global 'triple'
+    $P0 = $P1.$P2()
+
+=end PIR_FRAGMENT
+
+Parrot always treats a PMC used in the method position as a method object, so
+you can't pass a C<String> PMC as the method name.
+
+Methods can have multiple arguments and multiple return values just like
+subroutines:
+
+=begin PIR_FRAGMENT
+
+  ($P0, $S1) = $P2.'method'($I3, $P4)
+
+=end PIR_FRAGMENT
+
+The C<can>X<can opcode> opcode checks whether an object has a particular
+method. It returns 0 (false) or 1 (true):
+
+=begin PIR_FRAGMENT
+
+    $I0 = can $P3, 'add'
+
+=end PIR_FRAGMENT
+
+=head2 Inheritance
+
+X<inheritance>
+X<classes;inheritance>
+The C<subclass>X<subclass opcode> opcode creates a new class that
+inherits methods and attributes from another class. It takes two
+arguments: the name of the parent class and the name of the new class:
+
+=begin PIR_FRAGMENT
+
+    $P3 = subclass 'Foo', 'Bar'
+
+=end PIR_FRAGMENT
+
+C<subclass> can also take a class object as the parent class instead of
+a class name:
+
+=begin PIR_FRAGMENT
+
+    $P3 = subclass $P2, 'Bar'
+
+=end PIR_FRAGMENT
+
+X<multiple inheritance>
+The C<addparent>X<addparent opcode> opcode also adds a parent class to a
+subclass. This is especially useful for multiple inheritance, as
+the C<subclass> opcode only accepts a single parent class:
+
+=begin PIR_FRAGMENT
+
+  $P4 = newclass 'Baz'
+  addparent $P3, $P4
+  addparent $P3, $P5
+
+=end PIR_FRAGMENT
+
+To override an inherited method in the child class, define a method with the
+same name in the subclass. This example code overrides C<Bar>'s C<who_am_i>
+method to return a more meaningful name:
+
+=begin PIR
+
+  .namespace [ 'Bar' ]
+
+  .sub 'who_am_i' :method
+    .return( 'I am proud to be a Bar' )
+  .end
+
+=end PIR
+
+X<new opcode>
+Object creation for subclasses is the same as for ordinary classes:
+
+=begin PIR_FRAGMENT
+
+    $P5 = new 'Bar'
+
+=end PIR_FRAGMENT
+
+Calls to inherited methods are just like calls to methods defined in
+the class:
+
+=begin PIR_FRAGMENT
+
+    $P1.'increment'()
+
+=end PIR_FRAGMENT
+
+The C<isa> opcode checks whether an object is an instance of or inherits
+from a particular class. It returns 0 (false) or 1 (true):
+
+=begin PIR_FRAGMENT
+
+    $I0 = isa $P3, 'Foo'
+    $I0 = isa $P3, 'Bar'
+
+=end PIR_FRAGMENT
+
+=head2 Overriding Vtable Functions
+
+X<overriding vtable functions>
+X<vtable functions;overriding>
+The C<Object> PMCX<Object PMC> is a core PMC written in C that provides
+basic object-like behavior. Every object instantiated from a PIR class
+inherits a default set of vtable functions from C<Object>, but you can
+override them with your own PIR subroutines.
+
+The C<:vtable>X<:vtable subroutine modifier> modifier marks a subroutine
+as a vtable override. As it does with methods, Parrot stores vtable
+overrides in the class associated with the currently selected namespace:
+
+=begin PIR
+
+  .sub 'init' :vtable
+    $P6 = new 'Integer'
+    setattribute self, 'bar', $P6
+    .return()
+  .end
+
+=end PIR
+
+Subroutines acting as vtable overrides must either have the name of an actual
+vtable function or include the vtable function name in the C<:vtable> modifier:
+
+=begin PIR
+
+  .sub foozle :vtable('init')
+    # ...
+  .end
+
+=end PIR
+
+You must call methods on objects explicitly, but Parrot calls vtable functions
+implicitly in multiple contexts.  For example, creating a new object with C<$P3
+= new 'Foo'> will call C<init> with the new C<Foo> object.
+
+As an example of some of the common vtable overrides, the C<=>X<=
+operator> operator (or C<set>X<set opcode> opcode) calls C<Foo>'s
+vtable function C<set_integer_native> when its left-hand side is a
+C<Foo> object and the argument is an integer literal or integer
+variable:
+
+=begin PIR_FRAGMENT
+
+    $P3 = 30
+
+=end PIR_FRAGMENT
+
+The C<+>X<+ operator> operator (or C<add>X<add opcode> opcode) calls
+C<Foo>'s C<add> vtable function when it adds two C<Foo> objects:
+
+=begin PIR_FRAGMENT
+
+    $P3 = new 'Foo'
+    $P3 = 3
+    $P4 = new 'Foo'
+    $P4 = 1774
+
+    $P5 = $P3 + $P4
+    # or:
+    add $P5, $P3, $P4
+
+=end PIR_FRAGMENT
+
+The C<inc>X<inc opcode> opcode calls C<Foo>'s C<increment> vtable
+function when it increments a C<Foo> object:
+
+=begin PIR_FRAGMENT
+
+    inc $P3
+
+=end PIR_FRAGMENT
+
+Parrot calls C<Foo>'s C<get_integer> and C<get_string> vtable functions to
+retrieve an integer or string value from a C<Foo> object:
+
+=begin PIR_FRAGMENT
+
+    $I10 = $P5  # get_integer
+    say $P5     # get_string
+
+=end PIR_FRAGMENT
+
+=head2 Introspection
+
+X<introspection>
+X<classes;introspection>
+Classes defined in PIR using the C<newclass> opcode are instances of the
+C<Class> PMCX<Class PMC>. This PMC contains all the meta-information for
+the class, such as attribute definitions, methods, vtable overrides, and
+its inheritance hierarchy. The opcode C<inspect>X<inspect opcode> 
+provides a way to peek behind the curtain of encapsulation to see what
+makes a class tick. When called with no arguments, C<inspect> returns an
+associative array containing data on all characteristics of the class
+that it chooses to reveal:
+
+=begin PIR_FRAGMENT
+
+  $P1 = inspect $P0
+  $P2 = $P1['attributes']
+
+=end PIR_FRAGMENT
+
+When called with a string argument, C<inspect> only returns the data for
+a specific characteristic of the class:
+
+=begin PIR_FRAGMENT
+
+  $P0 = inspect $P1, 'parents'
+
+=end PIR_FRAGMENT
+
+Table 7-1 shows the introspection characteristics supported by
+C<inspect>.
+
+=begin table Class Introspection
+
+=headrow
+
+=row
+
+=cell Characteristic
+
+=cell Description
+
+=bodyrows
+
+=row
+
+=cell C<attributes>
+
+=cell Information about the attributes the class will instantiate in
+its objects. An associative array, where the keys are the attribute
+names and the values are hashes of metadata.
+
+=row
+
+=cell C<flags>
+
+=cell An C<Integer> PMC containing any integer flags set on the class
+object.
+
+=row
+
+=cell C<methods>
+
+=cell A list of methods provided by the class. An associative array
+where the keys are the method names and the values are the invocable
+method objects.
+
+=row
+
+=cell C<name>
+
+=cell A C<String> PMC containing the name of the class.
+
+=row
+
+=cell C<namespace>
+
+=cell The C<NameSpace> PMC associated with the class.
+
+=row
+
+=cell C<parents>
+
+=cell An array of C<Class> objects that this class inherits from
+directly (via C<subclass> or C<add_parent>). Does not include indirectly
+inherited parents.
+
+=row
+
+=cell C<roles>
+
+=cell An array of C<Role> objects composed into the class.
+
+=row
+
+=cell C<vtable_overrides>
+
+=cell A list of vtable overrides defined by the class. An associative
+array where the keys are the vtable names and the values are the
+invocable sub objects.
+
+=end table
+
+=cut
+
+# Local variables:
+#   c-file-style: "parrot"
+# End:
+# vim: expandtab shiftwidth=4:

Added: branches/tt761_keys_revamp/docs/book/pir/ch08_io.pod
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/tt761_keys_revamp/docs/book/pir/ch08_io.pod	Sat Jul  4 21:38:28 2009	(r39884)
@@ -0,0 +1,388 @@
+=pod
+
+=head1 I/O
+
+X<FileHandle PMC>
+Parrot handles all I/O in Parrot with a set of PMCs. The C<FileHandle> PMC
+takes care of reading from and writing to files and file-like streams.  The
+C<Socket> PMC takes care of network I/O.
+
+=head2 FileHandle Opcodes
+
+The C<open>X<open opcode> opcode opens a new filehandle. It takes a
+string argument, which is the path to the file:
+
+=begin PIR_FRAGMENT
+
+  $P0 = open 'my/file/name.txt'
+
+=end PIR_FRAGMENT
+
+By default, it opens the filehandle as read-only, but an optional second string
+argument can specify the mode for the file. The modes are C<r> for read, C<w>
+for write, C<a> for append, and C<p> for pipe:N<These are the same as the C
+language read-modes, so may be familiar.>
+
+=begin PIR_FRAGMENT
+
+  $P0 = open 'my/file/name.txt', 'a'
+
+  $P0 = open 'myfile.txt', 'r'
+
+=end PIR_FRAGMENT
+
+You can combine modes; a handle that can read and write uses the mode string
+C<rw>. A handle that can read and write but will not overwrite the existing
+contents uses C<ra> instead.
+
+The C<close>X<close opcode> opcode closes a filehandle when it's no
+longer needed.  Closing a filehandle doesn't destroy the object, it only
+makes that filehandle object available for opening a different
+file.N<It's generally not a good idea to manually close the standard
+input, standard output, or standard error filehandles, though you can
+recreate them.>
+
+=begin PIR_FRAGMENT
+
+  close $P0
+
+=end PIR_FRAGMENT
+
+The C<print>X<print opcode> opcode prints a string argument or the
+string form of an integer, number, or PMC to a filehandle:
+
+=begin PIR_FRAGMENT
+
+  print $P0, 'Nobody expects'
+
+=end PIR_FRAGMENT
+
+It also has a one-argument variant that always prints to standard
+output:
+
+=begin PIR_FRAGMENT
+
+  print 'the Spanish Inquisition'
+
+=end PIR_FRAGMENT
+
+The C<say>X<say opcode> opcode also prints to standard output, but it
+appends a trailing newline to whatever it prints. Another opcode worth
+mentioning is the C<printerr>X<printerr opcode> opcode, which prints an
+argument to the standard error instead of standard output:
+
+=begin PIR_FRAGMENT
+
+  say 'Turnip'
+
+  printerr 'Blancmange'
+
+=end PIR_FRAGMENT
+
+The C<read>X<read opcode> and C<readline>X<readline opcode> opcodes read
+values from a filehandle.  C<read> takes an integer value and returns a
+string with that many characters (if possible). C<readline> reads a line
+of input from a filehandle and returns the string without the trailing
+newline:
+
+=begin PIR_FRAGMENT
+
+  $S0 = read $P0, 10
+
+  $S0 = readline $P0
+
+=end PIR_FRAGMENT
+
+The C<read> opcode has a one-argument variant that reads from standard input:
+
+=begin PIR_FRAGMENT
+
+      $S0 = read 10
+
+=end PIR_FRAGMENT
+
+The C<getstdin>X<getstdin opcode>, C<getstdout>X<getstdout opcode>, and
+C<getstderr>X<getstderr opcode> opcodes fetch the filehandle objects for
+the standard streams: standard input, standard output, and standard
+error:
+
+=begin PIR_FRAGMENT
+
+  $P0 = getstdin    # Standard input handle
+  $P1 = getstdout   # Standard output handle
+  $P2 = getstderr   # Standard error handle
+
+=end PIR_FRAGMENT
+
+Once you have the filehandle for one of the standard streams, you can use it
+just like any other filehandle object:
+
+=begin PIR_FRAGMENT
+
+  $P0 = getstdout
+  print $P0, 'hello'
+
+=end PIR_FRAGMENT
+
+This following example reads data from the file F<myfile.txt> one line at a
+time using the C<readline> opcode. As it loops over the lines of the file, it
+checks the boolean value of the read-only filehandle C<$P0> to test whether the
+filehandle has reached the end of the file:
+
+=begin PIR
+
+  .sub 'main'
+    $P0 = getstdout
+    $P1 = open 'myfile.txt', 'r'
+    loop_top:
+      $S0 = readline $P1
+      print $P0, $S0
+      if $P1 goto loop_top
+    close $P1
+  .end
+
+=end PIR
+
+=head2 FileHandle Methods
+
+The methods available on a filehandle object are mostly duplicates of the
+opcodes, though sometimes they provide more options. Behind the scenes many of
+the opcodes call the filehandle's methods anyway, so the choice between the two
+is more a matter of style preference than anything else.
+
+=head3 open
+
+The C<open>X<open method> method opens a stream in an existing
+filehandle object. It takes two optional string arguments: the name of
+the file to open and the open mode.
+
+=begin PIR_FRAGMENT
+
+  $P0 = new 'FileHandle'
+  $P0.'open'('myfile.txt', 'r')
+
+=end PIR_FRAGMENT
+
+The C<open> opcode internally creates a new filehandle PMC and calls its
+C<open> method on it. The opcode version is shorter to write, but it also
+creates a new PMC for every call, while the method can reopen an existing
+filehandle PMC with a new file.
+
+When reopening a filehandle, Parrot will reuse the previous filename associated
+with the filehandle unless you provide a different filename.  The same goes for
+the mode.
+
+=head3 close
+
+The C<close>X<close method> method closes the filehandle. This does not
+destroy the filehandle object; you can reopen it with the C<open> method
+later.
+
+=begin PIR_FRAGMENT
+
+  $P0.'close'()
+
+=end PIR_FRAGMENT
+
+=head3 is_closed
+
+The C<is_closed>X<is_closed method> method checks if the filehandle is
+closed. It returns true if the filehandle has been closed or was never
+opened, and false if it is currently open:
+
+=begin PIR_FRAGMENT
+
+  $I0 = $P0.'is_closed'()
+
+=end PIR_FRAGMENT
+
+=head3 print
+
+The C<print>X<print method> method prints a given value to the
+filehandle. The argument can be an integer, number, string, or PMC.
+
+=begin PIR_FRAGMENT
+
+  $P0.'print'('Hello!')
+
+=end PIR_FRAGMENT
+
+=head3 puts
+
+The C<puts>X<puts method> method is similar to C<print>, but it only
+takes a string argument.
+
+=begin PIR_FRAGMENT
+
+  $P0.'puts'('Hello!')
+
+=end PIR_FRAGMENT
+
+=head3 read
+
+The C<read>X<read method> method reads a specified number of bytes from the filehandle
+object and returns them in a string.
+
+=begin PIR_FRAGMENT
+
+  $S0 = $P0.'read'(10)
+
+=end PIR_FRAGMENT
+
+If the remaining bytes in the filehandle are fewer than the requested
+number of bytes, returns a string containing the remaining bytes.
+
+=head3 readline
+
+The C<readline>X<readline method> method reads an entire line up to a
+newline character or the end-of-file mark from the filehandle object and
+returns it in a string.
+
+=begin PIR_FRAGMENT
+
+  $S0 = $P0.'readline'()
+
+=end PIR_FRAGMENT
+
+=head3 readline_interactive
+
+The C<readline_interactive>X<readline_interactive method> method is
+useful for command-line scripts.  It writes the single argument to the
+method as a prompt to the screen, then reads back a line of input.
+
+=begin PIR_FRAGMENT
+
+  $S0 = $P0.'readline_interactive'('Please enter your name:')
+
+=end PIR_FRAGMENT
+
+=head3 readall
+
+The C<readall>X<readall method> method reads an entire file. If the
+filehandle is closed, it will open the file given by the passed in
+string argument, read the entire file, and then close the filehandle.
+
+=begin PIR_FRAGMENT
+
+  $S0 = $P0.'readall'('myfile.txt')
+
+=end PIR_FRAGMENT
+
+If the filehandle is already open, C<readall> will read the contents of the
+file, and won't close the filehandle when it's finished. Don't pass the name
+argument when working with a file you've already opened.
+
+=begin PIR_FRAGMENT
+
+  $S0 = $P0.'readall'()
+
+=end PIR_FRAGMENT
+
+=head3 mode
+
+The C<mode>X<mode method> method returns the current file access mode
+for the filehandle object.
+
+=begin PIR_FRAGMENT
+
+  $S0 = $P0.'mode'()
+
+=end PIR_FRAGMENT
+
+=head3 encoding
+
+The C<encoding>X<encoding method> method sets or retrieves the string
+encoding behavior of the filehandle.
+
+=begin PIR_FRAGMENT
+
+ $P0.'encoding'('utf8')
+ $S0 = $P0.'encoding'()
+
+=end PIR_FRAGMENT
+
+See L<Encodings and Charsets> in Chapter 4 for more details on the
+encodings supported in Parrot.
+
+=head3 buffer_type
+
+The C<buffer_type>X<buffer_type method> method sets or retrieves the
+buffering behavior of the filehandle object. The argument or return
+value is one of: C<unbuffered> to disable buffering, C<line-buffered> to
+read or write when the filehandle encounters a line ending, or
+C<full-buffered> to read or write bytes when the buffer is full.
+
+=begin PIR_FRAGMENT
+
+  $P0.'buffer_type'('full-buffered')
+  $S0 = $P0.'buffer_type'()
+
+=end PIR_FRAGMENT
+
+=head3 buffer_size
+
+The C<buffer_size>X<buffer_size method> method sets or retrieves the
+buffer size of the filehandle object.
+
+=begin PIR_FRAGMENT
+
+  $P0.'buffer_size'(1024)
+  $I0 = $P0.'buffer_size'()
+
+=end PIR_FRAGMENT
+
+The buffer size set on the filehandle is only a suggestion.  Parrot may
+allocate a larger buffer, but it will never allocate a smaller buffer.
+
+=head3 flush
+
+The C<flush>X<flush method> method flushes the buffer if the filehandle
+object is working in a buffered mode.
+
+=begin PIR_FRAGMENT
+
+  $P0.'flush'()
+
+=end PIR_FRAGMENT
+
+=head3 eof
+
+The C<eof>X<eof method> method checks whether a filehandle object has
+reached the end of the current file. It returns true if the filehandle
+is at the end of the current file and false otherwise.
+
+=begin PIR_FRAGMENT
+
+  $I0 = $P0.'eof'()
+
+=end PIR_FRAGMENT
+
+=head3 isatty
+
+The C<isatty>X<isatty method> method returns a boolean value whether the
+filehandle is a TTY terminal.
+
+=begin PIR_FRAGMENT
+
+  $P0.'isatty'()
+
+=end PIR_FRAGMENT
+
+=head3 get_fd
+
+The C<get_fd>X<get_fd method> method returns the integer file descriptor
+of the current filehandle object. Not all operating systems use integer
+file descriptors. Those that don't simply return C<-1>.
+
+=begin PIR_FRAGMENT
+
+  $I0 = $P0.'get_fd'()
+
+=end PIR_FRAGMENT
+
+=cut
+
+# Local variables:
+#   c-file-style: "parrot"
+# End:
+# vim: expandtab shiftwidth=4:

Added: branches/tt761_keys_revamp/docs/book/pir/ch09_exceptions.pod
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/tt761_keys_revamp/docs/book/pir/ch09_exceptions.pod	Sat Jul  4 21:38:28 2009	(r39884)
@@ -0,0 +1,394 @@
+=pod
+
+=head1 Exceptions
+
+X<exceptions>
+Exceptions provide a way of subverting the normal flow of control. Their main
+use is error reporting and cleanup tasks, but sometimes exceptions are just a
+funny way to jump from one code location to another one. Parrot uses a robust
+exception mechanism and makes it available to PIR.
+
+Exceptions are objects that hold essential information about an exceptional
+situation: the error message, the severity and type of the error, the location
+of the error, and backtrace information about the chain of calls that led to
+the error. Exception handlers are ordinary subroutines, but user code never
+calls them directly from within user code. Instead, Parrot invokes an
+appropriate exception handler to catch a thrown exception.
+
+=head2 Throwing Exceptions
+
+X<exceptions; throwing>
+The C<throw>X<throw opcode> opcode throws an exception object. This
+example creates a new C<Exception>X<Exception PMC> object in C<$P0> and
+throws it:
+
+=begin PIR_FRAGMENT
+
+  $P0 = new 'Exception'
+  throw $P0
+
+=end PIR_FRAGMENT
+
+Setting the string value of an exception object sets its error message:
+
+=begin PIR_FRAGMENT
+
+  $P0 = new 'Exception'
+  $P0 = "I really had my heart set on halibut."
+  throw $P0
+
+=end PIR_FRAGMENT
+
+Other parts of Parrot throw their own exceptions.  The C<die>X<die
+opcode> opcode throws a fatal (that is, uncatchable) exception. Many
+opcodes throw exceptions to indicate error conditions. The C</> operator
+(the C<div> opcode), for example, throws an exception on attempted
+division by zero.
+
+When no appropriate handlers are available to catch an exception, Parrot treats
+it as a fatal error and exits, printing the exception message followed by a
+backtrace showing the location of the thrown exception:
+
+  I really had my heart set on halibut.
+  current instr.: 'main' pc 6 (pet_store.pir:4)
+
+=head2 Catching Exceptions
+
+X<exception handlers>
+X<exceptions; catching>
+Exception handlers catch exceptions, making it possible to recover from
+errors in a controlled way, instead of terminating the process entirely.
+
+The C<push_eh>X<push_eh opcode> opcode creates an exception handler
+object and stores it in the list of currently active exception handlers.
+The body of the exception handler is a labeled section of code inside
+the same subroutine as the call to C<push_eh>.  The opcode takes one
+argument, the name of the label:
+
+=begin PIR_FRAGMENT
+
+  push_eh my_handler
+    $P0 = new 'Exception'
+    throw $P0
+
+    say 'never printed'
+
+  my_handler:
+    say 'caught an exception'
+
+=end PIR_FRAGMENT
+
+This example creates an exception handler with a destination address of
+the C<my_handler> label, then creates a new exception and throws it. At
+this point, Parrot checks to see if there are any appropriate exception
+handlers in the currently active list. It finds C<my_handler> and runs
+it, printing "caught an exception". The "never printed" line never runs,
+because the exceptional control flow skips right over it.
+
+Because Parrot scans the list of active handlers from newest to oldest,
+you don't want to leave exception handlers lying around when you're done
+with them.  The C<pop_eh>X<pop_eh opcode> opcode removes an exception
+handler from the list of currently active handlers:
+
+=begin PIR_FRAGMENT
+
+  push_eh my_handler
+    $I0 = $I1 / $I2
+    pop_eh
+
+    say 'maybe printed'
+
+    goto skip_handler
+
+  my_handler:
+    say 'caught an exception'
+    pop_eh
+
+  skip_handler:
+
+=end PIR_FRAGMENT
+
+This example creates an exception handler C<my_handler> and then runs a a
+division operation that will throw a "division by zero" exception if C<$I2> is
+0. When C<$I2> is 0, C<div> throws an exception.  The exception handler catches
+it, prints "caught an exception", and then clears itself with C<pop_eh>. When
+C<$I2> is a non-zero value, there is no exception.  The code clears the
+exception handler with C<pop_eh>, then prints "maybe printed".  The C<goto>
+skips over the code of the exception handler, as it's just a labeled unit of
+code within the subruotine.
+
+The exception object provides access to various attributes of the
+exception for additional information about what kind of error it was,
+and what might have caused it. The directive
+C<.get_results>X<.get_results directive> retrieves the C<Exception>
+object from inside the handler:
+
+=begin PIR_FRAGMENT
+
+  my_handler:
+    .get_results($P0)
+
+=end PIR_FRAGMENT
+
+Not all handlers are able to handle all kinds of exceptions. If a handler
+determines that it's caught an exception it can't handle, it can C<rethrow> the
+exception to the next handler in the list of active handlers:
+
+=begin PIR_FRAGMENT
+
+  my_handler:
+    .get_results($P0)
+    rethrow $P0
+
+=end PIR_FRAGMENT
+
+If none of the active handlers can handle the exception, the exception becomes
+a fatal error.  Parrot will exit, just as if it could find no handlers.
+
+X<exceptions;resuming>
+X<resumable exceptions>
+
+An exception handler creates a return continuation with a snapshot of the
+current interpreter context. If the handler is successful, it can resume
+running at the instruction immediately after the one that threw the exception.
+This resume continuation is available from the C<resume> attribute of the
+exception object. To resume after the exception handler is complete, call the
+resume handler like an ordinary subroutine:
+
+=begin PIR_FRAGMENT
+
+  my_handler:
+    .get_results($P0)
+    $P1 = $P0['resume']
+    $P1()
+
+=end PIR_FRAGMENT
+
+=head2 Exception PMC
+
+X<Exception PMC>
+X<Exception PMC;message>
+C<Exception> objects contain several useful pieces of information about the
+exception. To set and retrieve the exception message, use the C<message> key on
+the exception object:
+
+=begin PIR_FRAGMENT
+
+  $P0            = new 'Exception'
+  $P0['message'] = "this is an error message for the exception"
+
+=end PIR_FRAGMENT
+
+... or set and retrieve the string value of the exception object directly:
+
+=begin PIR_FRAGMENT
+
+  $S0 = $P0
+
+=end PIR_FRAGMENT
+
+X<Exception PMC;severity>
+X<Exception PMC;type>
+The severity and type of the exception are both integer values:
+
+=begin PIR_FRAGMENT
+
+  $P0['severity'] = 1
+  $P0['type']     = 2
+
+=end PIR_FRAGMENT
+
+X<Exception PMC;payload>
+The payload holds any user-defined data attached to the exception object:
+
+=begin PIR_FRAGMENT
+
+  $P0['payload'] = $P2
+
+=end PIR_FRAGMENT
+
+The attributes of the exception are useful in the handler for making decisions
+about how and whether to handle an exception and report its results:
+
+=begin PIR_FRAGMENT
+
+  my_handler:
+    .get_results($P2)
+    $S0 = $P2['message']
+    print 'caught exception: "'
+    print $S0
+    $I0 = $P2['type']
+    print '", of type '
+    say $I0
+
+=end PIR_FRAGMENT
+
+=head2 ExceptionHandler PMC
+
+X<ExceptionHandler PMC>
+Exception handlers are subroutine-like PMC objects, derived from Parrot's
+C<Continuation> type. When you use C<push_eh> with a label to create an
+exception handler, Parrot creates the handler PMC for you. You can also create
+it directly by creating a new C<ExceptionHandler> object, and setting
+its destination address to the label of the handler using the
+C<set_addr> opcodeX<set_addr opcode>:
+
+=begin PIR_FRAGMENT
+
+    $P0 = new 'ExceptionHandler'
+    set_addr $P0, my_handler
+    push_eh $P0
+    # ...
+
+  my_handler:
+    # ...
+
+=end PIR_FRAGMENT
+
+X<can_handle method>
+C<ExceptionHandler> PMCs have several methods for setting or checking handler
+attributes. The C<can_handle> method reports whether the handler is willing or
+able to handle a particular exception. It takes one argument, the exception
+object to test:
+
+=begin PIR_FRAGMENT
+
+  $I0 = $P0.'can_handle'($P1)
+
+=end PIR_FRAGMENT
+
+X<min_severity method>
+X<max_severity method>
+The C<min_severity> and C<max_severity> methods set and retrieve the severity
+attributes of the handler, allowing it to refuse to handle any exceptions whose
+severity is too high or too low. Both take a single optional integer argument
+to set the severity; both return the current value of the attribute as a
+result:
+
+=begin PIR_FRAGMENT
+
+  $P0.'min_severity'(5)
+  $I0 = $P0.'max_severity'()
+
+=end PIR_FRAGMENT
+
+X<handle_types method>
+X<handle_types_except method>
+The C<handle_types> and C<handle_types_except> methods tell the
+exception handler what types of exceptions it should or shouldn't
+handle. Both take a list of integer types, which correspond to the
+C<type> attribute set on an exception object:
+
+=begin PIR_FRAGMENT
+
+  $P0.'handle_types'(5, 78, 42)
+
+=end PIR_FRAGMENT
+
+The following example creates an exception handler that only handles
+exception types 1 and 2. Instead of having C<push_eh> create the
+exception handler object, it creates a new C<ExceptionHandler> object
+manually. It then calls C<handle_types> to identify the exception types
+it will handle:
+
+=begin PIR_FRAGMENT
+
+  $P0 = new 'ExceptionHandler'
+  set_addr $P0, my_handler
+  $P0.'handle_types'(1, 2)
+  push_eh $P0
+
+=end PIR_FRAGMENT
+
+This handler can only handle exception objects with a type of 1 or 2.  Parrot
+will skip over this handler for all other exception types.
+
+=begin PIR_FRAGMENT
+
+  $P1         = new 'Exception'
+  $P1['type'] = 2
+  throw $P1                     # caught
+
+  $P1         = new 'Exception'
+  $P1['type'] = 3
+  throw $P1                     # uncaught
+
+=end PIR_FRAGMENT
+
+=head2 Annotations
+
+X<bytecode annotations>
+Annotations are pieces of metadata code stored in a bytecode file.  This is
+especially important when dealing with high-level languages, where annotations
+contain information about the HLL's source code such as the current line number
+and file name.
+
+Create an annotation with the C<.annotate>X<.annotate directive>
+directive. Annotations consist of a key/value pair, where the key is a
+string and the value is an integer, a number, or a string.  Bytecode
+stores annotations as constants in the compiled bytecode.  Consequently,
+you may not store PMCs.
+
+=begin PIR_FRAGMENT
+
+  .annotate 'file', 'mysource.lang'
+  .annotate 'line', 42
+  .annotate 'compiletime', 0.3456
+
+=end PIR_FRAGMENT
+
+Annotations exist, or are "in force" throughout the entire subroutine or
+until their redefinition.  Creating a new annotation with the same name
+as an old one overwrites it with the new value. The
+C<annotations>X<annotations opcode> opcode retrieves the current hash of
+annotations:
+
+=begin PIR_FRAGMENT
+
+  .annotate 'line', 1
+  $P0 = annotations # {'line' => 1}
+
+  .annotate 'line', 2
+  $P0 = annotations # {'line' => 2}
+
+=end PIR_FRAGMENT
+
+To retrieve a single annotation by name, use the name with C<annotations>:
+
+=begin PIR_FRAGMENT
+
+  $P0 = annotations 'line'
+
+=end PIR_FRAGMENT
+
+Exception objects contain information about the annotations that were in
+force when the exception was thrown. Retrieve them with the
+C<annotations>X<annotations method> method on the exception PMC object:
+
+=begin PIR_FRAGMENT
+
+  $I0 = $P0.'annotations'('line')  # only the 'line' annotation
+  $P1 = $P0.'annotations'()        # hash of all annotations
+
+=end PIR_FRAGMENT
+
+Exceptions can also include a backtraceX<backtrace method> to display
+the program flow to the point of the throw:
+
+=begin PIR_FRAGMENT
+
+  $P1 = $P0.'backtrace'()
+
+=end PIR_FRAGMENT
+
+The backtrace PMC is an array of hashes. Each element in the array corresponds
+to a function in the current call chain. Each hash has two elements:
+C<annotation> (the hash of annotations in effect at that point) and C<sub> (the
+Sub PMC of that function).
+
+=cut
+
+# Local variables:
+#   c-file-style: "parrot"
+# End:
+# vim: expandtab shiftwidth=4:

Modified: branches/tt761_keys_revamp/docs/parrothist.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/parrothist.pod	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/docs/parrothist.pod	Sat Jul  4 21:38:28 2009	(r39884)
@@ -91,5 +91,6 @@
  Allison     1.0.0          2009-Mar-17     "Haru Tatsu"
  Francois    1.1.0          2009-Apr-21     "Half-moon Conure"
  Infinoid    1.2.0          2009-May-19     "Bird Brain"
+ Whiteknight 1.3.0          2009-Jun-16     "Andean Swift"
 
 =cut

Modified: branches/tt761_keys_revamp/docs/pdds/pdd19_pir.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/pdds/pdd19_pir.pod	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/docs/pdds/pdd19_pir.pod	Sat Jul  4 21:38:28 2009	(r39884)
@@ -1171,7 +1171,7 @@
 The automatic name munging on C<.macro_local> variables allows for using
 multiple macros, like so:
 
-=begin PIR
+=begin PIR_TODO
 
   .macro foo(a)
   .macro_local int $a
@@ -1186,7 +1186,7 @@
     .bar("x")
   .end
 
-=end PIR
+=end PIR_TODO
 
 This will result in code for the parser as follows:
 
@@ -1221,20 +1221,24 @@
 
 =begin PIR_FRAGMENT
 
+  .macro foo(b)
+    #...
+  .endm
+
   .foo("x")
 
 =end PIR_FRAGMENT
 
 there will be two variables: C<b> and C<x>. When the macro is invoked twice:
 
-=begin PIR
+=begin PIR_TODO
 
   .sub main
     .foo("x")
     .foo("y")
   .end
 
-=end PIR
+=end PIR_TODO
 
 the resulting code that is given to the parser will read as follows:
 
@@ -1267,10 +1271,9 @@
       .param int b
       .param int c
 
-      .begin_return
-        .set_return xy
-      .end_return
-
+      # ...
+      .local pmc xy
+      .return(xy) 
     .end
 
 =end PIR
@@ -1303,7 +1306,7 @@
 
 =head3 NCI Call
 
-=begin PIR_FRAGMENT
+=begin PIR_FRAGMENT_TODO
 
     load_lib $P0, "libname"
     dlfunc $P1, $P0, "funcname", "signature"
@@ -1317,7 +1320,7 @@
       .get_result r
     .end_call
 
-=end PIR_FRAGMENT
+=end PIR_FRAGMENT_TODO
 
 =head3 Subroutine Call Syntactic Sugar
 
@@ -1339,16 +1342,16 @@
 
 Instead of the label a subroutine object can be used too:
 
-=begin PIR_FRAGMENT
+=begin PIR_FRAGMENT_TODO
 
    get_global $P0, "sub_label"
    $P0(args)
 
-=end PIR_FRAGMENT
+=end PIR_FRAGMENT_TODO
 
 =head3 Methods
 
-=begin PIR
+=begin PIR_TODO
 
   .namespace [ "Foo" ]
 
@@ -1365,7 +1368,7 @@
     ...
   .end
 
-=end PIR
+=end PIR_TODO
 
 The variable "self" automatically refers to the invocating object, if the
 subroutine declaration contains "method".
@@ -1375,7 +1378,7 @@
 The syntax is very similar to subroutine calls. The call is done with
 C<.meth_call> which must immediately be preceded by the C<.invocant>:
 
-=begin PIR_FRAGMENT
+=begin PIR_FRAGMENT_TODO
 
    .local int x, y, z
    .local pmc class, obj
@@ -1392,7 +1395,7 @@
    .end_call
    ...
 
-=end PIR_FRAGMENT
+=end PIR_FRAGMENT_TODO
 
 
 The return continuation is optional. The method can be a string

Modified: branches/tt761_keys_revamp/docs/pdds/pdd27_multiple_dispatch.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/pdds/pdd27_multiple_dispatch.pod	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/docs/pdds/pdd27_multiple_dispatch.pod	Sat Jul  4 21:38:28 2009	(r39884)
@@ -105,7 +105,7 @@
 matching, for a passed in signature. The signature passed in is an array of
 PMCs, and the types are extracted from the types of the array elements.
 
-=item get_pmc_keyed_string
+=item get_pmc_keyed_str
 
 Return an array of matching candidates, sorted from best matching to worst
 matching, for a passed in signature. The signature passed in is a simple type

Modified: branches/tt761_keys_revamp/docs/project/release_manager_guide.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/project/release_manager_guide.pod	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/docs/project/release_manager_guide.pod	Sat Jul  4 21:38:28 2009	(r39884)
@@ -33,8 +33,8 @@
 For example, you could select a name from
 L<http://en.wikipedia.org/wiki/List_of_parrots>.
 
-Set up your account on L<http://www.parrot.org/> and ask one of Allison, Jerry,
-Jeff, Will, or chromatic to bestow you story-creating powers.
+Set up your account on L<http://www.parrot.org/> and ask an existing release
+manager to provide you with admin privileges if you don't already have them.
 
 =item 1.
 
@@ -230,14 +230,13 @@
 
 =item 10.
 
-Update the website. You will need an account on L<http://www.parrot.org>.
+Update the website. You will need an account with administrative rights
+on L<http://www.parrot.org>.
 
 =over 4
 
 =item a
 
-At this step, the "editor" privilege is needed, "poster" is not enough.
-
 Add a new page for the release announcement with "Create content" -> "Story".
 There's some additional stuff needed at the top of the page; use one of the
 old announcements as a guide.
@@ -265,8 +264,6 @@
 
 =item e
 
-At this step, the "admin" privilege is needed.
-
 Under "Administer" -> "Site building" -> "URL Redirects", change the URL for
 "release/current" to the FTP directory for the new release (for example,
 F<ftp://ftp.parrot.org/pub/parrot/releases/devel/0.8.1>). Also update
@@ -364,14 +361,13 @@
 The starred releases are Parrot's twice-yearly supported releases, see
 F<docs/project/support_policy.pod>.
 
- - June 16, 2009     - 1.3  - whiteknight
  - July 21, 2009     - 1.4* - cotto
  - August 18, 2009   - 1.5  - rgrjr
- - Sept 21, 2009     - 1.6  -
+ - Sept 15, 2009     - 1.6  - particle
  - Oct 20, 2009      - 1.7  -
- - Nov 24, 2009      - 1.8  -
- - Dec 22, 2009      - 1.9  -
- - Jan 18, 2010      - 2.0* -
+ - Nov 17, 2009      - 1.8  -
+ - Dec 15, 2009      - 1.9  -
+ - Jan 19, 2010      - 2.0* -
 
 =cut
 

Modified: branches/tt761_keys_revamp/docs/user/pir/objects.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/user/pir/objects.pod	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/docs/user/pir/objects.pod	Sat Jul  4 21:38:28 2009	(r39884)
@@ -383,7 +383,7 @@
 
     .sub getname :method
         $P0 = getattribute self, "name"
-        print $P0
+        .return($P0)
     .end
 
     .sub speak :method

Modified: branches/tt761_keys_revamp/docs/user/pir/pmcs.pod
==============================================================================
--- branches/tt761_keys_revamp/docs/user/pir/pmcs.pod	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/docs/user/pir/pmcs.pod	Sat Jul  4 21:38:28 2009	(r39884)
@@ -21,17 +21,18 @@
 String register number 15). Parrot programs consist of lines of
 text where each line contains one opcode and its arguments.
 
-Each subroutine will have as many registers
-available as necessary; a simple subroutine will only need
-a few whereas complex subroutines with many calculations will
-need a larger number of registers. This is a fundamental
-difference from the original design of Parrot, in which there
-were 32 registers for each of the built-in types (int, num,
-pmc, string).
-PIR also provides for a more "natural" syntax for opcodes.
-Rather than saying C<set $I1, 0> to assign a zero to the $I1
-register, you may say instead C<$I1 = 0>.
-PIR also provides syntax for easily creating named variables
+Each subroutine will have as many registers available of each basic type
+(int, num, string, and pmc) as necessary; a simple subroutine will only
+need a few whereas complex subroutines with many calculations will need
+a larger number of registers.  This is a fundamental difference from
+hardware CPUs (and the original design of Parrot), in which there are a
+fixed number of registers.
+
+PIR also provides for a more "natural" syntax for opcodes than
+the standard assembly language C<op arg, arg> format.
+Rather than writing C<set $I1, 0> to assign a zero to the $I1
+register, you may instead write C<$I1 = 0>.
+PIR also provides easy syntax for creating named variables
 and constants, subroutines, passing parameters to subroutines,
 accessing parameters by name, etc.
 
@@ -39,14 +40,12 @@
 
 =head2 What's a PMC?
 
-Integers, strings, and arbitrary floating point numbers are
-common data types in most programming languages, but what's
-a PMC? PMC stands for "Polymorphic Container". PMCs are how
-Parrot handles more complicated structures and behaviors
-(hence the magic :) Some examples of PMC usage would be for
-arrays, hashes, data structures, objects, etc. Anything that
-can't be expressed using just integers, floating point
-numbers and strings can be expressed with a PMC.
+Integers, strings, and floating point numbers are common data types in
+most programming languages, but what's a PMC?  PMC stands for
+"I<P>olyI<M>orphic I<C>ontainer".  PMCs are how Parrot handles more
+complicated structures and behaviors, such as arrays, hashes, and
+objects. anything that can't be expressed using just integers,
+floating point numbers and strings can be expressed with a PMC.
 
 Parrot comes with many types of PMC that encapsulate common,
 useful behavior.
@@ -63,8 +62,8 @@
     Hash            A generic, resizable hash
     Random          Obtain a random number
     String          Similar to a string register but in PMC form
-    Integer         Similar to an integer register but in PMC form
-    Float           Similar to a number register but in PMC form
+    Integer         Similar to an int register but in PMC form
+    Float           Similar to a num register but in PMC form
     Exception       The standard exception mechanism
     Timer           A timer of course :)
 

Modified: branches/tt761_keys_revamp/editor/pir_vim.in
==============================================================================
--- branches/tt761_keys_revamp/editor/pir_vim.in	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/editor/pir_vim.in	Sat Jul  4 21:38:28 2009	(r39884)
@@ -105,8 +105,8 @@
 
 " Folding rules
 syn region foldManual  start=/^\s*#.*{{{/ end=/^\s*#.*}}}/ contains=ALL keepend fold
-syn region foldMakro   start=/\.macro/ end=/\.endm/ contains=ALLBUT,pirDirectiveMacro keepend fold
-syn region foldSub     start=/\.sub/ end=/\.end/ contains=ALLBUT,pirDirectiveSub,pirDirectiveMacro keepend fold
+syn region foldMakro   start=/\.macro/ end=/^\s*\.endm/ contains=ALLBUT,pirDirectiveMacro keepend fold
+syn region foldSub     start=/\.sub/ end=/^\s*\.end/ contains=ALLBUT,pirDirectiveSub,pirDirectiveMacro keepend fold
 syn region foldIf      start=/^\s*if.*goto\s*\z(\I\i*\)\s*$/ end=/^\s*\z1:\s*$/ contains=ALLBUT,pirDirectiveSub,pirDirectiveMacro keepend fold
 syn region foldUnless  start=/^\s*unless.*goto\s*\z(\I\i*\)\s*$/ end=/^\s*\z1:\s*$/ contains=ALLBUT,pirDirectiveSub,pirDirectiveMacro keepend fold
 

Added: branches/tt761_keys_revamp/examples/opengl/math.pir
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/tt761_keys_revamp/examples/opengl/math.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -0,0 +1,99 @@
+# Copyright (C) 2009, Parrot Foundation.
+# $Id$
+
+=head1 TITLE
+
+math.pir - Demo OpenGL::Math module
+
+=head1 SYNOPSIS
+
+    $ cd parrot-home
+    $ ./parrot examples/opengl/math.pir
+
+=head1 DESCRIPTION
+
+NOTE: THIS IS JUST A STUB WHILE OpenGL::Math IS BEING DEVELOPED.  IT WILL BE
+      FILLED OUT LATER.
+
+This is a simple demo of functionality available from the C<OpenGL::Math>
+Parrot module.
+
+=cut
+
+.sub main :main
+    # Load OpenGL::Math and data dumping debug module
+    load_bytecode 'OpenGL/Math.pbc'
+    load_bytecode 'dumper.pbc'
+
+    # Create some sample data
+    .local pmc vec1, vec2
+    (vec1, vec2) = make_test_vectors()
+
+    # Run a few simple tests
+    sanity(vec1, vec2)
+    normalize(vec1)
+.end
+
+.sub make_test_vectors
+    # Test some basics
+    $P0 = new 'FixedFloatArray'
+    $P0 = 4
+    $P0[0] = 0.5
+    $P0[1] = 1.0
+    $P0[2] = 2.0
+    $P0[3] = 4.0
+
+    $P1 = new 'FixedFloatArray'
+    $P1 = 4
+    $P1[0] = 1.0
+    $P1[1] = 2.0
+    $P1[2] = 3.0
+    $P1[3] = 4.0
+
+    .local pmc Vec4
+    Vec4 = get_class ['OpenGL';'Math';'Vec4']
+
+    $P2 = new Vec4
+    $P2.'set_vals'($P0)
+
+    $P3 = Vec4.'new'('vals' => $P1)
+
+    .return ($P2, $P3)
+.end
+
+.sub sanity
+    .param pmc vec1
+    .param pmc vec2
+
+    .local pmc vec3
+    vec3 = vec1.'mul'(vec2)
+
+    say "\nvec1 * vec2 => vec3"
+    _dumper(vec1, 'vec1')
+    _dumper(vec2, 'vec2')
+    _dumper(vec3, 'vec3')
+
+    .local pmc scaled
+    scaled = vec1.'mul_num'(3)
+
+    say "\nvector * 3 => scaled"
+    _dumper(vec1,   'vector')
+    _dumper(scaled, 'scaled')
+.end
+
+.sub normalize
+    .param pmc vector
+
+    .local pmc normalized
+    normalized = vector.'normalize'()
+
+    say "\nnormalize(vector) => normalized"
+    _dumper(vector,     'vector')
+    _dumper(normalized, 'normalized')
+.end
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/tt761_keys_revamp/examples/opengl/shapes.p6
==============================================================================
--- branches/tt761_keys_revamp/examples/opengl/shapes.p6	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/examples/opengl/shapes.p6	Sat Jul  4 21:38:28 2009	(r39884)
@@ -31,22 +31,30 @@
 use OpenGL:from<parrot>;
 use NCI::Utils:from<parrot>;
 
+# XXX: Need a better way to import constants
 # None of these currently work; they all create an inescapable new lexical pad
 # require 'glutconst.p6';
 # 'glutconst.p6'.evalfile;
 # eval open('glutconst.p6').slurp;
 
+# Parrot
+constant DATATYPE_FLOAT         = -84;
+
+# GLUT
 constant GLUT_RGBA              = 0x0000;
 constant GLUT_DOUBLE            = 0x0002;
 constant GLUT_DEPTH             = 0x0010;
 constant GLUT_STENCIL           = 0x0020;
 
+# OpenGL
 constant GL_DEPTH_BUFFER_BIT    = 0x0100;
 constant GL_STENCIL_BUFFER_BIT  = 0x0400;
 constant GL_COLOR_BUFFER_BIT    = 0x4000;
 
+constant GL_POINTS              = 0x0000;
 constant GL_FALSE               = 0x0000;
 constant GL_TRUE                = 0x0001;
+constant GL_ONE                 = 0x0001;
 constant GL_TRIANGLES           = 0x0004;
 constant GL_EQUAL               = 0x0202;
 constant GL_ALWAYS              = 0x0207;
@@ -54,15 +62,20 @@
 constant GL_ONE_MINUS_SRC_ALPHA = 0x0303;
 constant GL_FRONT               = 0x0404;
 constant GL_BACK                = 0x0405;
+constant GL_LIGHTING            = 0x0B50;
 constant GL_DEPTH_TEST          = 0x0B71;
 constant GL_STENCIL_TEST        = 0x0B90;
 constant GL_NORMALIZE           = 0x0BA1;
 constant GL_BLEND               = 0x0BE2;
+constant GL_SPECULAR            = 0x1202;
+constant GL_POSITION            = 0x1203;
+constant GL_SHININESS           = 0x1601;
+constant GL_AMBIENT_AND_DIFFUSE = 0x1602;
 constant GL_MODELVIEW           = 0x1700;
 constant GL_PROJECTION          = 0x1701;
 constant GL_KEEP                = 0x1E00;
 constant GL_REPLACE             = 0x1E01;
-
+constant GL_LIGHT0              = 0x4000;
 
 our $glut_window;
 
@@ -75,6 +88,8 @@
 our $time_sim    = 0.0;
 our $time_sim_dt = 0.0;
 
+our (@pfx_pos, @pfx_vel);
+
 
 sub MAIN(*@ARGS is rw) {
     # Initialize GLUT and create GLUT window
@@ -89,7 +104,7 @@
     # Enter the GLUT main loop
     glutMainLoop();
 
-    # Rakudo bug -- glutMainLoop() never returns, but Rakudo dies without this
+    # XXX: Rakudo bug -- glutMainLoop() never returns, but Rakudo dies without this
     return;
 }
 
@@ -127,7 +142,7 @@
 
     glViewport(0, 0, $width, $height);
 
-    # Rakudo bug -- Rakudo dies without this
+    # XXX: Rakudo bug -- Rakudo dies without this
     return;
 }
 
@@ -184,6 +199,7 @@
     # Set stencil for just the reflecting area
     glEnable(GL_STENCIL_TEST);
     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+    # XXX: Rakudo bug - decimalized constant in PIR code does wrong thing
     # glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
     glStencilFunc(GL_ALWAYS, 1, +^0);
 
@@ -192,6 +208,7 @@
 
     # Now only draw where stencil is set
     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+    # XXX: Same Rakudo bug (wrong constant)
     # glStencilFunc(GL_EQUAL, 1, 0xffffffff);
     glStencilFunc(GL_EQUAL, 1, +^0);
 
@@ -248,14 +265,41 @@
     glRotatef(90, 1, 0, 0);
 
     # Annulus floor (shapes sit in various spots above it)
-#     my $glu_quadric = gluNewQuadric();
-#     gluDisk($glu_quadric, 1, 2, 128, 1);
-#     gluDeleteQuadric($glu_quadric);
+    my $glu_quadric = gluNewQuadric();
+    gluDisk($glu_quadric, 1, 2, 128, 1);
+    gluDeleteQuadric($glu_quadric);
 
     glPopMatrix();
 }
 
+sub make_float4($a = 0.0, $b = 0.0, $c = 0.0, $d = 1.0) {
+    my @float4_layout = (DATATYPE_FLOAT, 0, 0) xx 4;
+
+    # XXX: How do I do this in pure Perl 6 in Rakudo?
+    return Q:PIR{
+        $P0 = find_lex '@float4_layout'
+        $P1 = new 'ManagedStruct', $P0
+        $P2 = find_lex '$a'
+        $N0 = $P2
+        $P1[0] = $N0
+        $P2 = find_lex '$b'
+        $N0 = $P2
+        $P1[1] = $N0
+        $P2 = find_lex '$c'
+        $N0 = $P2
+        $P1[2] = $N0
+        $P2 = find_lex '$d'
+        $N0 = $P2
+        $P1[3] = $N0
+        %r  = $P1
+    };
+}
+
 sub set_lights {
+    my $position := make_float4(0.0, 2.0, 0.0, 1.0);
+
+    glEnable(GL_LIGHT0);
+    glLightfv(GL_LIGHT0, GL_POSITION, $position);
 }
 
 sub draw_objects {
@@ -283,12 +327,26 @@
 }
 
 sub draw_lit_teapot {
-}
+    # Lit cyan teapot at +X
 
-sub update_particle_effect {
-}
+    glPushMatrix();
+    glTranslatef(1.5, .4, 0);
+    glRotatef(90, 0, 1, 0);
 
-sub draw_particle_effect {
+    glEnable(GL_LIGHTING);
+
+    my $color := make_float4(0.0, 0.8, 0.8, 1.0);
+    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, $color);
+
+    $color := make_float4(1.0, 1.0, 1.0, 1.0);
+    glMaterialfv(GL_FRONT, GL_SPECULAR,  $color);
+    glMaterialf( GL_FRONT, GL_SHININESS, 64);
+
+    glutSolidTeapot(.5);
+
+    glDisable(GL_LIGHTING);
+
+    glPopMatrix();
 }
 
 sub set_2d_view {
@@ -299,359 +357,119 @@
     glLoadIdentity();
 }
 
-
-=begin pod
-
-.sub main :main
-    # Init miscellaneous globals
-    init_globals()
-
-    # Create particle effect
-    init_particle_effect()
-.end
-
-.sub init_globals
-    # Create structure definition for float4 structure
-    .local pmc float4
-    float4 = new 'ResizablePMCArray'
-    push float4, .DATATYPE_FLOAT
-    push float4, 0
-    push float4, 0
-    push float4, .DATATYPE_FLOAT
-    push float4, 0
-    push float4, 0
-    push float4, .DATATYPE_FLOAT
-    push float4, 0
-    push float4, 0
-    push float4, .DATATYPE_FLOAT
-    push float4, 0
-    push float4, 0
-    set_global 'float4', float4
-.end
-
-.sub init_particle_effect
-    .local pmc pfx_pos, pfx_vel
-    pfx_pos = new 'ResizablePMCArray'
-    pfx_vel = new 'ResizablePMCArray'
-
-    new_particle(0, pfx_pos, pfx_vel)
-
-    set_global 'pfx_pos', pfx_pos
-    set_global 'pfx_vel', pfx_vel
-.end
-
-.sub set_lights
-    glEnable(.GL_LIGHT0)
-
-    # Light above origin
-    .local pmc float4, position
-    float4   = get_global 'float4'
-    position = new 'ManagedStruct', float4
-    position[0] = 0.0
-    position[1] = 2.0
-    position[2] = 0.0
-    position[3] = 1.0
-
-    glLightfv(.GL_LIGHT0, .GL_POSITION, position)
-.end
-
-.sub draw_lit_teapot
-    # Lit cyan teapot at +X
-
-    glPushMatrix()
-    glTranslatef(1.5, .4, 0)
-    glRotatef(90, 0, 1, 0)
-
-    glEnable(.GL_LIGHTING)
-
-    .local pmc float4, color
-    float4 = get_global 'float4'
-    color  = new 'ManagedStruct', float4
-    color[0] = 0.0
-    color[1] = 0.8
-    color[2] = 0.8
-    color[3] = 1.0
-    glMaterialfv(.GL_FRONT, .GL_AMBIENT_AND_DIFFUSE, color)
-
-    color[0] = 1.0
-    color[1] = 1.0
-    color[2] = 1.0
-    color[3] = 1.0
-    glMaterialfv(.GL_FRONT, .GL_SPECULAR,  color)
-    glMaterialf (.GL_FRONT, .GL_SHININESS, 64)
-
-    glutSolidTeapot(.5)
-
-    glDisable(.GL_LIGHTING)
-
-    glPopMatrix()
-.end
-
-.sub new_particle
-    .param int particle_num
-    .param pmc pfx_pos
-    .param pmc pfx_vel
-
-    .local num x, y, z, vx, vy, vz
-    x  = 4.0
-    y  = 0.0
-    z  = 0.0
-
-    vx = 0.0
-    vy = 0.135
-    vz = 0.0
-
-    .local pmc random
-    .local num rand
-    random = new 'Random'
-    rand  = random
-    rand *= .1
-    x    += rand
-    rand  = random
-    rand *= .1
-    y    += rand
-    rand  = random
-    rand *= .1
-    z    += rand
-
-    rand  = random
-    rand -= .5
-    rand *= .01
-    vx   += rand
-    rand  = random
-    rand -= .5
-    rand *= .01
-    vy   += rand
-    rand  = random
-    rand -= .5
-    rand *= .01
-    vz   += rand
-
-    .local pmc pos
-    pos = new 'FixedFloatArray'
-    pos = 3
-    pos[0] = x
-    pos[1] = y
-    pos[2] = z
-
-    .local pmc vel
-    vel = new 'FixedFloatArray'
-    vel = 3
-    vel[0] = vx
-    vel[1] = vy
-    vel[2] = vz
-
-    pfx_pos[particle_num] = pos
-    pfx_vel[particle_num] = vel
-.end
-
-.sub update_particle_effect
-    .param num dt
-
-    # "Black hole" particle effect at +Z
-
+sub update_particle_effect {
     # Speed up time a little; this effect is *slow*
-    dt *= 30.0
-
-    # Global particle state arrays
-    .local pmc pfx_pos, pfx_vel
-    pfx_pos = get_global 'pfx_pos'
-    pfx_vel = get_global 'pfx_vel'
+    my $dt = $time_sim_dt * 30;
 
     # Add a particle at random
-    .local int count
-    count = pfx_pos
-    if count > 1000 goto update_particles
-    .local pmc random
-    .local num rand
-    random = new 'Random'
-    rand   = random
-    rand  *= 4
-    if rand > dt goto update_particles
-    new_particle(count, pfx_pos, pfx_vel)
+    my $count = @pfx_pos.elems;
+    new_particle($count) if $count < 1000 && $dt > rand * 4;
 
     # Update all particles
-  update_particles:
-    dec count
-    if count < 0 goto update_particles_end
-
-    # Update particle states
-    update_particle(pfx_pos, pfx_vel, count, dt)
-
-    goto update_particles
-  update_particles_end:
-.end
-
-.sub update_particle
-    .param pmc pfx_pos
-    .param pmc pfx_vel
-    .param int particle_num
-    .param num dt
-
-    .local pmc pos, vel
-    pos = pfx_pos[particle_num]
-    vel = pfx_vel[particle_num]
+    update_particle($_, $dt) for ^$count;
+}
 
+sub new_particle($particle_num) {
+    @pfx_pos[$particle_num] = [ 4.0 + rand * .1,
+                                0.0 + rand * .1,
+                                0.0 + rand * .1 ];
+    @pfx_vel[$particle_num] = [ 0.0   + (rand - .5) * .01,
+                                0.135 + (rand - .5) * .01,
+                                0.0   + (rand - .5) * .01 ];
+
+    return;
+}
+
+sub update_particle($particle_num, $dt) {
     # Constants
-    .const num G           = -.075   # Gravitational force constant
-    .const num Cd          = -.00033 # Coefficient of drag
-    .const num event_grav  = -.3     # Gravity at "event horizon"
-    .const num min_dist2   =  .001   # Minimum distance**2 before calc blows up
-    .const num escape_dist = 30      # Distance at which "escape" occurs
+    constant G           = -.075;   # Gravitational force constant
+    constant Cd          = -.00033; # Coefficient of drag
+    constant event_grav  = -.3;     # Gravity at "event horizon"
+    constant min_dist2   =  .001;   # Minimum distance**2 before calc blows up
+    constant escape_dist = 30;      # Distance at which "escape" occurs
 
     # Particle states
-    .local num x, y, z, vx, vy, vz
-    x  = pos[0]
-    y  = pos[1]
-    z  = pos[2]
-    vx = vel[0]
-    vy = vel[1]
-    vz = vel[2]
+    my @pos := @pfx_pos[$particle_num];
+    my @vel := @pfx_vel[$particle_num];
 
     # Calculate distance and distance squared
-    .local num x2, y2, z2, dist2, dist
-    x2     = x * x
-    y2     = y * y
-    z2     = z * z
-    dist2  = x2 + y2
-    dist2 += z2
-    if dist2 >= min_dist2 goto dist2_ok
-    dist2  = min_dist2
-  dist2_ok:
-    dist   = sqrt dist2
+    my $dist_squared = [+] @pos >>*<< @pos;
+       $dist_squared = min_dist2 unless $dist_squared > min_dist2;
+    my $distance     = sqrt($dist_squared);
 
     # If distance is too great, particle has "escaped"; regenerate it
-    if dist < escape_dist goto dist_ok
-    new_particle(particle_num, pfx_pos, pfx_vel)
-    .return ()
-  dist_ok:
+    return new_particle($particle_num) if $distance > escape_dist;
 
     # Compute gravity force
-    .local num grav
-    grav = G / dist2
+    my $gravity = G / $dist_squared;
 
     # If gravity is too strong, it has "passed the event horizon"; regenerate it
-    if grav > event_grav goto grav_ok
-    new_particle(particle_num, pfx_pos, pfx_vel)
-    .return ()
-  grav_ok:
+    return new_particle($particle_num) if $gravity <= event_grav;
 
     # Calculate gravity vector (always directed toward center of "hole")
-    .local num gx, gy, gz
-    gx  = x / dist
-    gy  = y / dist
-    gz  = z / dist
-    gx *= grav
-    gy *= grav
-    gz *= grav
+    my @grav = @pos >>/>> $distance >>*>> $gravity;
 
     # Calculate drag vector (always directed opposite of velocity)
     # NOTE: Using drag proportional to velocity, instead of velocity squared
-    .local num dragx, dragy, dragz
-    dragx = Cd * vx
-    dragy = Cd * vy
-    dragz = Cd * vz
+    my @drag = @vel >>*>> Cd;
 
     # Acceleration is gravity + drag
-    .local num ax, ay, az
-    ax = gx + dragx
-    ay = gy + dragy
-    az = gz + dragz
+    my @acc = @grav >>+<< @drag;
 
     # Update velocity and position with simple Euler integration
-    .local num dvx, dvy, dvz
-    .local num  dx,  dy,  dz
-    dvx  = ax * dt
-    dvy  = ay * dt
-    dvz  = az * dt
-    vx  += dvx
-    vy  += dvy
-    vz  += dvz
-    dx   = vx * dt
-    dy   = vy * dt
-    dz   = vz * dt
-    x   += dx
-    y   += dy
-    z   += dz
-
-    # Save new values back to particle state
-    vel[0] = vx
-    vel[1] = vy
-    vel[2] = vz
-    pos[0] = x
-    pos[1] = y
-    pos[2] = z
-.end
+    @vel = @vel >>+<< @acc >>*>> $dt;
+    @pos = @pos >>+<< @vel >>*>> $dt;
+}
 
-.sub draw_particle_effect
+sub draw_particle_effect {
     # "Black hole" particle effect at +Z
 
     # Make it visually interesting
-    glPushMatrix()
-    glTranslatef(0, .3, 1.5)
-    glRotatef(-20, 0, 0, 1)
-    glRotatef( 90, 1, 0, 0)
-    glScalef(.15, .15, .15)
+    glPushMatrix();
+    glTranslatef(0, .3, 1.5);
+    glRotatef(-20, 0, 0, 1);
+    glRotatef( 90, 1, 0, 0);
+    glScalef(.15, .15, .15);
 
     # OpenGL state for "glowing transparent particles"
-    glEnable(.GL_BLEND)
-    glBlendFunc(.GL_SRC_ALPHA, .GL_ONE)
-    glDepthMask(.GL_FALSE)
-    glPointSize(4)
-
-    # XXXX: Disabled for now because it's broken on many systems;
-    #       will replace later with textured quads
-    # glEnable(.GL_POINT_SMOOTH)
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+    glDepthMask(GL_FALSE);
+    glPointSize(4);
+
+    # XXX: Disabled for now because it's broken on many systems;
+    #      will replace later with textured quads
+    # glEnable(GL_POINT_SMOOTH);
 
 #     # Show plane of effect
-#     glColor4f(1, 1, 1, .2)
-#     glBegin(.GL_QUADS)
-#     glVertex3f(-2, -2, 0)
-#     glVertex3f( 2, -2, 0)
-#     glVertex3f( 2,  2, 0)
-#     glVertex3f(-2,  2, 0)
-#     glEnd()
-
-    # Start drawing particles
-    glColor4f(1, 1, 1, .5)
-    glBegin(.GL_POINTS)
-
-    # Global particle state arrays
-    .local pmc pfx_pos, pfx_vel
-    pfx_pos = get_global 'pfx_pos'
-    pfx_vel = get_global 'pfx_vel'
-
-    # Loop over all particles, updating and drawing them
-    .local int count
-    count = pfx_pos
-  draw_particle_loop:
-    dec count
-    if count < 0 goto draw_particle_loop_end
-
-    # Draw particle
-    .local pmc pos
-    .local num x, y, z
-    pos = pfx_pos[count]
-    x   = pos[0]
-    y   = pos[1]
-    z   = pos[2]
-    glVertex3f(x, y, z)
-
-    goto draw_particle_loop
-
-    # Finished with all particles
-  draw_particle_loop_end:
-    glEnd()
+#     glColor4f(1, 1, 1, .2);
+#     glBegin(GL_QUADS);
+#     glVertex3f(-2, -2, 0);
+#     glVertex3f( 2, -2, 0);
+#     glVertex3f( 2,  2, 0);
+#     glVertex3f(-2,  2, 0);
+#     glEnd();
+
+    # White color, but semi-transparent
+    glColor4f(1, 1, 1, .5);
+
+    # Draw all particles
+    glBegin(GL_POINTS);
+    for @pfx_pos -> $pos {
+        # XXX: Rakudo bug - appears not to properly unpack for NCI calls
+        # glVertex3f(|$pos);
+        my ($x, $y, $z) = @($pos)[0..2];
+        glVertex3f($x, $y, $z);
+    }
+    glEnd();
 
     # Done, return to normal OpenGL state
-    glDepthMask(.GL_TRUE)
-    glDisable(.GL_BLEND)
-
-    glPopMatrix()
-.end
+    glDepthMask(GL_TRUE);
+    glDisable(GL_BLEND);
 
+    glPopMatrix();
+}
 
-=end pod
 
 # Local Variables:
 #   mode: pir

Copied and modified: branches/tt761_keys_revamp/examples/pge/demo.pir (from r39858, branches/tt761_keys_revamp/compilers/pge/demo.pir)
==============================================================================
--- branches/tt761_keys_revamp/compilers/pge/demo.pir	Wed Jul  1 22:38:36 2009	(r39858, copy source)
+++ branches/tt761_keys_revamp/examples/pge/demo.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -58,7 +58,7 @@
   match_result:
     unless match goto match_fail
     print "match succeeded\n"
-    $P0 = find_global "_dumper"
+    $P0 = get_global "_dumper"
     $P0(match, "$/")
     goto read_loop
   match_fail:
@@ -90,7 +90,7 @@
   save_rule:
     if_null rulesub, match_nopattern
     x = substr x, 5
-    store_global x, rulesub
+    set_global x, rulesub
     print "Saved as "
     print x
     print "\n"
@@ -104,7 +104,7 @@
 
   print_exp:
     if_null rulesub, match_nopattern
-    $P0 = find_global "_dumper"
+    $P0 = get_global "_dumper"
     $P0(exp, "exp")
     goto read_loop
 

Modified: branches/tt761_keys_revamp/examples/tutorial/01_temp_var.pir
==============================================================================
--- branches/tt761_keys_revamp/examples/tutorial/01_temp_var.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/examples/tutorial/01_temp_var.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -23,7 +23,7 @@
 
     $S5 = "Hello"    # set temp string var to "Hello"
 
-    $P0 = new 'String'
+    $P0 = new ['String']
     $P0 = "Ford"     # set temp PMC var to "Ford"
 
     say $I0

Modified: branches/tt761_keys_revamp/examples/tutorial/02_local_var.pir
==============================================================================
--- branches/tt761_keys_revamp/examples/tutorial/02_local_var.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/examples/tutorial/02_local_var.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -36,7 +36,7 @@
     print "\n"
 
     .local pmc player
-    player = new 'String'
+    player = new ['String']
     player = "Ford"     # set temp PMC var to "Ford"
     print player
     print "\n"

Modified: branches/tt761_keys_revamp/examples/tutorial/03_temp_var_basic_pmcs.pir
==============================================================================
--- branches/tt761_keys_revamp/examples/tutorial/03_temp_var_basic_pmcs.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/examples/tutorial/03_temp_var_basic_pmcs.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -18,15 +18,15 @@
 =cut
 
 .sub main :main
-    $P0 = new 'Integer'
+    $P0 = new ['Integer']
     $P0 = 42
     say $P0
 
-    $P1 = new 'Float'
+    $P1 = new ['Float']
     $P1 = 6.35
     say $P1
 
-    $P2 = new 'ResizableStringArray'
+    $P2 = new ['ResizableStringArray']
     $P2[0] = "Foo"
     $P2[1] = "Bar"
     $P2[2] = "Baz"

Modified: branches/tt761_keys_revamp/examples/tutorial/24_string_ops_clone.pir
==============================================================================
--- branches/tt761_keys_revamp/examples/tutorial/24_string_ops_clone.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/examples/tutorial/24_string_ops_clone.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -14,7 +14,7 @@
 .sub main :main
     .local pmc firstname
 
-    firstname = new 'String'
+    firstname = new ['String']
     firstname = "Ford"
     say firstname
 

Modified: branches/tt761_keys_revamp/examples/tutorial/30_arrays_basic.pir
==============================================================================
--- branches/tt761_keys_revamp/examples/tutorial/30_arrays_basic.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/examples/tutorial/30_arrays_basic.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -18,7 +18,7 @@
 .sub main :main
 
     .local pmc myarray
-    myarray = new 'ResizableStringArray'
+    myarray = new ['ResizableStringArray']
 
     myarray[0] = "Foo"
     push myarray, "Bar"

Modified: branches/tt761_keys_revamp/examples/tutorial/32_array_ops_sprintf.pir
==============================================================================
--- branches/tt761_keys_revamp/examples/tutorial/32_array_ops_sprintf.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/examples/tutorial/32_array_ops_sprintf.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -14,13 +14,13 @@
 .sub main :main
 
     .local pmc myarray
-    myarray = new 'ResizablePMCArray'
+    myarray = new ['ResizablePMCArray']
 
-    $P0 = new 'Integer'
+    $P0 = new ['Integer']
     $P0 = 42
     push myarray, $P0
 
-    $P1 = new 'Float'
+    $P1 = new ['Float']
     $P1 = 10.5
     push myarray, $P1
 

Modified: branches/tt761_keys_revamp/examples/tutorial/33_hashes.pir
==============================================================================
--- branches/tt761_keys_revamp/examples/tutorial/33_hashes.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/examples/tutorial/33_hashes.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -22,7 +22,7 @@
 .sub main :main
 
     .local pmc myhash
-    myhash = new 'Hash'
+    myhash = new ['Hash']
 
     myhash['foo'] = 5
     myhash['bar'] = "Hello"

Modified: branches/tt761_keys_revamp/examples/tutorial/34_multikey.pir
==============================================================================
--- branches/tt761_keys_revamp/examples/tutorial/34_multikey.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/examples/tutorial/34_multikey.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -17,8 +17,8 @@
 .sub main :main
 
     .local pmc myhash, innerarray
-    myhash  = new 'Hash'
-    innerarray = new 'ResizableIntegerArray'
+    myhash  = new ['Hash']
+    innerarray = new ['ResizableIntegerArray']
 
     $I0 = 2
     innerarray[2] = 42

Modified: branches/tt761_keys_revamp/examples/tutorial/40_file_ops.pir
==============================================================================
--- branches/tt761_keys_revamp/examples/tutorial/40_file_ops.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/examples/tutorial/40_file_ops.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -20,7 +20,7 @@
     close filein
 
     # Be nice and remove the temporary file we created.
-    $P1 = new 'OS'
+    $P1 = new ['OS']
     $P1.'rm'('40_file_ops_data.txt')
 .end
 

Modified: branches/tt761_keys_revamp/examples/tutorial/55_iterator.pir
==============================================================================
--- branches/tt761_keys_revamp/examples/tutorial/55_iterator.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/examples/tutorial/55_iterator.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -21,7 +21,7 @@
 
     myarray = split " ", "foo bar baz boz"
 
-    iter = new 'Iterator', myarray
+    iter = new ['Iterator'], myarray
   iter_loop:
     unless iter goto iter_end
 

Modified: branches/tt761_keys_revamp/examples/tutorial/56_defined.pir
==============================================================================
--- branches/tt761_keys_revamp/examples/tutorial/56_defined.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/examples/tutorial/56_defined.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -15,7 +15,7 @@
 
 .sub main :main
 
-    $P1 = new 'String'
+    $P1 = new ['String']
     $I0 = defined $P1
     if $I0 goto defined_P1
         say "$P1 is undefined"
@@ -32,7 +32,7 @@
 =cut
 
   end_defined_P1:
-    $P3 = new 'Undef'
+    $P3 = new ['Undef']
     $I0 = defined $P3
     if $I0 goto defined_P3
         say "$P3 is undefined"

Modified: branches/tt761_keys_revamp/examples/tutorial/57_exists.pir
==============================================================================
--- branches/tt761_keys_revamp/examples/tutorial/57_exists.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/examples/tutorial/57_exists.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -23,10 +23,10 @@
 
     # set up an array with two elements
     .local pmc my_array
-    my_array = new 'ResizablePMCArray'
-    $P0      = new 'String'
+    my_array = new ['ResizablePMCArray']
+    $P0      = new ['String']
     $P0      = "Hello"
-    $P1      = new 'Undef'
+    $P1      = new ['Undef']
     push my_array, $P0
     push my_array, $P1
 

Modified: branches/tt761_keys_revamp/examples/tutorial/61_namespaces.pir
==============================================================================
--- branches/tt761_keys_revamp/examples/tutorial/61_namespaces.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/examples/tutorial/61_namespaces.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -20,7 +20,7 @@
 
 .sub main :main
 
-   $P0 = new 'String'
+   $P0 = new ['String']
    $P0 = "Hello"
    set_global ["Different"; "Namespace"], "foo", $P0
 

Modified: branches/tt761_keys_revamp/examples/tutorial/70_class_object.pir
==============================================================================
--- branches/tt761_keys_revamp/examples/tutorial/70_class_object.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/examples/tutorial/70_class_object.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -37,7 +37,7 @@
     addattribute myclass, 'bar'
     addattribute myclass, 'baz'
 
-    myobj = new 'Foo'
+    myobj = new ['Foo']
     myobj.'set_bar'("Hello")
     myobj.'set_baz'(5)
 
@@ -61,7 +61,7 @@
 .sub set_bar :method
     .param string value
 
-    $P0 = new 'String'
+    $P0 = new ['String']
     $P0 = value
     setattribute self, "bar", $P0
 .end
@@ -74,7 +74,7 @@
 .sub set_baz :method
     .param int value
 
-    $P0 = new 'Integer'
+    $P0 = new ['Integer']
     $P0 = value
     setattribute self, "baz", $P0
 .end

Modified: branches/tt761_keys_revamp/examples/tutorial/81_continuation.pir
==============================================================================
--- branches/tt761_keys_revamp/examples/tutorial/81_continuation.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/examples/tutorial/81_continuation.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -15,7 +15,7 @@
 
 .sub main :main
     .local pmc cont
-    cont = new 'Continuation'
+    cont = new ['Continuation']
     set_addr cont, continued
 
     test_call(4, cont)

Modified: branches/tt761_keys_revamp/include/parrot/compiler.h
==============================================================================
--- branches/tt761_keys_revamp/include/parrot/compiler.h	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/include/parrot/compiler.h	Sat Jul  4 21:38:28 2009	(r39884)
@@ -126,8 +126,12 @@
 #define PARROT_IGNORABLE_RESULT
 #define PARROT_WARN_UNUSED_RESULT   __attribute__warn_unused_result__
 
+/* Pure functions have no side-effects, and depend only on parms or globals. e.g. strlen() */
 #define PARROT_PURE_FUNCTION                __attribute__pure__  __attribute__warn_unused_result__
+
+/* Const functions are pure functions, and do not examine targets of pointers. e.g. sqrt() */
 #define PARROT_CONST_FUNCTION               __attribute__const__ __attribute__warn_unused_result__
+
 #define PARROT_DOES_NOT_RETURN              /*@noreturn@*/ __attribute__noreturn__
 #define PARROT_DOES_NOT_RETURN_WHEN_FALSE   /*@noreturnwhenfalse@*/
 #define PARROT_MALLOC                       /*@only@*/ __attribute__malloc__ __attribute__warn_unused_result__

Modified: branches/tt761_keys_revamp/include/parrot/key.h
==============================================================================
--- branches/tt761_keys_revamp/include/parrot/key.h	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/include/parrot/key.h	Sat Jul  4 21:38:28 2009	(r39884)
@@ -167,7 +167,7 @@
         __attribute__nonnull__(2);
 
 PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
+PARROT_CAN_RETURN_NULL
 STRING * key_string(PARROT_INTERP, ARGIN(PMC *key))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);

Modified: branches/tt761_keys_revamp/include/parrot/memory.h
==============================================================================
--- branches/tt761_keys_revamp/include/parrot/memory.h	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/include/parrot/memory.h	Sat Jul  4 21:38:28 2009	(r39884)
@@ -70,6 +70,12 @@
     size_t size,
     size_t old_size);
 
+PARROT_EXPORT
+PARROT_MALLOC
+PARROT_CANNOT_RETURN_NULL
+char * mem_sys_strdup(ARGIN(const char *src))
+        __attribute__nonnull__(1);
+
 PARROT_MALLOC
 PARROT_CANNOT_RETURN_NULL
 void * mem__internal_allocate(
@@ -116,6 +122,8 @@
 #define ASSERT_ARGS_mem_sys_free __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_mem_sys_realloc __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
 #define ASSERT_ARGS_mem_sys_realloc_zeroed __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
+#define ASSERT_ARGS_mem_sys_strdup __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(src)
 #define ASSERT_ARGS_mem__internal_allocate __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(file)
 #define ASSERT_ARGS_mem__internal_allocate_zeroed __attribute__unused__ int _ASSERT_ARGS_CHECK = \

Modified: branches/tt761_keys_revamp/include/parrot/pmc.h
==============================================================================
--- branches/tt761_keys_revamp/include/parrot/pmc.h	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/include/parrot/pmc.h	Sat Jul  4 21:38:28 2009	(r39884)
@@ -45,6 +45,11 @@
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
+void gc_unregister_pmc(PARROT_INTERP, ARGIN(PMC *pmc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
 void Parrot_create_mro(PARROT_INTERP, INTVAL type)
         __attribute__nonnull__(1);
 
@@ -118,10 +123,6 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
-void gc_unregister_pmc(PARROT_INTERP, ARGIN(PMC *pmc))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
 INTVAL get_new_vtable_index(PARROT_INTERP)
         __attribute__nonnull__(1);
 
@@ -143,6 +144,9 @@
 #define ASSERT_ARGS_gc_register_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(pmc)
+#define ASSERT_ARGS_gc_unregister_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(pmc)
 #define ASSERT_ARGS_Parrot_create_mro __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_PMC_is_null __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
@@ -172,9 +176,6 @@
 #define ASSERT_ARGS_pmc_type_p __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(name)
-#define ASSERT_ARGS_gc_unregister_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = \
-       PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(pmc)
 #define ASSERT_ARGS_get_new_vtable_index __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp)
 #define ASSERT_ARGS_temporary_pmc_free __attribute__unused__ int _ASSERT_ARGS_CHECK = \

Modified: branches/tt761_keys_revamp/include/parrot/stacks.h
==============================================================================
--- branches/tt761_keys_revamp/include/parrot/stacks.h	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/include/parrot/stacks.h	Sat Jul  4 21:38:28 2009	(r39884)
@@ -37,7 +37,7 @@
 /* #define STACK_ITEMSIZE(chunk) PObj_buflen(chunk) */
 
 
-typedef void (*Stack_cleanup_method)(Interp*, Stack_Entry_t *);
+typedef void (*Stack_cleanup_method)(PARROT_INTERP, ARGIN(struct Stack_Entry *));
 
 #define STACK_CLEANUP_NULL ((Stack_cleanup_method)NULLfunc)
 

Modified: branches/tt761_keys_revamp/include/parrot/sub.h
==============================================================================
--- branches/tt761_keys_revamp/include/parrot/sub.h	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/include/parrot/sub.h	Sat Jul  4 21:38:28 2009	(r39884)
@@ -169,9 +169,10 @@
 
 #define PMC_get_sub(interp, pmc, sub) \
     do { \
-        if ((pmc)->vtable->base_type == enum_class_Sub || \
-            (pmc)->vtable->base_type == enum_class_Coroutine || \
-            (pmc)->vtable->base_type == enum_class_Eval)  \
+        const INTVAL type = (pmc)->vtable->base_type; \
+        if (type == enum_class_Sub || \
+            type == enum_class_Coroutine || \
+            type == enum_class_Eval)  \
         {\
             GETATTR_Sub_sub((interp), (pmc), (sub)); \
         } \

Modified: branches/tt761_keys_revamp/include/parrot/thr_windows.h
==============================================================================
--- branches/tt761_keys_revamp/include/parrot/thr_windows.h	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/include/parrot/thr_windows.h	Sat Jul  4 21:38:28 2009	(r39884)
@@ -123,13 +123,13 @@
 
 typedef void (*Cleanup_Handler)(void *);
 
-#ifndef _STRUCT_TIMESPEC
-#  define _STRUCT_TIMESPEC
+#ifndef HAVE_STRUCT_TIMESPEC
+#  define HAVE_STRUCT_TIMESPEC
 struct timespec {
     time_t tv_sec;
     long tv_nsec;
 };
-#endif /* _STRUCT_TIMESPEC */
+#endif /* HAVE_STRUCT_TIMESPEC */
 
 #  undef CONST
 

Modified: branches/tt761_keys_revamp/lib/Parrot/Distribution.pm
==============================================================================
--- branches/tt761_keys_revamp/lib/Parrot/Distribution.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/lib/Parrot/Distribution.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -404,7 +404,6 @@
             config/auto/cpu/i386/memcpy_mmx_in.c
             config/auto/cpu/i386/memcpy_sse.c
             config/auto/cpu/i386/memcpy_sse_in.c
-            config/gen/config_h/config_h.in
             config/gen/config_h/feature_h.in
             compilers/imcc/imclexer.c
             compilers/imcc/imcparser.c
@@ -431,6 +430,7 @@
             compilers/pirc/macro/macrolexer.h
             compilers/pirc/macro/macroparser.c
             compilers/pirc/macro/macroparser.h
+            include/parrot/config.h
             src/gc/malloc.c
             } unless @exemptions;
 

Modified: branches/tt761_keys_revamp/lib/Parrot/Docs/Section/Parrot.pm
==============================================================================
--- branches/tt761_keys_revamp/lib/Parrot/Docs/Section/Parrot.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/lib/Parrot/Docs/Section/Parrot.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -60,7 +60,7 @@
             'Introduction',
             '',
             $self->new_item( 'Introduction to Parrot', 'docs/intro.pod'),
-            $self->new_item( 'Getting Started', 'docs/book/ch02_getting_started.pod'),
+            $self->new_item( 'Getting Started', 'docs/book/draft/ch02_getting_started.pod'),
             $self->new_item( 'Navigating the Docs', 'docs/parrot.pod'),
             $self->new_item( 'Roles & Responsibilities', 'docs/project/roles_responsibilities.pod'),
             $self->new_item( 'Release History', 'docs/parrothist.pod'),
@@ -80,9 +80,9 @@
         $self->new_group(
             'Implementing Languages on Parrot',
             '',
-            $self->new_item( 'Parrot Compiler Tools', 'docs/book/ch04_compiler_tools.pod'),
-            $self->new_item( 'Parrot Grammar Engine', 'docs/book/ch05_pge.pod'),
-            $self->new_item( 'Not Quite Perl', 'docs/book/ch06_nqp.pod'),
+            $self->new_item( 'Parrot Compiler Tools', 'docs/book/draft/ch04_compiler_tools.pod'),
+            $self->new_item( 'Parrot Grammar Engine', 'docs/book/draft/ch05_pge.pod'),
+            $self->new_item( 'Not Quite Perl', 'docs/book/draft/ch06_nqp.pod'),
             $self->new_item( 'Compiler FAQ', 'docs/compiler_faq.pod'),
         ),
         $self->new_group(
@@ -97,24 +97,38 @@
             $self->new_item( 'Syntax Highlighting for Vim & Emacs', 'editor/README.pod'),
         ),
         $self->new_group(
-            'Book',
+            'Book draft',
             '',
-            $self->new_item( 'Chapter 1 Introduction', 'docs/book/ch01_introduction.pod'),
-            $self->new_item( 'Chapter 2 Getting Started', 'docs/book/ch02_getting_started.pod'),
-            $self->new_item( 'Chapter 3 Parrot Intermediate Representation', 'docs/book/ch03_pir.pod'),
-            $self->new_item( 'Chapter 4 Parrot Compiler Tools', 'docs/book/ch04_compiler_tools.pod'),
-            $self->new_item( 'Chapter 5 Parrot Grammar Engine', 'docs/book/ch05_pge.pod'),
-            $self->new_item( 'Chapter 6 Not Quite Perl', 'docs/book/ch06_nqp.pod'),
-            $self->new_item( 'Chapter 7 Dynamic C-level Objects', 'docs/book/ch07_dynpmcs.pod'),
-            $self->new_item( 'Chapter 8 Dynamic Opcodes', 'docs/book/ch08_dynops.pod'),
-            $self->new_item( 'Chapter 10 Instruction Reference', 'docs/book/ch10_opcode_reference.pod'),
-            $self->new_item( 'Chapter 11 Directive Reference', 'docs/book/ch11_directive_reference.pod'),
-            $self->new_item( 'Chapter 12 PIR Operator Reference', 'docs/book/ch12_operator_reference.pod'),
-            $self->new_item( 'Appendix A Glossary', 'docs/book/appa_glossary.pod'),
-            $self->new_item( 'Appendix B Patch Submission', 'docs/book/appb_patch_submission.pod'),
-            $self->new_item( 'Appendix C ', 'docs/book/appc_command_line_options.pod'),
-            $self->new_item( 'Appendix D ', 'docs/book/appd_build_options.pod'),
-            $self->new_item( 'Appendix E ', 'docs/book/appe_source_code.pod'),
+            $self->new_item( 'Chapter 1 Introduction', 'docs/book/draft/ch01_introduction.pod'),
+            $self->new_item( 'Chapter 2 Getting Started', 'docs/book/draft/ch02_getting_started.pod'),
+            $self->new_item( 'Chapter 3 Parrot Intermediate Representation', 'docs/book/draft/ch03_pir.pod'),
+            $self->new_item( 'Chapter 4 Parrot Compiler Tools', 'docs/book/draft/ch04_compiler_tools.pod'),
+            $self->new_item( 'Chapter 5 Parrot Grammar Engine', 'docs/book/draft/ch05_pge.pod'),
+            $self->new_item( 'Chapter 6 Not Quite Perl', 'docs/book/draft/ch06_nqp.pod'),
+            $self->new_item( 'Chapter 7 Dynamic C-level Objects', 'docs/book/draft/ch07_dynpmcs.pod'),
+            $self->new_item( 'Chapter 8 Dynamic Opcodes', 'docs/book/draft/ch08_dynops.pod'),
+            $self->new_item( 'Chapter 10 Instruction Reference', 'docs/book/draft/ch10_opcode_reference.pod'),
+            $self->new_item( 'Chapter 11 Directive Reference', 'docs/book/draft/ch11_directive_reference.pod'),
+            $self->new_item( 'Chapter 12 PIR Operator Reference', 'docs/book/draft/ch12_operator_reference.pod'),
+            $self->new_item( 'Appendix A Glossary', 'docs/book/draft/appa_glossary.pod'),
+            $self->new_item( 'Appendix B Patch Submission', 'docs/book/draft/appb_patch_submission.pod'),
+            $self->new_item( 'Appendix C ', 'docs/book/draft/appc_command_line_options.pod'),
+            $self->new_item( 'Appendix D ', 'docs/book/draft/appd_build_options.pod'),
+            $self->new_item( 'Appendix E ', 'docs/book/draft/appe_source_code.pod'),
+        ),
+
+        $self->new_group(
+            'Book PIR',
+            '',
+            $self->new_item( 'Chapter 1 Introduction', 'docs/book/pir/ch01_introduction.pod'),
+            $self->new_item( 'Chapter 2 Getting Started', 'docs/book/pir/ch02_getting_started.pod'),
+            $self->new_item( 'Chapter 3 Basic Syntax', 'docs/book/pir/ch03_basic_syntax.pod'),
+            $self->new_item( 'Chapter 4 Variables', 'docs/book/pir/ch04_variables.pod'),
+            $self->new_item( 'Chapter 5 Control Structures', 'docs/book/pir/ch05_control_structures.pod'),
+            $self->new_item( 'Chapter 6 Subroutines', 'docs/book/pir/ch06_subroutines.pod'),
+            $self->new_item( 'Chapter 7 Objects', 'docs/book/pir/ch07_objects.pod'),
+            $self->new_item( 'Chapter 8 IO', 'docs/book/pir/ch08_io.pod'),
+            $self->new_item( 'Chapter 9 Exceptions', 'docs/book/pir/ch09_exceptions.pod'),
         ),
 
 #        Parrot::Docs::Section::C->new,

Modified: branches/tt761_keys_revamp/lib/Parrot/Install.pm
==============================================================================
--- branches/tt761_keys_revamp/lib/Parrot/Install.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/lib/Parrot/Install.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -173,12 +173,16 @@
 =cut
 
 sub create_directories {
-    my($destdir, $directories) = @_;
+    my ( $destdir, $directories ) = @_;
+
+    my @dirs_to_create = grep { ! -d } map { $destdir . $_ } sort keys %{$directories};
+
+    my $print_the_dirs = 0;
+    my $mode = oct('0777');
+
+    # We must use the legacy interface to support File::Path versions before 2.01.
+    my @dirs_created = mkpath( \@dirs_to_create, $print_the_dirs, $mode );
 
-    my @dirs_created = mkpath(
-        ( grep { ! -d } map { $destdir . $_ } keys %$directories ),
-        { mode => 0777 },
-    );
     return 1;
 }
 

Modified: branches/tt761_keys_revamp/lib/Parrot/OpTrans.pm
==============================================================================
--- branches/tt761_keys_revamp/lib/Parrot/OpTrans.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/lib/Parrot/OpTrans.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -16,9 +16,9 @@
 The subclass hierarchy is as follows:
 
     OpTrans
-       |_________________________
-       |           |             |
-       C         CGoto       Compiled
+       |___________
+       |           |
+       C         CGoto
        |           |
     CPrederef      |
        | |         |
@@ -259,8 +259,6 @@
 
 =item C<Parrot::OpTrans::CSwitch>
 
-=item C<Parrot::OpTrans::Compiled>
-
 =back
 
 =cut

Modified: branches/tt761_keys_revamp/lib/Parrot/OpTrans/C.pm
==============================================================================
--- branches/tt761_keys_revamp/lib/Parrot/OpTrans/C.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/lib/Parrot/OpTrans/C.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -50,7 +50,9 @@
 =cut
 
 sub defines {
+    my $type = __PACKAGE__;
     return <<END;
+/* defines - $0 -> $type */
 #undef CONST
 #define REL_PC     ((size_t)(cur_opcode - (opcode_t *)interp->code->base.data))
 #define CUR_OPCODE cur_opcode
@@ -184,8 +186,6 @@
 
 =item C<Parrot::OpTrans::CSwitch>
 
-=item C<Parrot::OpTrans::Compiled>
-
 =back
 
 =cut

Modified: branches/tt761_keys_revamp/lib/Parrot/OpTrans/CGP.pm
==============================================================================
--- branches/tt761_keys_revamp/lib/Parrot/OpTrans/CGP.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/lib/Parrot/OpTrans/CGP.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -162,8 +162,6 @@
 
 =item C<Parrot::OpTrans::CSwitch>
 
-=item C<Parrot::OpTrans::Compiled>
-
 =back
 
 =cut

Modified: branches/tt761_keys_revamp/lib/Parrot/OpTrans/CGoto.pm
==============================================================================
--- branches/tt761_keys_revamp/lib/Parrot/OpTrans/CGoto.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/lib/Parrot/OpTrans/CGoto.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -62,7 +62,9 @@
 =cut
 
 sub defines {
+    my $type = __PACKAGE__;
     return <<END;
+/* defines - $0 -> $type */
 #undef CONST
 #define REL_PC     ((size_t)(cur_opcode - (opcode_t*)interp->code->base.data))
 #define CUR_OPCODE cur_opcode
@@ -367,8 +369,6 @@
 
 =item C<Parrot::OpTrans::CSwitch>
 
-=item C<Parrot::OpTrans::Compiled>
-
 =back
 
 =cut

Modified: branches/tt761_keys_revamp/lib/Parrot/OpTrans/CPrederef.pm
==============================================================================
--- branches/tt761_keys_revamp/lib/Parrot/OpTrans/CPrederef.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/lib/Parrot/OpTrans/CPrederef.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -130,8 +130,6 @@
 
 =item C<Parrot::OpTrans::CSwitch>
 
-=item C<Parrot::OpTrans::Compiled>
-
 =back
 
 =cut

Modified: branches/tt761_keys_revamp/lib/Parrot/OpTrans/CSwitch.pm
==============================================================================
--- branches/tt761_keys_revamp/lib/Parrot/OpTrans/CSwitch.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/lib/Parrot/OpTrans/CSwitch.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -247,8 +247,6 @@
 
 =item C<Parrot::OpTrans::CPrederef>
 
-=item C<Parrot::OpTrans::Compiled>
-
 =back
 
 =cut

Deleted: branches/tt761_keys_revamp/lib/Parrot/OpTrans/Compiled.pm
==============================================================================
--- branches/tt761_keys_revamp/lib/Parrot/OpTrans/Compiled.pm	Sat Jul  4 21:38:28 2009	(r39883)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,242 +0,0 @@
-# Copyright (C) 2001-2004, Parrot Foundation.
-# $Id$
-
-=head1 NAME
-
-Parrot::OpTrans::Compiled - Transform Parrot Bytecode To C
-
-=head1 DESCRIPTION
-
-C<Parrot::OpTrans::Compiled> inherits from C<Parrot::OpTrans> and is
-used by F<tools/build/pbc2c.pl> to transform Parrot bytecode to a C code
-run loop.
-
-=head2 Instance Methods
-
-=over 4
-
-=cut
-
-package Parrot::OpTrans::Compiled;
-
-use strict;
-use warnings;
-
-use base qw( Parrot::OpTrans );
-
-=item C<defines()>
-
-Returns the C C<#define> macros required by the ops.
-
-=cut
-
-sub defines {
-    return <<END;
-#define REL_PC (cur_opcode - start_code)
-#define IREG(i) REG_INT(interp, i)
-#define NREG(i) REG_NUM(interp, i)
-#define PREG(i) REG_PMC(interp, i)
-#define SREG(i) REG_STR(interp, i)
-#define CONST(i) interp->code->const_table->constants[i]
-END
-}
-
-=item C<pc($pc)>
-
-=item C<pc()>
-
-Sets/gets the current position in Parrot code.
-
-=cut
-
-sub pc {
-    my $self = shift;
-
-    if (@_) {
-        $self->{PC} = shift;
-    }
-    else {
-        return $self->{PC};
-    }
-}
-
-=item C<args(@args)>
-
-=item C<args()>
-
-Sets/gets the transform's arguments.
-
-=cut
-
-sub args {
-    my $self = shift;
-
-    if (@_) {
-        $self->{ARGS} = [@_];
-    }
-    else {
-        return $self->{ARGS};
-    }
-}
-
-=item C<arg($index)>
-
-Returns the argument at index C<$index>.
-
-=cut
-
-sub arg {
-    my $self = shift;
-
-    return $self->{ARGS}[shift];
-}
-
-=item C<goto_address($address)>
-
-Transforms the C<goto ADDRESS($address)> macro in an ops file into the
-relevant C code.
-
-=cut
-
-sub goto_address {
-    my ( $self, $addr ) = @_;
-
-    #print STDERR "pbcc: map_ret_abs($addr)\n";
-
-    return "cur_opcode = $addr;\ngoto switch_label";
-}
-
-=item C<expr_offset($offset)>
-
-An offset expression is always an offset from C<start_code>, because
-the C<ret> instruction may be in a different runops core. C<ret> will
-always treat saved addresses as relative to C<start_code>, because that
-interpretation is global across all runops cores.
-
-=cut
-
-sub expr_offset {
-    my ( $self, $offset ) = @_;
-
-    return sprintf( "start_code + %d + %s", $self->pc, $offset );
-}
-
-=item C<goto_offset($offset)>
-
-Transforms the C<goto OFFSET($offset)> macro in an ops file into the
-relevant C code.
-
-=cut
-
-sub goto_offset {
-    my ( $self, $offset ) = @_;
-
-    if ( $offset =~ /^-?\d+$/ ) {
-        return sprintf( "goto PC_%d", $self->pc + $offset );
-    }
-    else {
-        return sprintf( "cur_opcode = &&PC_%d; cur_opcode += %s; goto switch_label",
-            $self->pc, $offset );
-    }
-
-    #print STDERR "pbcc: map_ret_rel($offset)\n";
-}
-
-=item C<goto_pop()>
-
-Transforms the C<goto POP()> macro in an ops file into the relevant C
-code.
-
-=cut
-
-sub goto_pop {
-    my ($self) = @_;
-
-    return "cur_opcode = pop_dest(interp);\ngoto switch_label";
-}
-
-my %arg_maps = (
-    'i'  => "IREG(%ld)",
-    'n'  => "NREG(%ld)",
-    'p'  => "PREG(%ld)",
-    's'  => "SREG(%ld)",
-    'k'  => "PREG(%ld)",
-    'ki' => "IREG(%ld)",
-
-    'ic'  => "%ld",
-    'nc'  => "CONST(%ld)->u.number",
-    'pc'  => "CONST(%ld)->u.key",
-    'sc'  => "CONST(%ld)->u.string",
-    'kc'  => "CONST(%ld)->u.key",
-    'kic' => "%ld",
-);
-
-=item C<access_arg($type, $value, $op)>
-
-Returns the C code for the specified op argument type (see
-C<Parrot::OpTrans>) and value. C<$op> is an instance of C<Parrot::Op>.
-
-=cut
-
-sub access_arg {
-    my ( $self, $type, $num, $op ) = @_;
-
-    #print STDERR "pbcc: map_arg($type, $num)\n";
-
-    return sprintf( $arg_maps{$type}, $self->arg( $num - 1 ) );
-}
-
-=item C<restart_address($address)>
-
-Returns the C code for C<restart ADDRESS($address)>.
-
-=cut
-
-sub restart_address {
-    my ( $self, $addr ) = @_;
-
-    die "pbc2c.pl: Cannot handle RESUME ops!";
-}
-
-=item C<restart_offset($offset)>
-
-Returns the C code for C<restart OFFSET($offset)>.
-
-=cut
-
-sub restart_offset {
-    my ( $self, $offset ) = @_;
-
-    die "pbc2c.pl: Cannot handle RESUME ops!";
-}
-
-=back
-
-=head1 SEE ALSO
-
-=over 4
-
-=item C<Parrot::OpTrans>
-
-=item C<Parrot::OpTrans::C>
-
-=item C<Parrot::OpTrans::CGP>
-
-=item C<Parrot::OpTrans::CGoto>
-
-=item C<Parrot::OpTrans::CPrederef>
-
-=item C<Parrot::OpTrans::CSwitch>
-
-=back
-
-=cut
-
-1;
-
-# Local Variables:
-#   mode: cperl
-#   cperl-indent-level: 4
-#   fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4:

Modified: branches/tt761_keys_revamp/lib/Parrot/OpsFile.pm
==============================================================================
--- branches/tt761_keys_revamp/lib/Parrot/OpsFile.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/lib/Parrot/OpsFile.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -85,9 +85,9 @@
 
 =item 2 behavior
 
-The presence (or absence) of certain flags will change how the op
-behaviors. For example, the lack of the C<flow> flag will cause the
-op to be implicitly terminated with C<goto NEXT()>. (See next section).
+The presence (or absence) of certain flags will change how the op behaves. For
+example, the lack of the C<flow> flag will cause the op to be implicitly
+terminated with C<goto NEXT()>. (See next section).
 
 The :deprecated flag will generate a diagnostic to standard error at
 runtime when a deprecated opcode is invoked and

Modified: branches/tt761_keys_revamp/lib/Parrot/OpsRenumber.pm
==============================================================================
--- branches/tt761_keys_revamp/lib/Parrot/OpsRenumber.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/lib/Parrot/OpsRenumber.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -8,11 +8,10 @@
 
 =head1 NAME
 
-Parrot::OpsRenumber - Methods holding functionality for F<tools/build/opsrenumber.pl>.
+Parrot::OpsRenumber - Methods holding functionality for F<tools/dev/opsrenumber.pl>.
 
 =head1 SYNOPSIS
 
-    use Parrot::Config qw( %PConfig );
     use Parrot::OpsRenumber;
 
     $self = Parrot::OpsRenumber->new( {

Modified: branches/tt761_keys_revamp/lib/Parrot/Pmc2c/Attribute.pm
==============================================================================
--- branches/tt761_keys_revamp/lib/Parrot/Pmc2c/Attribute.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/lib/Parrot/Pmc2c/Attribute.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -145,7 +145,7 @@
         $decl .= <<"EOA";
             PMC * const attr_value = VTABLE_get_attr_str(interp, \\
                               pmc, Parrot_str_new_constant(interp, "$attrname")); \\
-            (dest) =  (PMC_IS_NULL(attr_value) ? (STRING *) 0: VTABLE_get_string(interp, attr_value)); \\
+            (dest) =  (PMC_IS_NULL(attr_value) ? (STRING *)NULL : VTABLE_get_string(interp, attr_value)); \\
 EOA
     }
     elsif ($attrtype =~ $isptrtopmc) {

Modified: branches/tt761_keys_revamp/lib/Parrot/Pmc2c/PMC.pm
==============================================================================
--- branches/tt761_keys_revamp/lib/Parrot/Pmc2c/PMC.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/lib/Parrot/Pmc2c/PMC.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -204,6 +204,11 @@
     return $self->{parents};
 }
 
+sub direct_parents {
+    my ($self) = @_;
+    return $self->{direct_parents};
+}
+
 sub mixins {
     my ($self) = @_;
     return $self->{mixins};
@@ -235,7 +240,10 @@
 sub set_parents {
     my ( $self, $value ) = @_;
     $value             ||= [];
-    $self->{parents}     = $value;
+    $self->{parents}        = $value;
+    for my $dp (@{ $value }) {
+        push @{$self->{direct_parents}}, $dp;
+    }
     return 1;
 }
 

Modified: branches/tt761_keys_revamp/lib/Parrot/Pmc2c/PMC/RO.pm
==============================================================================
--- branches/tt761_keys_revamp/lib/Parrot/Pmc2c/PMC/RO.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/lib/Parrot/Pmc2c/PMC/RO.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -44,7 +44,7 @@
     my $self = bless Parrot::Pmc2c::PMC->new(
         {
             parents => [ $parent->name, @{ $parent->parents } ],    # prepend self to parrent
-            flags => { ( %{ $parent->get_flags } ), 'is_ro' => 1 }, # copy flags, set is_const
+            flags => { ( %{ $parent->get_flags } ), 'is_ro' => 1 }, # copy flags, set is_ro
             name       => $parent->name . "_ro",                    # set pmcname
             vtable     => $parent->vtable,                          # and alias vtable
             parentname => $parent->name,                            # set parentname

Modified: branches/tt761_keys_revamp/lib/Parrot/Pmc2c/PMCEmitter.pm
==============================================================================
--- branches/tt761_keys_revamp/lib/Parrot/Pmc2c/PMCEmitter.pm	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/lib/Parrot/Pmc2c/PMCEmitter.pm	Sat Jul  4 21:38:28 2009	(r39884)
@@ -94,6 +94,8 @@
 
     $c->emit( $self->update_vtable_func );
     $c->emit( $self->get_vtable_func );
+    $c->emit( $self->get_mro_func );
+    $c->emit( $self->get_isa_func );
     $c->emit( $self->init_func );
     $c->emit( $self->postamble );
 
@@ -135,6 +137,8 @@
     }
     $h->emit("${export}VTABLE* Parrot_${name}_get_vtable(PARROT_INTERP);\n");
     $h->emit("${export}VTABLE* Parrot_${name}_ro_get_vtable(PARROT_INTERP);\n");
+    $h->emit("${export}PMC*    Parrot_${name}_get_mro(PARROT_INTERP, PMC* mro);\n");
+    $h->emit("${export}Hash*   Parrot_${name}_get_isa(PARROT_INTERP, Hash* isa);\n");
 
 
     $self->gen_attributes;
@@ -586,32 +590,16 @@
 EOC
     }
 
-    $cout .= <<"EOC";
-    if (pass == 0) {
-EOC
-    for my $k ( keys %extra_vt ) {
-        $cout .= "        VTABLE *vt_$k;\n";
-    }
-
     my $flags = $self->vtable_flags;
     $cout .= <<"EOC";
-        Hash    *isa_hash  = NULL;
+    if (pass == 0) {
         VTABLE * const vt  = Parrot_${classname}_get_vtable(interp);
         vt->base_type      = $enum_name;
         vt->flags          = $flags;
         vt->attribute_defs = attr_defs;
+        interp->vtables[entry] = vt;
 
 EOC
-    for my $k ( keys %extra_vt ) {
-        my $k_flags = $self->$k->vtable_flags;
-        $cout .= <<"EOC";
-        vt_${k}                 = Parrot_${classname}_${k}_get_vtable(interp);
-        vt_${k}->base_type      = $enum_name;
-        vt_${k}->flags          = $k_flags;
-        vt_${k}->attribute_defs = attr_defs;
-
-EOC
-    }
 
     # init vtable slot
     if ( $self->is_dynamic ) {
@@ -620,7 +608,7 @@
         vt->whoami       = string_make(interp, "$classname", @{[length($classname)]},
                                        "ascii", PObj_constant_FLAG|PObj_external_FLAG);
         vt->provides_str = Parrot_str_append(interp, vt->provides_str,
-            string_make(interp, " $provides", @{[length($provides) + 1]}, "ascii",
+            string_make(interp, "$provides", @{[length($provides)]}, "ascii",
             PObj_constant_FLAG|PObj_external_FLAG));
 
 EOC
@@ -635,9 +623,7 @@
     if (@isa) {
         unshift @isa, $classname;
         $cout .= <<"EOC";
-
-        isa_hash         = parrot_new_hash(interp);
-        vt->isa_hash     = isa_hash;
+        vt->isa_hash     = Parrot_${classname}_get_isa(interp, NULL);
 EOC
     }
     else {
@@ -647,28 +633,23 @@
     }
 
     for my $k ( keys %extra_vt ) {
+        my $k_flags = $self->$k->vtable_flags;
         $cout .= <<"EOC";
-        vt_${k}->base_type    = entry;
-        vt_${k}->whoami       = vt->whoami;
-        vt_${k}->provides_str = vt->provides_str;
-EOC
-    }
-
-    for my $k ( keys %extra_vt ) {
-        $cout .= <<"EOC";
-        vt->${k}_variant_vtable    = vt_${k};
-        vt_${k}->${k}_variant_vtable = vt;
-        vt_${k}->isa_hash          = isa_hash;
-EOC
-    }
-
-    $cout .= <<"EOC";
-        interp->vtables[entry] = vt;
-EOC
+        {
+            VTABLE                   *vt_$k;
+            vt_${k}                 = Parrot_${classname}_${k}_get_vtable(interp);
+            vt_${k}->base_type      = $enum_name;
+            vt_${k}->flags          = $k_flags;
+            vt_${k}->attribute_defs = attr_defs;
+
+            vt_${k}->base_type           = entry;
+            vt_${k}->whoami              = vt->whoami;
+            vt_${k}->provides_str        = vt->provides_str;
+            vt->${k}_variant_vtable      = vt_${k};
+            vt_${k}->${k}_variant_vtable = vt;
+            vt_${k}->isa_hash            = vt->isa_hash;
+        }
 
-    for my $isa (@isa) {
-        $cout .= <<"EOC";
-        parrot_hash_put(interp, isa_hash, (void *)(CONST_STRING_GEN(interp, "$isa")), PMCNULL);
 EOC
     }
 
@@ -701,25 +682,12 @@
 
         $cout .= <<"EOC";
         {
-            PMC    * const mro = pmc_new(interp, enum_class_ResizableStringArray);
             VTABLE * const vt  = interp->vtables[entry];
 
-            vt->mro = mro;
+            vt->mro = Parrot_${classname}_get_mro(interp, PMCNULL);
 
             if (vt->ro_variant_vtable)
-                vt->ro_variant_vtable->mro = mro;
-
-EOC
-
-    @isa = $classname unless @isa;
-
-    for my $isa (@isa) {
-        $cout .= <<"EOC";
-            VTABLE_push_string(interp, mro, CONST_STRING_GEN(interp, "$isa"));
-EOC
-    }
-
-    $cout .= <<"EOC";
+                vt->ro_variant_vtable->mro = vt->mro;
         }
 
         /* set up MRO and _namespace */
@@ -730,22 +698,13 @@
     foreach my $method ( @{ $self->{methods} } ) {
         next unless $method->type eq Parrot::Pmc2c::Method::NON_VTABLE;
 
-        my $proto       = proto( $method->return_type, $method->parameters );
+        #these differ for METHODs
         my $method_name = $method->name;
-        my $symbol_name =
-            defined $method->symbol ? $method->symbol : $method->name;
+        my $symbol_name = $method->symbol;
 
-        if ( exists $method->{PCCMETHOD} ) {
-            $cout .= <<"EOC";
+        $cout .= <<"EOC";
         register_raw_nci_method_in_ns(interp, entry, F2DPTR(Parrot_${classname}_${method_name}), CONST_STRING_GEN(interp, "$symbol_name"));
 EOC
-        }
-        else {
-            $cout .= <<"EOC";
-        register_nci_method(interp, entry,
-                F2DPTR(Parrot_${classname}_${method_name}), "$symbol_name", "$proto");
-EOC
-        }
         if ( $method->{attrs}{write} ) {
             $cout .= <<"EOC";
         Parrot_mark_method_writes(interp, entry, "$symbol_name");
@@ -754,12 +713,14 @@
     }
 
     # include any class specific init code from the .pmc file
-    $cout .= <<"EOC" if $class_init_code;
+    if ($class_init_code) {
+        $cout .= <<"EOC";
         /* class_init */
         {
 $class_init_code
         }
 EOC
+    }
 
     $cout .= <<"EOC";
         {
@@ -798,6 +759,7 @@
 
     my $cout      = "";
     my $classname = $self->name;
+    my $export = $self->is_dynamic ? 'PARROT_DYNEXT_EXPORT ' : 'PARROT_EXPORT';
 
     my $vtable_updates = '';
     for my $name ( @{ $self->vtable->names } ) {
@@ -808,7 +770,8 @@
 
     $cout .= <<"EOC";
 
-PARROT_EXPORT VTABLE *Parrot_${classname}_update_vtable(VTABLE *vt) {
+$export
+VTABLE *Parrot_${classname}_update_vtable(VTABLE *vt) {
 $vtable_updates
     return vt;
 }
@@ -832,7 +795,8 @@
 
     $cout .= <<"EOC";
 
-PARROT_EXPORT VTABLE *Parrot_${classname}_ro_update_vtable(ARGMOD(VTABLE *vt)) {
+$export
+VTABLE *Parrot_${classname}_ro_update_vtable(ARGMOD(VTABLE *vt)) {
 $vtable_updates
     return vt;
 }
@@ -842,6 +806,88 @@
     $cout;
 }
 
+=item C<get_mro_func()>
+
+Returns the C code for the PMC's get_mro function.
+
+=cut
+
+sub get_mro_func {
+    my ($self) = @_;
+
+    my $cout      = "";
+    my $classname = $self->name;
+    my $get_mro = '';
+    my @parent_names;
+    my $export = $self->is_dynamic ? 'PARROT_DYNEXT_EXPORT ' : 'PARROT_EXPORT';
+
+    if ($classname ne 'default') {
+        for my $dp (reverse @{ $self->direct_parents}) {
+            $get_mro .= "    mro = Parrot_${dp}_get_mro(interp, mro);\n"
+            unless $dp eq 'default';
+        }
+    }
+
+    $cout .= <<"EOC";
+$export
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+PMC* Parrot_${classname}_get_mro(PARROT_INTERP, PMC* mro) {
+    if (PMC_IS_NULL(mro)) {
+        mro = pmc_new(interp, enum_class_ResizableStringArray);
+    }
+$get_mro
+    VTABLE_unshift_string(interp, mro,
+        string_make(interp, "$classname", @{[length($classname)]}, NULL, 0));
+    return mro;
+}
+
+EOC
+
+    $cout;
+}
+
+=item C<get_isa_func()>
+
+Returns the C code for the PMC's get_isa function.
+
+=cut
+
+sub get_isa_func {
+    my ($self) = @_;
+
+    my $cout      = "";
+    my $classname = $self->name;
+    my $get_isa = '';
+    my @parent_names;
+    my $export = $self->is_dynamic ? 'PARROT_DYNEXT_EXPORT ' : 'PARROT_EXPORT';
+
+    if ($classname ne 'default') {
+        for my $dp (reverse @{ $self->direct_parents}) {
+            $get_isa .= "    isa = Parrot_${dp}_get_isa(interp, isa);\n"
+            unless $dp eq 'default';
+        }
+    }
+
+    $cout .= <<"EOC";
+$export
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+Hash* Parrot_${classname}_get_isa(PARROT_INTERP, Hash* isa) {
+    if (isa == NULL) {
+        isa = parrot_new_hash(interp);
+    }
+$get_isa
+    parrot_hash_put(interp, isa, (void *)(CONST_STRING_GEN(interp, "$classname")), PMCNULL);
+    return isa;
+}
+
+EOC
+
+    $cout;
+}
+
+
 =item C<get_vtable_func()>
 
 Returns the C code for the PMC's update_vtable method.
@@ -853,19 +899,27 @@
 
     my $cout      = "";
     my $classname = $self->name;
+    my @other_parents = reverse @{ $self->direct_parents };
+    my $first_parent = shift @other_parents;
+    my $export = $self->is_dynamic ? 'PARROT_DYNEXT_EXPORT ' : 'PARROT_EXPORT';
 
     my $get_vtable = '';
-    foreach my $parent_name ( reverse ($self->name, @{ $self->parents }) ) {
-        if ($parent_name eq 'default') {
-            $get_vtable .= "    vt = Parrot_default_get_vtable(interp);\n";
-        }
-        else {
-            $get_vtable .= "    Parrot_${parent_name}_update_vtable(vt);\n";
-        }
+
+    if ($first_parent eq 'default') {
+        $get_vtable .= "    vt = Parrot_default_get_vtable(interp);\n";
     }
+    else {
+        $get_vtable .= "    vt = Parrot_${first_parent}_get_vtable(interp);\n";
+    }
+
+    foreach my $parent_name ( @other_parents) {
+        $get_vtable .= "    Parrot_${parent_name}_update_vtable(vt);\n";
+    }
+
+    $get_vtable .= "    Parrot_${classname}_update_vtable(vt);\n";
 
     $cout .= <<"EOC";
-PARROT_EXPORT
+$export
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 VTABLE* Parrot_${classname}_get_vtable(PARROT_INTERP) {
@@ -877,17 +931,22 @@
 EOC
 
     my $get_extra_vtable = '';
-    foreach my $parent_name ( reverse ($self->name, @{ $self->parents }) ) {
-        if ($parent_name eq 'default') {
-            $get_extra_vtable .= "    vt = Parrot_default_ro_get_vtable(interp);\n";
-        }
-        else {
-            $get_extra_vtable .= "    Parrot_${parent_name}_ro_update_vtable(vt);\n";
-        }
+
+    if ($first_parent eq 'default') {
+        $get_extra_vtable .= "    vt = Parrot_default_ro_get_vtable(interp);\n";
+    }
+    else {
+        $get_extra_vtable .= "    vt = Parrot_${first_parent}_ro_get_vtable(interp);\n";
     }
 
+    foreach my $parent_name ( @other_parents ) {
+        $get_extra_vtable .= "    Parrot_${parent_name}_ro_update_vtable(vt);\n";
+    }
+
+    $get_extra_vtable .= "    Parrot_${classname}_ro_update_vtable(vt);\n";
+
     $cout .= <<"EOC";
-PARROT_EXPORT
+$export
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 VTABLE* Parrot_${classname}_ro_get_vtable(PARROT_INTERP) {
@@ -969,7 +1028,7 @@
     1;
 }
 
-# Generate signle case for switch VTABLE
+# Generate single case for switch VTABLE
 sub generate_single_case {
     my ($self, $vt_method_name, $multi, @parameters) = @_;
 

Modified: branches/tt761_keys_revamp/runtime/parrot/library/CGI/QueryHash.pir
==============================================================================
--- branches/tt761_keys_revamp/runtime/parrot/library/CGI/QueryHash.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/runtime/parrot/library/CGI/QueryHash.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -93,7 +93,7 @@
     unless query goto END
 
     .local pmc query_hash, items, items_tmp_1, items_tmp_2
-    .local string query, kv, k, v, item_tmp_1, item_tmp_2, last_chars_of_k
+    .local string kv, k, v, item_tmp_1, item_tmp_2, last_chars_of_k
     .local int i, j, n, o, len_of_k
 
     query_hash      = new 'Hash'

Modified: branches/tt761_keys_revamp/runtime/parrot/library/Getopt/Obj.pir
==============================================================================
--- branches/tt761_keys_revamp/runtime/parrot/library/Getopt/Obj.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/runtime/parrot/library/Getopt/Obj.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -202,7 +202,6 @@
 
     key = name
 
-    .local string type
     type = spec."type"()
     $I2 = length val
 
@@ -220,7 +219,6 @@
 
     (name, spec) = self."getNameForKey"(key)
     if null name goto redofor
-    .local string type
     type = spec."type"()
     unless type == 'Boolean' goto error_2
 
@@ -263,7 +261,6 @@
 
 beginstore_1:
     # Store the value...
-    .local string type
     type = spec."type"()
     if_null val, undef
     if type == 'String' goto str
@@ -286,7 +283,6 @@
 array:
     $P0 = return[name]
     if null $P0 goto not_set
-    .local string type
     type = typeof $P0
     unless type != 'ResizableStringArray' goto endif_5
 not_set:
@@ -297,7 +293,6 @@
 hash:
     $P0 = return[name]
     if null $P0 goto not_set_hash
-    .local string type
     type = typeof $P0
     unless type != 'Hash' goto endif_7
 not_set_hash:

Modified: branches/tt761_keys_revamp/runtime/parrot/library/MIME/Base64.pir
==============================================================================
--- branches/tt761_keys_revamp/runtime/parrot/library/MIME/Base64.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/runtime/parrot/library/MIME/Base64.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -200,7 +200,7 @@
     goto START_5
     END_5:
 
-    .local int len, len_mod_4
+    .local int len_mod_4
     len = length base64_cleaned
     len_mod_4 = len % 4
 

Modified: branches/tt761_keys_revamp/runtime/parrot/library/OpenGL.pir
==============================================================================
--- branches/tt761_keys_revamp/runtime/parrot/library/OpenGL.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/runtime/parrot/library/OpenGL.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -108,6 +108,9 @@
     .local pmc libnames
 
     libnames = new 'ResizableStringArray'
+    # The following line brought to you by proprietary driver packages
+    # that don't update the libGL.so symlink properly, causing FAIL
+    push libnames, 'libGL.so.1'
     push libnames, 'libGL'
     push libnames, 'opengl32'
     push libnames, '/System/Library/Frameworks/OpenGL.framework/OpenGL'

Added: branches/tt761_keys_revamp/runtime/parrot/library/OpenGL/Math.pir
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/tt761_keys_revamp/runtime/parrot/library/OpenGL/Math.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -0,0 +1,549 @@
+# Copyright (C) 2009, Parrot Foundation.
+# $Id$
+
+=head1 NAME
+
+OpenGL;Math - Parrot extension for linear algebra following OpenGL conventions
+
+=head1 SYNOPSIS
+
+For more examples, look in F<examples/opengl/>, starting with
+F<examples/opengl/math.pir>.
+
+  # During init ...
+  load_bytecode 'OpenGL/Math.pbc'
+
+  # Later ...
+  XXX - NEED CODE HERE
+
+=head1 DESCRIPTION
+
+NOTE: THIS IS A WORK IN PROGRESS, AND SHOULD NOT BE CONSIDERED USABLE YET.
+
+Any 3D API has to pick certain conventions for handling of vectors and
+matrices, such as the handedness of the default coordinate systems,
+whether matrices are packed in column-major or row-major order, and
+so forth.
+
+This module implements the basic operations of linear algebra according
+to the conventions chosen by OpenGL, and attempts to do so efficiently
+within the bounds set by a pure PIR implementation.  It also provides
+efficient packing and unpacking of matrix and vector elements so that
+users need not directly understand the vagaries of OpenGL NCI structures.
+
+Finally, it is a primary goal that users of this module should not need to
+provide any hand-written versions of standard OpenGL matrix manipulations.
+Thus, methods are provided to perform rotations, translations, projections,
+etc.
+
+=cut
+
+.namespace ['OpenGL';'Math']
+
+=head2 OpenGL;Math
+
+The OpenGL;Math class/namespace handles the necessary housekeeping to make
+everything else work smoothly.
+
+=head3 Initialization
+
+The initialization routines are mostly for internal use only.  They
+include:
+
+=over 4
+
+=cut
+
+=item _opengl_math_init()
+
+At module load time, calls the other initialization routines in the proper
+order.
+
+=cut
+
+.sub _opengl_math_init :load
+    _create_classes()
+.end
+
+=item _create_classes()
+
+Creates Parrot classes to match each of the OpenGL;Math namespaces, and
+sets up their attributes.
+
+=cut
+
+.sub _create_classes
+    .local pmc Vec4
+    Vec4 = newclass ['OpenGL';'Math';'Vec4']
+    addattribute Vec4, 'vals'
+.end
+
+=back
+
+=cut
+
+
+.namespace ['OpenGL';'Math';'Vec4']
+
+=head2 OpenGL;Math;Vec4
+
+=head3 Instantiation
+
+=over 4
+
+=item Vec4 vec4 = new Vec4
+
+Create a new object representing a four-element vector.  You will need
+to set the initial values using the C<set_vals()> method.
+
+=item Vec4 vec4 = Vec4.'new'('vals' => vals)
+
+Create a new object representing a four-element vector, setting the
+initial values to the array PMC C<vals>.
+
+=back
+
+
+=head3 Accessors
+
+=over 4
+
+=item pmc vals = vector.get_vals()
+
+Return a four element array representing the current vector value.
+
+=cut
+
+.sub get_vals :method
+    $P0 = getattribute self, 'vals'
+    .return($P0)
+.end
+
+=item vector.set_vals(pmc vals)
+
+Set the current vector value to a four element array.
+
+=cut
+.sub set_vals :method
+    .param pmc vals
+
+    $I0 = vals
+    unless $I0 == 4 goto wrong_vector_length
+
+    setattribute self, 'vals', vals
+    .return()
+
+  wrong_vector_length:
+    $S0  = 'Input vector is wrong length ('
+    $S1  = $I0
+    $S0 .= $S1
+    $S0 .= ')'
+    die $S0
+.end
+
+=back
+
+
+=head3 Elementwise Operations
+
+=cut
+
+# Standard header for vec4-vec4 binop methods
+.macro vec4_extract_self_plus_vec_arg
+    .param pmc vec2
+
+    .local pmc v1, v2
+    v1 = getattribute self, 'vals'
+    v2 = getattribute vec2, 'vals'
+
+    $N10 = v1[0]
+    $N11 = v1[1]
+    $N12 = v1[2]
+    $N13 = v1[3]
+
+    $N20 = v2[0]
+    $N21 = v2[1]
+    $N22 = v2[2]
+    $N23 = v2[3]
+.endm
+
+# Standard header for vec3-vec3 binop methods
+.macro vec3_extract_self_plus_vec_arg
+    .param pmc vec2
+
+    .local pmc v1, v2
+    v1 = getattribute self, 'vals'
+    v2 = getattribute vec2, 'vals'
+
+    $N10 = v1[0]
+    $N11 = v1[1]
+    $N12 = v1[2]
+
+    $N20 = v2[0]
+    $N21 = v2[1]
+    $N22 = v2[2]
+.endm
+
+# Standard header for vec4-num binop methods
+.macro vec4_extract_self_plus_num_arg
+    .param num N
+
+    .local pmc v1
+    v1 = getattribute self, 'vals'
+
+    $N10 = v1[0]
+    $N11 = v1[1]
+    $N12 = v1[2]
+    $N13 = v1[3]
+.endm
+
+# Standard header for vec3-num binop methods
+.macro vec3_extract_self_plus_num_arg
+    .param num N
+
+    .local pmc v1
+    v1 = getattribute self, 'vals'
+
+    $N10 = v1[0]
+    $N11 = v1[1]
+    $N12 = v1[2]
+.endm
+
+# Standard footer for binop methods returning a vec4
+.macro vec4_return_new_result
+    .local pmc v3
+    v3 = new 'FixedFloatArray'
+    v3 = 4
+
+    v3[0] = $N30
+    v3[1] = $N31
+    v3[2] = $N32
+    v3[3] = $N33
+
+    .local pmc result
+    $P0 = typeof self
+    result = new $P0
+    setattribute result, 'vals', v3
+
+    .return(result)
+.endm
+
+# Standard footer for binop methods returning a vec4 = (vec3, w)
+.macro vec4_return_new_result_with_w(w)
+    .local pmc v3
+    v3 = new 'FixedFloatArray'
+    v3 = 4
+
+    v3[0] = $N30
+    v3[1] = $N31
+    v3[2] = $N32
+    v3[3] = .w
+
+    .local pmc result
+    $P0 = typeof self
+    result = new $P0
+    setattribute result, 'vals', v3
+
+    .return(result)
+.endm
+
+# A standard elementwise vec4 binop (vec4 op vec4 --> vec4)
+.macro vec4_vec4_vec4_binop(name, op)
+.sub .name :method
+    .vec4_extract_self_plus_vec_arg
+
+    $N30 = $N10 .op $N20
+    $N31 = $N11 .op $N21
+    $N32 = $N12 .op $N22
+    $N33 = $N13 .op $N23
+
+    .vec4_return_new_result
+.end
+.endm
+
+
+# A standard elementwise vec4-num binop (vec4 op num --> vec4)
+.macro vec4_num_vec4_binop(name, op)
+.sub .name :method
+    .vec4_extract_self_plus_num_arg
+
+    $N30 = $N10 .op N
+    $N31 = $N11 .op N
+    $N32 = $N12 .op N
+    $N33 = $N13 .op N
+
+    .vec4_return_new_result
+.end
+.endm
+
+
+=over 4
+
+=item Vec4 result = vec1.add(Vec4 vec2)
+
+=item Vec4 result = vec1.sub(Vec4 vec2)
+
+=item Vec4 result = vec1.mul(Vec4 vec2)
+
+=item Vec4 result = vec1.div(Vec4 vec2)
+
+=item Vec4 result = vec1.mod(Vec4 vec2)
+
+Calculate the elementwise addition, subtraction, multiplication, division,
+or modulus (C<vec1 [ + - * / % ] vec2>) and return a new C<Vec4> vector
+C<result>. No attempt is made in C<div> and C<mod> to prevent division by
+zero, XXX - SO WHAT HAPPENS?
+
+=cut
+
+.vec4_vec4_vec4_binop(add, +)
+
+.vec4_vec4_vec4_binop(sub, -)
+
+.vec4_vec4_vec4_binop(mul, *)
+
+.vec4_vec4_vec4_binop(div, /)
+
+.vec4_vec4_vec4_binop(mod, %)
+
+
+=item Vec4 result = vector.add_num(num N)
+
+=item Vec4 result = vector.sub_num(num N)
+
+=item Vec4 result = vector.mul_num(num N)
+
+=item Vec4 result = vector.div_num(num N)
+
+=item Vec4 result = vector.mod_num(num N)
+
+Calculate the elementwise addition, subtraction, multiplication, division,
+or modulus (C<vector [ + - * / % ] N>) and return a new C<Vec4> vector
+C<result>.  No attempt is made in C<div_num> and C<mod_num> to prevent
+division by zero, XXX - SO WHAT HAPPENS?
+
+=cut
+
+.vec4_num_vec4_binop(add_num, +)
+
+.vec4_num_vec4_binop(sub_num, -)
+
+.vec4_num_vec4_binop(mul_num, *)
+
+.vec4_num_vec4_binop(div_num, /)
+
+.vec4_num_vec4_binop(mod_num, %)
+
+
+=back
+
+
+=head3 Other Operations
+
+=over 4
+
+=item Vec4 cp = vec1.cross(Vec4 vec2)
+
+Calculate the cross product C<vec1 cross vec2> (using only the first three
+elements of each vector), and return the result as a new C<Vec4> whose
+first three elements are the cross product and whose last element is 1.0.
+
+=cut
+
+.sub cross :method
+    .vec3_extract_self_plus_vec_arg
+
+    $N0  = $N11 * $N22
+    $N1  = $N21 * $N12
+    $N30 = $N0 - $N1
+
+    $N2  = $N20 * $N12
+    $N3  = $N10 * $N22
+    $N31 = $N2 - $N3
+
+    $N4  = $N10 * $N21
+    $N5  = $N20 * $N11
+    $N32 = $N4 - $N5
+
+    .vec4_return_new_result_with_w(1.0)
+.end
+
+
+=item num dp = vec1.dot(Vec4 vec2)
+
+Calculate the dot product C<vec1 dot vec2> and return the result as a num.
+
+=cut
+
+.sub dot :method
+    .vec4_extract_self_plus_vec_arg
+
+    $N30 = $N10 * $N20
+    $N31 = $N11 * $N21
+    $N32 = $N12 * $N22
+    $N33 = $N13 * $N23
+
+    .local num result
+    result  = $N30 + $N31
+    result += $N32
+    result += $N33
+
+    .return(result)
+.end
+
+
+=item num dp3 = vec1.dot3(Vec4 vec2)
+
+Calculate the dot product C<vec1 dot vec2>, considering only the first
+three elements of each vector, and return the result as a num.
+
+=cut
+
+.sub dot3 :method
+    .vec3_extract_self_plus_vec_arg
+
+    $N30 = $N10 * $N20
+    $N31 = $N11 * $N21
+    $N32 = $N12 * $N22
+
+    .local num result
+    result  = $N30 + $N31
+    result += $N32
+
+    .return(result)
+.end
+
+
+=item num len = vector.length()
+
+Calculate the length of C<vector> as C<sqrt(vector dot vector)>, and return
+the result as a num.
+
+=cut
+
+.sub length :method
+    $N0 = self.'dot'(self)
+    $N1 = sqrt $N0
+
+    .return($N1)
+.end
+
+
+=item num len3 = vector.length3()
+
+Calculate the length of C<vector> as C<sqrt(vector dot3 vector)> (thus
+considering only the first three elements), and return the result as a num.
+
+=cut
+
+.sub length3 :method
+    $N0 = self.'dot3'(self)
+    $N1 = sqrt $N0
+
+    .return($N1)
+.end
+
+
+=item Vec4 result = vector.normalize()
+
+Calculate a normalized version of C<vector> as C<vector / length(vector)>,
+returning the result as a new C<Vec4>.
+
+=cut
+
+.sub normalize :method
+    $N0 = self.'length'()
+    $P0 = self.'div_num'($N0)
+
+    .return($P0)
+.end
+
+=item num dist = vec1.distance(vec2)
+
+Treat two vectors C<vec1> and C<vec2> as points and determine the distance
+between them as C<length(vec1 - vec2)>, returning the result as a num.
+
+=cut
+
+.sub distance :method
+    .param pmc vec2
+
+    $P0 = self.'sub'(vec2)
+    $N0 = $P0.'length'()
+
+    .return($N0)
+.end
+
+
+=item num dist3 = vec1.distance3(vec2)
+
+Treat two vectors C<vec1> and C<vec2> as points and determine the distance
+between them as C<length3(vec1 - vec2)> (thus considering only the first
+three elements), and returning the result as a num.
+
+=cut
+
+.sub distance3 :method
+    .param pmc vec2
+
+    $P0 = self.'sub'(vec2)
+    $N0 = $P0.'length3'()
+
+    .return($N0)
+.end
+
+=back
+
+
+
+=head3 Miscellaneous Methods
+
+=over 4
+
+=item __dump(pmc dumper, str label)
+
+Callback function for Parrot's C<Data::Dumper> clone.
+
+=cut
+
+.sub __dump :method
+    .param pmc    dumper
+    .param string label
+
+    $P0 = getattribute self, 'vals'
+
+    print '[ '
+    $I0 = 0
+  dump_loop:
+    $S0 = $P0[$I0]
+    print $S0
+    inc $I0
+    if $I0 >= 4 goto dump_loop_end
+    print ', '
+    goto dump_loop
+  dump_loop_end:
+    print ' ]'
+.end
+
+=back
+
+
+=head1 ROADMAP
+
+Over time, the API provided by this module will grow to incorporate
+related low-level operations, such as quaternion ops.  However, it will
+B<not> include high level components such as particle systems and physics
+simulations.  These are properly the domain of other modules that use
+this one, or NCI wrappers for libraries such as ODE (L<http://www.ode.org/>)
+and Bullet (L<http://www.bulletphysics.com/wordpress/>).
+
+In order to allow the greatest audience of users, this module will track
+the evolving experimental API for HLL access to PIR modules.
+
+=cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/tt761_keys_revamp/runtime/parrot/library/P6object.pir
==============================================================================
--- branches/tt761_keys_revamp/runtime/parrot/library/P6object.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/runtime/parrot/library/P6object.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -453,7 +453,7 @@
     setattribute how, 'parrotclass', parrotclass
 
     ##  create an anonymous class for the protoobject
-    .local pmc protoclass, protoobject, iter
+    .local pmc protoclass, protoobject
     protoclass = new 'Class'
     $P0 = get_class 'P6protoobject'
     ##  P6protoobject methods override parrotclass methods...

Modified: branches/tt761_keys_revamp/runtime/parrot/library/PGE/Util.pir
==============================================================================
--- branches/tt761_keys_revamp/runtime/parrot/library/PGE/Util.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/runtime/parrot/library/PGE/Util.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -160,7 +160,7 @@
   have_pos:
 
     # count newlines to the current position of the parse
-    .local int pos, npos, lines
+    .local int npos, lines
     .local string target
     $P99 = getattribute match, '$.target'
     target = $P99

Modified: branches/tt761_keys_revamp/runtime/parrot/library/Range.pir
==============================================================================
--- branches/tt761_keys_revamp/runtime/parrot/library/Range.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/runtime/parrot/library/Range.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -16,9 +16,9 @@
 =cut
 
 .macro exhausted_check()
-  .local pmc exhausted
-  exhausted = getattribute self, 'exhausted'
-  unless exhausted goto .$more
+  .local pmc exhausted_check
+  exhausted_check = getattribute self, 'exhausted'
+  unless exhausted_check goto .$more
   .local pmc exception
   exception = new 'Exception'
   exception[0] = 'Exhausted Range'
@@ -155,7 +155,7 @@
 .sub 'shift' :vtable('shift_pmc') :method
   .exhausted_check()
 
-  .local pmc exhausted, from, to, by
+  .local pmc from, to, by
   from = getattribute self, 'from'
   to   = getattribute self, 'to'
   by   = getattribute self, 'by'

Modified: branches/tt761_keys_revamp/runtime/parrot/library/Test/Builder/Output.pir
==============================================================================
--- branches/tt761_keys_revamp/runtime/parrot/library/Test/Builder/Output.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/runtime/parrot/library/Test/Builder/Output.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -138,7 +138,6 @@
 	i = 0
 
 	.local string first_char
-	.local string line
 
   LOOP:
     if i == 0 goto LINE_OK

Modified: branches/tt761_keys_revamp/runtime/parrot/library/Test/More.pir
==============================================================================
--- branches/tt761_keys_revamp/runtime/parrot/library/Test/More.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/runtime/parrot/library/Test/More.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -468,8 +468,7 @@
 structure.  It passes if they are equal and fails otherwise.  This will
 report the results with the optional test description in C<description>.
 
-This only handles comparisons of array-like structures.  It shouldn't be too
-hard to extend it for hash-like structures, too.
+This handles comparisons of array-like and hash-like structures.
 
 =cut
 
@@ -517,10 +516,10 @@
   report_diagnostic:
     ne diagnosis, '', return_it
 
-    .local string left
-    .local string right
-    right = pop position
-    left  = pop position
+    .local string left_value
+    .local string right_value
+    right_value = pop position
+    left_value  = pop position
 
     .local string nested_path
     nested_path = join '][', position
@@ -534,9 +533,9 @@
 
   show_expected:
     diagnosis  .= ': expected '
-    diagnosis  .= left
+    diagnosis  .= left_value
     diagnosis  .= ', received '
-    diagnosis  .= right
+    diagnosis  .= right_value
 
   return_it:
     test.'diag'( diagnosis )
@@ -640,27 +639,22 @@
 
   compare_contents:
     .local pmc l_iter
-    .local pmc r_iter
     .local int count
 
     l_iter = new 'Iterator', l_hash
-    r_iter = new 'Iterator', r_hash
     l_iter = 0
-    r_iter = 0
     count  = 0
 
-    .local pmc l_key
-    .local pmc r_key
+    .local pmc key
     .local pmc l_elem
     .local pmc r_elem
     .local int elems_equal
 
   iter_start:
     unless l_iter goto iter_end
-    l_key  = shift l_iter
-    r_key  = shift r_iter
-    l_elem = l_hash[ l_key ]
-    r_elem = r_hash[ r_key ]
+    key  = shift l_iter
+    l_elem = l_hash[ key ]
+    r_elem = r_hash[ key ]
 
     elems_equal = compare_elements( l_elem, r_elem, position )
     unless elems_equal goto elems_not_equal
@@ -669,7 +663,7 @@
     goto iter_start
 
   elems_not_equal:
-    unshift position, l_key
+    unshift position, key
     .return( 0 )
 
   iter_end:

Modified: branches/tt761_keys_revamp/src/debug.c
==============================================================================
--- branches/tt761_keys_revamp/src/debug.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/debug.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -3344,8 +3344,12 @@
 PDB_info(PARROT_INTERP)
 {
     ASSERT_ARGS(PDB_info)
-    Parrot_Interp itdeb = interp->pdb->debugger;
-    Parrot_Interp itp = interp->pdb->debugee;
+
+    /* If a debugger is created, use it for printing and use the
+     * data in his debugee. Otherwise, use current interpreter
+     * for both */
+    Parrot_Interp itdeb = interp->pdb ? interp->pdb->debugger : interp;
+    Parrot_Interp itp = interp->pdb ? interp->pdb->debugee : interp;
 
     Parrot_io_eprintf(itdeb, "Total memory allocated = %ld\n",
             interpinfo(itp, TOTAL_MEM_ALLOC));

Modified: branches/tt761_keys_revamp/src/embed.c
==============================================================================
--- branches/tt761_keys_revamp/src/embed.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/embed.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -644,7 +644,7 @@
     for (i = 0; i < argc; i++) {
         /* Run through argv, adding everything to @ARGS. */
         STRING * const arg =
-            string_make(interp, argv[i], strlen(argv[i]), NULL,
+            string_make(interp, argv[i], strlen(argv[i]), "unicode",
                 PObj_external_FLAG);
 
         if (Interp_debug_TEST(interp, PARROT_START_DEBUG_FLAG))

Modified: branches/tt761_keys_revamp/src/gc/alloc_memory.c
==============================================================================
--- branches/tt761_keys_revamp/src/gc/alloc_memory.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/gc/alloc_memory.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -343,6 +343,32 @@
 
 /*
 
+=item C<char * mem_sys_strdup(const char *src)>
+
+Copy a C string to a new block of memory allocated with mem_sys_allocate,
+that can be later deallocated with mem_sys_free.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_MALLOC
+PARROT_CANNOT_RETURN_NULL
+char *
+mem_sys_strdup(ARGIN(const char *src))
+{
+    ASSERT_ARGS(mem_sys_strdup)
+
+    size_t l = strlen(src);
+    char *result = (char *)mem_sys_allocate(l + 1);
+    memcpy(result, src, l);
+    result[l] = '\0';
+    return result;
+}
+
+/*
+
 =back
 
 =cut

Modified: branches/tt761_keys_revamp/src/gc/api.c
==============================================================================
--- branches/tt761_keys_revamp/src/gc/api.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/gc/api.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -15,6 +15,73 @@
 of the GC. This is documented in PDD 9 with supplementary notes in
 F<docs/memory_internals.pod>.
 
+=head1 GC OVERVIEW
+
+The GC is broken into a number of different files that each represent different
+components.
+
+=over 4
+
+=item F<src/gc/api.c>
+
+This is the main API file which provides access to functions which are used by
+the rest of Parrot core. In the long term, only the functions provided in this
+file should be visible to files outside the src/gc/ directory. Because this
+represents a public-facing API, the functions in this file are not related by
+theme.
+
+=item F<src/gc/alloc_memory.c>
+
+This file provides a number of functions and macros for allocating memory from
+the OS. These are typically wrapper functions with error-handling capabilities
+over malloc, calloc, or realloc.
+
+=item F<src/gc/alloc_register.c>
+
+This file implements the custom management and interface logic for
+Parrot_Context structures. The functions in this file are publicly available
+and are used throughout Parrot core for interacting with contexts and registers
+
+=item F<src/gc/alloc_resources.c>
+
+This file implements handling logic for strings and arbitrary-sized memory
+buffers. String storage is managed by special Memory_Pool structures, and use
+a separate compacting garbage collector to keep track of them.
+
+=item F<src/gc/gc_ims.c>
+
+=item F<src/gc/gc_gms.c>
+
+=item F<src/gc/gc_ms.c>
+
+These files are the individual GC cores which implement the primary tracing
+and sweeping logic. gc_ms.c is the mark&sweep collector core which is used in
+Parrot by default. gc_gms.c is an experimental and incomplete generational core.
+gc_ims.c is an experimental and incomplete incremental collector core.
+
+=item F<src/gc/mark_sweep.c>
+
+This file implements some routines that are commonly needed by the various GC
+cores and provide an abstraction layer that a GC core can use to interact with
+some of the architecture of Parrot.
+
+=item F<src/gc/system.c>
+
+This file implements logic for tracing processor registers and the system stack.
+Here there be dragons.
+
+=item F<src/gc/res_lea.c>
+
+=item F<src/gc/malloc.c>
+
+=item F<src/gc/malloc_trace.c>
+
+These three files implement various unused features, including a custom malloc
+implementation, and malloc wrappers for various purposes. These are unused.
+
+=back
+
+
 =head1 FUNCTIONS
 
 =over 4
@@ -325,7 +392,8 @@
 {
     ASSERT_ARGS(Parrot_gc_add_pmc_ext)
     Small_Object_Pool * const pool = interp->arena_base->pmc_ext_pool;
-    pmc->pmc_ext = (PMC_EXT *)pool->get_free_object(interp, pool);
+    if (!pmc->pmc_ext)
+        pmc->pmc_ext = (PMC_EXT *)pool->get_free_object(interp, pool);
     if (!pmc->pmc_ext)
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ALLOCATION_ERROR,
             "Parrot VM: PMC_EXT allocation failed!\n");
@@ -362,17 +430,16 @@
     Arenas            * const arena_base = interp->arena_base;
     Small_Object_Pool * const ext_pool   = arena_base->pmc_ext_pool;
 
+    if (!p->pmc_ext)
+        return;
+
     if (PObj_is_PMC_shared_TEST(p) && PMC_sync(p)) {
         MUTEX_DESTROY(PMC_sync(p)->pmc_lock);
         mem_internal_free(PMC_sync(p));
         PMC_sync(p) = NULL;
     }
-
-    if (p->pmc_ext) {
-        ext_pool->add_free_object(interp, ext_pool, p->pmc_ext);
-        ext_pool->num_free_objects++;
-    }
-
+    ext_pool->add_free_object(interp, ext_pool, p->pmc_ext);
+    ext_pool->num_free_objects++;
     p->pmc_ext = NULL;
 }
 
@@ -394,6 +461,9 @@
     ASSERT_ARGS(Parrot_gc_add_pmc_sync)
     if (!PObj_is_PMC_EXT_TEST(pmc))
         Parrot_gc_add_pmc_ext(interp, pmc);
+    if (PMC_sync(pmc))
+        /* This mutex already exists, leave it alone. */
+        return;
     PMC_sync(pmc) = mem_allocate_typed(Sync);
     if (!PMC_sync(pmc))
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ALLOCATION_ERROR,

Modified: branches/tt761_keys_revamp/src/hash.c
==============================================================================
--- branches/tt761_keys_revamp/src/hash.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/hash.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -718,6 +718,7 @@
     HashBucket   *bs, *b;
 
     void * const  old_mem  = hash->bs;
+    HashBucket *old_offset = (HashBucket*)((char*)hash + sizeof (Hash));
     const UINTVAL old_size = hash->mask + 1;
     const UINTVAL new_size = old_size << 1;
     const UINTVAL old_nb   = N_BUCKETS(old_size);
@@ -735,8 +736,16 @@
     */
 
     /* resize mem */
-    HashBucket * const new_mem =
-        (HashBucket *)mem_sys_realloc(old_mem, HASH_ALLOC_SIZE(new_size));
+    HashBucket *new_mem;
+    if (old_offset != old_mem) {
+        /* This buffer has been reallocated at least once before. */
+        new_mem = (HashBucket *)mem_sys_realloc(old_mem, HASH_ALLOC_SIZE(new_size));
+    }
+    else {
+        /* Allocate a new buffer. */
+        new_mem = (HashBucket *)mem_sys_allocate(HASH_ALLOC_SIZE(new_size));
+        memcpy(new_mem, old_mem, HASH_ALLOC_SIZE(old_size));
+    }
 
     /*
          +---+---+---+---+---+---+-+-+-+-+-+-+-+-+
@@ -952,7 +961,8 @@
 {
     ASSERT_ARGS(parrot_create_hash)
     HashBucket  *bp;
-    Hash * const hash = mem_allocate_typed(Hash);
+    void        *alloc = mem_sys_allocate(sizeof (Hash) + HASH_ALLOC_SIZE(INITIAL_BUCKETS));
+    Hash * const hash  = (Hash*)alloc;
     size_t       i;
 
     PARROT_ASSERT(INITIAL_BUCKETS % 4 == 0);
@@ -972,7 +982,7 @@
      * - use the bucket store and bi inside this structure
      * - when reallocate copy this part
      */
-    bp = (HashBucket *)mem_sys_allocate(HASH_ALLOC_SIZE(INITIAL_BUCKETS));
+    bp = (HashBucket *)((char*)alloc + sizeof (Hash));
     hash->free_list = NULL;
 
     /* fill free_list from hi addresses so that we can use
@@ -1013,7 +1023,9 @@
 parrot_hash_destroy(SHIM_INTERP, ARGMOD(Hash *hash))
 {
     ASSERT_ARGS(parrot_hash_destroy)
-    mem_sys_free(hash->bs);
+    HashBucket *bp = (HashBucket*)((char*)hash + sizeof (Hash));
+    if (bp != hash->bs)
+        mem_sys_free(hash->bs);
     mem_sys_free(hash);
 }
 

Modified: branches/tt761_keys_revamp/src/interp/inter_create.c
==============================================================================
--- branches/tt761_keys_revamp/src/interp/inter_create.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/interp/inter_create.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -466,6 +466,7 @@
                 interp->thread_data = NULL;
             }
 
+            parrot_free_vtables(interp);
             mem_sys_free(interp);
         }
     }

Modified: branches/tt761_keys_revamp/src/io/unix.c
==============================================================================
--- branches/tt761_keys_revamp/src/io/unix.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/io/unix.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -43,7 +43,7 @@
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
 PARROT_CONST_FUNCTION
-static INTVAL convert_flags_to_unix(INTVAL flags);
+static int convert_flags_to_unix(INTVAL flags);
 
 static INTVAL io_is_tty_unix(PIOHANDLE fd);
 #define ASSERT_ARGS_convert_flags_to_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
@@ -54,7 +54,7 @@
 
 /*
 
-=item C<static INTVAL convert_flags_to_unix(INTVAL flags)>
+=item C<static int convert_flags_to_unix(INTVAL flags)>
 
 Returns a UNIX-specific interpretation of C<flags> suitable for passing
 to C<open()> and C<fopen()> in C<Parrot_io_open_unix()> and
@@ -65,11 +65,11 @@
 */
 
 PARROT_CONST_FUNCTION
-static INTVAL
+static int
 convert_flags_to_unix(INTVAL flags)
 {
     ASSERT_ARGS(convert_flags_to_unix)
-    INTVAL oflags = 0;
+    int oflags = 0;
 
     if ((flags & (PIO_F_WRITE | PIO_F_READ)) == (PIO_F_WRITE | PIO_F_READ)) {
         oflags |= O_RDWR | O_CREAT;
@@ -149,7 +149,7 @@
               ARGIN(STRING *path), INTVAL flags)
 {
     ASSERT_ARGS(Parrot_io_open_unix)
-    INTVAL oflags;
+    int oflags;
     PIOHANDLE fd;
     char *spath;
 
@@ -338,8 +338,8 @@
 {
     ASSERT_ARGS(Parrot_io_close_unix)
     INTVAL result = 0;
-    PIOHANDLE file_descriptor = Parrot_io_get_os_handle(interp, filehandle);
-    int flags = Parrot_io_get_flags(interp, filehandle);
+    const PIOHANDLE file_descriptor = Parrot_io_get_os_handle(interp, filehandle);
+    const int flags = Parrot_io_get_flags(interp, filehandle);
 
     /* BSD and Solaris need explicit fsync() */
     if (file_descriptor >= 0) {
@@ -476,7 +476,7 @@
 Parrot_io_flush_unix(PARROT_INTERP, ARGMOD(PMC *filehandle))
 {
     ASSERT_ARGS(Parrot_io_flush_unix)
-    PIOHANDLE file_descriptor = Parrot_io_get_os_handle(interp, filehandle);
+    const PIOHANDLE file_descriptor = Parrot_io_get_os_handle(interp, filehandle);
     return fsync(file_descriptor);
 }
 
@@ -497,7 +497,7 @@
               ARGIN(STRING **buf))
 {
     ASSERT_ARGS(Parrot_io_read_unix)
-    PIOHANDLE file_descriptor = Parrot_io_get_os_handle(interp, filehandle);
+    const PIOHANDLE file_descriptor = Parrot_io_get_os_handle(interp, filehandle);
     INTVAL file_flags = Parrot_io_get_flags(interp, filehandle);
     STRING * const s = Parrot_io_make_string(interp, buf, 2048);
 
@@ -544,14 +544,14 @@
 Parrot_io_write_unix(PARROT_INTERP, ARGIN(PMC *filehandle), ARGMOD(STRING *s))
 {
     ASSERT_ARGS(Parrot_io_write_unix)
-    PIOHANDLE file_descriptor = Parrot_io_get_os_handle(interp, filehandle);
+    const PIOHANDLE file_descriptor = Parrot_io_get_os_handle(interp, filehandle);
     const char * const buffer = s->strstart;
     const char * ptr          = buffer;
 
     size_t to_write = s->bufused;
     size_t written  = 0;
 
-  write_through:
+    write_through:
     while (to_write > 0) {
         const int err = write(file_descriptor, ptr, to_write);
         if (err >= 0) {
@@ -719,8 +719,8 @@
         /* C strings for the execv call defined that way to avoid
          * const problems without copying them.
          */
-        static char auxarg0 [] = "/bin/sh";
-        static char auxarg1 [] = "-c";
+        static const char auxarg0[] = "/bin/sh";
+        static const char auxarg1[] = "-c";
 
         if (f_write) {
             /* the other end is writing - we read from the pipe */

Modified: branches/tt761_keys_revamp/src/jit/i386/jit_defs.c
==============================================================================
--- branches/tt761_keys_revamp/src/jit/i386/jit_defs.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/jit/i386/jit_defs.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -2277,13 +2277,13 @@
             case 'b':   /* buffer (void*) pass PObj_bufstart(SReg) */
                 emitm_call_cfunc(pc, get_nci_S);
                 emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1,
-                               (size_t) &PObj_bufstart((STRING *) 0));
+                               (size_t) &PObj_bufstart((STRING *) NULL));
                 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
                 break;
             case 'B':   /* buffer (void**) pass &PObj_bufstart(SReg) */
                 emitm_call_cfunc(pc, get_nci_S);
                 emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1,
-                              (size_t) &PObj_bufstart((STRING *) 0));
+                              (size_t) &PObj_bufstart((STRING *) NULL));
                 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
                 break;
             case 'S':

Modified: branches/tt761_keys_revamp/src/key.c
==============================================================================
--- branches/tt761_keys_revamp/src/key.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/key.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -440,13 +440,11 @@
 */
 
 PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
+PARROT_CAN_RETURN_NULL
 STRING *
 key_string(PARROT_INTERP, ARGIN(PMC *key))
 {
     ASSERT_ARGS(key_string)
-    INTVAL   int_key;
-    FLOATVAL num_key;
 
     switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
         /* remember to COW strings instead of returning them directly */
@@ -460,6 +458,7 @@
         }
         case KEY_string_FLAG | KEY_register_FLAG:
         {
+            INTVAL int_key;
             STRING *s;
             GETATTR_Key_int_key(interp, key, int_key);
             s = REG_STR(interp, int_key);
@@ -469,25 +468,36 @@
         }
         case KEY_pmc_FLAG | KEY_register_FLAG:
         {
+            INTVAL int_key;
             PMC *reg;
             GETATTR_Key_int_key(interp, key, int_key);
             reg = REG_PMC(interp, int_key);
             return VTABLE_get_string(interp, reg);
         }
         case KEY_integer_FLAG:
+        {
+            INTVAL int_key;
             GETATTR_Key_int_key(interp, key, int_key);
             return Parrot_str_from_int(interp, int_key);
+        }
         case KEY_integer_FLAG | KEY_register_FLAG:
+        {
+            INTVAL int_key;
             GETATTR_Key_int_key(interp, key, int_key);
             return Parrot_str_from_int(interp, REG_INT(interp, int_key));
-
+        }
         case KEY_number_FLAG:
+        {
+            FLOATVAL num_key;
             GETATTR_Key_num_key(interp, key, num_key);
             return Parrot_str_from_num(interp, num_key);
+        }
         case KEY_number_FLAG | KEY_register_FLAG:
+        {
+            INTVAL int_key;
             GETATTR_Key_int_key(interp, key, int_key);
             return Parrot_str_from_num(interp, REG_NUM(interp, int_key));
-
+        }
         default:
         case KEY_pmc_FLAG:
             return VTABLE_get_string(interp, key);
@@ -607,11 +617,13 @@
 {
     ASSERT_ARGS(key_mark)
     const UINTVAL flags = PObj_get_FLAGS(key) & KEY_type_FLAGS;
-    PMC          *next_key;
-    STRING       *str_key;
 
     if (flags == KEY_string_FLAG) {
+        STRING *str_key;
         GETATTR_Key_str_key(interp, key, str_key);
+
+        /* XXX str_key can be NULL from GETATTR_Key_str_key, */
+        /* so shouldn't be marked. */
         Parrot_gc_mark_PObj_alive(interp, (PObj *)str_key);
     }
 
@@ -620,13 +632,13 @@
      * the bucket_index and not the next key component
      * Note to self: shoot whoever thought this was a good idea.
      */
-    if (flags == KEY_hash_iterator_FLAGS)
-        return;
-
-    /* if iteration hasn't started, above flag isn't set yet */
-    GETATTR_Key_next_key(interp, key, next_key);
-    if (next_key && (void *)next_key != (void *)INITBucketIndex)
-        Parrot_gc_mark_PObj_alive(interp, (PObj *)next_key);
+    if (flags != KEY_hash_iterator_FLAGS) {
+        PMC *next_key;
+        /* if iteration hasn't started, above flag isn't set yet */
+        GETATTR_Key_next_key(interp, key, next_key);
+        if (next_key && (void *)next_key != (void *)INITBucketIndex)
+            Parrot_gc_mark_PObj_alive(interp, (PObj *)next_key);
+    }
 
 }
 
@@ -657,7 +669,7 @@
     INTVAL         int_key;
     STRING        *str_key;
 
-    for (;key;) {
+    while (key != NULL) {
         switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
             case KEY_integer_FLAG:
                 GETATTR_Key_int_key(interp, key, int_key);

Modified: branches/tt761_keys_revamp/src/library.c
==============================================================================
--- branches/tt761_keys_revamp/src/library.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/library.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -788,7 +788,7 @@
     char * const env = Parrot_getenv("PARROT_RUNTIME", &free_it);
 
     if (env)
-        return free_it ? env : str_dup(env);
+        return free_it ? env : mem_sys_strdup(env);
     else {
         PMC    * const config_hash =
             VTABLE_get_pmc_keyed_int(interp, interp->iglobals, (INTVAL) IGLOBALS_CONFIG_HASH);
@@ -799,7 +799,7 @@
             return Parrot_str_to_cstring(interp, s);
         }
         else
-            return str_dup(".");
+            return mem_sys_strdup(".");
     }
 }
 

Modified: branches/tt761_keys_revamp/src/main.c
==============================================================================
--- branches/tt761_keys_revamp/src/main.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/main.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -19,7 +19,6 @@
 */
 
 #include <stdio.h>
-#include <string.h>
 
 #include "parrot/parrot.h"
 #include "parrot/embed.h"
@@ -57,7 +56,7 @@
        available. */
     Parrot_set_executable_name(interp, Parrot_str_new(interp, argv[0], 0));
 
-    sourcefile = strdup(parseflags(interp, &argc, &argv));
+    sourcefile = parseflags(interp, &argc, &argv);
     status     = imcc_run(interp, sourcefile, argc, argv);
     UNUSED(status);
 

Modified: branches/tt761_keys_revamp/src/oo.c
==============================================================================
--- branches/tt761_keys_revamp/src/oo.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/oo.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -300,7 +300,7 @@
     PObj_is_object_SET(cloned);
 
     /* Now create the underlying structure, and clone attributes list.class. */
-    cloned_guts               = mem_allocate_typed(Parrot_Object_attributes);
+    cloned_guts               = mem_allocate_zeroed_typed(Parrot_Object_attributes);
     PMC_data(cloned)          = cloned_guts;
     cloned_guts->_class       = obj->_class;
     cloned_guts->attrib_store = VTABLE_clone(interp, obj->attrib_store);

Modified: branches/tt761_keys_revamp/src/ops/cmp.ops
==============================================================================
--- branches/tt761_keys_revamp/src/ops/cmp.ops	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/ops/cmp.ops	Sat Jul  4 21:38:28 2009	(r39884)
@@ -704,6 +704,10 @@
 
 Sets $1 to 1 if the object is null, 0 otherwise.
 
+=item B<isnull>(out INT, in STR)
+
+Sets $1 to 1 if the string is null, 0 otherwise.
+
 =cut
 
 inline op issame(out INT, invar PMC, invar PMC) {
@@ -740,6 +744,10 @@
     $1 = PMC_IS_NULL($2);
 }
 
+inline op isnull(out INT, in STR) {
+    $1 = STRING_IS_NULL($2);
+}
+
 =item B<isgt>(out INT, in INT, in INT)
 
 =item B<isgt>(out INT, in NUM, in NUM)

Modified: branches/tt761_keys_revamp/src/ops/ops.num
==============================================================================
--- branches/tt761_keys_revamp/src/ops/ops.num	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/ops/ops.num	Sat Jul  4 21:38:28 2009	(r39884)
@@ -1278,3 +1278,5 @@
 find_name_p_sc                 1254
 find_sub_not_null_p_s          1255
 find_sub_not_null_p_sc         1256
+isnull_i_s                     1257
+isnull_i_sc                    1258

Modified: branches/tt761_keys_revamp/src/packdump.c
==============================================================================
--- branches/tt761_keys_revamp/src/packdump.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/packdump.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -37,7 +37,7 @@
         __attribute__nonnull__(2)
         __attribute__nonnull__(3);
 
-static void pobj_flag_dump(PARROT_INTERP, ARGIN_NULLOK(long flags))
+static void pobj_flag_dump(PARROT_INTERP, long flags)
         __attribute__nonnull__(1);
 
 #define ASSERT_ARGS_PackFile_Constant_dump __attribute__unused__ int _ASSERT_ARGS_CHECK = \
@@ -88,7 +88,7 @@
 /* [this desperately needs better abstraction, so we're not duplicating the enum
  * PObj_enum definition in the include/parrot/pobj.h file.  -- rgr, 1-Mar-08.]
  */
-static const char *flag_bit_names[] =
+PARROT_OBSERVER static const char * const flag_bit_names[] =
 {
     "private0",
     "private1",
@@ -135,7 +135,7 @@
 */
 
 static void
-pobj_flag_dump(PARROT_INTERP, ARGIN_NULLOK(long flags))
+pobj_flag_dump(PARROT_INTERP, long flags)
 {
     ASSERT_ARGS(pobj_flag_dump)
     INTVAL idx = 0;

Modified: branches/tt761_keys_revamp/src/packfile.c
==============================================================================
--- branches/tt761_keys_revamp/src/packfile.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/packfile.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -2408,7 +2408,7 @@
     self->size        = 0;
     self->data        = NULL;
     self->id          = 0;
-    self->name        = str_dup(name);
+    self->name        = mem_sys_strdup(name);
 }
 
 
@@ -2753,7 +2753,7 @@
     }
 
     /* find seg e.g. CODE_DB => CODE and attach it */
-    code_name              = str_dup(debug->base.name);
+    code_name              = mem_sys_strdup(debug->base.name);
     str_len                = strlen(code_name);
     code_name[str_len - 3] = '\0';
     code                   = (PackFile_ByteCode *)PackFile_find_segment(interp,
@@ -3529,7 +3529,7 @@
 
     self->fixups[i]         = mem_allocate_typed(PackFile_FixupEntry);
     self->fixups[i]->type   = type;
-    self->fixups[i]->name   = str_dup(label);
+    self->fixups[i]->name   = mem_sys_strdup(label);
     self->fixups[i]->offset = offs;
     self->fixups[i]->seg    = self->code;
 }
@@ -4330,7 +4330,7 @@
     }
 
     /* Need to associate this segment with the applicable code segment. */
-    code_name              = str_dup(self->base.name);
+    code_name              = mem_sys_strdup(self->base.name);
     str_len                = strlen(code_name);
     code_name[str_len - 4] = '\0';
     code                   = (PackFile_ByteCode *)PackFile_find_segment(interp,

Modified: branches/tt761_keys_revamp/src/parrot_debugger.c
==============================================================================
--- branches/tt761_keys_revamp/src/parrot_debugger.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/parrot_debugger.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -184,7 +184,7 @@
             Parrot_pbc_load(interp, pf);
 
             IMCC_push_parser_state(interp);
-            IMCC_INFO(interp)->state->file = strdup(filename);
+            IMCC_INFO(interp)->state->file = mem_sys_strdup(filename);
 
             if (!(imc_yyin_set(fopen(filename, "r"), yyscanner)))    {
                 IMCC_fatal_standalone(interp, EXCEPTION_PIO_ERROR,

Modified: branches/tt761_keys_revamp/src/pbc_merge.c
==============================================================================
--- branches/tt761_keys_revamp/src/pbc_merge.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/pbc_merge.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -378,7 +378,7 @@
     /* Stash produced bytecode. */
     bc_seg->base.data = bc;
     bc_seg->base.size = cursor;
-    bc_seg->base.name = str_dup("MERGED");
+    bc_seg->base.name = mem_sys_strdup("MERGED");
     return bc_seg;
 }
 

Modified: branches/tt761_keys_revamp/src/pmc.c
==============================================================================
--- branches/tt761_keys_revamp/src/pmc.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/pmc.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -364,16 +364,12 @@
     /* Do we need one? */
     if (flags & VTABLE_PMC_NEEDS_EXT) {
         /* If we need an ext area, go allocate one */
-        if (!has_ext)
-            Parrot_gc_add_pmc_ext(interp, pmc);
+        Parrot_gc_add_pmc_ext(interp, pmc);
         newflags |= PObj_is_PMC_EXT_FLAG;
-        PARROT_ASSERT(pmc->pmc_ext != NULL);
         PARROT_ASSERT((newflags & PObj_is_PMC_EXT_FLAG) != 0);
     }
     else {
-        if (has_ext)
-            Parrot_gc_free_pmc_ext(interp, pmc);
-        pmc->pmc_ext = NULL;
+        Parrot_gc_free_pmc_ext(interp, pmc);
         PMC_data(pmc) = NULL;
         newflags &= ~PObj_is_PMC_EXT_FLAG;
         PARROT_ASSERT((newflags & PObj_is_PMC_EXT_FLAG) == 0);
@@ -818,13 +814,9 @@
         interp->vtables[type]->pmc_class = _class;
     }
     else {
-        if (PObj_is_PMC_EXT_TEST(_class))
-            Parrot_gc_free_pmc_ext(interp, _class);
-
+        Parrot_gc_free_pmc_ext(interp, _class);
         gc_flag_CLEAR(is_special_PMC, _class);
-
         PObj_is_PMC_shared_CLEAR(_class);
-
         interp->vtables[type]->pmc_class = _class;
     }
 
@@ -938,6 +930,7 @@
 
 */
 
+PARROT_EXPORT
 void
 gc_unregister_pmc(PARROT_INTERP, ARGIN(PMC *pmc))
 {

Modified: branches/tt761_keys_revamp/src/pmc/bignum.pmc
==============================================================================
--- branches/tt761_keys_revamp/src/pmc/bignum.pmc	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/pmc/bignum.pmc	Sat Jul  4 21:38:28 2009	(r39884)
@@ -474,18 +474,22 @@
 
 static void
 bignum_div_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) {
-    BIGNUM *bn, *bn_self, *bn_dest;
+    BIGNUM bn, *bn_self, *bn_dest;
     GETATTR_BigNum_bn(interp, self, bn_self);
     GETATTR_BigNum_bn(interp, dest, bn_dest);
     int_check_divide_zero(interp, value);
+    mpf_init(bn.b);
 
     if (value < 0) {
-        mpf_set_d(bn->b, -value);
-        mpf_div(bn_dest->b, bn_self->b, bn->b);
+        mpf_set_d(bn.b, -value);
+        mpf_div(bn_dest->b, bn_self->b, bn.b);
         mpf_neg(bn_dest->b, bn_dest->b);
     }
-    else
-        mpf_div(bn_dest->b, bn_self->b, bn->b);
+    else {
+        mpf_set_d(bn.b, value);
+        mpf_div(bn_dest->b, bn_self->b, bn.b);
+    }
+    mpf_clear(bn.b);
 }
 
 /* There's no such mpf_fdiv, only mpz_fdiv and mpf_div */
@@ -1350,6 +1354,13 @@
         return dest;
     }
 
+    VTABLE PMC *divide_float(FLOATVAL value, PMC *dest) {
+        dest = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
+
+        bignum_div_bignum_float(INTERP, SELF, value, dest);
+        return dest;
+    }
+
     MULTI void i_divide(BigNum value) {
         bignum_div_bignum(INTERP, SELF, value, SELF);
     }

Modified: branches/tt761_keys_revamp/src/pmc/filehandle.pmc
==============================================================================
--- branches/tt761_keys_revamp/src/pmc/filehandle.pmc	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/pmc/filehandle.pmc	Sat Jul  4 21:38:28 2009	(r39884)
@@ -359,7 +359,8 @@
     METHOD readline_interactive(STRING *prompt :optional, INTVAL got_prompt :opt_flag) {
         STRING *string_result = NULL;
 #ifdef PARROT_HAS_READLINE
-    char * const r = readline(got_prompt ? prompt->strstart : NULL);
+    /* 4-column indent to get c_indent.t to DTRT */
+        char * const r = readline(got_prompt ? prompt->strstart : NULL);
 
         if (r) {
             if (*r)
@@ -391,7 +392,10 @@
             }
         }
 #endif
-        RETURN(STRING *string_result);
+        if (string_result)
+            RETURN(STRING *string_result);
+        else
+            RETURN(PMC *PMCNULL);
     }
 
 /*

Modified: branches/tt761_keys_revamp/src/pmc/multisub.pmc
==============================================================================
--- branches/tt761_keys_revamp/src/pmc/multisub.pmc	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/pmc/multisub.pmc	Sat Jul  4 21:38:28 2009	(r39884)
@@ -84,7 +84,7 @@
         return SUPER(key);
     }
 
-    VTABLE PMC *get_pmc_keyed_string(STRING *s) {
+    VTABLE PMC *get_pmc_keyed_str(STRING *s) {
         PMC * const sub = Parrot_mmd_sort_manhattan(INTERP, SELF);
         if (PMC_IS_NULL(sub))
             Parrot_ex_throw_from_c_args(INTERP, NULL, 1, "No applicable methods.\n");

Modified: branches/tt761_keys_revamp/src/pmc/parrotinterpreter.pmc
==============================================================================
--- branches/tt761_keys_revamp/src/pmc/parrotinterpreter.pmc	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/pmc/parrotinterpreter.pmc	Sat Jul  4 21:38:28 2009	(r39884)
@@ -242,8 +242,8 @@
             PMC_data(SELF) = attrs;
             create_interp(SELF, INTERP);
             PARROT_ASSERT(attrs->interp);
-            PObj_active_destroy_SET(SELF);
         }
+        PObj_active_destroy_SET(SELF);
     }
 
 /*
@@ -806,7 +806,7 @@
 Optionally sets the parrot handler passed as second argument
 as the specified standard handler.
 
-This method is experimental.
+This method is experimental. See TT #264.
 
 =cut
 

Modified: branches/tt761_keys_revamp/src/pmc/parrotrunningthread.pmc
==============================================================================
--- branches/tt761_keys_revamp/src/pmc/parrotrunningthread.pmc	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/pmc/parrotrunningthread.pmc	Sat Jul  4 21:38:28 2009	(r39884)
@@ -50,6 +50,7 @@
             mem_allocate_zeroed_typed(Parrot_ParrotRunningThread_attributes);
         attrs->tid = -1;
         PMC_data(SELF) = attrs;
+        PObj_active_destroy_SET(SELF);
     }
 
 /*

Modified: branches/tt761_keys_revamp/src/pmc/parrotthread.pmc
==============================================================================
--- branches/tt761_keys_revamp/src/pmc/parrotthread.pmc	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/pmc/parrotthread.pmc	Sat Jul  4 21:38:28 2009	(r39884)
@@ -70,7 +70,6 @@
 
     pmc_reuse(interp, thread, enum_class_ParrotRunningThread, 0);
 
-    PObj_active_destroy_CLEAR(thread);
     PObj_custom_mark_CLEAR(thread);
     VTABLE_set_integer_native(interp, thread, tid);
 

Modified: branches/tt761_keys_revamp/src/pmc/stringhandle.pmc
==============================================================================
--- branches/tt761_keys_revamp/src/pmc/stringhandle.pmc	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/pmc/stringhandle.pmc	Sat Jul  4 21:38:28 2009	(r39884)
@@ -220,7 +220,7 @@
             SET_ATTR_mode(INTERP, SELF, open_mode);
         }
 
-        Parrot_io_open(INTERP, SELF, filename, open_mode);
+        SELF = Parrot_io_open(INTERP, SELF, filename, open_mode);
 
         RETURN(PMC *SELF);
     }

Modified: branches/tt761_keys_revamp/src/pmc/sub.pmc
==============================================================================
--- branches/tt761_keys_revamp/src/pmc/sub.pmc	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/pmc/sub.pmc	Sat Jul  4 21:38:28 2009	(r39884)
@@ -491,6 +491,8 @@
             Parrot_gc_mark_PObj_alive(INTERP, (PObj *) sub->ns_entry_name);
         if (!PMC_IS_NULL(sub->namespace_name))
             Parrot_gc_mark_PObj_alive(INTERP, (PObj *) sub->namespace_name);
+        if (!PMC_IS_NULL(sub->namespace_stash))
+            Parrot_gc_mark_PObj_alive(INTERP, (PObj *) sub->namespace_stash);
         if (!PMC_IS_NULL(sub->multi_signature))
             Parrot_gc_mark_PObj_alive(INTERP, (PObj *) sub->multi_signature);
         if (!PMC_IS_NULL(sub->lex_info))

Modified: branches/tt761_keys_revamp/src/runcore/cores.c
==============================================================================
--- branches/tt761_keys_revamp/src/runcore/cores.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/runcore/cores.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -149,7 +149,7 @@
 The precomputed goto core is an amazingly fast optimized core that uses
 the same computed goto feature, but performs the array dereferencing
 before the core even starts. The compiled bytecode is fed into a
-preprocessor that converts the bytecode instruction numbers into lable
+preprocessor that converts the bytecode instruction numbers into label
 pointer values. In the computed goto core, you have this
 operation to move to the next opcode:
 
@@ -489,7 +489,7 @@
             Parrot_ex_throw_from_c_args(interp, NULL, 1,
                 "attempt to access code outside of current code segment");
 
-        Parrot_gc_mark_and_sweep(interp, 0);
+        Parrot_gc_mark_and_sweep(interp, GC_TRACE_FULL);
         CONTEXT(interp)->current_pc = pc;
 
         DO_OP(pc, interp);

Modified: branches/tt761_keys_revamp/src/runcore/trace.c
==============================================================================
--- branches/tt761_keys_revamp/src/runcore/trace.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/runcore/trace.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -471,20 +471,20 @@
 done:
 
     if (interp->code->annotations) {
-        PMC *annot = PackFile_Annotations_lookup(interp, interp->code->annotations,
+        PMC * const annot = PackFile_Annotations_lookup(interp, interp->code->annotations,
                 pc - code_start + 1, NULL);
         if (!PMC_IS_NULL(annot)) {
-            PMC *pfile = VTABLE_get_pmc_keyed_str(interp, annot,
+            PMC * const pfile = VTABLE_get_pmc_keyed_str(interp, annot,
                     Parrot_str_new_constant(interp, "file"));
-            PMC *pline = VTABLE_get_pmc_keyed_str(interp, annot,
+            PMC * const pline = VTABLE_get_pmc_keyed_str(interp, annot,
                     Parrot_str_new_constant(interp, "line"));
             if ((!PMC_IS_NULL(pfile)) && (!PMC_IS_NULL(pline))) {
                 /* The debugger interpreter may not be the same as
                  * the main interpreter, extract values from the
                  * PMC instad of passing them directly
                  */
-                STRING *file = VTABLE_get_string(interp, pfile);
-                INTVAL line = VTABLE_get_integer(interp, pline);
+                STRING * const file = VTABLE_get_string(interp, pfile);
+                const INTVAL line   = VTABLE_get_integer(interp, pline);
                 Parrot_io_eprintf(debugger, " (%Ss:%li)", file, (long)line);
             }
         }

Modified: branches/tt761_keys_revamp/src/stacks.c
==============================================================================
--- branches/tt761_keys_revamp/src/stacks.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/stacks.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -335,8 +335,8 @@
           ARGOUT_NULLOK(void *where), Stack_entry_type type)
 {
     ASSERT_ARGS(stack_pop)
-    Stack_Chunk_t     *cur_chunk   = *stack_p;
-    Stack_Entry_t * const entry    =
+    Stack_Chunk_t * const cur_chunk = *stack_p;
+    Stack_Entry_t * const entry =
         (Stack_Entry_t *)stack_prepare_pop(interp, stack_p);
 
     /* Types of 0 mean we don't care */

Modified: branches/tt761_keys_revamp/src/string/api.c
==============================================================================
--- branches/tt761_keys_revamp/src/string/api.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/string/api.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -426,23 +426,21 @@
 
     /* a table could possibly simplify the logic */
     if (a->encoding == Parrot_utf8_encoding_ptr &&
-            (b->charset == Parrot_ascii_charset_ptr ||
-             b->charset == Parrot_iso_8859_1_charset_ptr)) {
+            b->charset == Parrot_ascii_charset_ptr) {
         if (a->strlen == a->bufused) {
             *e = Parrot_fixed_8_encoding_ptr;
-            return Parrot_ascii_charset_ptr;
+            return b->charset;
         }
         *e = a->encoding;
         return a->charset;
     }
     if (b->encoding == Parrot_utf8_encoding_ptr &&
-            (a->charset == Parrot_ascii_charset_ptr ||
-             a->charset == Parrot_iso_8859_1_charset_ptr)) {
+            a->charset == Parrot_ascii_charset_ptr) {
         if (b->strlen == b->bufused) {
             *e = Parrot_fixed_8_encoding_ptr;
             return a->charset;
         }
-        *e = Parrot_utf8_encoding_ptr;
+        *e = b->encoding;
         return b->charset;
     }
     if (a->encoding != b->encoding)
@@ -562,14 +560,22 @@
         a->encoding = enc;
     }
     else {
-        /* upgrade to utf16 */
-        Parrot_utf16_encoding_ptr->to_encoding(interp, a, NULL);
-        b = Parrot_utf16_encoding_ptr->to_encoding(interp, b,
+        /* upgrade strings for concatenation */
+        enc = (a->encoding == Parrot_utf16_encoding_ptr ||
+                  b->encoding == Parrot_utf16_encoding_ptr ||
+                  a->encoding == Parrot_ucs2_encoding_ptr ||
+                  b->encoding == Parrot_ucs2_encoding_ptr)
+              ? Parrot_utf16_encoding_ptr
+              : Parrot_utf8_encoding_ptr;
+
+        Parrot_unicode_charset_ptr->to_charset(interp, a, NULL);
+        b = Parrot_unicode_charset_ptr->to_charset(interp, b,
                 Parrot_gc_new_string_header(interp, 0));
 
-        /* result could be mixed ucs2 / utf16 */
-        if (b->encoding == Parrot_utf16_encoding_ptr)
-            a->encoding = Parrot_utf16_encoding_ptr;
+        if (a->encoding != enc)
+            enc->to_encoding(interp, a, NULL);
+        if (b->encoding != enc)
+            enc->to_encoding(interp, b, NULL);
     }
 
     /* calc usable and total bytes */
@@ -2315,20 +2321,29 @@
             return 0.0;
     }
 
-    if (d && d_is_safe) {
-        f = mantissa + (1.0 * d / powl(10, d_length));
-    }
+/* local macro to call proper pow version depending on FLOATVAL */
+#if NUMVAL_SIZE == DOUBLE_SIZE
+#  define POW pow
+#else
+#  define POW powl
+#endif
+
+     if (d && d_is_safe) {
+        f = mantissa + (1.0 * d / POW(10.0, d_length));
+     }
 
     if (sign < 0)
         f = -f;
 
     if (e) {
         if (e_sign == 1)
-            f *= powl(10, e);
+            f *= POW(10.0, e);
         else
-            f /= powl(10, e);
+            f /= POW(10.0, e);
     }
 
+#undef POW
+
     return f;
 }
 
@@ -3325,8 +3340,8 @@
 =item C<PMC* Parrot_str_split(PARROT_INTERP, STRING *delim, STRING *str)>
 
 Splits the string C<str> at the delimiter C<delim>, returning a
-C<ResizableStringArray> of results. Returns PMCNULL if the string or the
-delimiter is NULL.
+C<ResizableStringArray>, or his mapped type in the current HLL,
+of results. Returns PMCNULL if the string or the delimiter is NULL.
 
 =cut
 
@@ -3346,7 +3361,7 @@
     if (STRING_IS_NULL(delim) || STRING_IS_NULL(str))
         return PMCNULL;
 
-    res  = pmc_new(interp, enum_class_ResizableStringArray);
+    res  = pmc_new(interp, Parrot_get_ctx_HLL_type(interp, enum_class_ResizableStringArray));
     slen = Parrot_str_byte_length(interp, str);
 
     if (!slen)

Modified: branches/tt761_keys_revamp/src/string/charset/unicode.c
==============================================================================
--- branches/tt761_keys_revamp/src/string/charset/unicode.c	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/src/string/charset/unicode.c	Sat Jul  4 21:38:28 2009	(r39884)
@@ -417,16 +417,17 @@
 {
     ASSERT_ARGS(upcase)
 #if PARROT_HAS_ICU
-
     UErrorCode err;
     int dest_len, src_len, needed;
+#endif
 
     if (src->bufused  == src->strlen
-    &&  src->encoding == Parrot_utf8_encoding_ptr) {
+            && src->encoding == Parrot_utf8_encoding_ptr) {
         Parrot_ascii_charset_ptr->upcase(interp, src);
         return;
     }
 
+#if PARROT_HAS_ICU
     src = Parrot_utf16_encoding_ptr->to_encoding(interp, src, NULL);
     /*
        U_CAPI int32_t U_EXPORT2
@@ -510,17 +511,18 @@
 downcase(PARROT_INTERP, ARGIN(STRING *src))
 {
     ASSERT_ARGS(downcase)
+#if PARROT_HAS_ICU
+    UErrorCode err;
+    int dest_len, src_len;
+#endif
+
     if (src->bufused  == src->strlen
-    &&  src->encoding == Parrot_utf8_encoding_ptr) {
+            && src->encoding == Parrot_utf8_encoding_ptr) {
         Parrot_ascii_charset_ptr->downcase(interp, src);
         return;
     }
-    else {
-#if PARROT_HAS_ICU
-
-    UErrorCode err;
-    int dest_len, src_len;
 
+#if PARROT_HAS_ICU
     src = Parrot_utf16_encoding_ptr->to_encoding(interp, src, NULL);
     /*
 U_CAPI int32_t U_EXPORT2
@@ -554,7 +556,6 @@
     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
         "no ICU lib loaded");
 #endif
-    }
 }
 
 

Modified: branches/tt761_keys_revamp/t/codingstd/c_indent.t
==============================================================================
--- branches/tt761_keys_revamp/t/codingstd/c_indent.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/codingstd/c_indent.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -45,106 +45,97 @@
 
     foreach my $path (@_) {
         my @source;
-        open my $fh, '<', $path
+        open my $IN, '<', $path
             or die "Can not open '$path' for reading!\n";
-        @source = <$fh>;
+        @source = <$IN>;
 
-        my @stack;    # for tracking indention level
-        my $line_cnt       = 0;
-        my $f              = undef;
-        my $prev_last_char = '';
-        my $last_char      = '';
-        my $in_comment     = 0;
-
-        foreach (@source) {
-            $line_cnt++;
-            next unless defined $_;
-            chomp;
+        my %state = (
+            stack           => [],
+            line_cnt        => 0,
+            bif             => undef,
+            prev_last_char  => '',
+            last_char       => '',
+            in_comment      => 0,
+        );
+
+        foreach my $line (@source) {
+            $state{line_cnt}++;
+            chomp $line;
+#            dump_state(\%state, $line);
+            next unless $line;
 
-            $prev_last_char = $last_char;
-            $last_char = substr( $_, -1, 1 );
+            $state{prev_last_char} = $state{last_char};
+            $state{last_char} = substr( $line, -1, 1 );
 
             # ignore multi-line comments (except the first line)
-            $in_comment = 0, next if $in_comment && m{\*/} && $' !~ m{/\*};
-            next if $in_comment;
-            $in_comment = 1 if m{/\*} && $' !~ m{\*/};
+            $state{in_comment} = 0, next if $state{in_comment} &&
+                $line =~ m{\*/} &&
+                $' !~ m{/\*};
+            next if $state{in_comment};
+            $state{in_comment} = 1
+                if $line =~ m{/\*} &&
+                $' !~ m{\*/};
 
             ## preprocessor scan
-            if (
-                m/ ^ \s* \#
-                    (\s*)
-                    ( ifndef | ifdef | if )
-                    \s+(.*)
-                  /x
-                )
+            if ( $line =~ m/^\s*\#(\s*)(ifndef|ifdef|if)\s+(.*)/ )
             {
-                next if (m/PARROT_IN_CORE|_GUARD/);
-                next if (m/__cplusplus/);
-
-                my $indent = q{  } x @stack;
-                if ( $1 ne $indent ) {
-                    push @pp_indent => "$path:$line_cnt\n"
-                        . "     got: $_"
-                        . "expected: #$indent$2 $3'\n";
+                my ($prespace, $condition, $postspace) = ($1,$2,$3);
+                next if ($line =~ m/PARROT_IN_CORE|_GUARD/);
+                next if ($line =~ m/__cplusplus/);
+
+                my $indent = q{  } x @{ $state{stack} };
+                if ( $prespace ne $indent ) {
+                    push @pp_indent => "$path:$state{line_cnt}\n"
+                        . "     got: $line"
+                        . "expected: #$indent$condition $postspace'\n";
                     $pp_failed{"$path\n"} = 1;
                 }
-                push @stack, "#$2 $3";
+                push @{ $state{stack} }, "#$condition $postspace";
+                $state{bif} = undef;
                 next;
             }
-            if (
-                m/ ^ \s* \#
-                    (\s*)
-                    ( else | elif )
-                  /x
-                )
+            if ( $line =~ m/^\s*\#(\s*)(else|elif)/)
             {
 
+                my ($prespace, $condition) = ($1,$2);
                 # stay where we are, but indenting should be
                 # back even with the opening brace.
-                my $indent = q{  } x ( @stack - 1 );
-                if ( $1 ne $indent ) {
-                    push @pp_indent => "$path:$line_cnt\n"
-                        . "     got: $_"
-                        . "expected: #$indent$2 -- it's inside of "
-                        . ( join ' > ', @stack ) . "\n";
+                my $indent = q{  } x ( @{ $state{stack} } - 1 );
+                if ( $prespace ne $indent ) {
+                    push @pp_indent => "$path:$state{line_cnt}\n"
+                        . "     got: $line"
+                        . "expected: #$indent$condition -- it's inside of "
+                        . ( join ' > ', @{ $state{stack} } ) . "\n";
                     $pp_failed{"$path\n"} = 1;
                 }
                 next;
             }
-            if (
-                m/ ^ \s* \#
-                    (\s*)
-                    (endif)
-                  /x
-                )
+            if ( $line =~ m/^\s*\#(\s*)(endif)/)
             {
-                my $indent = q{  } x ( @stack - 1 );
-                if ( $1 ne $indent ) {
-                    push @pp_indent => "$path:$line_cnt\n"
-                        . "     got: $_"
-                        . "expected: #$indent$2 --  it's inside of "
-                        . ( join ' > ', @stack ) . "\n";
+                my ($prespace, $condition) = ($1,$2);
+                my $indent = q{  } x ( @{ $state{stack} } - 1 );
+                if ( $prespace ne $indent ) {
+                    push @pp_indent => "$path:$state{line_cnt}\n"
+                        . "     got: $line"
+                        . "expected: #$indent$condition --  it's inside of "
+                        . ( join ' > ', @{ $state{stack} } ) . "\n";
                     $pp_failed{"$path\n"} = 1;
                 }
-                pop @stack;
+                pop @{ $state{stack} };
                 next;
             }
-            next unless @stack;
+            next unless @{ $state{stack} };
 
-            if (
-                m/ ^ \s* \#
-                    (\s*)
-                    (.*)
-                  /x
-                )
+            if ( $line =~ m/^\s*\#(\s*)(.*)/)
             {
-                next if (m/ASSERT_ARGS_/); # autogenerated by headerizer
-                my $indent = q{  } x (@stack);
-                if ( $1 ne $indent ) {
-                    push @pp_indent => "$path:$line_cnt\n"
-                        . "     got: $_"
-                        . "expected: #$indent$2 -- it's inside of "
-                        . ( join ' > ', @stack ) . "\n";
+                my ($prespace, $condition) = ($1,$2);
+                next if ($line =~ m/ASSERT_ARGS_/); # autogenerated by headerizer
+                my $indent = q{  } x (@{ $state{stack} });
+                if ( $prespace ne $indent ) {
+                    push @pp_indent => "$path:$state{line_cnt}\n"
+                        . "     got: $line"
+                        . "expected: #$indent$condition -- it's inside of "
+                        . ( join ' > ', @{ $state{stack} } ) . "\n";
                     $pp_failed{"$path\n"} = 1;
                 }
                 next;
@@ -155,40 +146,42 @@
             # probably overkill for this task.  For now we just check the
             # first line of a function, and assume that more likely than not
             # indenting is consistent within a func body.
-            if (/^(\s*).*\{\s*$/) {
+            if ($line =~ /^(\s*).*\{\s*$/) {
 
+                my $prespace = $1;
                 # note the beginning of a block, and its indent depth.
-                $f = length($1);
+                $state{bif} = length($prespace);
                 next;
             }
 
-            if (/^\s*([\#\}])/) {
+            if ($line =~ /^\s*([\#\}])/) {
 
+                my $closing_punc = $1;
                 # skip the last line of the func or cpp directives.
-                $f = undef if ( $1 eq "}" );
+                $state{bif} = undef if ( $closing_punc eq "}" );
                 next;
             }
 
-            if ( defined($f) ) {
+            if ( defined($state{bif}) ) {
 
                 # first line of a block
-                if ( $f == 0 ) {
+                if ( $state{bif} == 0 ) {
 
                     # first line of a top-level block (first line of a function,
                     # in other words)
-                    my ($indent) = /^(\s*)/;
+                    my ($indent) = $line =~ /^(\s*)/;
                     if ( length($indent) != 4 ) {
-                        push @c_indent => "$path:$line_cnt\n"
+                        push @c_indent => "$path:$state{line_cnt}\n"
                             . "    apparent non-4 space indenting ("
                             . length($indent)
                             . " spaces)\n";
                         $c_failed{"$path\n"} = 1;
                     }
                 }
-                $f = undef;
+                $state{bif} = undef;
             }
 
-            my ($indent) = /^(\s+)/ or next;
+            my ($indent) = $line =~ /^(\s+)/ or next;
             $indent = length($indent);
 
             # Ignore the indentation of the current line if that
@@ -197,8 +190,11 @@
             # The indentation of the previous line is not considered.
             # Check sanity by verifying that the indentation of the current line
             # is divisible by four.
-            if ( $indent % 4 && !$in_comment && $prev_last_char eq ';' ) {
-                push @c_indent => "$path:$line_cnt\n"
+            if ( $indent % 4 &&
+                !$state{in_comment} &&
+                $state{prev_last_char} eq ';'
+            ) {
+                push @c_indent => "$path:$state{line_cnt}\n"
                     . "    apparent non-4 space indenting ($indent space"
                     . ( $indent == 1 ? '' : 's' ) . ")\n";
                 $c_failed{"$path\n"} = 1;
@@ -226,6 +222,17 @@
             . " files:\n at c_indent" );
 }
 
+sub dump_state {
+    my ($state, $line) = @_;
+    print STDERR (join q{|} => (
+        $state->{line_cnt},
+        (defined($state->{bif}) ? $state->{bif} : q{u}),
+        $state->{in_comment},
+        (join q{*} => @{ $state->{stack} }),
+        $line,
+    ) ), "\n";
+}
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4

Modified: branches/tt761_keys_revamp/t/compilers/imcc/syn/errors.t
==============================================================================
--- branches/tt761_keys_revamp/t/compilers/imcc/syn/errors.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/compilers/imcc/syn/errors.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -13,7 +13,7 @@
 plan skip_all => 'No reason to compile invalid PBC here'
     if $ENV{TEST_PROG_ARGS} && $ENV{TEST_PROG_ARGS} =~ m/--run-pbc/;
 
-plan tests => 5;
+plan tests => 6;
 
 ## tests for imcc error messages
 
@@ -78,6 +78,20 @@
 /^error:imcc:syntax error, unexpected IDENTIFIER, expecting/
 END_EXPECTED
 
+TODO: {
+  local $TODO = 'TT #767';
+
+pir_error_output_like( <<'END_PIR', <<'END_EXPECTED', 'no multiple .local, TT #767' );
+.sub main :main
+  .local pmc p
+  .local string p
+.end
+END_PIR
+/^error:imcc:syntax error, duplicated IDENTIFIER/
+END_EXPECTED
+
+}
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4

Modified: branches/tt761_keys_revamp/t/compilers/imcc/syn/regressions.t
==============================================================================
--- branches/tt761_keys_revamp/t/compilers/imcc/syn/regressions.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/compilers/imcc/syn/regressions.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -6,7 +6,7 @@
 use warnings;
 use lib qw( . lib ../lib ../../lib );
 use Test::More;
-use Parrot::Test tests => 14;
+use Parrot::Test tests => 15;
 
 pir_error_output_like( <<'CODE', <<'OUT', 'invalid get_results syntax');
 .sub main :main
@@ -191,6 +191,15 @@
 OUT
 
 }
+
+pir_error_output_like( <<'CODE', <<'OUT', 'No segfault from syntax error, RT #60172');
+.sub 'main'
+    ($S0) = 'blah'(:pir_only=>1)
+.end
+CODE
+/syntax error.+unexpected/
+OUT
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4

Modified: branches/tt761_keys_revamp/t/compilers/pge/perl6regex/context.t
==============================================================================
--- branches/tt761_keys_revamp/t/compilers/pge/perl6regex/context.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/compilers/pge/perl6regex/context.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -32,7 +32,7 @@
     load_bytecode "PGE/Glob.pbc"
     load_bytecode "PGE/Text.pbc"
     .local string target, pattern
-    .local pmc perl6regex, rulesub, pir, exp, match
+    .local pmc perl6regex, rulesub, pir, match
     perl6regex = compreg 'PGE::Perl6Regex'
     null match
     null rulesub

Modified: branches/tt761_keys_revamp/t/examples/pod.t
==============================================================================
--- branches/tt761_keys_revamp/t/examples/pod.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/examples/pod.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -39,7 +39,7 @@
             $snippet->{code} .  "\n.end";
     }
 
-    # Generate a temp file we can compile.
+    # Generate a temp file for the source.
     my ($fh,$tempfile) = tempfile(
         SUFFIX => '.' . lc $snippet->{type},
         UNLINK => 1
@@ -47,21 +47,38 @@
     print {$fh} $snippet->{code};
     close $fh;
 
+    # Generate a temp file for stderr
+    my ($err_fh,$err_tempfile) = tempfile(
+        SUFFIX => '.err',
+        UNLINK => 1
+    );
+    close $err_fh;
+
     # Send the output to /dev/null; similar to perl5's -c
     my $cmd = File::Spec->curdir() . $PConfig{slash} .
               $PConfig{test_prog} . " -o " . File::Spec->devnull() . " " .
-              $tempfile;
-
+              $tempfile . ' 2> ' . $err_tempfile;
+ 
     my $description = join (':', map {$snippet->{$_}}
         qw(file line type modifier));
 
+    my $rc = system($cmd);
+    open my $errout_fh, '<', $err_tempfile;
+
+    my $error_output; 
+    {
+        undef local $/;
+        $error_output = <$errout_fh>;
+    }
+ 
+    my $todo = 0;
+    $todo = 1 if ($snippet->{modifier} =~ /TODO|INVALID/);
     TODO: {
         # conditionally TODO the file.
-        local $TODO = "invalid code" if $snippet->{modifier} =~
-            /TODO|INVALID/;
-        is(system($cmd), 0 , $description);
-    }
+        local $TODO = 'invalid code' if $todo;
 
+        is ($error_output,'',$description);
+    } 
 }
 
 sub get_samples {

Modified: branches/tt761_keys_revamp/t/library/p6object.t
==============================================================================
--- branches/tt761_keys_revamp/t/library/p6object.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/library/p6object.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -1,5 +1,5 @@
 #!./parrot
-# Copyright (C) 2001-2008, Parrot Foundation.
+# Copyright (C) 2001-2009, Parrot Foundation.
 # $Id$
 
 =head1 NAME
@@ -26,7 +26,7 @@
     test_namespace.'export_to'(curr_namespace, exports)
 
     ##  set our plan
-    plan(234)
+    plan(252)
 
     ##  make sure we can load the P6object library
     push_eh load_fail
@@ -460,6 +460,15 @@
     $I0 = isnull $P0
     ok($I0, ".new_class didn't store ['parrot'], 'WXY'")
     p6obj_tests(wxyproto, 'WXY', 'isa'=>'WXY P6object', 'can'=>'foo')
+
+    ## build a Parrotclass
+    .local pmc vwx_nsarray, vwx_ns, vwx_parrotclass, vwx_proto 
+    vwx_nsarray = new 'ResizablePMCArray'
+    push vwx_nsarray, 'VWX'
+    vwx_ns = get_hll_namespace vwx_nsarray
+    vwx_parrotclass = newclass vwx_ns
+    vwx_proto = p6meta.'register'(vwx_parrotclass)
+    p6obj_tests(vwx_proto, 'VWX', 'can'=>'foo')
 .end
 
 .namespace ['XYZ']
@@ -472,6 +481,11 @@
     .return ('WXY::foo')
 .end
 
+.namespace ['VWX']
+.sub 'foo' :method
+    .return ('WXY::foo')
+.end
+
 =back
 
 =cut

Modified: branches/tt761_keys_revamp/t/library/test_more.t
==============================================================================
--- branches/tt761_keys_revamp/t/library/test_more.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/library/test_more.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -22,7 +22,7 @@
     exports = split " ", "plan test_out test_diag test_fail test_pass test_test"
     test_namespace.'export_to'(curr_namespace, exports)
 
-    plan( 74 )
+    plan( 75 )
 
     test_skip()
     test_todo()
@@ -346,24 +346,29 @@
     test_test( 'failing is_deeply() for hashes with different numbers of keys' )
 
     left['bar']  = 1
-    right['foo'] = 1
+    right['bar'] = 1
 
     test_fail( 'more diag' )
     is_deeply( left, right, 'more diag' )
     test_diag( 'Mismatch: expected 2 elements, received 1' )
     test_test( '... with description and proper pluralization' )
 
-    right['bar'] = 2
+    right['foo'] = 2
 
     test_fail()
     is_deeply( left, right )
-    test_diag( 'Mismatch at [bar]: expected 1, received 2' )
+    test_diag( 'Mismatch at [foo]: expected 1, received 2' )
     test_test( 'failing is_deeply() for hash with value mismatch' )
 
     test_fail( '2 is not 1' )
     is_deeply( left, right, '2 is not 1' )
-    test_diag( 'Mismatch at [bar]: expected 1, received 2' )
+    test_diag( 'Mismatch at [foo]: expected 1, received 2' )
     test_test( '... with description' )
+
+    right['foo'] = 1
+    test_pass()
+    is_deeply( left, right )
+    test_test( 'passing test is_deeply() for hashes created in different orders' )
 .end
 
 .sub test_is_deeply_mismatch

Modified: branches/tt761_keys_revamp/t/oo/metamodel.t
==============================================================================
--- branches/tt761_keys_revamp/t/oo/metamodel.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/oo/metamodel.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -1,4 +1,4 @@
-#!./parrot
+#!parrot
 # Copyright (C) 2007-2008, Parrot Foundation.
 # $Id$
 

Modified: branches/tt761_keys_revamp/t/op/arithmetics.t
==============================================================================
--- branches/tt761_keys_revamp/t/op/arithmetics.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/op/arithmetics.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -149,12 +149,7 @@
 # print -0.0 as -0
 #
 
-TODO: {
-    my @todo;
-    @todo = ( todo => '-0.0 not implemented, TT #313' )
-        if $^O =~ m/(?:openbsd)/i;
-
-pasm_output_is( <<'CODE', <<OUTPUT, 'negate -0.0', @todo );
+pasm_output_is( <<'CODE', <<OUTPUT, 'negate -0.0' );
         set N0, 0
         neg N0
         say N0
@@ -176,7 +171,6 @@
 -0
 OUTPUT
 
-}
 
 
 #

Modified: branches/tt761_keys_revamp/t/op/cmp-nonbranch.t
==============================================================================
--- branches/tt761_keys_revamp/t/op/cmp-nonbranch.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/op/cmp-nonbranch.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -17,7 +17,7 @@
 =cut
 
 
-.const int TESTS = 90
+.const int TESTS = 93
 
 .macro EXP()
   exp_nok:
@@ -38,6 +38,10 @@
     desc = .op
 .endm
 
+.macro RESET_DESC(op)
+    desc = .op
+.endm
+
 .macro CONCAT_RES()
     $S98 = $I1
     concat res, $S98
@@ -53,7 +57,8 @@
     'isntsame'()
     'istrue'()
     'isfalse'()
-    'isnull'()
+    'isnull_pmc'()
+    'isnull_string'()
     'isgt'()
     'isge'()
     'isle'()
@@ -159,9 +164,9 @@
 .end
 
 
-.sub 'isnull'
+.sub 'isnull_pmc'
     .local int exp, res
-    .SET_DESC('isnull')
+    .SET_DESC('isnull pmc')
 
   init:
     $S0 = 'FUBAR'
@@ -189,6 +194,18 @@
 .end
 
 
+.sub 'isnull_string'
+    .local int res
+    null $S0
+    res = isnull $S0
+    is(res, 1, 'isnull string null')
+    $S0 = 'something'
+    res = isnull $S0
+    is(res, 0, 'isnull string non null')
+    res = isnull 'H'
+    is(res, 0, 'isnull string constant')
+.end
+
 .sub 'isgt'
     .local string exp, res
 
@@ -209,7 +226,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isgt_i_ic_i')
+    .RESET_DESC('isgt_i_ic_i')
     set $I1, 111
     set $I3, 333
     isgt $I1, 222, $I3
@@ -221,7 +238,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isgt_i_i_ic')
+    .RESET_DESC('isgt_i_i_ic')
     set $I1, 111
     set $I2, 222
     isgt $I1, $I2, 223
@@ -233,7 +250,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isgt_i_ic_ic')
+    .RESET_DESC('isgt_i_ic_ic')
     set $I1, 111
     isgt $I1, 222, 223
     .CONCAT_RES()
@@ -244,7 +261,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isgt_i_n_n')
+    .RESET_DESC('isgt_i_n_n')
     set $I1, 111
     set $N2, 2.22
     set $N3, 3.33
@@ -259,7 +276,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isgt_i_nc_n')
+    .RESET_DESC('isgt_i_nc_n')
     set $I1, 111
     set $N3, 3.33
     isgt $I1, 2.22, $N3
@@ -271,7 +288,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isgt_i_n_nc')
+    .RESET_DESC('isgt_i_n_nc')
     set $I1, 111
     set $N2, 2.22
     isgt $I1, $N2, 2.23
@@ -283,7 +300,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isgt_i_nc_nc')
+    .RESET_DESC('isgt_i_nc_nc')
     set $I1, 111
     isgt $I1, 2.22, 2.23
     .CONCAT_RES()
@@ -294,7 +311,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isgt_i_s_s')
+    .RESET_DESC('isgt_i_s_s')
     set $I1, 111
     set $S2, "Aaa"
     set $S3, "Bbb"
@@ -309,7 +326,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isgt_i_sc_s')
+    .RESET_DESC('isgt_i_sc_s')
     set $I1, 111
     set $S3, "Bbb"
     isgt $I1, "Aaa", $S3
@@ -321,7 +338,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isgt_i_s_sc')
+    .RESET_DESC('isgt_i_s_sc')
     set $I1, 111
     set $S2, "Bbb"
     isgt $I1, $S2, "Ccc"
@@ -333,7 +350,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isgt_i_sc_sc')
+    .RESET_DESC('isgt_i_sc_sc')
     set $I1, 111
     isgt $I1, "Bbb", "Ccc"
     .CONCAT_RES()
@@ -365,7 +382,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isge_i_ic_i')
+    .RESET_DESC('isge_i_ic_i')
     set $I1, 111
     set $I3, 333
     isge $I1, 222, $I3
@@ -377,7 +394,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isge_i_i_ic')
+    .RESET_DESC('isge_i_i_ic')
     set $I1, 111
     set $I2, 222
     isge $I1, $I2, 223
@@ -389,7 +406,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isge_i_ic_ic')
+    .RESET_DESC('isge_i_ic_ic')
     set $I1, 111
     isge $I1, 222, 223
     .CONCAT_RES()
@@ -400,7 +417,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isge_i_n_n')
+    .RESET_DESC('isge_i_n_n')
     set $I1, 111
     set $N2, 2.22
     set $N3, 3.33
@@ -415,7 +432,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isge_i_nc_n')
+    .RESET_DESC('isge_i_nc_n')
     set $I1, 111
     set $N3, 3.33
     isge $I1, 2.22, $N3
@@ -427,7 +444,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isge_i_n_nc')
+    .RESET_DESC('isge_i_n_nc')
     set $I1, 111
     set $N2, 2.22
     isge $I1, $N2, 2.23
@@ -439,7 +456,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isge_i_nc_nc')
+    .RESET_DESC('isge_i_nc_nc')
     set $I1, 111
     isge $I1, 2.22, 2.23
     .CONCAT_RES()
@@ -450,7 +467,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isge_i_s_s')
+    .RESET_DESC('isge_i_s_s')
     set $I1, 111
     set $S2, "Aaa"
     set $S3, "Bbb"
@@ -465,7 +482,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isge_i_sc_s')
+    .RESET_DESC('isge_i_sc_s')
     set $I1, 111
     set $S3, "Bbb"
     isge $I1, "Aaa", $S3
@@ -477,7 +494,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isge_i_s_sc')
+    .RESET_DESC('isge_i_s_sc')
     set $I1, 111
     set $S2, "Bbb"
     isge $I1, $S2, "Ccc"
@@ -489,7 +506,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isge_i_sc_sc')
+    .RESET_DESC('isge_i_sc_sc')
     set $I1, 111
     isge $I1, "Bbb", "Ccc"
     .CONCAT_RES()
@@ -521,7 +538,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isle_i_ic_i')
+    .RESET_DESC('isle_i_ic_i')
     set $I1, 111
     set $I3, 333
     isle $I1, 222, $I3
@@ -533,7 +550,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isle_i_i_ic')
+    .RESET_DESC('isle_i_i_ic')
     set $I1, 111
     set $I2, 222
     isle $I1, $I2, 223
@@ -545,7 +562,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isle_i_ic_ic')
+    .RESET_DESC('isle_i_ic_ic')
     set $I1, 111
     isle $I1, 222, 223
     .CONCAT_RES()
@@ -556,7 +573,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isle_i_n_n')
+    .RESET_DESC('isle_i_n_n')
     set $I1, 111
     set $N2, 2.22
     set $N3, 3.33
@@ -571,7 +588,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isle_i_nc_n')
+    .RESET_DESC('isle_i_nc_n')
     set $I1, 111
     set $N3, 3.33
     isle $I1, 2.22, $N3
@@ -583,7 +600,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isle_i_n_nc')
+    .RESET_DESC('isle_i_n_nc')
     set $I1, 111
     set $N2, 2.22
     isle $I1, $N2, 2.23
@@ -595,7 +612,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isle_i_nc_nc')
+    .RESET_DESC('isle_i_nc_nc')
     set $I1, 111
     isle $I1, 2.22, 2.23
     .CONCAT_RES()
@@ -606,7 +623,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isle_i_s_s')
+    .RESET_DESC('isle_i_s_s')
     set $I1, 111
     set $S2, "Aaa"
     set $S3, "Bbb"
@@ -621,7 +638,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isle_i_sc_s')
+    .RESET_DESC('isle_i_sc_s')
     set $I1, 111
     set $S3, "Bbb"
     isle $I1, "Aaa", $S3
@@ -633,7 +650,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isle_i_s_sc')
+    .RESET_DESC('isle_i_s_sc')
     set $I1, 111
     set $S2, "Bbb"
     isle $I1, $S2, "Ccc"
@@ -645,7 +662,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isle_i_sc_sc')
+    .RESET_DESC('isle_i_sc_sc')
     set $I1, 111
     isle $I1, "Bbb", "Ccc"
     .CONCAT_RES()
@@ -677,7 +694,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('islt_i_ic_i')
+    .RESET_DESC('islt_i_ic_i')
     set $I1, 111
     set $I3, 333
     islt $I1, 222, $I3
@@ -689,7 +706,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('islt_i_i_ic')
+    .RESET_DESC('islt_i_i_ic')
     set $I1, 111
     set $I2, 222
     islt $I1, $I2, 223
@@ -701,7 +718,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('islt_i_ic_ic')
+    .RESET_DESC('islt_i_ic_ic')
     set $I1, 111
     islt $I1, 222, 223
     .CONCAT_RES()
@@ -712,7 +729,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('islt_i_n_n')
+    .RESET_DESC('islt_i_n_n')
     set $I1, 111
     set $N2, 2.22
     set $N3, 3.33
@@ -727,7 +744,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('islt_i_nc_n')
+    .RESET_DESC('islt_i_nc_n')
     set $I1, 111
     set $N3, 3.33
     islt $I1, 2.22, $N3
@@ -739,7 +756,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('islt_i_n_nc')
+    .RESET_DESC('islt_i_n_nc')
     set $I1, 111
     set $N2, 2.22
     islt $I1, $N2, 2.23
@@ -751,7 +768,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('islt_i_nc_nc')
+    .RESET_DESC('islt_i_nc_nc')
     set $I1, 111
     islt $I1, 2.22, 2.23
     .CONCAT_RES()
@@ -762,7 +779,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('islt_i_s_s')
+    .RESET_DESC('islt_i_s_s')
     set $I1, 111
     set $S2, "Aaa"
     set $S3, "Bbb"
@@ -777,7 +794,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('islt_i_sc_s')
+    .RESET_DESC('islt_i_sc_s')
     set $I1, 111
     set $S3, "Bbb"
     islt $I1, "Aaa", $S3
@@ -789,7 +806,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('islt_i_s_sc')
+    .RESET_DESC('islt_i_s_sc')
     set $I1, 111
     set $S2, "Bbb"
     islt $I1, $S2, "Ccc"
@@ -801,7 +818,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('islt_i_sc_sc')
+    .RESET_DESC('islt_i_sc_sc')
     set $I1, 111
     islt $I1, "Bbb", "Ccc"
     .CONCAT_RES()
@@ -833,7 +850,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('iseq_i_ic_i')
+    .RESET_DESC('iseq_i_ic_i')
     set $I1, 111
     set $I3, 333
     iseq $I1, 222, $I3
@@ -845,7 +862,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('iseq_i_i_ic')
+    .RESET_DESC('iseq_i_i_ic')
     set $I1, 111
     set $I2, 222
     iseq $I1, $I2, 223
@@ -857,7 +874,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('iseq_i_ic_ic')
+    .RESET_DESC('iseq_i_ic_ic')
     set $I1, 111
     iseq $I1, 222, 223
     .CONCAT_RES()
@@ -868,7 +885,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('iseq_i_n_n')
+    .RESET_DESC('iseq_i_n_n')
     set $I1, 111
     set $N2, 2.22
     set $N3, 3.33
@@ -883,7 +900,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('iseq_i_nc_n')
+    .RESET_DESC('iseq_i_nc_n')
     set $I1, 111
     set $N3, 3.33
     iseq $I1, 2.22, $N3
@@ -895,7 +912,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('iseq_i_n_nc')
+    .RESET_DESC('iseq_i_n_nc')
     set $I1, 111
     set $N2, 2.22
     iseq $I1, $N2, 2.23
@@ -907,7 +924,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('iseq_i_nc_nc')
+    .RESET_DESC('iseq_i_nc_nc')
     set $I1, 111
     iseq $I1, 2.22, 2.23
     .CONCAT_RES()
@@ -918,7 +935,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('iseq_i_s_s')
+    .RESET_DESC('iseq_i_s_s')
     set $I1, 111
     set $S2, "Aaa"
     set $S3, "Bbb"
@@ -933,7 +950,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('iseq_i_sc_s')
+    .RESET_DESC('iseq_i_sc_s')
     set $I1, 111
     set $S3, "Bbb"
     iseq $I1, "Aaa", $S3
@@ -945,7 +962,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('iseq_i_s_sc')
+    .RESET_DESC('iseq_i_s_sc')
     set $I1, 111
     set $S2, "Bbb"
     iseq $I1, $S2, "Ccc"
@@ -957,7 +974,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('iseq_i_sc_sc')
+    .RESET_DESC('iseq_i_sc_sc')
     set $I1, 111
     iseq $I1, "Bbb", "Ccc"
     .CONCAT_RES()
@@ -989,7 +1006,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isne_i_ic_i')
+    .RESET_DESC('isne_i_ic_i')
     set $I1, 111
     set $I3, 333
     isne $I1, 222, $I3
@@ -1001,7 +1018,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isne_i_i_ic')
+    .RESET_DESC('isne_i_i_ic')
     set $I1, 111
     set $I2, 222
     isne $I1, $I2, 223
@@ -1013,7 +1030,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isne_i_ic_ic')
+    .RESET_DESC('isne_i_ic_ic')
     set $I1, 111
     isne $I1, 222, 223
     .CONCAT_RES()
@@ -1024,7 +1041,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isne_i_n_n')
+    .RESET_DESC('isne_i_n_n')
     set $I1, 111
     set $N2, 2.22
     set $N3, 3.33
@@ -1039,7 +1056,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isne_i_nc_n')
+    .RESET_DESC('isne_i_nc_n')
     set $I1, 111
     set $N3, 3.33
     isne $I1, 2.22, $N3
@@ -1051,7 +1068,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isne_i_n_nc')
+    .RESET_DESC('isne_i_n_nc')
     set $I1, 111
     set $N2, 2.22
     isne $I1, $N2, 2.23
@@ -1063,7 +1080,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isne_i_nc_nc')
+    .RESET_DESC('isne_i_nc_nc')
     set $I1, 111
     isne $I1, 2.22, 2.23
     .CONCAT_RES()
@@ -1074,7 +1091,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isne_i_s_s')
+    .RESET_DESC('isne_i_s_s')
     set $I1, 111
     set $S2, "Aaa"
     set $S3, "Bbb"
@@ -1089,7 +1106,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isne_i_sc_s')
+    .RESET_DESC('isne_i_sc_s')
     set $I1, 111
     set $S3, "Bbb"
     isne $I1, "Aaa", $S3
@@ -1101,7 +1118,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isne_i_s_sc')
+    .RESET_DESC('isne_i_s_sc')
     set $I1, 111
     set $S2, "Bbb"
     isne $I1, $S2, "Ccc"
@@ -1113,7 +1130,7 @@
     is( res, exp, desc)
 
     res = ''
-    .SET_DESC('isne_i_sc_sc')
+    .RESET_DESC('isne_i_sc_sc')
     set $I1, 111
     isne $I1, "Bbb", "Ccc"
     .CONCAT_RES()

Modified: branches/tt761_keys_revamp/t/op/debuginfo.t
==============================================================================
--- branches/tt761_keys_revamp/t/op/debuginfo.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/op/debuginfo.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -29,8 +29,6 @@
 
 #SKIP: {
 #skip "disabled on fast-core",1 if $ENV{TEST_PROG_ARGS} =~ /--runcore=(fast|cgoto)/;
-TODO: {
-    local $TODO = q|Not yet passing on 'fast' or 'cgoto' runcores|;
 
 pasm_output_like( <<'CODE', <<"OUTPUT", "getline, getfile" );
 .pcc_sub main:
@@ -43,8 +41,6 @@
 /$nolineno/
 OUTPUT
 
-} # END TODO
-
 pir_error_output_like( <<'CODE', <<'OUTPUT', "debug backtrace - Null PMC access" );
 .sub main
     print "ok 1\n"
@@ -173,7 +169,8 @@
 #SKIP: {
 #skip "disabled on this core",2 if $ENV{TEST_PROG_ARGS} =~ /--runcore=(fast|cgoto|jit|switch)/;
 TODO: {
-    local $TODO = q|Not yet passing on 'fast', 'cgoto', 'jit' or 'switch' runcores|;
+    local $TODO = q|Not yet passing on 'cgoto', 'jit' or 'switch' runcores|
+        if $ENV{TEST_PROG_ARGS} =~ /--runcore=(cgoto|jit|switch)/;
 
 # See "RT #43269 and .annotate
 pir_error_output_like( <<'CODE', <<"OUTPUT", "setfile and setline" );
@@ -188,6 +185,12 @@
 /$nolineno/
 OUTPUT
 
+} # END TODO
+
+TODO: {
+    local $TODO = q|Not yet passing on 'jit' or 'switch' runcores|
+        if $ENV{TEST_PROG_ARGS} =~ /--runcore=(jit|switch)/;
+
 $nolineno = $ENV{TEST_PROG_ARGS} =~ /--runcore=(fast|cgoto|jit|switch)/
     ? '\(\(unknown file\):-1\)' : '\(foo.p6:128\)';
 # See "RT #43269 and .annotate

Modified: branches/tt761_keys_revamp/t/op/globals.t
==============================================================================
--- branches/tt761_keys_revamp/t/op/globals.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/op/globals.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -1,13 +1,7 @@
-#!perl
-# Copyright (C) 2001-2008, Parrot Foundation.
+#!parrot
+# Copyright (C) 2001-2009, Parrot Foundation.
 # $Id$
 
-use strict;
-use warnings;
-use lib qw( . lib ../lib ../../lib );
-use Test::More;
-use Parrot::Test tests => 9;
-
 =head1 NAME
 
 t/op/globals.t - Global Variables
@@ -22,124 +16,145 @@
 
 =cut
 
-pasm_output_is( <<'CODE', '12', "set/get" );
-        new P0, 'Integer'
-        new P1, 'Integer'
-        set P0, 12
-        set P1, 7
-        set_global "Integer", P0
-        get_global P1, "Integer"
-        print P1
-        end
-CODE
-
-pasm_error_output_like( <<'CODE', <<'OUTPUT', "get null global" );
-       null S0
-       get_global P1, S0
-       end
-CODE
-/Tried to get null global/
-OUTPUT
-
-pasm_output_is( <<'CODE', <<OUT, "not found null" );
-        get_global P1, "no_such_global"
-        print "ok 1\n"
-        defined I0, P1
-        unless I0, ok2
-        print "not "
-ok2:    print "ok 2\n"
-        end
-CODE
-ok 1
-ok 2
-OUT
-
-pir_output_is( <<'CODE', <<OUT, "get/set global with key" );
-.namespace [ "Monkey" ]
-.sub main :main
-        set_it()
-        $P1 = get_hll_global [ "Monkey" ; "Toaster" ], "Explosion"
-        print $P1
+.const int TESTS = 12
+
+.namespace []
+
+.sub 'test' :main
+    .include 'test_more.pir'
+
+    plan(TESTS)
+
+    root_integer()
+    get_null_global()
+    not_found_null()
+    get_set_global_with_key()
+    fetch_and_store()
+    find_null_global()
+    get_hll_global_not_found()
+    find_store_with_key()
 .end
-.sub set_it
-        $P0 = new 'String'
-        $P0 = "Ook...BANG!\n"
-        set_global [ "Toaster" ], "Explosion", $P0
+
+.namespace []
+.sub 'root_integer'
+    $P0 = new ['Integer']
+    $P1 = new ['Integer']
+
+    $P0 = 12
+    $P1 = 7
+
+    set_global "Integer", $P0
+    $P1 = get_global "Integer"
+
+    is($P1, 12, 'root_integer')
+.end
+
+.sub 'get_null_global'
+    $S0 = null
+
+    $I0 = 0
+    push_eh get_null_global_catch
+    $P1 = get_global $S0
+    pop_eh
+    goto get_null_global_end
+
+  get_null_global_catch:
+    $I0 = 1
+
+  get_null_global_end:
+    ok($I0, 'get null global')
 .end
-CODE
-Ook...BANG!
-OUT
-
-pir_output_is( <<'CODE', <<OUT, "get/set root global with key" );
-.namespace [ "Monkey" ]
-.sub main :main
-        set_it()
-        $P1 = get_hll_global [ "Monkey" ; "Toaster" ], "Explosion"
-        print $P1
+
+.sub 'not_found_null'
+    $P1 = get_global 'no_such_global'
+    ok(1, 'not_found_null get_global returns')
+
+    $I0 = defined $P1
+    nok($I0, 'not_found_null get_global returns null')
+.end
+
+.sub 'get_set_global_with_key'
+    $P0 = get_global ['Monkey'], 'do_explosion'
+    $I0 = defined $P0
+    ok($I0, 'get_global of a sub with a key')
+    $P0()
 .end
-.sub set_it
+
+.namespace ['Monkey']
+.sub 'do_explosion'
+    set_it()
+    $P1 = get_hll_global [ "Monkey" ; "Toaster" ], "Explosion"
+    is($P1, "Ook...BANG!\n", 'get/set_global with key')
+.end
+
+.sub 'set_it'
         $P0 = new 'String'
         $P0 = "Ook...BANG!\n"
-        set_root_global [ "parrot"; "Monkey"; "Toaster" ], "Explosion", $P0
+        set_global [ "Toaster" ], "Explosion", $P0
 .end
-CODE
-Ook...BANG!
-OUT
 
 #----------------------------------------------------------------
 # LEGACY
 #----------------------------------------------------------------
 
-pasm_output_is( <<'CODE', '12', "Fetch and store" );
-        new P0, 'Integer'
-        new P1, 'Integer'
-        set P0, 12
-        set P1, 7
-        set_global "Integer", P0
-        get_hll_global P1, "Integer"
-        print P1
-        end
-CODE
-
-pasm_error_output_like( <<'CODE', <<'OUTPUT', "Find null global" );
-       null S0
-       get_hll_global P1, S0
-       end
-CODE
-/Tried to get null global/
-OUTPUT
-
-pasm_output_is( <<'CODE', <<OUT, "not found null" );
-        get_hll_global P1, "no_such_global"
-        print "ok 1\n"
-        defined I0, P1
-        unless I0, ok2
-        print "not "
-ok2:    print "ok 2\n"
-        end
-CODE
-ok 1
-ok 2
-OUT
-
-pir_output_is( <<'CODE', <<OUT, "find/store global with key" );
-.sub main :main
-        set_it()
-        $P1 = get_hll_global [ "Monkey" ; "Toaster" ], "Explosion"
-        print $P1
+.namespace []
+
+.sub 'fetch_and_store'
+    $P0 = new 'Integer'
+    $P1 = new 'Integer'
+
+    $P0 = 12
+    $P1 = 7
+
+    set_global 'Integer', $P0
+    $P1 = get_hll_global 'Integer'
+    is($P1, 12, 'Fetch and store')
 .end
-.sub set_it
-        $P0 = new 'String'
-        $P0 = "Ook...BANG!\n"
-        set_hll_global [ "Monkey" ; "Toaster" ], "Explosion", $P0
+
+.sub 'find_null_global'
+    $S0 = null
+    push_eh find_null_global_catch
+    $P1 = get_hll_global $S0
+    pop_eh
+    $I0 = 0
+    goto find_null_global_end
+
+  find_null_global_catch:
+    $I0 = 1
+  find_null_global_end:
+    ok($I0, 'Find null global')
+.end
+
+.sub 'get_hll_global_not_found'
+    $P1 = get_hll_global 'no such global'
+    ok(1, 'get_hll_global returns if not found')
+
+    $I0 = defined $P1
+    nok($I0, 'get_hll_global returns null if not found')
+.end
+
+.sub 'find_store_with_key'
+    $P0 = get_global ['Monkey2'], 'do_explosion'
+    $I0 = defined $P0
+    ok($I0, 'get_hll_global of a sub with a key')
+    $P0()
+.end
+
+.namespace ['Monkey2']
+.sub 'do_explosion'
+    set_it()
+    $P1 = get_hll_global [ "Monkey2" ; "Toaster" ], "Explosion"
+    is($P1, "Ook...BANG, again!\n", 'find/store global with key')
+.end
+
+.sub 'set_it'
+    $P0 = new 'String'
+    $P0 = "Ook...BANG, again!\n"
+    set_hll_global [ "Monkey2"; "Toaster" ], "Explosion", $P0
 .end
-CODE
-Ook...BANG!
-OUT
 
 # Local Variables:
-#   mode: cperl
-#   cperl-indent-level: 4
+#   mode: pir
 #   fill-column: 100
 # End:
-# vim: expandtab shiftwidth=4:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/tt761_keys_revamp/t/op/ifunless.t
==============================================================================
--- branches/tt761_keys_revamp/t/op/ifunless.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/op/ifunless.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -1,13 +1,7 @@
-#!perl
+#!parrot
 # Copyright (C) 2001-2005, Parrot Foundation.
 # $Id$
 
-use strict;
-use warnings;
-use lib qw( . lib ../lib ../../lib );
-use Test::More;
-use Parrot::Test tests => 6;
-
 =head1 NAME
 
 t/op/ifunless.t - If/Unless
@@ -22,181 +16,203 @@
 
 =cut
 
-pasm_output_is( <<CODE, <<OUTPUT, "if_i_ic" );
-        set     I0, 2147483647
-        set     I1, -2147483648
-        set     I2, 0
-
-        if      I0, ONE
-        branch  ERROR
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        if      I1, TWO
-        branch ERROR
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-        if      I2, ERROR
-        branch  THREE
-        print   "bad\\n"
-
-THREE:
-        print   "ok 3\\n"
-        end
-
-ERROR:
-        print   "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-ok 3
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "if_n_ic" );
-        set     N0, 0.1
-        set     N1, -0.1
-        set     N2, 0.0
-
-        if N0, ONE
-        branch  ERROR
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        if      N1, TWO
-        branch ERROR
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-        if      N2, ERROR
-        branch  THREE
-        print   "bad\\n"
-
-THREE:
-        print   "ok 3\\n"
-        end
-
-ERROR:
-        print   "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-ok 3
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "if_s_ic" );
-        set     S0, "Hello World"
-        set     S1, ""
-
-        if      S0, ONE
-        branch  ERROR
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        if      S1, ERROR
-        branch  TWO
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-        end
-
-ERROR:
-        print   "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "unless_i_ic" );
-        set     I0, 0
-        set     I1, -2147483648
-
-        unless  I0, ONE
-        branch  ERROR
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        unless  I1, ERROR
-        branch TWO
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-        end
-
-ERROR:
-        print   "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "unless_n_ic" );
-        set     N0, 0.0
-        set     N1, -0.1
-
-        unless N0, ONE
-        branch  ERROR
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        unless  N1, ERROR
-        branch TWO
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-        end
-
-ERROR:
-        print   "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "unless_s_ic" );
-        set     S1, "Hello World"
-        set     S0, ""
-
-        unless S0, ONE
-        branch  ERROR
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        unless  S1, ERROR
-        branch TWO
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-        end
-
-ERROR:
-        print   "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-OUTPUT
+.const int TESTS = 14
+
+.sub 'test' :main
+    .include 'test_more.pir'
+
+    plan(TESTS)
+
+    if_i_ic_positive()
+    if_i_ic_negative()
+    if_i_ic_zero()
+    if_n_ic_positive()
+    if_n_ic_negative()
+    if_n_ic_zero()
+    if_s_ic_helloworld()
+    if_s_ic_empty()
+
+    unless_i_ic_zero()
+    unless_i_ic_negative()
+    unless_n_ic_zero()
+    unless_n_ic_negative()
+    unless_s_ic_empty()
+    unless_s_ic_helloworld()
+
+.end
+
+.sub 'if_i_ic_positive'
+    $I0 = 2147483647
+
+    $I1 = 0
+    if $I0 goto if_i_ic_positive_ok
+    goto if_i_ic_positive_end
+
+  if_i_ic_positive_ok:
+    $I1 = 1
+  if_i_ic_positive_end:
+    ok($I1, "if_i_ic with a positive integer")
+.end
+
+.sub 'if_i_ic_negative'
+    $I0 = -2147483647
+
+    $I1 = 0
+    if $I0 goto if_i_ic_negative_ok
+    goto if_i_ic_negative_end
+
+  if_i_ic_negative_ok:
+    $I1 = 1
+  if_i_ic_negative_end:
+    ok($I1, "if_i_ic with a negative integer")
+.end
+
+.sub 'if_i_ic_zero'
+    $I0 = 0
+
+    $I1 = 0
+    if $I0 goto if_i_ic_zero_end
+    $I1 = 1
+
+  if_i_ic_zero_end:
+    ok($I1, "if_i_ic with integer zero")
+.end
+
+.sub 'if_n_ic_positive'
+    $N0 = 0.1
+
+    $I1 = 0
+    if $N0 goto if_n_ic_positive_ok
+    goto if_n_ic_positive_end
+
+  if_n_ic_positive_ok:
+    $I1 = 1
+  if_n_ic_positive_end:
+    ok($I1, "if_n_ic with a positive float")
+.end
+
+.sub 'if_n_ic_negative'
+    $N0 = -0.1
+
+    $I1 = 0
+    if $N0 goto if_n_ic_negative_ok
+    goto if_n_ic_negative_end
+
+  if_n_ic_negative_ok:
+    $I1 = 1
+  if_n_ic_negative_end:
+    ok($I1, "if_n_ic with a negative float")
+.end
+
+.sub 'if_n_ic_zero'
+    $N0 = 0.0
+
+    $I1 = 0
+    if $N0 goto if_n_ic_zero_end
+    $I1 = 1
+
+  if_n_ic_zero_end:
+    ok($I1, "if_n_ic with float zero")
+.end
+
+.sub 'if_s_ic_helloworld'
+    $S0 = "Hello World"
+
+    $I1 = 0
+    if $S0 goto if_s_ic_helloworld_ok
+    goto if_s_ic_helloworld_end
+
+  if_s_ic_helloworld_ok:
+    $I1 = 1
+  if_s_ic_helloworld_end:
+    ok($I1, "if_s_ic with a non-empty string")
+.end
+
+.sub 'if_s_ic_empty'
+    $S0 = ''
+
+    $I1 = 0
+    if $S0 goto if_s_ic_empty_end
+    $I1 = 1
+
+  if_s_ic_empty_end:
+    ok($I1, "if_n_ic with the empty string")
+.end
+
+.sub 'unless_i_ic_zero'
+    $I0 = 0
+
+    $I1 = 0
+    unless $I0 goto unless_i_ic_zero_ok
+    goto unless_i_ic_zero_end
+
+  unless_i_ic_zero_ok:
+    $I1 = 1
+  unless_i_ic_zero_end:
+    ok($I1, "unless_i_ic with integer zero")
+.end
+
+.sub 'unless_i_ic_negative'
+    $I0 = -2147483648
+
+    $I1 = 0
+    unless $I0 goto unless_i_ic_negative_end
+    $I1 = 1
+
+  unless_i_ic_negative_end:
+    ok($I1, "unless_i_ic with a negative integer")
+.end
+
+.sub 'unless_n_ic_zero'
+    $N0 = 0.0
+
+    $I1 = 0
+    unless $N0 goto unless_n_ic_zero_ok
+    goto unless_n_ic_zero_end
+
+  unless_n_ic_zero_ok:
+    $I1 = 1
+  unless_n_ic_zero_end:
+    ok($I1, "unless_n_ic with float zero")
+.end
+
+.sub 'unless_n_ic_negative'
+    $N0 = -0.1
+
+    $I1 = 0
+    unless $N0 goto unless_n_ic_negative_end
+    $I1 = 1
+
+  unless_n_ic_negative_end:
+    ok($I1, "unless_n_ic with a negative float")
+.end
+
+.sub 'unless_s_ic_empty'
+    $S0 = ''
+
+    $I1 = 0
+    unless $S0 goto unless_s_ic_empty_ok
+    goto unless_s_ic_empty_end
+
+  unless_s_ic_empty_ok:
+    $I1 = 1
+  unless_s_ic_empty_end:
+    ok($I1, "unless_s_ic with the empty string")
+.end
+
+.sub 'unless_s_ic_helloworld'
+    $S0 = "Hello World"
+
+    $I1 = 0
+    unless $S0 goto unless_s_ic_helloworld_end
+    $I1 = 1
+
+  unless_s_ic_helloworld_end:
+    ok($I1, "unless_s_ic with a non-empty string")
+.end
 
 # Local Variables:
-#   mode: cperl
-#   cperl-indent-level: 4
+#   mode: pir
 #   fill-column: 100
 # End:
-# vim: expandtab shiftwidth=4:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/tt761_keys_revamp/t/op/integer.t
==============================================================================
--- branches/tt761_keys_revamp/t/op/integer.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/op/integer.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -1,13 +1,7 @@
-#!perl
-# Copyright (C) 2001-2008, Parrot Foundation.
+#!parrot
+# Copyright (C) 2001-2009, Parrot Foundation.
 # $Id$
 
-use strict;
-use warnings;
-use lib qw( . lib ../lib ../../lib );
-use Test::More;
-use Parrot::Test tests => 56;
-
 =head1 NAME
 
 t/op/integer.t - Integer Registers
@@ -22,1359 +16,1099 @@
 
 =cut
 
-pasm_output_is( <<CODE, <<OUTPUT, "set_i_ic" );
-        # XXX: Need a test for writing outside the set of available
-        # registers.  Parrot doesn't check for this at the moment.
-        set     I0, 0
-        set     I1, 1
-        set     I2, 2
-        set     I3, 3
-        set     I4, 4
-        set     I5, 5
-        set     I6, 6
-        set     I7, 7
-        set     I8, 8
-        set     I9, 9
-        set     I10, 10
-        set     I11, 11
-        set     I12, 12
-        set     I13, 13
-        set     I14, 14
-        set     I15, 15
-        set     I16, 16
-        set     I17, 17
-        set     I18, 18
-        set     I19, 19
-        set     I20, 20
-        set     I21, 21
-        set     I22, 22
-        set     I23, 23
-        set     I24, 24
-        set     I25, 25
-        set     I26, 26
-        set     I27, 27
-        set     I28, 28
-        set     I29, 29
-        set     I30, 30
-        set     I31, 31
-
-        print   I0
-        print   "\\n"
-        print   I1
-        print   "\\n"
-        print   I2
-        print   "\\n"
-        print   I3
-        print   "\\n"
-        print   I4
-        print   "\\n"
-        print   I5
-        print   "\\n"
-        print   I6
-        print   "\\n"
-        print   I7
-        print   "\\n"
-        print   I8
-        print   "\\n"
-        print   I9
-        print   "\\n"
-        print   I10
-        print   "\\n"
-        print   I11
-        print   "\\n"
-        print   I12
-        print   "\\n"
-        print   I13
-        print   "\\n"
-        print   I14
-        print   "\\n"
-        print   I15
-        print   "\\n"
-        print   I16
-        print   "\\n"
-        print   I17
-        print   "\\n"
-        print   I18
-        print   "\\n"
-        print   I19
-        print   "\\n"
-        print   I20
-        print   "\\n"
-        print   I21
-        print   "\\n"
-        print   I22
-        print   "\\n"
-        print   I23
-        print   "\\n"
-        print   I24
-        print   "\\n"
-        print   I25
-        print   "\\n"
-        print   I26
-        print   "\\n"
-        print   I27
-        print   "\\n"
-        print   I28
-        print   "\\n"
-        print   I29
-        print   "\\n"
-        print   I30
-        print   "\\n"
-        print   I31
-        print   "\\n"
-        end
-        set     I0, 0
-        end
-CODE
-0
-1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "set_i" );
-        set     I0, 42
-        set     I1, I0
-        print   I1
-        print   "\\n"
-        end
-CODE
-42
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "add_i" );
-        set     I0, 0x11223344
-        add     I1, I0, I0
-        print   I1
-        print   "\\n"
-
-        add     I2, I0, I1
-        print   I2
-        print   "\\n"
-
-        add     I2, I2, I2
-        print   I2
-        print   "\\n"
-
-        end
-CODE
-574908040
-862362060
-1724724120
-OUTPUT
-
-pasm_output_is( <<'CODE', <<'OUTPUT', "abs(i, i|ic|n|nc)" );
-        set     I0, 1
-        abs     I1, -1
-        abs     I0, I0
-        set     I2, -1
-        abs     I2, I2
-        print   I0
-        print   "\n"
-        print   I1
-        print   "\n"
-        print   I2
-        print   "\n"
-
-        end
-CODE
-1
-1
-1
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "sub_(i|ic, i|ic)" );
-        set     I0, 0x12345678
-        set     I1, 0x01234567
-        sub     I2, I0, I1
-        print   I2
-        print   "\\n"
-
-        set     I1, 1234
-        sub     I0, I1, 1230
-        print   I0
-        sub     I0, 1244, I1
-        print   I0
-        sub     I0, 13, 12
-        print   I0
-        print   "\\n"
-        end
-CODE
-286331153
-4101
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "mul_i" );
-        set     I0, 7
-        set     I1, 29
-        mul     I2, I0, I1
-        print   I2
-        print   "\\n"
-
-        mul     I2, I0, 29
-        print   I2
-        print   "\\n"
-        end
-CODE
-203
-203
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "div_i" );
-        set     I0, 0x33333333
-        set     I1, 0x11111111
-        div     I2, I0, I1
-        print   I2
-        print   "\\n"
-
-        set     I0, 11
-        set     I1, 2
-        div     I2, I0, I1
-        print   I2
-        print   "\\n"
-
-        set     I0, 9
-        set     I1, -4
-        div     I2, I0, I1
-        print   I2
-        print   "\\n"
-
-        set     I0, 12
-        div     I1, 144, I0
-        print   I1
-        div     I1, I0, 3
-        print   I1
-        div     I1, 120, 12
-        print   I1
-        print   "\\n"
-
-        end
-CODE
-3
-5
--2
-12410
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "mod_i" );
-        set     I0, 5
-        set     I1, 0
-        mod     I2, I0, I1
-        print   I2
-        print   "\\n"
-
-        set     I0, 0
-        set     I1, 3
-        mod     I2, I0, I1
-        print   I2
-        print   "\\n"
-
-        set     I0, 5
-        set     I1, 3
-        mod     I2, I0, I1
-        print   I2
-        print   "\\n"
-
-        set     I0, 5
-        set     I1, -3
-        mod     I2, I0, I1
-        print   I2
-        print   "\\n"
-
-        set     I0, -5
-        set     I1, 3
-        mod     I2, I0, I1
-        print   I2
-        print   "\\n"
-
-        set     I0, -5
-        set     I1, -3
-        mod     I2, I0, I1
-        print   I2
-        print   "\\n"
-
-        set     I0, 12
-        mod     I1, I0, 10
-        print   I1
-        mod     I1, 14, I0
-        print   I1
-        mod     I1, 13, 11
-        print   I1
-        print   "\\n"
-
-        end
-CODE
-5
-0
-2
--1
-1
--2
-222
-OUTPUT
-
-pir_output_is( <<'CODE', <<'OUTPUT', "mod - negative, zero rest (#36003)" );
-.sub test :main
-
-   $I1 = mod 3, 3
-   print "3 mod 3 = "
-   print $I1
-   print "\n"
-
-   $I1 = mod -3, 3
-   print "-3 mod 3 = "
-   print $I1
-   print "\n"
-
-   $I1 = mod 3, -3
-   print "3 mod -3 = "
-   print $I1
-   print "\n"
-
-   $I1 = mod -3, -3
-   print "-3 mod -3 = "
-   print $I1
-   print "\n"
-
-   end
-.end
-CODE
-3 mod 3 = 0
--3 mod 3 = 0
-3 mod -3 = 0
--3 mod -3 = 0
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "cmod_i" );
-        set     I0, 5
-        set     I1, 3
-        cmod    I2, I0, I1
-        print   I2
-        print   "\\n"
-        print   I0
-        print   "\\n"
-        print   I1
-        print   "\\n"
-
-        set     I0, 12
-        cmod    I1, I0, 10
-        print   I1
-        cmod    I1, 14, I0
-        print   I1
-        cmod    I1, 13, 11
-        print   I1
-        print   "\\n"
-        end
-CODE
-2
-5
-3
-222
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "eq_i_ic" );
-        set     I0, 0x12345678
-        set     I1, 0x12345678
-        set     I2, 0x76543210
-
-        eq      I0, I1, ONE
-        branch  ERROR
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        eq      I1, I2, ERROR
-        branch TWO
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-        end
-
-ERROR:
-        print   "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "eq_ic_ic" );
-        set     I0, -42
-
-        eq      I0, 42, ERROR
-        branch  ONE
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        eq      I0, -42, TWO
-        branch ERROR
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-
-        set     I0, 12
-        eq      I0, 12, THREE
-        print   "not good three "
-THREE:  print   "ok 3\\n"
-
-        eq      12, 12, FOUR
-        print   "12 not 12, what? "
-FOUR:   print   "ok 4\\n"
-
-        end
-
-ERROR:
-        print   "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-ok 3
-ok 4
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "ne_i_ic" );
-        set     I0, 0xa0b0c0d
-        set     I1, 0xa0b0c0d
-        set     I2, 0
-
-        ne      I0, I2, ONE
-        branch  ERROR
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        ne      I0, I1, ERROR
-        branch  TWO
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-        end
-
-ERROR:
-        print   "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "ne_ic_ic" );
-        set     I0, 427034409
-
-        ne      I0, 427034409, ERROR
-        branch  ONE
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        ne      I0, 427034408, TWO
-        branch  ERROR
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-        end
-
-ERROR:
-        print   "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "lt_i_ic" );
-        set     I0, 2147483647
-        set     I1, -2147483648
-        set     I2, 0
-        set     I3, 0
-
-        lt      I1, I0, ONE
-        branch  ERROR
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        lt      I0, I1, ERROR
-        branch  TWO
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-        lt      I2, I3, ERROR
-        branch  THREE
-        print   "bad\\n"
-
-THREE:
-        print   "ok 3\\n"
-        end
-
-ERROR:
-        print "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-ok 3
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "lt_ic_ic" );
-        set     I0, 2147483647
-        set     I1, -2147483648
-        set     I2, 0
-
-        lt      I0, -2147483648, ERROR
-        branch  ONE
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        lt      I1, 2147483647, TWO
-        branch  ERROR
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-        lt      I0, 0, ERROR
-        branch  THREE
-        print   "bad\\n"
-
-THREE:
-        print   "ok 3\\n"
-        end
-
-ERROR:
-        print   "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-ok 3
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "le_i_ic" );
-        set     I0, 2147483647
-        set     I1, -2147483648
-        set     I2, 0
-        set     I3, 0
-
-        le      I1, I0, ONE
-        branch  ERROR
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        le      I0, I1, ERROR
-        branch  TWO
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-        le      I2, I3, THREE
-        branch  ERROR
-        print   "bad\\n"
-
-THREE:
-        print   "ok 3\\n"
-        end
-
-ERROR:
-        print "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-ok 3
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "le_ic_ic" );
-        set     I0, 2147483647
-        set     I1, -2147483648
-        set     I2, 0
-
-        le      I0, -2147483648, ERROR
-        branch  ONE
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        le      I1, 2147483647, TWO
-        branch  ERROR
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-        le      I2, 0, THREE
-        branch  ERROR
-        print   "bad\\n"
-
-THREE:
-        print   "ok 3\\n"
-        end
-
-ERROR:
-        print   "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-ok 3
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "gt_i_ic" );
-        set     I0, -2147483648
-        set     I1, 2147483647
-        set     I2, 0
-        set     I3, 0
-
-        gt      I1, I0, ONE
-        branch  ERROR
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        gt      I0, I1, ERROR
-        branch  TWO
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-        gt      I2, I3, ERROR
-        branch  THREE
-        print   "bad\\n"
-
-THREE:
-        print   "ok 3\\n"
-        end
-
-ERROR:
-        print "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-ok 3
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "gt_ic_ic" );
-        set     I0, -2147483648
-        set     I1, 2147483647
-        set     I2, 0
-
-        gt      I0, 2147483647, ERROR
-        branch  ONE
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        gt      I1, -2147483648, TWO
-        branch  ERROR
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-        gt      I0, 0, ERROR
-        branch  THREE
-        print   "bad\\n"
-
-THREE:
-        print   "ok 3\\n"
-        end
-
-ERROR:
-        print   "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-ok 3
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "ge_i_ic" );
-        set     I0, -2147483648
-        set     I1, 2147483647
-        set     I2, 0
-        set     I3, 0
-
-        ge      I1, I0, ONE
-        branch  ERROR
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        ge      I0, I1, ERROR
-        branch  TWO
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-        ge      I2, I3, THREE
-        branch  ERROR
-        print   "bad\\n"
-
-THREE:
-        print   "ok 3\\n"
-        end
-
-ERROR:
-        print "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-ok 3
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "ge_ic_ic" );
-        set     I0, -2147483648
-        set     I1, 2147483647
-        set     I2, 0
-
-        ge      I0, 2147483647, ERROR
-        branch  ONE
-        print   "bad\\n"
-
-ONE:
-        print   "ok 1\\n"
-        ge      I1, -2147483648, TWO
-        branch  ERROR
-        print   "bad\\n"
-
-TWO:
-        print   "ok 2\\n"
-        ge      I2, 0, THREE
-        branch  ERROR
-        print   "bad\\n"
-
-THREE:
-        print   "ok 3\\n"
-        end
-
-ERROR:
-        print   "bad\\n"
-        end
-CODE
-ok 1
-ok 2
-ok 3
-OUTPUT
-
-pasm_output_is( <<'CODE', <<OUTPUT, "not_i_i" );
-        set I0, 1
-        not I1, I0
-        print I1
-        print "\n"
-
-        not I2, I1
-        print I2
-        print "\n"
-
-        set I3, 12345
-        not I4, I3
-        print I4
-        print "\n"
-
-        set I5, -1
-        not I6, I5
-        print I6
-        print "\n"
-
-        not I7, 0
-        print I7
-        print "\n"
-        not I7, 1
-        print I7
-        print "\n"
-
-        end
-CODE
-0
-1
-0
-0
-1
-0
-OUTPUT
-
-pasm_output_is( <<'CODE', <<OUTPUT, "and" );
-        set I0, 0
-        set I1, 10
-
-        set I2, 1
-        and I2, I1, I0
-        print I2
-        print "\n"
-
-        set I2, 1
-        and I2, I0, I1
-        print I2
-        print "\n"
-
-        set I2, 1
-        and I2, I0, I0
-        print I2
-        print "\n"
-
-        set I2, 1
-        and I2, I2, I1
-        print I2
-        print "\n"
-
-        end
-CODE
-0
-0
-0
-10
-OUTPUT
-
-pasm_output_is( <<'CODE', <<OUTPUT, "or" );
-        set I0, 0
-        set I1, 10
-
-        set I2, 42
-        or I2, I1, I0
-        print I2
-        print "\n"
-
-        set I2, 42
-        or I2, I0, I1
-        print I2
-        print "\n"
-
-        or I2, I0, I0
-        print I2
-        print "\n"
-
-        or I2, I2, I1
-        print I2
-        print "\n"
-
-        end
-CODE
-10
-10
-0
-10
-OUTPUT
-
-pasm_output_is( <<'CODE', <<OUTPUT, "xor" );
-        set I0, 0
-        set I1, 2
-
-        set I2, 42
-        xor I2, I1, I0
-        print I2
-        print "\n"
-
-        set I2, 42
-        xor I2, I0, I1
-        print I2
-        print "\n"
-
-        xor I2, I0, I0
-        print I2
-        print "\n"
-
-        xor I2, I1, I1
-        print I2
-        print "\n"
-
-        set I2, 1
-        xor I2, I2, I2
-        print I2
-        print "\n"
-
-        end
-CODE
-2
-2
-0
-0
-0
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "inc_i" );
-        set     I0, 0
-
-        inc     I0
-        print   I0
-        print   "\\n"
-
-        inc     I0
-        inc     I0
-        inc     I0
-        inc     I0
-        print   I0
-        print   "\\n"
-
-        end
-CODE
-1
-5
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "add_i_i" );
-        set     I0, 0
-        set     I1, 2
-        set     I2, -2
-
-        add     I0, I1
-        print   I0
-        print   "\\n"
-
-        add     I0, I2
-        print   I0
-        print   "\\n"
-        end
-CODE
-2
-0
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "add_i_ic" );
-        set     I0, 0
-
-        add     I0, 5
-        print   I0
-        print   "\\n"
-
-        add     I0, -10
-        print   I0
-        print   "\\n"
-        end
-CODE
-5
--5
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "dec_i" );
-        set     I0, 0
-
-        dec     I0
-        print   I0
-        print   "\\n"
-
-        dec     I0
-        dec     I0
-        dec     I0
-        dec     I0
-        print   I0
-        print   "\\n"
-
-        end
-CODE
--1
--5
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "sub_i_i" );
-        set     I0, 0
-        set     I1, 3
-        set     I2, -3
-
-        sub     I0, I1
-        print   I0
-        print   "\\n"
-
-        sub     I0, I2
-        print   I0
-        print   "\\n"
-        end
-CODE
--3
-0
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "sub_i_ic" );
-        set     I0, 0
-
-        sub     I0, 5
-        print   I0
-        print   "\\n"
-
-        sub     I0, -10
-        print   I0
-        print   "\\n"
-        end
-CODE
--5
-5
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "set_n_i" );
-        set     I0, 0
-        set     N0, I0
-        print   N0
-        print   "\\n"
-
-        set     I1, 2147483647
-        set     N1, I1
-        print   N1
-        print   "\\n"
-
-        set     I2, -2147483648
-        set     N2, I2
-        print   N2
-        print   "\\n"
-        end
-CODE
-0
-2147483647
--2147483648
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "cleari" );
-        set     I0, 0xdeadbee
-        set     I1, 0xdeadbee
-        set     I2, 0xdeadbee
-        set     I3, 0xdeadbee
-        set     I4, 0xdeadbee
-        set     I5, 0xdeadbee
-        set     I6, 0xdeadbee
-        set     I7, 0xdeadbee
-        set     I8, 0xdeadbee
-        set     I9, 0xdeadbee
-        set     I10, 0xdeadbee
-        set     I11, 0xdeadbee
-        set     I12, 0xdeadbee
-        set     I13, 0xdeadbee
-        set     I14, 0xdeadbee
-        set     I15, 0xdeadbee
-        set     I16, 0xdeadbee
-        set     I17, 0xdeadbee
-        set     I18, 0xdeadbee
-        set     I19, 0xdeadbee
-        set     I20, 0xdeadbee
-        set     I21, 0xdeadbee
-        set     I22, 0xdeadbee
-        set     I23, 0xdeadbee
-        set     I24, 0xdeadbee
-        set     I25, 0xdeadbee
-        set     I26, 0xdeadbee
-        set     I27, 0xdeadbee
-        set     I28, 0xdeadbee
-        set     I29, 0xdeadbee
-        set     I30, 0xdeadbee
-        set     I31, 0xdeadbee
-        cleari
-        print   I0
-        print   I1
-        print   I2
-        print   I3
-        print   I4
-        print   I5
-        print   I6
-        print   I7
-        print   I8
-        print   I9
-        print   I10
-        print   I11
-        print   I12
-        print   I13
-        print   I14
-        print   I15
-        print   I16
-        print   I17
-        print   I18
-        print   I19
-        print   I20
-        print   I21
-        print   I22
-        print   I23
-        print   I24
-        print   I25
-        print   I26
-        print   I27
-        print   I28
-        print   I29
-        print   I30
-        print   I31
-        print   "\\n"
-        end
-CODE
-00000000000000000000000000000000
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "neg_i" );
-    neg I0,3
-    neg I0,I0
-    neg I0
-    print I0
-    print "\\n"
-    end
-CODE
--3
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "mul_i_i" );
-    set I0,3
-    set I1,4
-    mul I0,I1
-    print I0
-    print "\\n"
-    end
-CODE
-12
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "fact_i_i" );
-    set I0, 3
-    set I1, 11
-    set I2, 0
-    set I3, -563
-    fact I5, I0
-    print I5
-    print "\\n"
-    fact I6, I1
-    print I6
-    print "\\n"
-    fact I7, I2
-    print I7
-    print "\\n"
-    fact I8, I3
-    print I8
-    print "\\n"
-    end
-CODE
-6
-39916800
-1
-1
-OUTPUT
-
-pasm_output_is( <<CODE, <<OUTPUT, "fact_i_ic" );
-    fact I5, 3
-    print I5
-    print "\\n"
-    fact I6, 11
-    print I6
-    print "\\n"
-    fact I7, 0
-    print I7
-    print "\\n"
-    fact I8, -563
-    print I8
-    print "\\n"
-    end
-CODE
-6
-39916800
-1
-1
-OUTPUT
-
-pasm_output_is( <<'CODE', <<OUTPUT, "exchange" );
-    set I10, 10
-    set I20, 20
-    exchange I10, I20
-    print I10
-    print "\n"
-    print I20
-    print "\n"
-
-    set I30, 30
-    exchange I30, I30
-    print I30
-    print "\n"
-    end
-CODE
-20
-10
-30
-OUTPUT
-
-pasm_output_is( <<'CODE', <<OUTPUT, "null" );
-    set I1, 1000
-    print I1
-    print "\n"
-
-    null I1
-    print I1
-    print "\n"
-
-    end
-CODE
-1000
-0
-OUTPUT
-
-pasm_error_output_like( <<'CODE', <<OUTPUT, "div_i_i by zero" );
-        set I0, 0
-        set I1, 10
-        div I1, I0
-        end
-CODE
-/.*Divide by zero.*/
-OUTPUT
-
-pasm_error_output_like( <<'CODE', <<OUTPUT, "div_i_ic by zero" );
-        set I1, 10
-        div I1, 0
-        end
-CODE
-/.*Divide by zero.*/
-OUTPUT
-
-pasm_error_output_like( <<'CODE', <<OUTPUT, "div_i_i_i by zero" );
-        set I0, 0
-        set I1, 10
-        div I2, I1, I0
-        end
-CODE
-/.*Divide by zero.*/
-OUTPUT
-
-pasm_error_output_like( <<'CODE', <<OUTPUT, "div_i_ic_i by zero" );
-        set I0, 0
-        div I2, 10, I0
-        end
-CODE
-/.*Divide by zero.*/
-OUTPUT
-
-pasm_error_output_like( <<'CODE', <<OUTPUT, "div_i_i_ic by zero" );
-        set I1, 10
-        div I2, I1, 0
-        end
-CODE
-/.*Divide by zero.*/
-OUTPUT
-
-pasm_error_output_like( <<'CODE', <<OUTPUT, "fdiv_i_i by zero" );
-        set I0, 0
-        set I1, 10
-        fdiv I1, I0
-        end
-CODE
-/.*Divide by zero.*/
-OUTPUT
-
-pasm_error_output_like( <<'CODE', <<OUTPUT, "fdiv_i_ic by zero" );
-        set I1, 10
-        fdiv I1, 0
-        end
-CODE
-/.*Divide by zero.*/
-OUTPUT
-
-pasm_error_output_like( <<'CODE', <<OUTPUT, "fdiv_i_i_i by zero" );
-        set I0, 0
-        set I1, 10
-        fdiv I2, I1, I0
-        end
-CODE
-/.*Divide by zero.*/
-OUTPUT
-
-pasm_error_output_like( <<'CODE', <<OUTPUT, "fdiv_i_ic_i by zero" );
-        set I0, 0
-        fdiv I2, 10, I0
-        end
-CODE
-/.*Divide by zero.*/
-OUTPUT
-
-pasm_error_output_like( <<'CODE', <<OUTPUT, "fdiv_i_i_ic by zero" );
-        set I1, 10
-        fdiv I2, I1, 0
-        end
-CODE
-/.*Divide by zero.*/
-OUTPUT
-
-pasm_error_output_like( <<'CODE', <<OUTPUT, "cmod_i_i_i by zero" );
-        set I0, 0
-        set I1, 10
-        cmod I2, I1, I0
-        end
-CODE
-/.*Divide by zero.*/
-OUTPUT
-
-pasm_error_output_like( <<'CODE', <<OUTPUT, "cmod_i_ic_i by zero" );
-        set I0, 0
-        cmod I2, 10, I0
-        end
-CODE
-/.*Divide by zero.*/
-OUTPUT
-
-pasm_error_output_like( <<'CODE', <<OUTPUT, "cmod_i_i_ic by zero" );
-        set I1, 10
-        cmod I2, I1, 0
-        end
-CODE
-/.*Divide by zero.*/
-OUTPUT
-
-pasm_output_is( <<'CODE', <<OUTPUT, "mod_i_i_i by zero" );
-        set I0, 0
-        set I1, 10
-        mod I2, I1, I0
-        print I2
-        print "\n"
-        end
-CODE
-10
-OUTPUT
-
-pasm_output_is( <<'CODE', <<OUTPUT, "mod_i_ic_i by zero" );
-        set I0, 0
-        mod I2, 10, I0
-        print I2
-        print "\n"
-        end
-CODE
-10
-OUTPUT
-
-pasm_output_is( <<'CODE', <<OUTPUT, "mod_i_i_ic by zero" );
-        set I1, 10
-        mod I2, I1, 0
-        print I2
-        print "\n"
-        end
-CODE
-10
-OUTPUT
+.const int TESTS = 202
+
+.sub 'test' :main
+    .include 'test_more.pir'
+
+    plan(TESTS)
+    test_set_ic()
+    test_set()
+    test_add_i_i_i()
+    test_add_i_i()
+    test_abs()
+    test_sub()
+    test_mul()
+    test_div()
+    test_mod()
+    mod_negative_zero_rest()
+    test_cmod()
+    test_eq()
+    test_ne()
+    test_lt()
+    test_le()
+    test_gt()
+    test_ge()
+    test_not()
+    test_and()
+    test_or()
+    test_xor()
+    test_inc()
+    test_dec()
+    test_sub_i_i()
+    test_set_n()
+    test_cleari()
+    test_neg()
+    test_fact()
+    test_mul_i_i()
+    test_exchange()
+    test_null()
+    test_div_i_i_by_zero()
+    test_div_i_ic_by_zero()
+    test_div_i_i_i_by_zero()
+    test_div_i_ic_i_by_zero()
+    test_div_i_i_ic_by_zero()
+    test_fdiv_i_i_by_zero()
+    test_fdiv_i_ic_by_zero()
+    test_fdiv_i_i_i_by_zero()
+    test_fdiv_i_ic_i_by_zero()
+    test_fdiv_i_i_ic_by_zero()
+    test_cmod_i_i_i_by_zero()
+    test_cmod_i_ic_i_by_zero()
+    test_cmod_i_i_ic_by_zero()
+    test_mod_i_i_i_by_zero()
+    test_mod_i_ic_i_by_zero()
+    test_mod_i_i_ic_by_zero()
+.end
+
+.sub 'test_set_ic'
+    $I0 = 0
+    $I1 = 1
+    $I2 = 2
+    $I3 = 3
+    $I4 = 4
+    $I5 = 5
+    $I6 = 6
+    $I7 = 7
+    $I8 = 8
+    $I9 = 9
+    $I10 = 10
+    $I11 = 11
+    $I12 = 12
+    $I13 = 13
+    $I14 = 14
+    $I15 = 15
+    $I16 = 16
+    $I17 = 17
+    $I18 = 18
+    $I19 = 19
+    $I20 = 20
+    $I21 = 21
+    $I22 = 22
+    $I23 = 23
+    $I24 = 24
+    $I25 = 25
+    $I26 = 26
+    $I27 = 27
+    $I28 = 28
+    $I29 = 29
+    $I30 = 30
+    $I31 = 31
+
+    $S0 = $I0
+    is($S0, "0", "set_i_ic with 0")
+    $S0 = $I1
+    is($S0, "1", "set_i_ic with 1")
+    $S0 = $I2
+    is($S0, "2", "set_i_ic with 2")
+    $S0 = $I3
+    is($S0, "3", "set_i_ic with 3")
+    $S0 = $I4
+    is($S0, "4", "set_i_ic with 4")
+    $S0 = $I5
+    is($S0, "5", "set_i_ic with 5")
+    $S0 = $I6
+    is($S0, "6", "set_i_ic with 6")
+    $S0 = $I7
+    is($S0, "7", "set_i_ic with 7")
+    $S0 = $I8
+    is($S0, "8", "set_i_ic with 8")
+    $S0 = $I9
+    is($S0, "9", "set_i_ic with 9")
+    $S0 = $I10
+    is($S0, "10", "set_i_ic with 10")
+    $S0 = $I11
+    is($S0, "11", "set_i_ic with 11")
+    $S0 = $I12
+    is($S0, "12", "set_i_ic with 12")
+    $S0 = $I13
+    is($S0, "13", "set_i_ic with 13")
+    $S0 = $I14
+    is($S0, "14", "set_i_ic with 14")
+    $S0 = $I15
+    is($S0, "15", "set_i_ic with 15")
+    $S0 = $I16
+    is($S0, "16", "set_i_ic with 16")
+    $S0 = $I17
+    is($S0, "17", "set_i_ic with 17")
+    $S0 = $I18
+    is($S0, "18", "set_i_ic with 18")
+    $S0 = $I19
+    is($S0, "19", "set_i_ic with 19")
+    $S0 = $I20
+    is($S0, "20", "set_i_ic with 20")
+    $S0 = $I21
+    is($S0, "21", "set_i_ic with 21")
+    $S0 = $I22
+    is($S0, "22", "set_i_ic with 22")
+    $S0 = $I23
+    is($S0, "23", "set_i_ic with 23")
+    $S0 = $I24
+    is($S0, "24", "set_i_ic with 24")
+    $S0 = $I25
+    is($S0, "25", "set_i_ic with 25")
+    $S0 = $I26
+    is($S0, "26", "set_i_ic with 26")
+    $S0 = $I27
+    is($S0, "27", "set_i_ic with 27")
+    $S0 = $I28
+    is($S0, "28", "set_i_ic with 28")
+    $S0 = $I29
+    is($S0, "29", "set_i_ic with 29")
+    $S0 = $I30
+    is($S0, "30", "set_i_ic with 30")
+    $S0 = $I31
+    is($S0, "31", "set_i_ic with 31")
+.end
+
+.sub 'test_set'
+    $I0 = 42
+    $I1 = $I0
+    $S0 = $I1
+    is($S0, '42', 'set_i')
+.end
+
+.sub 'test_add_i_i_i'
+    $I0 = 0x11223344
+    $I1 = $I0 + $I0
+    is($I1, 574908040, 'add_i_i - first')
+
+    $I2 = $I0 + $I1
+    is($I2, 862362060, 'add_i_i - second')
+
+    $I2 = $I2 + $I2
+    is($I2, 1724724120, 'add_i_i - third')
+.end
+
+.sub 'test_add_i_i'
+    $I0 = 0
+    $I1 = 2
+    $I2 = -2
+
+    add $I0, $I1
+    is($I0, 2, 'add_i_i - zero is neutral')
+
+    add $I0, $I2
+    is($I0, 0, 'add_i_i - inverse')
+
+    $I0 = 0
+    add $I0, 5
+    is($I0, 5, 'add_i_ic - zero is neutral')
+
+    add $I0, -10
+    is($I0, -5, 'add_i_ic')
+.end
+
+.sub 'test_abs'
+    $I0 = abs 1
+
+    $I1 = 1
+    $I1 = abs $I1
+
+    $I2 = abs -1
+
+    $I3 = -1
+    $I3 = abs $I3
+
+    is($I0, 1, 'abs_i_ic')
+    is($I1, 1, 'abs_i_i')
+    is($I2, 1, 'abs_i_nc')
+    is($I3, 1, 'abs_i_n')
+.end
+
+.sub 'test_sub'
+    $I0 = 0x12345678
+    $I1 = 0x01234567
+    $I2 = $I0 - $I1
+    is($I2, 286331153, 'sub_i_i_i')
+
+    $I1 = 1234
+
+    $I0 = $I1 - 1230
+    is($I0, 4, 'sub_i_i_ic')
+
+    $I0 = 1244 - $I1
+    is($I0, 10, 'sub_i_ic_i')
+
+    $I0 = 13 - 12
+    is($I0, 1, 'sub_i_ic_ic')
+.end
+
+.sub 'test_mul'
+    $I0 = 7
+    $I1 = 29
+
+    $I2 = $I0 * $I1
+    is($I2, 203, 'mul_i_i_i')
+
+    $I2 = $I0 * 29
+    is($I2, 203, 'mul_i_i_ic')
+.end
+
+.sub 'test_div'
+    $I0 = 0x33333333
+    $I1 = 0x11111111
+    $I2 = $I0 / $I1
+    is($I2, 3, 'div_i_i_i - exact')
+
+    $I0 = 11
+    $I1 = 2
+    $I2 = $I0 / $I1
+    is($I2, 5, 'div_i_i_i - quotient with positive integers')
+
+    $I0 = 9
+    $I1 = -4
+    $I2 = $I0 / $I1
+    is($I2, -2, 'div_i_i_i - quotient with negative divisor')
+
+    $I0 = 12
+
+    $I1 = 144 / $I0
+    is($I1, 12, 'div_i_ic_i')
+
+    $I1 = $I0 / 3
+    is($I1, 4, 'div_i_i_ic')
+
+    $I1 = 120 / 12
+    is($I1, 10, 'div_i_ic_ic')
+.end
+
+.sub 'test_mod'
+    $I0 = 5
+    $I1 = 0
+    $I2 = mod $I0, $I1
+    is($I2, 5, 'mod_i_i_i by 0')
+
+    $I0 = 0
+    $I1 = 3
+    $I2 = mod $I0, $I1
+    is($I2, 0, 'mod_i_i_i of 0')
+
+    $I0 = 5
+    $I1 = 3
+    $I2 = mod $I0, $I1
+    is($I2, 2, 'mod_i_i_i - remainder of 5 / 3')
+
+    $I0 = 5
+    $I1 = -3
+    $I2 = mod $I0, $I1
+    is($I2, -1, 'mod_i_i_i - remainder of 5 / -3')
+
+    $I0 = -5
+    $I1 = 3
+    $I2 = mod $I0, $I1
+    is($I2, 1, 'mod_i_i_i - remainder of -5 / 3')
+
+    $I0 = -5
+    $I1 = -3
+    $I2 = mod $I0, $I1
+    is($I2, -2, 'mod_i_i_i - remainder of -5 / -3')
+
+    $I0 = 12
+
+    $I1 = mod $I0, 10
+    is($I1, 2, 'mod_i_i_ic')
+
+    $I1 = mod 14, $I0
+    is($I1, 2, 'mod_i_ic_i')
+
+    $I1 = mod 13, 11
+    is($I1, 2, 'mod_i_ic_ic')
+.end
+
+.sub 'mod_negative_zero_rest'
+    $I1 = mod 3, 3
+    is($I1, 0, 'mod - negative, zero rest (#36003), 3 mod 3 = 0')
+
+    $I1 = mod -3, 3
+    is($I1, 0, 'mod - negative, zero rest (#36003), -3 mod 3 = 0')
+
+    $I1 = mod 3, -3
+    is($I1, 0, 'mod - negative, zero rest (#36003), 3 mod -3 = 0')
+
+    $I1 = mod -3, -3
+    is($I1, 0, 'mod - negative, zero rest (#36003), -3 mod -3 = 0')
+.end
+
+.sub 'test_cmod'
+    $I0 = 5
+    $I1 = 3
+    $I2 = cmod $I0, $I1
+    is($I2, 2, 'cmod_i_i_i')
+    is($I0, 5, 'cmod_i_i_i - dividend unchanged')
+    is($I1, 3, 'cmod_i_i_i - divisor unchanged')
+
+    $I0 = 12
+
+    $I1 = cmod $I0, 10
+    is($I1, 2, 'cmod_i_i_ic')
+
+    $I1 = cmod 14, $I0
+    is($I1, 2, 'cmod_i_ic_i')
+
+    $I1 = cmod 13, 11
+    is($I1, 2, 'cmod_i_ic_ic')
+.end
+
+.sub 'test_eq'
+    $I0 = 0x12345678
+    $I1 = 0x12345678
+    $I2 = 0x76543210
+
+    $I3 = 1
+    if $I0 == $I1 goto test_eq_1
+    $I3 = 0
+  test_eq_1:
+    ok($I3, 'eq_i_i - equal')
+
+    $I3 = 1
+    unless $I1 == $I2 goto test_eq_2
+    $I3 = 0
+  test_eq_2:
+    ok($I3, 'eq_i_i - different')
+
+    $I0 = -42
+    $I3 = 0
+    if $I0 == 42 goto test_eq_3
+    $I3 = 1
+  test_eq_3:
+    ok($I3, 'eq_i_ic - different')
+
+    $I3 = 0
+    unless $I0 == -42 goto test_eq_4
+    $I3 = 1
+  test_eq_4:
+    ok($I3, 'eq_i_ic - equal')
+
+    $I0 = 12
+    $I3 = 0
+    unless $I0 == 12 goto test_eq_5
+    $I3 = 1
+  test_eq_5:
+    ok($I3, 'eq_i_ic - 12 == 12')
+
+    $I3 = 0
+    unless 12 == 12 goto test_eq_6
+    $I3 = 1
+  test_eq_6:
+    ok($I3, 'eq_ic_ic - equal')
+
+    $I3 = 1
+    unless 12 == 21 goto test_eq_7
+    $I3 = 0
+  test_eq_7:
+    ok($I3, 'eq_ic_ic - different')
+.end
+
+.sub 'test_ne'
+    $I0 = 0xa0b0c0d
+    $I1 = 0xa0b0c0d
+    $I2 = 0
+
+    $I3 = 0
+    unless $I0 != $I2 goto test_ne_1
+    $I3 = 1
+  test_ne_1:
+    ok($I3, 'ne_i_i - different')
+
+    $I3 = 0
+    if $I0 != $I1 goto test_ne_2
+    $I3 = 1
+  test_ne_2:
+    ok($I3, 'ne_i_i - equal')
+
+    $I0 = 427034409
+    $I3 = 0
+    if $I0 != 427034409 goto test_ne_3
+    $I3 = 1
+  test_ne_3:
+    ok($I3, 'ne_i_ic - equal')
+
+    $I3 = 0
+    unless $I0 != 427034408 goto test_ne_4
+    $I3 = 1
+  test_ne_4:
+    ok($I3, 'ne_i_ic - different')
+.end
+
+.sub 'test_lt'
+    $I0 = 2147483647
+    $I1 = -2147483648
+    $I2 = 0
+    $I3 = 0
+
+    $I4 = 0
+    unless $I1 < $I0 goto test_lt_1
+    $I4 = 1
+  test_lt_1:
+    ok($I4, 'lt_i_i - true inequality')
+
+    $I4 = 0
+    if $I0 < $I1 goto test_lt_2
+    $I4 = 1
+  test_lt_2:
+    ok($I4, 'lt_i_i - false inequality')
+
+    $I4 = 0
+    if $I2 < $I3 goto test_lt_3
+    $I4 = 1
+  test_lt_3:
+    ok($I4, 'lt_i_i - irreflexivity')
+
+    $I4 = 0
+    if $I0 < -2147483648 goto test_lt_4
+    $I4 = 1
+  test_lt_4:
+    ok($I4, 'lt_i_ic - false inequality')
+
+    $I4 = 0
+    unless $I1 < 2147483647 goto test_lt_5
+    $I4 = 1
+  test_lt_5:
+    ok($I4, 'lt_i_ic - true inequality')
+
+    $I4 = 0
+    if $I0 < 0 goto test_lt_6
+    $I4 = 1
+  test_lt_6:
+    ok($I4, 'lt_i_ic - irreflexivity')
+.end
+
+.sub 'test_le'
+    $I0 = 2147483647
+    $I1 = -2147483648
+    $I2 = 0
+    $I3 = 0
+
+    $I4 = 0
+    unless $I1 <= $I0 goto test_le_1
+    $I4 = 1
+  test_le_1:
+    ok($I4, 'le_i_i - true inequality')
+
+    $I4 = 0
+    if $I0 <= $I1 goto test_le_2
+    $I4 = 1
+  test_le_2:
+    ok($I4, 'le_i_i - false inequality')
+
+    $I4 = 0
+    unless $I2 <= $I3 goto test_le_3
+    $I4 = 1
+  test_le_3:
+    ok($I4, 'le_i_i - reflexive')
+
+    $I4 = 0
+    if $I0 <= -2147483648 goto test_le_4
+    $I4 = 1
+  test_le_4:
+    ok($I4, 'le_i_ic - false inequality')
+
+    $I4 = 0
+    unless $I1 <= 2147483647 goto test_le_5
+    $I4 = 1
+  test_le_5:
+    ok($I4, 'le_i_ic - true inequality')
+
+    $I4 = 0
+    unless $I2 <= 0 goto test_le_6
+    $I4 = 1
+  test_le_6:
+    ok($I4, 'le_i_ic - reflexivity')
+.end
+
+.sub 'test_gt'
+    $I0 = -2147483648
+    $I1 = 2147483647
+    $I2 = 0
+    $I3 = 0
+
+    $I4 = 0
+    unless $I1 > $I0 goto test_gt_1
+    $I4 = 1
+  test_gt_1:
+    ok($I4, 'gt_i_i - true inequality')
+
+    $I4 = 0
+    if $I0 > $I1 goto test_gt_2
+    $I4 = 1
+  test_gt_2:
+    ok($I4, 'gt_i_i - false inequality')
+
+    $I4 = 0
+    if $I2 > $I3 goto test_gt_3
+    $I4 = 1
+  test_gt_3:
+    ok($I4, 'gt_i_i - irreflexive')
+
+    $I4 = 0
+    if $I0 > 2147483647 goto test_gt_4
+    $I4 = 1
+  test_gt_4:
+    ok($I4, 'gt_i_ic - false inequality')
+
+    $I4 = 0
+    unless $I1 > -2147483648 goto test_gt_5
+    $I4 = 1
+  test_gt_5:
+    ok($I4, 'gt_i_ic - true inequality')
+
+    $I4 = 0
+    if $I0 > 0 goto test_gt_6
+    $I4 = 1
+  test_gt_6:
+    ok($I4, 'gt_i_ic - another false inequality')
+.end
+
+.sub 'test_ge'
+    $I0 = -2147483648
+    $I1 = 2147483647
+    $I2 = 0
+    $I3 = 0
+
+    $I4 = 0
+    unless $I1 >= $I0 goto test_ge_1
+    $I4 = 1
+  test_ge_1:
+    ok($I4, 'ge_i_i - true inequality')
+
+    $I4 = 0
+    if $I0 >= $I1 goto test_ge_2
+    $I4 = 1
+  test_ge_2:
+    ok($I4, 'ge_i_i - false inequality')
+
+    $I4 = 0
+    unless $I2 >= $I3 goto test_ge_3
+    $I4 = 1
+  test_ge_3:
+    ok($I4, 'ge_i_i - reflexive')
+
+    $I4 = 0
+    if $I0 >= 2147483647 goto test_ge_4
+    $I4 = 1
+  test_ge_4:
+    ok($I4, 'ge_i_ic - false inequality')
+
+    $I4 = 0
+    unless $I1 >= -2147483648 goto test_ge_5
+    $I4 = 1
+  test_ge_5:
+    ok($I4, 'ge_i_ic - true inequality')
+
+    $I4 = 0
+    unless $I2 >= 0 goto test_ge_6
+    $I4 = 1
+  test_ge_6:
+    ok($I4, 'ge_i_ic - reflexivity')
+.end
+
+.sub 'test_not'
+    $I0 = 1
+    $I1 = not $I0
+    is($I1, 0, 'not_i_i - not 1')
+
+    $I2 = not $I1
+    is($I2, 1, 'not_i_i - not (not 1)')
+
+    $I3 = 12345
+    $I4 = not $I3
+    is($I4, 0, 'not_i_i of a positive integer')
+
+    $I5 = -1
+    $I6 = not $I5
+    is($I6, 0, 'not_i_i of a negative integer')
+
+    $I7 = 1
+    $I7 = not 1
+    is($I7, 0, 'not_i_ic')
+.end
+
+.sub 'test_and'
+    $I0 = 0
+    $I1 = 10
+
+    $I2 = 1
+    $I2 = and $I1, $I0
+    is($I2, 0, 'and - zero is right absorbing')
+
+    $I2 = 1
+    $I2 = and $I0, $I1
+    is($I2, 0, 'and - zero is left absorbing')
+
+    $I2 = 1
+    $I2 = and $I0, $I0
+    is($I2, 0, 'and - diagonal zero')
+
+    $I2 = 1
+    $I2 = and $I2, $I1
+    is($I2, 10, 'and - true operands')
+.end
+
+.sub 'test_or'
+    $I0 = 0
+    $I1 = 10
+
+    $I2 = 42
+    $I2 = or $I1, $I0
+    is($I2, 10, 'or_i_i')
+
+    $I2 = 42
+    $I2 = or $I0, $I1
+    is($I2, 10, 'or_i_i - symmetric case')
+
+    $I2 = or $I0, $I0
+    is($I2, 0, 'or_i_i - false arguments')
+
+    $I2 = or $I2, $I1
+    is($I2, 10, 'or_i_i - reflexive')
+.end
+
+.sub 'test_xor'
+    $I0 = 0
+    $I1 = 2
+
+    $I2 = 42
+    $I2 = xor $I1, $I0
+    is($I2, 2, 'xor - zero is right neutral')
+
+    $I2 = 42
+    $I2 = xor $I0, $I1
+    is($I2, 2, 'xor - zero is left neutral')
+
+    $I2 = xor $I0, $I0
+    is($I2, 0, 'xor - nilpotent on zero')
+
+    $I2 = xor $I1, $I1
+    is($I2, 0, 'xor - nilpotent on 2')
+    
+    $I2 = xor $I2, $I2
+    is($I2, 0, 'xor - nilpotent on other')
+.end
+
+.sub 'test_inc'
+    $I0 = 0
+    inc $I0
+    is($I0, 1, 'inc_i (first)')
+    inc $I0
+    inc $I0
+    inc $I0
+    inc $I0
+    is($I0, 5, 'inc_i (second)')
+.end
+
+.sub 'test_dec'
+    $I0 = 0
+    dec $I0
+    is($I0, -1, 'dec_i (first)')
+    dec $I0
+    dec $I0
+    dec $I0
+    dec $I0
+    is($I0, -5, 'dec_i (second)')
+.end
+
+.sub 'test_sub_i_i'
+    $I0 = 0
+    $I1 = 3
+    $I2 = -3
+
+    sub $I0, $I1
+    is($I0, -3, 'sub_i_i')
+
+    sub $I0, $I2
+    is($I0, 0, 'sub_i_i - inverse')
+
+    $I0 = 0
+    sub $I0, 5
+    is($I0, -5, 'sub_i_ic - first')
+
+    sub $I0, -10
+    is($I0, 5, 'sub_i_ic - second')
+.end
+
+.sub 'test_set_n'
+    $I0 = 0
+    $N0 = $I0
+    is($N0, 0.0, 'set_n_i -zero')
+
+    $I1 = 2147483647
+    $N1 = $I1
+    is($N1, 2147483647.0, 'set_n_i - positive integer')
+
+    $I2 = -2147483648
+    $N2 = $I2
+    is($N2, -2147483648.0, 'set_n_i - negative integer')
+.end
+
+.sub 'test_cleari'
+    $I0 = 0xdeadbee
+    $I1 = 0xdeadbee
+    $I2 = 0xdeadbee
+    $I3 = 0xdeadbee
+    $I4 = 0xdeadbee
+    $I5 = 0xdeadbee
+    $I6 = 0xdeadbee
+    $I7 = 0xdeadbee
+    $I8 = 0xdeadbee
+    $I9 = 0xdeadbee
+    $I10 = 0xdeadbee
+    $I11 = 0xdeadbee
+    $I12 = 0xdeadbee
+    $I13 = 0xdeadbee
+    $I14 = 0xdeadbee
+    $I15 = 0xdeadbee
+    $I16 = 0xdeadbee
+    $I17 = 0xdeadbee
+    $I18 = 0xdeadbee
+    $I19 = 0xdeadbee
+    $I20 = 0xdeadbee
+    $I21 = 0xdeadbee
+    $I22 = 0xdeadbee
+    $I23 = 0xdeadbee
+    $I24 = 0xdeadbee
+    $I25 = 0xdeadbee
+    $I26 = 0xdeadbee
+    $I27 = 0xdeadbee
+    $I28 = 0xdeadbee
+    $I29 = 0xdeadbee
+    $I30 = 0xdeadbee
+    $I31 = 0xdeadbee
+
+    cleari
+
+    is($I0, 0, 'cleari - $I0 cleared')
+    is($I1, 0, 'cleari - $I1 cleared')
+    is($I2, 0, 'cleari - $I2 cleared')
+    is($I3, 0, 'cleari - $I3 cleared')
+    is($I4, 0, 'cleari - $I4 cleared')
+    is($I5, 0, 'cleari - $I5 cleared')
+    is($I6, 0, 'cleari - $I6 cleared')
+    is($I7, 0, 'cleari - $I7 cleared')
+    is($I8, 0, 'cleari - $I8 cleared')
+    is($I9, 0, 'cleari - $I9 cleared')
+    is($I10, 0, 'cleari - $I10 cleared')
+    is($I11, 0, 'cleari - $I11 cleared')
+    is($I12, 0, 'cleari - $I12 cleared')
+    is($I13, 0, 'cleari - $I13 cleared')
+    is($I14, 0, 'cleari - $I14 cleared')
+    is($I15, 0, 'cleari - $I15 cleared')
+    is($I16, 0, 'cleari - $I16 cleared')
+    is($I17, 0, 'cleari - $I17 cleared')
+    is($I18, 0, 'cleari - $I18 cleared')
+    is($I19, 0, 'cleari - $I19 cleared')
+    is($I20, 0, 'cleari - $I20 cleared')
+    is($I21, 0, 'cleari - $I21 cleared')
+    is($I22, 0, 'cleari - $I22 cleared')
+    is($I23, 0, 'cleari - $I23 cleared')
+    is($I24, 0, 'cleari - $I24 cleared')
+    is($I25, 0, 'cleari - $I25 cleared')
+    is($I26, 0, 'cleari - $I26 cleared')
+    is($I27, 0, 'cleari - $I27 cleared')
+    is($I28, 0, 'cleari - $I28 cleared')
+    is($I29, 0, 'cleari - $I29 cleared')
+    is($I30, 0, 'cleari - $I30 cleared')
+    is($I31, 0, 'cleari - $I31 cleared')
+.end
+
+.sub 'test_neg'
+    $I0 = neg 3
+    $I0 = neg $I0
+    neg $I0
+
+    is($I0, -3, 'neg_i')
+.end
+
+.sub 'test_mul_i_i'
+    $I0 = 3
+    $I1 = 4
+    mul $I0, $I1
+
+    is($I0, 12, 'mul_i_i')
+.end
+
+.sub 'test_fact'
+    $I0 = 3
+    $I1 = 11
+    $I2 = 0
+    $I3 = -563
+
+    $I5 = fact $I0
+    is($I5, 6, 'fact_i_i - first')
+
+    $I6 = fact $I1
+    is($I6, 39916800, 'fact_i_i - second')
+
+    $I7 = fact $I2
+    is($I7, 1, 'fact_i_i on zero')
+
+    $I8 = fact $I3
+    is($I8, 1, 'fact_i_i on a negative integer')
+
+    # Now run the same tests, with constants instead
+    $I5 = fact 3
+    is($I5, 6, 'fact_i_ic - first')
+
+    $I6 = fact 11
+    is($I6, 39916800, 'fact_i_ic - second')
+
+    $I7 = fact 0
+    is($I7, 1, 'fact_i_ic on zero')
+
+    $I8 = fact -563
+    is($I8, 1, 'fact_i_ic on a negative integer')
+.end
+
+.sub 'test_exchange'
+    $I10 = 10
+    $I20 = 20
+    exchange $I10, $I20
+    is($I10, 20, 'exchange - first operand ok')
+    is($I20, 10, 'exchange - second operand ok')
+
+    $I30 = 30
+    exchange $I30, $I30
+    is($I30, 30, 'exchange - reflexive')
+.end
+
+.sub 'test_null'
+    $I1 = 1000
+    is($I1, 1000, 'null_i - before null')
+    null $I1
+    is($I1, 0, 'null_i - after null')
+.end
+
+.sub 'test_div_i_i_by_zero'
+    $I0 = 0
+    $I1 = 10
+    push_eh test_div_i_i_by_zero_catch
+    div $I1, $I0
+    pop_eh
+    $I2 = 0
+    goto test_div_i_i_by_zero_end
+
+  test_div_i_i_by_zero_catch:
+    $I2 = 1
+
+  test_div_i_i_by_zero_end:
+    ok($I2, 'div_i_i by zero')
+.end
+
+.sub 'test_div_i_ic_by_zero'
+    $I1 = 10
+    push_eh test_div_i_ic_by_zero_catch
+    div $I1, 0
+    pop_eh
+    $I2 = 0
+    goto test_div_i_ic_by_zero_end
+
+  test_div_i_ic_by_zero_catch:
+    $I2 = 1
+
+  test_div_i_ic_by_zero_end:
+    ok($I2, 'div_i_ic by zero')
+.end
+
+.sub 'test_div_i_i_i_by_zero'
+    $I0 = 0
+    $I1 = 10
+    push_eh test_div_i_i_i_by_zero_catch
+    $I2 = div $I1, $I0
+    pop_eh
+    $I3 = 0
+    goto test_div_i_i_i_by_zero_end
+
+  test_div_i_i_i_by_zero_catch:
+    $I3 = 1
+
+  test_div_i_i_i_by_zero_end:
+    ok($I3, 'div_i_i_i by zero')
+.end
+
+.sub 'test_div_i_ic_i_by_zero'
+    $I0 = 0
+    push_eh test_div_i_ic_i_by_zero_catch
+    $I2 = div 10, $I0
+    pop_eh
+    $I3 = 0
+    goto test_div_i_ic_i_by_zero_end
+
+  test_div_i_ic_i_by_zero_catch:
+    $I3 = 1
+
+  test_div_i_ic_i_by_zero_end:
+    ok($I3, 'div_i_ic_i by zero')
+.end
+
+.sub 'test_div_i_i_ic_by_zero'
+    $I1 = 10
+    push_eh test_div_i_i_ic_by_zero_catch
+    $I2 = div $I1, 0
+    pop_eh
+    $I3 = 0
+    goto test_div_i_i_ic_by_zero_end
+
+  test_div_i_i_ic_by_zero_catch:
+    $I3 = 1
+
+  test_div_i_i_ic_by_zero_end:
+    ok($I3, 'div_i_i_ic by zero')
+.end
+
+.sub 'test_fdiv_i_i_by_zero'
+    $I0 = 0
+    $I1 = 10
+    push_eh test_fdiv_i_i_by_zero_catch
+    fdiv $I1, $I0
+    pop_eh
+    $I2 = 0
+    goto test_fdiv_i_i_by_zero_end
+
+  test_fdiv_i_i_by_zero_catch:
+    $I2 = 1
+
+  test_fdiv_i_i_by_zero_end:
+    ok($I2, 'fdiv_i_i by zero')
+.end
+
+.sub 'test_fdiv_i_ic_by_zero'
+    $I1 = 10
+    push_eh test_fdiv_i_ic_by_zero_catch
+    fdiv $I1, 0
+    pop_eh
+    $I2 = 0
+    goto test_fdiv_i_ic_by_zero_end
+
+  test_fdiv_i_ic_by_zero_catch:
+    $I2 = 1
+
+  test_fdiv_i_ic_by_zero_end:
+    ok($I2, 'fdiv_i_ic by zero')
+.end
+
+.sub 'test_fdiv_i_i_i_by_zero'
+    $I0 = 0
+    $I1 = 10
+    push_eh test_fdiv_i_i_i_by_zero_catch
+    $I2 = fdiv $I1, $I0
+    pop_eh
+    $I3 = 0
+    goto test_fdiv_i_i_i_by_zero_end
+
+  test_fdiv_i_i_i_by_zero_catch:
+    $I3 = 1
+
+  test_fdiv_i_i_i_by_zero_end:
+    ok($I3, 'fdiv_i_i_i by zero')
+.end
+
+.sub 'test_fdiv_i_ic_i_by_zero'
+    $I0 = 0
+    push_eh test_fdiv_i_ic_i_by_zero_catch
+    $I2 = fdiv 10, $I0
+    pop_eh
+    $I3 = 0
+    goto test_fdiv_i_ic_i_by_zero_end
+
+  test_fdiv_i_ic_i_by_zero_catch:
+    $I3 = 1
+
+  test_fdiv_i_ic_i_by_zero_end:
+    ok($I3, 'fdiv_i_ic_i by zero')
+.end
+
+.sub 'test_fdiv_i_i_ic_by_zero'
+    $I1 = 10
+    push_eh test_fdiv_i_i_ic_by_zero_catch
+    $I2 = fdiv $I1, 0
+    pop_eh
+    $I3 = 0
+    goto test_fdiv_i_i_ic_by_zero_end
+
+  test_fdiv_i_i_ic_by_zero_catch:
+    $I3 = 1
+
+  test_fdiv_i_i_ic_by_zero_end:
+    ok($I3, 'fdiv_i_i_ic by zero')
+.end
+
+.sub 'test_cmod_i_i_i_by_zero'
+    $I0 = 0
+    $I1 = 10
+    push_eh test_cmod_i_i_i_by_zero_catch
+    $I2 = cmod $I1, $I0
+    pop_eh
+    $I3 = 0
+    goto test_cmod_i_i_i_by_zero_end
+
+  test_cmod_i_i_i_by_zero_catch:
+    $I3 = 1
+
+  test_cmod_i_i_i_by_zero_end:
+    ok($I3, 'cmod_i_i_i by zero')
+.end
+
+.sub 'test_cmod_i_ic_i_by_zero'
+    $I0 = 0
+    push_eh test_cmod_i_ic_i_by_zero_catch
+    $I2 = cmod 10, $I0
+    pop_eh
+    $I3 = 0
+    goto test_cmod_i_ic_i_by_zero_end
+
+  test_cmod_i_ic_i_by_zero_catch:
+    $I3 = 1
+
+  test_cmod_i_ic_i_by_zero_end:
+    ok($I3, 'cmod_i_ic_i by zero')
+.end
+
+.sub 'test_cmod_i_i_ic_by_zero'
+    $I1 = 10
+    push_eh test_cmod_i_i_ic_by_zero_catch
+    $I2 = cmod $I1, 0
+    pop_eh
+    $I3 = 0
+    goto test_cmod_i_i_ic_by_zero_end
+
+  test_cmod_i_i_ic_by_zero_catch:
+    $I3 = 1
+
+  test_cmod_i_i_ic_by_zero_end:
+    ok($I3, 'cmod_i_i_ic by zero')
+.end
+
+.sub 'test_mod_i_i_i_by_zero'
+    $I0 = 0
+    $I1 = 10
+    $I2 = mod $I1, $I0
+    is($I2, 10, 'mod_i_i_i by zero')
+.end
+
+.sub 'test_mod_i_ic_i_by_zero'
+    $I0 = 0
+    $I2 = mod 10, $I0
+    is($I2, 10, 'mod_i_ic_i by zero')
+.end
+
+.sub 'test_mod_i_i_ic_by_zero'
+    $I1 = 10
+    $I2 = mod $I1, 0
+    is($I2, 10, 'mod_i_i_ic by zero')
+.end
 
 # Local Variables:
-#   mode: cperl
-#   cperl-indent-level: 4
+#   mode: pir
 #   fill-column: 100
 # End:
-# vim: expandtab shiftwidth=4:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/tt761_keys_revamp/t/op/io.t
==============================================================================
--- branches/tt761_keys_revamp/t/op/io.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/op/io.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -1,14 +1,7 @@
-#!perl
+#!parrot
 # Copyright (C) 2008, Parrot Foundation.
 # $Id$
 
-use strict;
-use warnings;
-use lib qw( . lib ../lib ../../lib );
-
-use Test::More;
-use Parrot::Test tests => 4;
-
 =head1 NAME
 
 t/op/io.t - Testing io opcodes
@@ -23,118 +16,140 @@
 
 =cut
 
-pir_output_is( <<'CODE', <<'OUTPUT', 'open with null filename' );
-.sub main
-    push_eh failed
-    $P0 = open $S0, '<'
-    say 'never'
-    goto finish
-failed:
-    say 'Catched'
-finish:
-.end
-CODE
-Catched
-OUTPUT
-
-pir_output_is( <<'CODE', <<'OUTPUT', 'open with null mode' );
-.sub main
-    push_eh failed
-    $P0 = open 'some_name', $S0
-    say 'never'
-    goto finish
-failed:
-    say 'Catched'
-finish:
-.end
-CODE
-Catched
-OUTPUT
+.const int TESTS = 4
 
-TODO: {
-local $TODO = 'Unimplemented in this platform, TT #661' unless $^O =~ /linux|darwin|MSWin32/;
+.sub 'main' :main
+    .include 'test_more.pir'
 
-pir_output_like( <<'CODE', <<'OUTPUT', 'open pipe for reading' );
-.include 'iglobals.pasm'
+    plan(TESTS)
+
+    open_null_filename()
+    open_null_mode()
+    open_pipe_for_reading()
+    open_pipe_for_writing()
+.end
+
+.sub 'open_null_filename'
+    push_eh open_null_filename_failed
+    null $S0
+    $P0 = open $S0, 'r'
+    nok(1, 'open with null filename')
+    .return ()
+
+  open_null_filename_failed:
+    ok(1, 'open with null filename')
+.end
 
-.sub testreadpipe :main
-  .local pmc interp
-  interp = getinterp
-  .local pmc conf
-  conf = interp[.IGLOBALS_CONFIG_HASH]
-  .local string command
-  command = conf['build_dir']
-  .local string aux
-  aux = conf['slash']
-  command .= aux
-  aux = conf['test_prog']
-  command .= aux
-  aux = conf['exe']
-  command .= aux
-  command .= ' -V'
-
-  .local pmc pipe
-  pipe = open command, 'rp'
-  unless pipe goto failed
-  .local string line
-nextline:
-  line = readline pipe
-  print line
-  if pipe goto nextline
-  .return()
-failed:
-  say 'FAILED'
-.end
-CODE
-/This is Parrot.*/
-OUTPUT
+.sub 'open_null_mode'
+    push_eh open_null_mode_failed
+    null $S0
+    $P0 = open 'some_name', $S0
+    nok(1, 'open with null mode')
+    .return ()
+
+  open_null_mode_failed:
+    ok(1, 'open with null mode')
+.end
 
-}
+.sub 'tt661_todo_test' :anon
+    # Checks whether the platform is linux, MSWin32, darwin: on other
+    # platforms, the following tests are todo'ed.
+    .include 'sysinfo.pasm'
+    $S0 = sysinfo .SYSINFO_PARROT_OS
+    if $S0 == 'linux' goto tt661_ok
+    if $S0 == 'MSWin32' goto tt661_ok
+    if $S0 == 'darwin' goto tt661_ok
+    if $S0 == 'openbsd' goto tt661_ok
 
-TODO: {
-local $TODO = 'Unimplemented in this platform, TT #661' unless $^O =~ /linux|darwin|MSWin32/;
+    .return (0)
+
+  tt661_ok:
+    .return (1)
+.end
 
-pir_output_is( <<'CODE', <<'OUTPUT', 'open pipe for writing' );
 .include 'iglobals.pasm'
 
-.sub testwritepipe :main
-  .local pmc interp
-  interp = getinterp
-  .local pmc conf
-  conf = interp[.IGLOBALS_CONFIG_HASH]
-  .local string command
-  command = conf['build_dir']
-  .local string aux
-  aux = conf['slash']
-  command .= aux
-  .local string filename
-  filename .= command
-  filename .= 'examples/pasm/cat.pasm'
-  aux = conf['test_prog']
-  command .= aux
-  aux = conf['exe']
-  command .= aux
-  command .= ' '
-  command .= filename
-
-  .local pmc pipe
-  pipe = open command, 'wp'
-  unless pipe goto failed
-  pipe.'puts'("Hello, pipe!\n")
-  close pipe
-  .return()
-failed:
-  say 'FAILED'
-.end
-CODE
-Hello, pipe!
-OUTPUT
+.sub 'open_pipe_for_reading'
+    $I0 = tt661_todo_test()
+    unless $I0 goto open_pipe_for_reading_todoed
+
+    .local pmc interp
+    interp = getinterp
+
+    .local pmc conf
+    conf = interp[.IGLOBALS_CONFIG_HASH]
+
+    .local string command
+    command = conf['build_dir']
+
+    .local string aux
+    aux = conf['slash']
+    command .= aux
+    aux = conf['test_prog']
+    command .= aux
+    aux = conf['exe']
+    command .= aux
+    command .= ' -V'
+
+    .local pmc pipe
+    pipe = open command, 'rp'
+    unless pipe goto open_pipe_for_reading_failed
+    .local string line
+    line = readline pipe
+    like('This is Parrot', ":s This is Parrot", 'open pipe for reading')
+    .return ()
+
+  open_pipe_for_reading_failed:
+    nok(1, 'open pipe for reading')
+    .return ()
 
-}
+  open_pipe_for_reading_todoed:
+    todo(1, 'Unimplemented in this platform, TT #661')
+.end
+
+.sub 'open_pipe_for_writing'
+    $I0 = tt661_todo_test()
+    unless $I0 goto open_pipe_for_writing_todoed
+
+    .local pmc interp
+    interp = getinterp
+
+    .local pmc conf
+    conf = interp[.IGLOBALS_CONFIG_HASH]
+
+    .local string command
+    command = conf['build_dir']
+
+    .local string aux
+    aux = conf['slash']
+    command .= aux
+    .local string filename
+    filename .= command
+    filename .= 'examples/pasm/cat.pasm'
+    aux = conf['test_prog']
+    command .= aux
+    aux = conf['exe']
+    command .= aux
+    command .= ' '
+    command .= filename
+
+    .local pmc pipe
+    pipe = open command, 'wp'
+    unless pipe goto open_pipe_for_writing_failed
+    pipe.'puts'("ok - open pipe for writing\n")
+    close pipe
+    .return ()
+
+  open_pipe_for_writing_failed:
+    nok(1, 'open pipe for writing')
+    .return ()
+
+  open_pipe_for_writing_todoed:
+    todo(1, 'Unimplemented in this platform, TT #661')
+.end
 
 # Local Variables:
-#   mode: cperl
-#   cperl-indent-level: 4
+#   mode: pir
 #   fill-column: 100
 # End:
-# vim: expandtab shiftwidth=4:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/tt761_keys_revamp/t/op/lexicals.t
==============================================================================
--- branches/tt761_keys_revamp/t/op/lexicals.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/op/lexicals.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -226,7 +226,6 @@
     .local pmc pad, interp
     interp = getinterp
     pad = interp["lexpad"]
-    .local pmc pad
     unless null pad goto ok
     print "pad is NULL\n"
     end

Modified: branches/tt761_keys_revamp/t/op/string.t
==============================================================================
--- branches/tt761_keys_revamp/t/op/string.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/op/string.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -7,7 +7,7 @@
 use lib qw( . lib ../lib ../../lib );
 
 use Test::More;
-use Parrot::Test tests => 165;
+use Parrot::Test tests => 166;
 use Parrot::Config;
 
 =head1 NAME
@@ -2639,6 +2639,41 @@
 
 OUTPUT
 
+pir_output_is( <<'CODE', <<'OUTPUT', 'split HLL mapped' );
+.HLL 'foohll'
+.sub main
+    .local pmc RSA, fooRSA
+    RSA = get_class ['ResizableStringArray']
+    fooRSA = subclass ['ResizableStringArray'], 'fooRSA'
+    .local pmc interp
+    interp = getinterp
+    interp.'hll_map'(RSA, fooRSA)
+    .local pmc a
+    split a, "a", "afooabara"
+    .local string t
+    t = typeof a
+    say t
+    .local int n, i
+    n = a
+    say n
+    i = 0
+loop:
+    .local string s
+    s = a[i]
+    say s
+    inc i
+    if i != n goto loop
+.end
+CODE
+fooRSA
+5
+
+foo
+b
+r
+
+OUTPUT
+
 pasm_output_is( <<'CODE', <<'OUTPUT', 'join' );
 _main:
     new P0, 'ResizablePMCArray'

Modified: branches/tt761_keys_revamp/t/op/stringu.t
==============================================================================
--- branches/tt761_keys_revamp/t/op/stringu.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/op/stringu.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -6,7 +6,7 @@
 use warnings;
 use lib qw( . lib ../lib ../../lib );
 use Test::More;
-use Parrot::Test tests => 31;
+use Parrot::Test tests => 32;
 use Parrot::Config;
 
 =head1 NAME
@@ -550,6 +550,31 @@
 OUT
 }
 
+pir_output_is( <<'CODE', <<'OUT', 'concatenation of utf8 and iso-8859-1 (TT#752)' );
+.sub 'main'
+
+    $S1 = chr 0xe5
+    $S2 = chr 0x263b
+
+    $S0 = unicode:"\u00e5\u263b"
+    $S3 = concat $S1, $S2
+    if $S0 == $S3 goto equal_1
+    print "not "
+  equal_1:
+    say "equal"
+
+    $S0 = unicode:"\u263b\u00e5"
+    $S3 = concat $S2, $S1
+    if $S0 == $S3 goto equal_2
+    print "not "
+  equal_2:
+    say "equal"
+.end
+CODE
+equal
+equal
+OUT
+
 
 # Local Variables:
 #   mode: cperl

Modified: branches/tt761_keys_revamp/t/pmc/bignum.t
==============================================================================
--- branches/tt761_keys_revamp/t/pmc/bignum.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/pmc/bignum.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -25,7 +25,7 @@
 =cut
 
 if ( $PConfig{gmp} ) {
-    plan tests => 32;
+    plan tests => 33;
 }
 else {
     plan skip_all => "No BigNum PMC enabled";
@@ -385,6 +385,29 @@
 ok 2
 OUT
 
+pasm_output_is( <<'CODE', <<'OUT', "div float" );
+     new P0, ['BigNum']
+     set P0, "100000000000000000000"
+     new P1, ['BigNum']
+     div P1, P0, 10.0
+     new P2, ['BigNum']
+     set P2, "10000000000000000000"
+     eq P1, P2, OK1
+     print "not "
+OK1: say "ok 1"
+
+     set P0, "100000000000000"
+     div P1, P0, -10.0
+     set P2, "-10000000000000"
+     eq  P1, P2, OK2
+     print "not "
+OK2: say "ok 2"
+     end
+CODE
+ok 1
+ok 2
+OUT
+
 my @todo_sig = ( todo => "missing signature" );
 for my $op ( "/", "%" ) {
     for my $type ( "BigNum", "BigInt", "Integer" ) {

Modified: branches/tt761_keys_revamp/t/pmc/capture.t
==============================================================================
--- branches/tt761_keys_revamp/t/pmc/capture.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/pmc/capture.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -1,14 +1,7 @@
-#!perl
+#! parrot
 # Copyright (C) 2001-2008, Parrot Foundation.
 # $Id$
 
-use strict;
-use warnings;
-use lib qw( . lib ../lib ../../lib );
-
-use Test::More;
-use Parrot::Test tests => 8;
-
 =head1 NAME
 
 t/pmc/capture.t - Test the Capture PMC
@@ -24,29 +17,33 @@
 
 =cut
 
-my $PRE = <<PRE;
+.const int TESTS = 47
+
 .sub 'test' :main
-    .local pmc capt
-    capt = new ['Capture']
-PRE
+    .include 'test_more.pir'
+
+    plan(TESTS)
 
-my $POST = <<POST;
-    goto end
-  nok:
-    print 'not '
-  ok:
-    say 'ok'
-  end:
+    test_new_capture()
+    basic_capture_tests()
+    test_defined_delete_exists()
+    test_hash_list()
+    test_get_integer()
+    test_get_number()
+    test_keyed_int_delegation()
+    test_list_delegation()
 .end
-POST
 
-pir_output_is( $PRE . <<'CODE'. $POST, <<'OUT', 'new' );
-CODE
-OUT
+.sub 'test_new_capture'
+    .local pmc capt
+
+    capt = new ['Capture']
+    ok(1, 'new Capture')
+.end
 
-pir_output_is( <<'CODE', <<'OUTPUT', "Basic capture tests" );
-.sub main :main
+.sub 'basic_capture_tests'
     .local pmc capt
+
     capt = new ['Capture']
 
     capt[0] = 0
@@ -78,107 +75,90 @@
     capt['delta'] = $P0
 
     $I0 = elements capt
-    print $I0
-    print "\n"
+    is($I0, 12, 'elements')
 
     $I0 = capt[11]
-    print $I0
-    print " "
+    is($I0, 7, 'get_integer_keyed_int')
+    
     $P0 = capt[10]
-    print $P0
-    print " "
+    is($P0, 'six', 'get_pmc_keyed_int')
+
     $N0 = capt[9]
-    print $N0
-    print " "
+    is($N0, 5.5, 'get_number_keyed_int')
+
     $S0 = capt[8]
-    say $S0
+    is($S0, '4', 'get_string_keyed_int')
 
     $I0 = pop capt
-    print $I0
-    print " "
+    is($I0, 7, 'pop an integer')
+
     $P0 = pop capt
-    print $P0
-    print " "
+    is($P0, 'six', 'pop a PMC')
+
     $N0 = pop capt
-    print $N0
-    print " "
+    is($N0, 5.5, 'pop a number')
+
     $S0 = pop capt
-    say $S0
+    is($S0, '4', 'pop a string')
 
     $I0 = elements capt
-    print $I0
-    print "\n"
+    is($I0, 8, 'elements after pop')
 
     $I0 = shift capt
-    print $I0
-    print " "
+    is($I0, 11, 'shift an integer')
+    
     $P0 = shift capt
-    print $P0
-    print " "
+    is($P0, 'ten', 'shift a PMC')
+    
     $N0 = shift capt
-    print $N0
-    print " "
+    is($N0, 9.5, 'shift a number')
+    
     $S0 = shift capt
-    say $S0
+    is($S0, '8', 'shift a string')
 
     $I0 = elements capt
-    print $I0
-    print "\n"
+    is($I0, 4, 'elements after shift')
+
+    $P0 = pop capt
+    is($P0, 3, 'pop 1 out of 4')
+
+    $P0 = pop capt
+    is($P0, 'two', 'pop 2 out of 4')
 
-  loop:
-    $I0 = elements capt
-    if $I0 < 1 goto end
     $P0 = pop capt
-    say $P0
-    goto loop
-  end:
+    is($P0, 1.5, 'pop 3 out of 4')
+
+    $P0 = pop capt
+    is($P0, 0, 'pop 4 out of 4')
 
     $I0 = capt['delta']
-    print $I0
-    print " "
+    is($I0, 15, 'get_integer_keyed_str')
+
     $P0 = capt['gamma']
-    print $P0
-    print " "
+    is($P0, 'fourteen', 'get_pmc_keyed_str')
+    
     $N0 = capt['beta']
-    print $N0
-    print " "
-    $S0 = capt['alpha']
-    say $S0
+    is($N0, 13.5, 'get_number_keyed_str')
 
+    $S0 = capt['alpha']
+    is($S0, '12', 'get_string_keyed_str')
 .end
 
-CODE
-12
-7 six 5.5 4
-7 six 5.5 4
-8
-11 ten 9.5 8
-4
-3
-two
-1.5
-0
-15 fourteen 13.5 12
-OUTPUT
-
-pir_output_is( <<'CODE', <<'OUTPUT', "defined, delete, exists" );
-.sub main :main
+.sub 'test_defined_delete_exists'
     .local pmc capt
     capt = new ['Capture']
 
     $I0 = defined capt[2]
+    nok($I0, 'defined_i initially false')
+
     $I1 = exists capt[2]
-    print $I0
-    print " "
-    print $I1
-    print "\n"
+    nok($I1, 'exists_i initially false')
 
     $I0 = defined capt['alpha']
+    nok($I0, 'defined_s initially false')
+
     $I1 = exists capt['alpha']
-    print $I0
-    print " "
-    print $I1
-    print "\n"
+    nok($I1, 'exists_s initially false')
 
     capt[2] = 1
     capt['alpha'] = 1
@@ -186,117 +166,115 @@
     capt['beta'] = $P0
 
     $I0 = defined capt[2]
+    ok($I0, 'defined_i true after set')
+
     $I1 = exists capt[2]
-    print $I0
-    print " "
-    print $I1
-    print "\n"
+    ok($I1, 'exists_i true after set')
 
     $I0 = defined capt['alpha']
+    ok($I0, 'defined_s true after set')
+
     $I1 = exists capt['alpha']
-    print $I0
-    print " "
-    print $I1
-    print "\n"
+    ok($I1, 'exists_s true after set')
 
     $I0 = defined capt[1]
+    nok($I0, 'defined_i - no intermediate element created')
+
     $I1 = exists capt[1]
-    print $I0
-    print " "
-    print $I1
-    print "\n"
+    nok($I1, 'exists_i - no intermediate element created')
 
     $I0 = defined capt['beta']
+    nok($I0, 'defined_s checks for Undef values...')
+
     $I1 = exists capt['beta']
-    print $I0
-    print " "
-    print $I1
-    print "\n"
+    ok($I1, 'but exists_s does not care')
 
     delete capt[2]
     delete capt['alpha']
 
     $I0 = defined capt[2]
+    nok($I0, 'defined_i false after delete')
     $I1 = exists capt[2]
-    print $I0
-    print " "
-    print $I1
-    print "\n"
+    nok($I1, 'exists_i false after delete')
 
     $I0 = defined capt['alpha']
+    nok($I0, 'defined_s false after delete')
     $I1 = exists capt['alpha']
-    print $I0
-    print " "
-    print $I1
-    print "\n"
+    nok($I1, 'exists_s false after delete')
+.end
 
+.sub 'test_hash_list'
+    .local pmc capt
 
-.end
-CODE
-0 0
-0 0
-1 1
-1 1
-0 0
-0 1
-0 0
-0 0
-OUTPUT
+    capt = new ['Capture']
 
-pir_output_is( $PRE . <<'CODE'. $POST, <<'OUTPUT', "hash, list" );
     $P0 = capt.'list'()
     $P1 = capt.'hash'()
 
-    $S0 = typeof $P0
-    $S1 = typeof $P1
+    isa_ok($P0, 'ResizablePMCArray', "capt.'list'")
+    isa_ok($P1, 'Hash', "capt.'hash'")
+.end
 
-    say $S0
-    say $S1
-CODE
-ResizablePMCArray
-Hash
-OUTPUT
+.sub 'test_get_integer'
+    .local pmc capt
 
-pir_error_output_like( $PRE . <<'CODE'. $POST, <<'OUT', 'get_integer not implemented' );
+    capt = new ['Capture']
+    push_eh test_get_integer_catch
     $I0 = capt
-CODE
-/get_integer\(\) not implemented in class 'Capture'/
-OUT
 
-pir_error_output_like( $PRE . <<'CODE'. $POST, <<'OUT', 'get_number not implemented' );
+    nok(1, 'get_integer not implemented')
+    .return ()
+
+  test_get_integer_catch:
+    .local pmc exception
+    .local string message
+    .get_results (exception)
+
+    message = exception['message']
+    like(message, ':s get_integer\(\) not implemented', 'get_integer not implemented')
+    .return ()
+.end
+
+.sub 'test_get_number'
+    .local pmc capt
+
+    capt = new ['Capture']
+    push_eh test_get_number_catch
     $N0 = capt
-CODE
-/get_number\(\) not implemented in class 'Capture'/
-OUT
-
-pir_output_is( <<'CODE', <<'OUTPUT', '*_keyed_int delegation' );
-.sub main :main
-    $P99 = subclass 'Capture', 'Match'
+
+    nok(1, 'get_number not implemented')
+    .return ()
+
+  test_get_number_catch:
+    .local pmc exception
+    .local string message
+    .get_results (exception)
+
+    message = exception['message']
+    like(message, ':s get_number\(\) not implemented', 'get_number not implemented')
+    .return ()
+.end
+
+
+.sub 'test_keyed_int_delegation'
+    $P99 = subclass ['Capture'], ['Match']
     $P1 = new ['Match']
     $P1[1] = 1
     $I1 = elements $P1
-    print $I1
-    print "\n"
+    is($I1, 2, 'elements - delegated to parent class')
 
-    $P99 = subclass 'Match', 'Exp'
+    $P99 = subclass ['Match'], ['Exp']
     $P2 = new ['Exp']
     $P2[1] = 1
     $I2 = elements $P2
-    print $I2
-    print "\n"
-
+    is($I2, 2, 'elements - delegated twice')
 .end
-CODE
-2
-2
-OUTPUT
-
-pir_output_is( <<'CODE', <<'OUTPUT', 'list method delegation' );
-.sub main :main
-    $P0 = subclass 'Capture', 'Match'
+
+.sub 'test_list_delegation'
+    $P0 = subclass ['Capture'], ['Match2']
     addattribute $P0, '$.abc'
     addattribute $P0, '$.xyz'
-    $P1 = new ['Match']
+    $P1 = new ['Match2']
     $P1[1] = 1
 
     $P2 = new ['String']
@@ -307,16 +285,11 @@
     $P2 = $P1.'list'()
     $P2 = 0
     $I0 = elements $P2
-    print $I0
-    print "\n"
+    is($I0, 0, 'list method delegation')
 .end
-CODE
-0
-OUTPUT
 
 # Local Variables:
-#   mode: cperl
-#   cperl-indent-level: 4
+#   mode: pir
 #   fill-column: 100
 # End:
-# vim: expandtab shiftwidth=4:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/tt761_keys_revamp/t/pmc/exceptionhandler.t
==============================================================================
--- branches/tt761_keys_revamp/t/pmc/exceptionhandler.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/pmc/exceptionhandler.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -60,7 +60,6 @@
     eh = 0
     c()
   error_handler_one:
-    .local pmc e, c
     .get_results (e)
     ok(1, 'Min and Max severity for exception handlers')
     c = e['resume']
@@ -93,14 +92,12 @@
     goto subclass_handler
 
   typed_handler_one:
-    .local pmc e, c
     .get_results (e)
     ok(1, 'Exception Handler type checks work')
     c = e['resume']
     eh = 0
     c()
   typed_handler_two:
-    .local pmc e, c
     .get_results (e)
     ok(0, 'Exception Handler type checks work')
     c = e['resume']

Modified: branches/tt761_keys_revamp/t/pmc/namespace.t
==============================================================================
--- branches/tt761_keys_revamp/t/pmc/namespace.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/pmc/namespace.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -1451,7 +1451,6 @@
 
     key      = create_nested_key( 'Child' )
 
-    .local pmc grandchild_ns
     grandchild_ns = child_ns.'find_namespace'( key )
     if_null grandchild_ns, CHECK_SIBLING
     print "Grandchild still exists\\n"
@@ -1561,7 +1560,6 @@
     child_ns = parent_ns.'find_namespace'( 'Child' )
     child_ns.'del_sub'( 'dummy' )
 
-    .local pmc my_sub
     my_sub = get_global [ 'Parent'; 'Child' ], 'dummy'
     if_null my_sub, CHILD_NO_DUMMY
     print "Child did not delete dummy\\n"

Modified: branches/tt761_keys_revamp/t/pmc/nci.t
==============================================================================
--- branches/tt761_keys_revamp/t/pmc/nci.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/pmc/nci.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -2525,8 +2525,7 @@
     i = new ['Integer']
     i = 2
     j = mult( 21, i )       # call signature is PI
-    print j
-    print "\n"
+    say j
 .end
 CODE
 42

Modified: branches/tt761_keys_revamp/t/steps/auto_icu-01.t
==============================================================================
--- branches/tt761_keys_revamp/t/steps/auto_icu-01.t	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/t/steps/auto_icu-01.t	Sat Jul  4 21:38:28 2009	(r39884)
@@ -403,13 +403,27 @@
        \$stderr,
    );
 
-   like($stdout, qr/Adding -I $icuheaders to ccflags for icu headers/,
-       "Got expected verbose output");
+   if ($icuheaders =~ /\s/) {
+       like($stdout, qr/Adding -I \"\Q$icuheaders\E\" to ccflags for icu headers/,
+           "Got expected verbose output");
+   }
+   else {
+       like($stdout, qr/Adding -I \Q$icuheaders\E to ccflags for icu headers/,
+           "Got expected verbose output");
+   }
+}
+if ($icuheaders =~ /\s/) {
+    like($conf->data->get( 'ccflags' ),
+        qr/-I \"\Q$icuheaders\E\"/,
+        "ccflags augmented as expected"
+    );
+}
+else {
+    like($conf->data->get( 'ccflags' ),
+        qr/-I \Q$icuheaders\E/,
+        "ccflags augmented as expected"
+    );
 }
-like($conf->data->get( 'ccflags'),
-    qr/-I $icuheaders/,
-    "ccflags augmented as expected"
-);
 $conf->data->set( ccflags => $status ); # re-set for next test
 
 {
@@ -430,10 +444,19 @@
 
    ok(! $stdout, "No verbose output, as expected");
 }
-like($conf->data->get( 'ccflags'),
-    qr/-I $icuheaders/,
-    "ccflags augmented as expected"
-);
+
+if ($icuheaders =~ /\s/) {
+    like($conf->data->get( 'ccflags'),
+        qr/-I \"\Q$icuheaders\E\"/,
+        "ccflags augmented as expected"
+    );
+}
+else {
+    like($conf->data->get( 'ccflags'),
+        qr/-I \Q$icuheaders\E/,
+        "ccflags augmented as expected"
+    );
+}
 $conf->data->set( ccflags => $status ); # re-set for next test
 
 ########## _set_no_configure_with_icu() ##########
@@ -652,7 +675,7 @@
                 "Got expected verbose output re --ldflags");
             like($stdout, qr/icushared:  captured/s,
                 "Got expected verbose output re icushared");
-            like($stdout, qr/For icushared, found $icushared and $without/s,
+            like($stdout, qr/For icushared, found \Q$icushared\E and $without/s,
                 "Got expected verbose output re icushared");
             like($stdout, qr/Trying $icuconfig with '--prefix'/s,
                 "Got expected verbose output re --prefix");

Modified: branches/tt761_keys_revamp/tools/build/nativecall.pl
==============================================================================
--- branches/tt761_keys_revamp/tools/build/nativecall.pl	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/tools/build/nativecall.pl	Sat Jul  4 21:38:28 2009	(r39884)
@@ -96,7 +96,7 @@
 
 
 my $temp_cnt = 0;
-my @put_pointer;
+my (@put_pointer, @put_pointer_nci_too, @nci_defs);
 my %seen;
 
 while (<>) {
@@ -141,18 +141,38 @@
 
     my $ret_sig = $sig_table{$ret};
 
-    print_function(
-        $sig, $ret,
-        $args, [@arg],
-        $ret_sig->{as_return}, $ret_sig->{return_type_decl},
-        $ret_sig->{func_call_assign}, $ret_sig->{other_decl},
-        $ret_sig->{ret_assign}, \@temps,
-        \@extra_preamble, \@extra_postamble,
-        \@put_pointer
-    );
+    if ($args =~ /[234]/) {
+        push @nci_defs, create_function(
+            $sig, $ret,
+            $args, [@arg],
+            $ret_sig->{as_return}, $ret_sig->{return_type_decl},
+            $ret_sig->{func_call_assign}, $ret_sig->{other_decl},
+            $ret_sig->{ret_assign}, \@temps,
+            \@extra_preamble, \@extra_postamble,
+            \@put_pointer_nci_too,
+        );
+    }
+    else {
+        print {$NCI} create_function(
+            $sig, $ret,
+            $args, [@arg],
+            $ret_sig->{as_return}, $ret_sig->{return_type_decl},
+            $ret_sig->{func_call_assign}, $ret_sig->{other_decl},
+            $ret_sig->{ret_assign}, \@temps,
+            \@extra_preamble, \@extra_postamble,
+            \@put_pointer,
+        );
+    }
 }
 
-print_tail( \@put_pointer );
+print {$NCI} <<"END_FUNCS";
+
+#endif
+ at nci_defs
+
+END_FUNCS
+
+print_tail( \@put_pointer, \@put_pointer_nci_too );
 
 # append the C code coda
 print $NCI <<"EOC";
@@ -328,6 +348,7 @@
     }
 }
 
+#ifndef CAN_BUILD_CALL_FRAMES
 /* All our static functions that call in various ways. Yes, terribly
    hackish, but that is just fine */
 
@@ -404,7 +425,7 @@
     return;
 }
 
-sub print_function {
+sub create_function {
     my (
         $sig,          $return,        $params,             $args,
         $ret_type,     $ret_type_decl, $return_assign,      $other_decl,
@@ -412,6 +433,8 @@
         $put_pointer_ref,
     ) = @_;
 
+    my $func = '';
+
     $other_decl ||= "";
 
     $other_decl .= join( "\n    ", @{$temps_ref} );
@@ -429,7 +452,7 @@
 
         my $call_params = join( ",", @$args );
 
-        print $NCI <<"HEADER";
+        $func = <<"HEADER";
 static void
 pcf_${return}_$fix_params(PARROT_INTERP, PMC *self)
 {
@@ -455,7 +478,7 @@
         # Things are more simple, when there are no params
         # call state var not needed if there are no params and a void return
         $call_state = '' if 'v' eq $return;
-        print $NCI <<"HEADER";
+        $func       = <<"HEADER";
 static void
 pcf_${return}_(PARROT_INTERP, PMC *self)
 {
@@ -488,13 +511,15 @@
 PUT_POINTER
 
     #        qq|        parrot_hash_put( interp, known_frames, const_cast("$key"), $value );|;
-    return;
+
+    return $func;
 }
 
 sub print_tail {
-    my ($put_pointer_ref) = @_;
+    my ($put_pointer_ref, $put_pointer_nci_ref) = @_;
 
-    my $put_pointer = join( "\n", @{$put_pointer_ref} );
+    my $put_pointer     = join( "\n", @{$put_pointer_ref} );
+    my $put_pointer_nci = join( "\n", @{$put_pointer_nci_ref} );
     print $NCI <<"TAIL";
 
 
@@ -511,7 +536,6 @@
 {
     char       *c;
     STRING     *ns, *message;
-    STRING     *jit_key_name;
     PMC        *b;
     PMC        *iglobals;
     PMC        *temp_pmc;
@@ -522,8 +546,12 @@
     /* And in here is the platform-independent way. Which is to say
        "here there be hacks" */
     signature_len = Parrot_str_byte_length(interp, signature);
+
+#ifndef CAN_BUILD_CALL_FRAMES
     if (0 == signature_len)
        return F2DPTR(pcf_v_);
+#endif
+
     /* remove deprecated void argument 'v' character */
     if (2 == signature_len && 'v' == Parrot_str_indexed(interp, signature, 1)) {
        Parrot_warn(interp, PARROT_WARNINGS_ALL_FLAG, "function signature argument character 'v' ignored");
@@ -542,17 +570,11 @@
         HashPointer = pmc_new(interp, enum_class_Hash);
         VTABLE_set_pmc_keyed_int(interp, iglobals, IGLOBALS_NCI_FUNCS,
                 HashPointer);
-
-$put_pointer
-
     }
 
 #if defined(CAN_BUILD_CALL_FRAMES)
     /* Try if JIT code can build that signature. If yes, we are done */
-
-    jit_key_name = CONST_STRING(interp, "_XJIT_");
-    jit_key_name = Parrot_str_concat(interp, jit_key_name, signature, 0);
-    b            = VTABLE_get_pmc_keyed_str(interp, HashPointer, jit_key_name);
+    b            = VTABLE_get_pmc_keyed_str(interp, HashPointer, signature);
 
     PARROT_ASSERT(PMC_IS_NULL(b) || b->vtable);
 
@@ -577,7 +599,7 @@
             SETATTR_ManagedStruct_custom_clone_func(interp, temp_pmc, Parrot_jit_clone_buffer);
             SETATTR_ManagedStruct_custom_clone_priv(interp, temp_pmc, priv);
 #endif /* PARROT_HAS_EXEC_PROTECT */
-            VTABLE_set_pmc_keyed_str(interp, HashPointer, jit_key_name, temp_pmc);
+            VTABLE_set_pmc_keyed_str(interp, HashPointer, signature, temp_pmc);
             return result;
         }
     }
@@ -586,6 +608,15 @@
 
     b = VTABLE_get_pmc_keyed_str(interp, HashPointer, signature);
 
+    if (PMC_IS_NULL(b)) {
+$put_pointer_nci
+#ifndef CAN_BUILD_CALL_FRAMES
+$put_pointer
+#endif
+
+        b = VTABLE_get_pmc_keyed_str(interp, HashPointer, signature);
+    }
+
     PARROT_ASSERT(PMC_IS_NULL(b) || b->vtable);
 
     if ((!PMC_IS_NULL(b)) && b->vtable->base_type == enum_class_UnManagedStruct)

Modified: branches/tt761_keys_revamp/tools/build/ops2c.pl
==============================================================================
--- branches/tt761_keys_revamp/tools/build/ops2c.pl	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/tools/build/ops2c.pl	Sat Jul  4 21:38:28 2009	(r39884)
@@ -155,8 +155,6 @@
 
 =item C<Parrot::OpTrans::CGoto>
 
-=item C<Parrot::OpTrans::Compiled>
-
 =item C<Parrot::OpTrans::CGP>
 
 =item C<Parrot::OpTrans::CSwitch>

Modified: branches/tt761_keys_revamp/tools/dev/branch_status.pl
==============================================================================
--- branches/tt761_keys_revamp/tools/dev/branch_status.pl	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/tools/dev/branch_status.pl	Sat Jul  4 21:38:28 2009	(r39884)
@@ -53,11 +53,8 @@
         $newest->atts->{revision};
     my $created_date = $oldest->first_child('date')->xml_text;
     my $updated_date = $newest->first_child('date')->xml_text;
-    my $author_txt;
-    if (scalar keys %authors == 1) {
-         $author_txt = $creator;
-    }
-    else {
+    my $author_txt = '';
+    if (scalar keys %authors != 1) {
         my @counts;
         foreach my $author (sort {$authors{$b} <=> $authors{$a}} keys %authors) {
             push @counts, "$author [$authors{$author}]";
@@ -81,8 +78,11 @@
                   $revisions,
 '|       creator: {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<} |',
                   $creator,
+($author_txt ne '') ?
+(
 '|       authors: {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<} |',
                   $author_txt,
+): (),
 '|    created on: {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<} |',
                   $created_date,
 '|    updated on: {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<} |',

Modified: branches/tt761_keys_revamp/tools/dev/fetch_languages.pl
==============================================================================
--- branches/tt761_keys_revamp/tools/dev/fetch_languages.pl	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/tools/dev/fetch_languages.pl	Sat Jul  4 21:38:28 2009	(r39884)
@@ -9,7 +9,8 @@
 
     perl fetch_languages.pl
 
-    perl fetch_languages.pl --update
+    perl fetch_languages.pl [--update] [--lang=<hll>]
+
 
 =head1 DESCRIPTION
 
@@ -19,6 +20,8 @@
 
 2009-03-14 Salvaged from https:/svn.parrot.org/parrot/trunk/config/gen/makefiles/languages.in at 37396.
 
+2009-06-28 --lang=<hll> option added by s1n++.
+
 =cut
 
 use strict;
@@ -29,8 +32,8 @@
 use Pod::Usage;
 use Cwd;
 
-my ( $update_flag, $checkout_flag ) = ( 0, 1 );
-GetOptions( 'update' => \$update_flag ) or pod2usage();
+my ( $update_flag, $checkout_flag, $lang_flag ) = ( 0, 1, undef );
+GetOptions( 'lang=s' => \$lang_flag, 'update' => \$update_flag ) or pod2usage();
 
 my $languages_dir = 'languages';
 mkdir $languages_dir;
@@ -304,6 +307,7 @@
 );
 
 foreach (@hlls) {
+    next if $lang_flag && $_->{name} ne $lang_flag;
     if ($checkout_flag && ! -d $_->{name}) {
         my @cmd = ( @{ $checkout_cmd{ $_->{scm} } }, $_->{repository}, $_->{name} );
         my $dir = getcwd();

Modified: branches/tt761_keys_revamp/tools/dev/parrot.supp
==============================================================================
--- branches/tt761_keys_revamp/tools/dev/parrot.supp	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/tools/dev/parrot.supp	Sat Jul  4 21:38:28 2009	(r39884)
@@ -85,7 +85,8 @@
    fun:trace_active_PMCs
 }
 
-# strip out the system library nonsense
+# strip out GNU/Linux system library nonsense
+# Start with the linker stuff
 {
    gnuld-index-cond
    Memcheck:Cond
@@ -99,6 +100,18 @@
    obj:/lib*/ld-*.so
 }
 {
+   gnuld-strlen-value8
+   Memcheck:Value8
+   fun:strlen
+   obj:/lib*/ld-*.so
+}
+{
+   gnuld-strcmp-value8
+   Memcheck:Value8
+   fun:strcmp
+   obj:/lib*/ld-*.so
+}
+{
    gnuld-libc-memalign-cond
    Memcheck:Cond
    fun:__libc_memalign
@@ -321,26 +334,40 @@
    obj:/lib*/ld-*.so
 }
 {
-   gnuld-dl-fini-cond
+   gnuld-dl-sort-fini-value8
+   Memcheck:Value8
+   fun:_dl_sort_fini
+   obj:/lib*/ld-*.so
+}
+{
+   gnuld-dl-sort-fini-cond
    Memcheck:Cond
-   fun:_dl_fini
+   fun:_dl_sort_fini
    obj:/lib*/ld-*.so
 }
+# C Runtime / Linker stub stuff
 {
-   gnuld-dl-fini-value8
-   Memcheck:Value8
+   gnucrt-dl-fini-cond
+   Memcheck:Cond
    fun:_dl_fini
-   obj:/lib*/ld-*.so
 }
 {
-   gnuld-dl-sort-fini-value8
+   gnucrt-dl-fini-value8
    Memcheck:Value8
-   fun:_dl_sort_fini
-   obj:/lib*/ld-*.so
+   fun:_dl_fini
 }
+# LibC stuff
 {
-   gnuld-dl-sort-fini-cond
+   gnuc-vgnu-freeres-cond
    Memcheck:Cond
-   fun:_dl_sort_fini
-   obj:/lib*/ld-*.so
+   obj:/lib*/libc-*.so
+   obj:/lib*/libc-*.so
+   fun:_vgnU_freeres
+}
+{
+   gnuc-vgnu-freeres-value8
+   Memcheck:Value8
+   obj:/lib*/libc-*.so
+   obj:/lib*/libc-*.so
+   fun:_vgnU_freeres
 }

Modified: branches/tt761_keys_revamp/tools/dev/pbc_to_exe.pir
==============================================================================
--- branches/tt761_keys_revamp/tools/dev/pbc_to_exe.pir	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/tools/dev/pbc_to_exe.pir	Sat Jul  4 21:38:28 2009	(r39884)
@@ -20,33 +20,36 @@
 
 .sub 'main' :main
     .param pmc    argv
+
+    load_bytecode 'config.pbc'
+
     .local string infile
     .local string cfile
     .local string objfile
     .local string exefile
-    .local string out
-    .local int    closeresult
-
-    .local string gcc
-    .local int    is_gcc
-    load_bytecode 'config.pbc'
-    $P0 = '_config'()
-    gcc    = $P0['gccversion']
-    $I0    = length gcc
-    is_gcc = $I0 > 0
 
     (infile, cfile, objfile, exefile) = 'handle_args'(argv)
     unless infile > '' goto err_infile
 
+
+    .local string code_type
+    code_type = 'determine_code_type'()
+
     .local string codestring
-    unless is_gcc goto code_for_non_gcc
+    if code_type == 'gcc'  goto code_for_gcc
+    if code_type == 'msvc' goto code_for_msvc
+    goto code_for_default
   code_for_gcc:
     codestring = 'generate_code_gcc'(infile)
     goto code_end
-  code_for_non_gcc:
+  code_for_msvc:
+    codestring = 'generate_code_msvc'(infile)
+    goto code_end
+  code_for_default:
     codestring = 'generate_code'(infile)
   code_end:
 
+
   open_outfile:
     .local pmc outfh
     outfh = open cfile, 'w'
@@ -54,6 +57,7 @@
     print outfh, <<'HEADER'
 #include "parrot/parrot.h"
 #include "parrot/embed.h"
+const void * get_program_code(void);
 HEADER
 
     print outfh, codestring
@@ -63,11 +67,15 @@
         {
             PackFile     *pf;
             Parrot_Interp interp;
+            const unsigned char *program_code_addr;
+
+            program_code_addr = (const unsigned char *)get_program_code();
+            if (!program_code_addr)
+                return 1;
 
             Parrot_set_config_hash();
 
             interp = Parrot_new( NULL );
-
             if (!interp)
                 return 1;
 
@@ -76,9 +84,11 @@
             Parrot_set_flag(interp, PARROT_DESTROY_FLAG);
 
             pf = PackFile_new(interp, 0);
+            if (!pf)
+                return 1;
 
             if (!PackFile_unpack(interp, pf,
-                    (const opcode_t *)program_code, bytecode_size))
+                    (const opcode_t *)program_code_addr, bytecode_size))
                 return 1;
 
             do_sub_pragmas(interp, pf->cur_cs, PBC_PBC, NULL);
@@ -92,13 +102,23 @@
         }
 MAIN
 
+
     # The close opcode does not return a result code,
     # use the method instead.
+    .local int    closeresult
     closeresult = outfh.'close'()
     unless closeresult == 0 goto err_close
 
+
+    .local string extra_obj
+    extra_obj = ''
+    if code_type != 'msvc' goto no_extra
+    extra_obj  = 'replace_pbc_extension'(infile, '.RES')
+  no_extra:
+
+
     'compile_file'(cfile, objfile)
-    'link_file'(objfile, exefile)
+    'link_file'(objfile, exefile, extra_obj)
     .return ()
 
   err_infile:
@@ -113,6 +133,11 @@
 .sub 'handle_args'
     .param pmc argv
 
+    .local string obj, exe
+    $P0    = '_config'()
+    obj    = $P0['o']
+    exe    = $P0['exe']
+
     .local pmc args
     args   = argv
 
@@ -133,49 +158,23 @@
     .return ()
 
   proper_install:
-    .local string cfile, objfile, obj, exefile, exe
+    .local string cfile, objfile, exefile
 
-    $P0    = '_config'()
-    obj    = $P0['o']
-    exe    = $P0['exe']
+    cfile   = 'replace_pbc_extension'(infile, '.c')
+    objfile = 'replace_pbc_extension'(infile, obj)
+    $S0     = 'replace_pbc_extension'(infile, exe)
+    exefile = concat 'installable_', $S0
 
-    .local int infile_len
-    infile_len  = length infile
-    infile_len -= 3
-
-    cfile       = substr infile, 0, infile_len
-    cfile      .= 'c'
-
-    dec infile_len
-    objfile     = substr infile, 0, infile_len
-    exefile     = 'installable_'
-    exefile    .= objfile
-    exefile    .= exe
-    objfile    .= obj
     .return(infile, cfile, objfile, exefile)
 
   proper_args:
-    .local string infile, cfile, objfile, obj, exefile, exe
-
-    $P0    = '_config'()
-    obj    = $P0['o']
-    exe    = $P0['exe']
 
     $P0    = shift args
     infile = shift args
 
-    .local int infile_len
-    infile_len  = length infile
-    infile_len -= 3
-
-    cfile       = substr infile, 0, infile_len
-    cfile      .= 'c'
-
-    dec infile_len
-    objfile     = substr infile, 0, infile_len
-    objfile    .= obj
-    exefile     = substr infile, 0, infile_len
-    exefile    .= exe
+    cfile   = 'replace_pbc_extension'(infile, '.c')
+    objfile = 'replace_pbc_extension'(infile, obj)
+    exefile = 'replace_pbc_extension'(infile, exe)
 
     # substitute .c for .pbc
     # remove .c for executable
@@ -184,6 +183,31 @@
     .return(infile, cfile, objfile, exefile)
 .end
 
+.sub 'determine_code_type'
+    .local pmc    config
+    .local string gcc_ver
+    .local string cc
+    .local string os_name
+
+    config = '_config'()
+
+    gcc_ver = config['gccversion']
+    unless gcc_ver > '' goto not_gcc
+    .return ('gcc')
+  not_gcc:
+
+    cc      = config['cc']
+    os_name = config['osname']
+
+    if os_name != 'MSWin32' goto not_msvc
+    if cc      != 'cl'      goto not_msvc
+    .return ('msvc')
+  not_msvc:
+
+    .return ('default')
+.end
+
+
 .sub 'generate_code'
     .param string infile
     .local pmc ifh
@@ -227,12 +251,20 @@
     $S0 = size
     codestring .= $S0
     codestring .= ";\n"
+    codestring .= <<'END_OF_FUNCTION'
+        const void * get_program_code(void)
+        {
+            return program_code;
+        }
+END_OF_FUNCTION
+
     .return (codestring)
 
   err_infile:
     die "cannot open infile"
 .end
 
+
 # The PBC will be represented as a C string, so this sub builds a table
 # of the C representation of each ASCII character, for lookup by ordinal value.
 .sub 'generate_encoding_table'
@@ -312,12 +344,161 @@
     $S0 = size
     codestring .= $S0
     codestring .= ";\n"
+
+    codestring .= <<'END_OF_FUNCTION'
+        const void * get_program_code(void)
+        {
+            return program_code;
+        }
+END_OF_FUNCTION
+
     .return (codestring)
 
   err_infile:
     die "cannot open infile"
 .end
 
+
+# Transforms the .pbc path into one with a different extension.
+# Passing '' means no extension.
+# Extensions without leading dots will have a dot pre-pended.
+.sub 'replace_pbc_extension'
+    .param string pbc_path
+    .param string new_extension
+
+    $S0 = substr pbc_path, -4
+    downcase $S0
+    if $S0 != '.pbc' goto err_pbc_path_not_pbc
+    .local string base_path
+     base_path = substr pbc_path, 0
+     substr base_path, -4, 4, ''
+
+    .local string new_path
+    new_path = substr base_path, 0
+
+    unless new_extension > '' goto ext_null
+
+    $S1 = substr new_extension, 0, 1
+    if $S1 == '.' goto has_dot
+    new_path .= '.'
+
+  has_dot:
+    new_path .= new_extension
+
+  ext_null:
+    .return (new_path)
+
+  err_pbc_path_not_pbc:
+    die "input pbc file name does not end in '.pbc'"
+.end
+
+
+# In addition to generating the code for inclusion in the C file,
+# this sub creates supplemental .rc and .RES files.
+.sub 'generate_code_msvc'
+    .param string pbc_path
+
+    .local string rc_path
+    .local string res_path
+    rc_path  = 'replace_pbc_extension'(pbc_path, '.rc' )
+    res_path = 'replace_pbc_extension'(pbc_path, '.res')
+
+    # The exact numbers are not relevant;
+    # they are used to identify the resource within the final executable.
+    .local string rc_constant_defines
+    rc_constant_defines = <<'END_OF_DEFINES'
+#define RESOURCE_NAME_ID_WHOLE_PBC 333
+#define RESOURCE_TYPE_ID_WHOLE_PBC 444
+END_OF_DEFINES
+
+
+    .local string rc_contents
+    rc_contents  = ''
+    rc_contents .= rc_constant_defines
+    rc_contents .= 'RESOURCE_NAME_ID_WHOLE_PBC RESOURCE_TYPE_ID_WHOLE_PBC '
+    rc_contents .= pbc_path
+    rc_contents .= "\n"
+
+    .local pmc rc_fh
+    rc_fh = open rc_path, 'w'
+    unless rc_fh goto err_rc_open
+    print rc_fh, rc_contents
+    $I0 = rc_fh.'close'()
+    unless $I0 == 0 goto err_rc_close
+
+
+    .local int pbc_size
+    $P1 = new ['OS']
+    $P2 = $P1.'stat'(pbc_path)
+    pbc_size = $P2[7]
+
+
+    .local string codestring
+    codestring  = ''
+    codestring .= '#include <windows.h>'
+    codestring .= "\n"
+    codestring .= rc_constant_defines
+    codestring .= "const unsigned int bytecode_size = "
+    $S0 = pbc_size
+    codestring .= $S0
+    codestring .= ";\n"
+
+    codestring .= <<'END_OF_FUNCTION'
+        const void * get_program_code(void)
+        {
+            HRSRC   hResource;
+            DWORD   size;
+            HGLOBAL hPBC;
+            LPVOID  actual_pointer_to_pbc_in_memory;
+
+            hResource = FindResource(
+                NULL,
+                MAKEINTRESOURCE(RESOURCE_NAME_ID_WHOLE_PBC),
+                MAKEINTRESOURCE(RESOURCE_TYPE_ID_WHOLE_PBC)
+            );
+            if (!hResource)
+                return NULL;
+
+            size = SizeofResource( NULL, hResource );
+            if (size != bytecode_size)
+                return NULL;
+
+            hPBC = LoadResource( NULL, hResource );
+            if (!hPBC)
+                return NULL;
+
+            actual_pointer_to_pbc_in_memory = LockResource( hPBC );
+            if (!actual_pointer_to_pbc_in_memory)
+                return NULL;
+
+            return actual_pointer_to_pbc_in_memory;
+        }
+END_OF_FUNCTION
+
+    .local string rc_cmd
+    rc_cmd  = 'rc '
+    rc_cmd .= rc_path
+
+    say rc_cmd
+    .local int status
+    status = spawnw rc_cmd
+    unless status goto rc_ok
+
+    die "RC command failed"
+  rc_ok:
+
+    .return (codestring)
+
+  err_h_open:
+    die "cannot open .h file"
+  err_rc_open:
+    die "cannot open .rc file"
+  err_h_close:
+    die "cannot close .h file"
+  err_rc_close:
+    die "cannot close .rc file"
+.end
+
 # util functions
 .sub 'compile_file'
     .param string cfile
@@ -371,6 +552,7 @@
 .sub 'link_file'
     .param string objfile
     .param string exefile
+    .param string extra_obj
     .param int install :optional
 
     $P0 = '_config'()
@@ -415,6 +597,12 @@
     link .= pathquote
     link .= objfile
     link .= pathquote
+    unless extra_obj > '' goto skip_extra_obj
+    link .= ' '
+    link .= pathquote
+    link .= extra_obj
+    link .= pathquote
+  skip_extra_obj:
     link .= ' '
     link .= config
     link .= ' '

Modified: branches/tt761_keys_revamp/tools/util/release.json
==============================================================================
--- branches/tt761_keys_revamp/tools/util/release.json	Sat Jul  4 18:44:48 2009	(r39883)
+++ branches/tt761_keys_revamp/tools/util/release.json	Sat Jul  4 21:38:28 2009	(r39884)
@@ -1,9 +1,9 @@
 {
-    "release.version"  : "1.2.0",
-    "release.name"     : "Bird Brain",
+    "release.version"  : "1.3.0",
+    "release.name"     : "Andean Swift",
     "release.day"      : "Tuesday",
-    "release.date"     : "19 May 2009",
-    "release.nextdate" : "16 June 2009",
+    "release.date"     : "16 June 2009",
+    "release.nextdate" : "21 July 2009",
 
     "web.root"         : "http://parrot.org/",
     "web.source"       : "download",
@@ -11,13 +11,13 @@
     "web.repository"   : "https://svn.parrot.org/parrot/trunk/",
 
     "bugday.day"       : "Saturday",
-    "bugday.date"      : "13 June 2009",
+    "bugday.date"      : "18 July 2009",
 
     "wiki.root"        : "https://trac.parrot.org/parrot/wiki/",
-    "wiki.bugday"      : "bug_day_2009_06_13",
+    "wiki.bugday"      : "bug_day_2009_07_18",
 
     "cpan.search"      : "http://search.cpan.org/dist/parrot",
-    "ftp.path"         : "ftp://ftp.parrot.org/pub/parrot/releases/devel/1.2.0/",
+    "ftp.path"         : "ftp://ftp.parrot.org/pub/parrot/releases/devel/1.3.0/",
     "subversion.root"  : "http://subversion.tigris.org/",
     "svk.root"         : "http://svk.bestpractical.com/"
 }


More information about the parrot-commits mailing list