[svn:parrot] r38132 - in branches/headercleanup: . compilers/imcc compilers/json compilers/ncigen/src compilers/nqp/bootstrap compilers/nqp/src compilers/pct compilers/pct/src compilers/pct/src/PAST compilers/pct/src/PCT compilers/pct/src/POST compilers/pge compilers/pge/PGE compilers/pirc/src compilers/tge compilers/tge/TGE config/auto config/auto/format config/gen config/gen/call_list config/gen/config_pm config/gen/makefiles config/gen/platform config/gen/platform/generic config/gen/platform/openbsd docs docs/book docs/book/draft docs/book/figs docs/dev docs/pdds docs/pdds/draft editor examples/benchmarks examples/japh examples/languages/abc examples/languages/squaak examples/namespace examples/nci examples/opengl examples/pasm examples/sdl examples/sdl/lcd examples/sdl/minesweeper examples/sdl/tetris examples/shootout examples/streams examples/subs examples/tcl examples/tge/branch examples/tge/branch/lib examples/tutorial ext/Parrot-Embed/t ext/SQLite3 include/pa rrot lib/Parrot lib/Parrot/Pmc2c lib/Parrot/Pmc2c/PMC ports/cpan ports/cygwin ports/debian runtime/parrot/include runtime/parrot/library runtime/parrot/library/Config runtime/parrot/library/Data runtime/parrot/library/Data/Dumper runtime/parrot/library/Getopt runtime/parrot/library/Math runtime/parrot/library/NCI runtime/parrot/library/PGE runtime/parrot/library/Stream runtime/parrot/library/Tcl runtime/parrot/library/Test runtime/parrot/library/Test/Builder runtime/parrot/library/YAML runtime/parrot/library/YAML/Dumper src src/call src/dynpmc src/gc src/interp src/io src/jit/i386 src/jit/ppc src/pmc src/string src/string/charset src/string/encoding t/codingstd t/compilers/tge t/dynpmc t/op t/perl/testlib t/pmc t/src t/tools/ops2pm/samples tools/build tools/dev tools/util

chromatic at svn.parrot.org chromatic at svn.parrot.org
Wed Apr 15 19:17:24 UTC 2009


Author: chromatic
Date: Wed Apr 15 19:17:06 2009
New Revision: 38132
URL: https://trac.parrot.org/parrot/changeset/38132

Log:
Brought the headercleanup branch up to date with trunk at r37950.

Added:
   branches/headercleanup/docs/book/appa_glossary.pod
      - copied unchanged from r38131, trunk/docs/book/appa_glossary.pod
   branches/headercleanup/docs/book/appb_patch_submission.pod
      - copied unchanged from r38131, trunk/docs/book/appb_patch_submission.pod
   branches/headercleanup/docs/book/appc_command_line_options.pod
      - copied unchanged from r38131, trunk/docs/book/appc_command_line_options.pod
   branches/headercleanup/docs/book/appd_build_options.pod
      - copied unchanged from r38131, trunk/docs/book/appd_build_options.pod
   branches/headercleanup/docs/book/appe_source_code.pod
      - copied unchanged from r38131, trunk/docs/book/appe_source_code.pod
   branches/headercleanup/docs/book/ch01_introduction.pod
      - copied unchanged from r38131, trunk/docs/book/ch01_introduction.pod
   branches/headercleanup/docs/book/ch03_pir.pod
      - copied unchanged from r38131, trunk/docs/book/ch03_pir.pod
   branches/headercleanup/docs/book/ch04_compiler_tools.pod
      - copied unchanged from r38131, trunk/docs/book/ch04_compiler_tools.pod
   branches/headercleanup/docs/book/ch05_pge.pod
      - copied unchanged from r38131, trunk/docs/book/ch05_pge.pod
   branches/headercleanup/docs/book/ch06_nqp.pod
      - copied unchanged from r38131, trunk/docs/book/ch06_nqp.pod
   branches/headercleanup/docs/book/ch07_dynpmcs.pod
      - copied unchanged from r38131, trunk/docs/book/ch07_dynpmcs.pod
   branches/headercleanup/docs/book/ch08_dynops.pod
      - copied unchanged from r38131, trunk/docs/book/ch08_dynops.pod
   branches/headercleanup/docs/book/ch09_pasm.pod
      - copied unchanged from r38131, trunk/docs/book/ch09_pasm.pod
   branches/headercleanup/docs/book/ch10_opcode_reference.pod
      - copied unchanged from r38131, trunk/docs/book/ch10_opcode_reference.pod
   branches/headercleanup/docs/book/ch11_directive_reference.pod
      - copied unchanged from r38131, trunk/docs/book/ch11_directive_reference.pod
   branches/headercleanup/docs/book/ch12_operator_reference.pod
      - copied unchanged from r38131, trunk/docs/book/ch12_operator_reference.pod
   branches/headercleanup/docs/book/draft/
      - copied from r38131, trunk/docs/book/draft/
Replaced:
   branches/headercleanup/docs/book/draft/chXX_hlls.pod
      - copied unchanged from r38131, trunk/docs/book/draft/chXX_hlls.pod
   branches/headercleanup/docs/book/draft/chXX_library.pod
      - copied unchanged from r38131, trunk/docs/book/draft/chXX_library.pod
   branches/headercleanup/docs/book/draft/chXX_testing_and_debugging.pod
      - copied unchanged from r38131, trunk/docs/book/draft/chXX_testing_and_debugging.pod
Deleted:
   branches/headercleanup/docs/book/appX_patch_submission.pod
   branches/headercleanup/docs/book/ch01_overview.pod
   branches/headercleanup/docs/book/ch03_pir_basics.pod
   branches/headercleanup/docs/book/ch04_pir_subroutines.pod
   branches/headercleanup/docs/book/ch05_pasm.pod
   branches/headercleanup/docs/book/ch06_library.pod
   branches/headercleanup/docs/book/ch07_testing_and_debugging.pod
   branches/headercleanup/docs/book/ch08_architecture.pod
   branches/headercleanup/docs/book/ch09_pct.pod
   branches/headercleanup/docs/book/ch10_hlls.pod
   branches/headercleanup/docs/book/ch11_pmcs.pod
   branches/headercleanup/docs/book/ch12_opcodes.pod
   branches/headercleanup/docs/book/ch13_reference.pod
   branches/headercleanup/docs/book/figs/
   branches/headercleanup/examples/benchmarks/shared_ref.pasm
   branches/headercleanup/examples/benchmarks/shared_ref.pl
   branches/headercleanup/lib/Parrot/Pmc2c/PMC/Ref.pm
   branches/headercleanup/lib/Parrot/Pmc2c/PMC/SharedRef.pm
   branches/headercleanup/src/pmc/ref.pmc
   branches/headercleanup/src/pmc/sharedref.pmc
   branches/headercleanup/t/pmc/ref.t
   branches/headercleanup/t/pmc/sharedref.t
Modified:
   branches/headercleanup/   (props changed)
   branches/headercleanup/DEPRECATED.pod
   branches/headercleanup/MANIFEST
   branches/headercleanup/MANIFEST.SKIP
   branches/headercleanup/NEWS
   branches/headercleanup/PBC_COMPAT
   branches/headercleanup/compilers/imcc/main.c
   branches/headercleanup/compilers/imcc/parser_util.c
   branches/headercleanup/compilers/json/JSON.pir
   branches/headercleanup/compilers/json/test.pir
   branches/headercleanup/compilers/ncigen/src/NCIGENAST.pir
   branches/headercleanup/compilers/ncigen/src/NCIPIR.pir
   branches/headercleanup/compilers/nqp/bootstrap/nqp.pir
   branches/headercleanup/compilers/nqp/src/builtins.pir
   branches/headercleanup/compilers/pct/PCT.pir
   branches/headercleanup/compilers/pct/src/PAST.pir
   branches/headercleanup/compilers/pct/src/PAST/Compiler.pir
   branches/headercleanup/compilers/pct/src/PAST/Node.pir
   branches/headercleanup/compilers/pct/src/PCT/HLLCompiler.pir
   branches/headercleanup/compilers/pct/src/PCT/Node.pir
   branches/headercleanup/compilers/pct/src/POST/Compiler.pir
   branches/headercleanup/compilers/pct/src/POST/Node.pir
   branches/headercleanup/compilers/pge/PGE.pir
   branches/headercleanup/compilers/pge/PGE/Exp.pir
   branches/headercleanup/compilers/pge/PGE/Match.pir
   branches/headercleanup/compilers/pge/PGE/P5Regex.pir
   branches/headercleanup/compilers/pge/PGE/Perl6Regex.pir
   branches/headercleanup/compilers/pge/PGE/Regex.pir
   branches/headercleanup/compilers/pge/demo.pir
   branches/headercleanup/compilers/pirc/src/bcgen.c
   branches/headercleanup/compilers/tge/TGE.pir
   branches/headercleanup/compilers/tge/TGE/Compiler.pir
   branches/headercleanup/compilers/tge/TGE/Grammar.pir
   branches/headercleanup/compilers/tge/TGE/Rule.pir
   branches/headercleanup/compilers/tge/TGE/Tree.pir
   branches/headercleanup/compilers/tge/tgc.pir
   branches/headercleanup/config/auto/format/intval_maxmin_c.in   (props changed)
   branches/headercleanup/config/auto/pmc.pm
   branches/headercleanup/config/gen/call_list/misc.in
   branches/headercleanup/config/gen/config_pm/config_lib_pasm.in
   branches/headercleanup/config/gen/makefiles/root.in
   branches/headercleanup/config/gen/opengl.pm
   branches/headercleanup/config/gen/platform/generic/itimer.c
   branches/headercleanup/config/gen/platform/generic/memexec.c
   branches/headercleanup/config/gen/platform/generic/stat.c
   branches/headercleanup/config/gen/platform/openbsd/memexec.c
   branches/headercleanup/config/gen/platform/platform_interface.h
   branches/headercleanup/docs/book/README
   branches/headercleanup/docs/book/ch02_getting_started.pod
   branches/headercleanup/docs/dev/c_functions.pod   (props changed)
   branches/headercleanup/docs/pdds/draft/pdd08_keys.pod
   branches/headercleanup/docs/pdds/draft/pdd16_native_call.pod
   branches/headercleanup/docs/pdds/pdd07_codingstd.pod
   branches/headercleanup/docs/pmc.pod
   branches/headercleanup/editor/pir-mode.el
   branches/headercleanup/editor/skeleton.pir
   branches/headercleanup/examples/benchmarks/addit.pasm
   branches/headercleanup/examples/benchmarks/bench_newp.pasm
   branches/headercleanup/examples/benchmarks/float4.pir
   branches/headercleanup/examples/benchmarks/freeze.pasm
   branches/headercleanup/examples/benchmarks/gc_alloc_new.pasm
   branches/headercleanup/examples/benchmarks/gc_alloc_reuse.pasm
   branches/headercleanup/examples/benchmarks/gc_generations.pasm
   branches/headercleanup/examples/benchmarks/gc_header_new.pasm
   branches/headercleanup/examples/benchmarks/gc_header_reuse.pasm
   branches/headercleanup/examples/benchmarks/gc_waves_headers.pasm
   branches/headercleanup/examples/benchmarks/gc_waves_sizeable_data.pasm
   branches/headercleanup/examples/benchmarks/gc_waves_sizeable_headers.pasm
   branches/headercleanup/examples/benchmarks/mops.pasm
   branches/headercleanup/examples/benchmarks/mops_intval.pasm
   branches/headercleanup/examples/benchmarks/oo1.pasm
   branches/headercleanup/examples/benchmarks/oo2.pasm
   branches/headercleanup/examples/benchmarks/oo3.pasm
   branches/headercleanup/examples/benchmarks/oo4.pasm
   branches/headercleanup/examples/benchmarks/primes.pasm
   branches/headercleanup/examples/benchmarks/primes_i.pasm
   branches/headercleanup/examples/benchmarks/stress.pasm
   branches/headercleanup/examples/benchmarks/stress1.pasm
   branches/headercleanup/examples/benchmarks/stress2.pasm
   branches/headercleanup/examples/benchmarks/stress3.pasm
   branches/headercleanup/examples/benchmarks/vpm.pir
   branches/headercleanup/examples/japh/japh1.pasm
   branches/headercleanup/examples/japh/japh3.pasm
   branches/headercleanup/examples/japh/japh4.pasm
   branches/headercleanup/examples/japh/japh5.pasm
   branches/headercleanup/examples/languages/abc/   (props changed)
   branches/headercleanup/examples/languages/abc/abc.pir
   branches/headercleanup/examples/languages/squaak/   (props changed)
   branches/headercleanup/examples/namespace/namespace_dump.pir
   branches/headercleanup/examples/nci/QtHelloWorld.pasm
   branches/headercleanup/examples/opengl/shapes.pir
   branches/headercleanup/examples/opengl/static-triangle.pir
   branches/headercleanup/examples/opengl/triangle.pir
   branches/headercleanup/examples/pasm/cat.pasm
   branches/headercleanup/examples/pasm/fact.pasm
   branches/headercleanup/examples/pasm/hello.pasm
   branches/headercleanup/examples/pasm/trace.pasm
   branches/headercleanup/examples/sdl/anim_image.pir
   branches/headercleanup/examples/sdl/anim_image_dblbuf.pir
   branches/headercleanup/examples/sdl/blue_font.pir
   branches/headercleanup/examples/sdl/blue_rect.pir
   branches/headercleanup/examples/sdl/bounce_parrot_logo.pir
   branches/headercleanup/examples/sdl/lcd/clock.pir
   branches/headercleanup/examples/sdl/minesweeper/eventhandler.pir
   branches/headercleanup/examples/sdl/minesweeper/mines.pir
   branches/headercleanup/examples/sdl/move_parrot_logo.pir
   branches/headercleanup/examples/sdl/raw_pixels.pir
   branches/headercleanup/examples/sdl/tetris/app.pir
   branches/headercleanup/examples/sdl/tetris/block.pir
   branches/headercleanup/examples/sdl/tetris/blockdata.pir
   branches/headercleanup/examples/sdl/tetris/blocks.pir
   branches/headercleanup/examples/sdl/tetris/board.pir
   branches/headercleanup/examples/sdl/tetris/boarddata.pir
   branches/headercleanup/examples/sdl/tetris/eventhandler.pir
   branches/headercleanup/examples/sdl/tetris/tetris.pir
   branches/headercleanup/examples/shootout/ack.pir
   branches/headercleanup/examples/shootout/binarytrees.pir
   branches/headercleanup/examples/shootout/fannkuch.pir
   branches/headercleanup/examples/shootout/fasta.pir
   branches/headercleanup/examples/shootout/harmonic.pir
   branches/headercleanup/examples/shootout/knucleotide.pir
   branches/headercleanup/examples/shootout/mandelbrot.pir
   branches/headercleanup/examples/shootout/nbody.pir
   branches/headercleanup/examples/shootout/nsieve-bits-2.pir
   branches/headercleanup/examples/shootout/nsieve-bits.pir
   branches/headercleanup/examples/shootout/nsieve.pir
   branches/headercleanup/examples/shootout/partialsums-2.pir
   branches/headercleanup/examples/shootout/partialsums.pir
   branches/headercleanup/examples/shootout/pidigits.pir
   branches/headercleanup/examples/shootout/random.pasm
   branches/headercleanup/examples/shootout/random.pir
   branches/headercleanup/examples/shootout/recursive-2.pir
   branches/headercleanup/examples/shootout/recursive.pir
   branches/headercleanup/examples/shootout/regexdna.pir
   branches/headercleanup/examples/shootout/revcomp.pir
   branches/headercleanup/examples/shootout/spectralnorm.pir
   branches/headercleanup/examples/shootout/sumcol.pir
   branches/headercleanup/examples/shootout/takfp.pir
   branches/headercleanup/examples/streams/Bytes.pir
   branches/headercleanup/examples/streams/Combiner.pir
   branches/headercleanup/examples/streams/Coroutine.pir
   branches/headercleanup/examples/streams/FileLines.pir
   branches/headercleanup/examples/streams/Filter.pir
   branches/headercleanup/examples/streams/Include.pir
   branches/headercleanup/examples/streams/Lines.pir
   branches/headercleanup/examples/streams/ParrotIO.pir
   branches/headercleanup/examples/streams/Replay.pir
   branches/headercleanup/examples/streams/SubCounter.pir
   branches/headercleanup/examples/streams/SubHello.pir
   branches/headercleanup/examples/streams/Writer.pir
   branches/headercleanup/examples/subs/bsr_ret.pasm
   branches/headercleanup/examples/subs/coroutine.pasm
   branches/headercleanup/examples/subs/jsr_ret.pasm
   branches/headercleanup/examples/subs/pasm_sub1.pasm
   branches/headercleanup/examples/tcl/tcltkdemo.pir
   branches/headercleanup/examples/tge/branch/lib/Branch.pir
   branches/headercleanup/examples/tge/branch/lib/Leaf.pir
   branches/headercleanup/examples/tge/branch/transform.pir
   branches/headercleanup/examples/tutorial/01_temp_var.pir
   branches/headercleanup/examples/tutorial/02_local_var.pir
   branches/headercleanup/examples/tutorial/03_temp_var_basic_pmcs.pir
   branches/headercleanup/examples/tutorial/04_pod_comments.pir
   branches/headercleanup/examples/tutorial/10_math_ops.pir
   branches/headercleanup/examples/tutorial/11_math_ops_self_mod.pir
   branches/headercleanup/examples/tutorial/12_math_ops_pasm.pir
   branches/headercleanup/examples/tutorial/13_logical_ops.pir
   branches/headercleanup/examples/tutorial/20_string_ops.pir
   branches/headercleanup/examples/tutorial/21_string_ops_repeat.pir
   branches/headercleanup/examples/tutorial/22_string_ops_length.pir
   branches/headercleanup/examples/tutorial/23_string_ops_substr.pir
   branches/headercleanup/examples/tutorial/24_string_ops_clone.pir
   branches/headercleanup/examples/tutorial/30_arrays_basic.pir
   branches/headercleanup/examples/tutorial/31_array_ops_split.pir
   branches/headercleanup/examples/tutorial/32_array_ops_sprintf.pir
   branches/headercleanup/examples/tutorial/33_hashes.pir
   branches/headercleanup/examples/tutorial/34_multikey.pir
   branches/headercleanup/examples/tutorial/40_file_ops.pir
   branches/headercleanup/examples/tutorial/50_goto.pir
   branches/headercleanup/examples/tutorial/51_if_unless.pir
   branches/headercleanup/examples/tutorial/52_if_compare.pir
   branches/headercleanup/examples/tutorial/53_loop.pir
   branches/headercleanup/examples/tutorial/55_iterator.pir
   branches/headercleanup/examples/tutorial/56_defined.pir
   branches/headercleanup/examples/tutorial/57_exists.pir
   branches/headercleanup/examples/tutorial/60_subroutines.pir
   branches/headercleanup/examples/tutorial/61_namespaces.pir
   branches/headercleanup/examples/tutorial/62_namespaces.pir
   branches/headercleanup/examples/tutorial/70_class_object.pir
   branches/headercleanup/examples/tutorial/81_continuation.pir
   branches/headercleanup/examples/tutorial/82_coroutine.pir
   branches/headercleanup/examples/tutorial/83_external_libraries.pir
   branches/headercleanup/examples/tutorial/90_writing_tests.pir
   branches/headercleanup/ext/Parrot-Embed/t/greet.pir
   branches/headercleanup/ext/SQLite3/SQLite3.pir
   branches/headercleanup/ext/SQLite3/test.pir
   branches/headercleanup/include/parrot/call.h   (props changed)
   branches/headercleanup/include/parrot/gc_api.h   (props changed)
   branches/headercleanup/include/parrot/gc_mark_sweep.h   (props changed)
   branches/headercleanup/include/parrot/gc_pools.h   (props changed)
   branches/headercleanup/include/parrot/oo.h
   branches/headercleanup/include/parrot/pobj.h
   branches/headercleanup/lib/Parrot/Distribution.pm
   branches/headercleanup/lib/Parrot/Ops2pm.pm
   branches/headercleanup/lib/Parrot/Pmc2c/PMC/Null.pm
   branches/headercleanup/lib/Parrot/Pmc2c/PMC/default.pm
   branches/headercleanup/lib/Parrot/Pmc2c/Pmc2cMain.pm
   branches/headercleanup/ports/cpan/pause_guide.pod   (props changed)
   branches/headercleanup/ports/cygwin/parrot-1.0.0-1.cygport   (props changed)
   branches/headercleanup/ports/debian/libparrot-dev.install.in   (props changed)
   branches/headercleanup/ports/debian/libparrot.install.in   (props changed)
   branches/headercleanup/ports/debian/parrot-doc.install.in   (props changed)
   branches/headercleanup/ports/debian/parrot.install.in   (props changed)
   branches/headercleanup/runtime/parrot/include/fp_equality.pasm
   branches/headercleanup/runtime/parrot/include/hllmacros.pir
   branches/headercleanup/runtime/parrot/include/sockets.pasm
   branches/headercleanup/runtime/parrot/library/Config/JSON.pir
   branches/headercleanup/runtime/parrot/library/Crow.pir
   branches/headercleanup/runtime/parrot/library/Data/Dumper.pir
   branches/headercleanup/runtime/parrot/library/Data/Dumper/Base.pir
   branches/headercleanup/runtime/parrot/library/Data/Dumper/Default.pir
   branches/headercleanup/runtime/parrot/library/Getopt/Obj.pir
   branches/headercleanup/runtime/parrot/library/JSON.pir
   branches/headercleanup/runtime/parrot/library/Math/Rand.pir   (props changed)
   branches/headercleanup/runtime/parrot/library/NCI/call_toolkit_init.pir
   branches/headercleanup/runtime/parrot/library/OpenGL.pir
   branches/headercleanup/runtime/parrot/library/PGE/Dumper.pir
   branches/headercleanup/runtime/parrot/library/PGE/Glob.pir
   branches/headercleanup/runtime/parrot/library/PGE/Hs.pir
   branches/headercleanup/runtime/parrot/library/PGE/Perl6Grammar.pir
   branches/headercleanup/runtime/parrot/library/PGE/Text.pir
   branches/headercleanup/runtime/parrot/library/PGE/Util.pir
   branches/headercleanup/runtime/parrot/library/Protoobject.pir
   branches/headercleanup/runtime/parrot/library/Range.pir
   branches/headercleanup/runtime/parrot/library/SDL.pir
   branches/headercleanup/runtime/parrot/library/Stream/Coroutine.pir
   branches/headercleanup/runtime/parrot/library/Tcl/Glob.pir
   branches/headercleanup/runtime/parrot/library/Test/Builder.pir
   branches/headercleanup/runtime/parrot/library/Test/Builder/Output.pir
   branches/headercleanup/runtime/parrot/library/Test/Builder/Test.pir
   branches/headercleanup/runtime/parrot/library/Test/Builder/TestPlan.pir
   branches/headercleanup/runtime/parrot/library/Test/Class.pir
   branches/headercleanup/runtime/parrot/library/Test/More.pir
   branches/headercleanup/runtime/parrot/library/YAML/Dumper.pir
   branches/headercleanup/runtime/parrot/library/YAML/Dumper/Base.pir
   branches/headercleanup/runtime/parrot/library/YAML/Dumper/Default.pir
   branches/headercleanup/runtime/parrot/library/ncurses.pasm
   branches/headercleanup/runtime/parrot/library/ncurses.pir
   branches/headercleanup/runtime/parrot/library/pcore.pir
   branches/headercleanup/runtime/parrot/library/postgres.pasm
   branches/headercleanup/runtime/parrot/library/postgres.pir
   branches/headercleanup/runtime/parrot/library/random_lib.pir
   branches/headercleanup/runtime/parrot/library/tcpstream.pir
   branches/headercleanup/src/call/ops.c   (props changed)
   branches/headercleanup/src/call/pcc.c   (props changed)
   branches/headercleanup/src/debug.c
   branches/headercleanup/src/dynpmc/dynlexpad.pmc
   branches/headercleanup/src/dynpmc/ext.pir
   branches/headercleanup/src/dynpmc/main.pasm
   branches/headercleanup/src/embed.c
   branches/headercleanup/src/exceptions.c
   branches/headercleanup/src/gc/api.c   (contents, props changed)
   branches/headercleanup/src/gc/generational_ms.c   (props changed)
   branches/headercleanup/src/gc/incremental_ms.c   (props changed)
   branches/headercleanup/src/gc/mark_sweep.c   (props changed)
   branches/headercleanup/src/gc/pools.c   (props changed)
   branches/headercleanup/src/gc/register.c
   branches/headercleanup/src/gc/system.c   (props changed)
   branches/headercleanup/src/interp/inter_create.c   (props changed)
   branches/headercleanup/src/io/socket_api.c
   branches/headercleanup/src/io/win32.c
   branches/headercleanup/src/jit.c
   branches/headercleanup/src/jit.h
   branches/headercleanup/src/jit/i386/jit_defs.c
   branches/headercleanup/src/jit/i386/jit_emit.h
   branches/headercleanup/src/jit/ppc/jit_emit.h
   branches/headercleanup/src/key.c
   branches/headercleanup/src/misc.c
   branches/headercleanup/src/nci_test.c
   branches/headercleanup/src/oo.c
   branches/headercleanup/src/pbc_info.c
   branches/headercleanup/src/pmc.c
   branches/headercleanup/src/pmc/array.pmc
   branches/headercleanup/src/pmc/bigint.pmc
   branches/headercleanup/src/pmc/class.pmc
   branches/headercleanup/src/pmc/codestring.pmc
   branches/headercleanup/src/pmc/continuation.pmc
   branches/headercleanup/src/pmc/coroutine.pmc
   branches/headercleanup/src/pmc/cpointer.pmc
   branches/headercleanup/src/pmc/default.pmc
   branches/headercleanup/src/pmc/hash.pmc
   branches/headercleanup/src/pmc/integer.pmc
   branches/headercleanup/src/pmc/key.pmc
   branches/headercleanup/src/pmc/lexinfo.pmc
   branches/headercleanup/src/pmc/managedstruct.pmc
   branches/headercleanup/src/pmc/namespace.pmc
   branches/headercleanup/src/pmc/nci.pmc
   branches/headercleanup/src/pmc/null.pmc
   branches/headercleanup/src/pmc/object.pmc
   branches/headercleanup/src/pmc/parrotinterpreter.pmc
   branches/headercleanup/src/pmc/pointer.pmc
   branches/headercleanup/src/pmc/retcontinuation.pmc
   branches/headercleanup/src/pmc/scalar.pmc
   branches/headercleanup/src/pmc/scheduler.pmc
   branches/headercleanup/src/pmc/socket.pmc
   branches/headercleanup/src/pmc/sub.pmc
   branches/headercleanup/src/pmc/task.pmc
   branches/headercleanup/src/pmc/undef.pmc
   branches/headercleanup/src/scheduler.c
   branches/headercleanup/src/string/api.c
   branches/headercleanup/src/string/charset/unicode.c
   branches/headercleanup/src/string/encoding/ucs2.c
   branches/headercleanup/src/string/encoding/utf8.c
   branches/headercleanup/src/thread.c
   branches/headercleanup/src/utils.c
   branches/headercleanup/t/codingstd/c_function_docs.t
   branches/headercleanup/t/codingstd/svn_id.t
   branches/headercleanup/t/compilers/tge/NoneGrammar.tg   (props changed)
   branches/headercleanup/t/dynpmc/pair.t   (props changed)
   branches/headercleanup/t/op/gc.t
   branches/headercleanup/t/perl/testlib/hello.pasm
   branches/headercleanup/t/pmc/codestring.t
   branches/headercleanup/t/pmc/managedstruct.t
   branches/headercleanup/t/pmc/nci.t
   branches/headercleanup/t/pmc/pmc.t
   branches/headercleanup/t/pmc/sockaddr.t
   branches/headercleanup/t/pmc/threads.t
   branches/headercleanup/t/src/embed.t   (props changed)
   branches/headercleanup/t/tools/ops2pm/samples/pic_ops.original
   branches/headercleanup/tools/build/nativecall.pl
   branches/headercleanup/tools/dev/fetch_languages.pl   (props changed)
   branches/headercleanup/tools/dev/mk_gitignore.pl   (props changed)
   branches/headercleanup/tools/dev/pbc_to_exe.pir
   branches/headercleanup/tools/util/perlcritic-cage.conf   (props changed)

Modified: branches/headercleanup/DEPRECATED.pod
==============================================================================
--- branches/headercleanup/DEPRECATED.pod	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/DEPRECATED.pod	Wed Apr 15 19:17:06 2009	(r38132)
@@ -46,10 +46,6 @@
 
 L<https://trac.parrot.org/parrot/ticket/189>
 
-=item ref [eligible in 1.1]
-
-L<https://trac.parrot.org/parrot/ticket/190>
-
 =item moved to dynpmc [eligible in 1.1]
 
 AddrRegistry, CodeString, Env, Eval, File, OS, PCCMETHOD_Test, StringHandle,
@@ -106,12 +102,6 @@
 
 =over 4
 
-=item PMC union struct [eligible in 1.1]
-
-This will be removed once all core PMCs have been updated.
-
-L<http://rt.perl.org/rt3/Ticket/Display.html?id=48014>
-
 =item :anon and :vtable named parameters to add_method [eligible in 1.1]
 
 If you want to override a vtable method/function when building a Class, then

Modified: branches/headercleanup/MANIFEST
==============================================================================
--- branches/headercleanup/MANIFEST	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/MANIFEST	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,7 +1,7 @@
 # ex: set ro:
 # $Id$
 #
-# generated by tools/dev/mk_manifest_and_skip.pl Wed Apr  1 16:50:29 2009 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Wed Apr 15 17:57:34 2009 UT
 #
 # See tools/dev/install_files.pl for documentation on the
 # format of this file.
@@ -411,21 +411,26 @@
 config/inter/types.pm                                       []
 config/inter/yacc.pm                                        []
 docs/book/README                                            []doc
-docs/book/appX_patch_submission.pod                         []
-docs/book/ch01_overview.pod                                 []
+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_basics.pod                               []
-docs/book/ch04_pir_subroutines.pod                          []
-docs/book/ch05_pasm.pod                                     []
-docs/book/ch06_library.pod                                  []
-docs/book/ch07_testing_and_debugging.pod                    []
-docs/book/ch08_architecture.pod                             []
-docs/book/ch09_pct.pod                                      []
-docs/book/ch10_hlls.pod                                     []
-docs/book/ch11_pmcs.pod                                     []
-docs/book/ch12_opcodes.pod                                  []
-docs/book/ch13_reference.pod                                []
-docs/book/figs/p6e_0801.png                                 []
+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/ch09_pasm.pod                                     []
+docs/book/ch10_opcode_reference.pod                         []
+docs/book/ch11_directive_reference.pod                      []
+docs/book/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/compiler_faq.pod                                       [devel]doc
 docs/configuration.pod                                      []
 docs/debug.pod                                              [devel]doc
@@ -613,8 +618,6 @@
 examples/benchmarks/primes2.rb                              [examples]
 examples/benchmarks/primes2_i.pir                           [examples]
 examples/benchmarks/primes_i.pasm                           [examples]
-examples/benchmarks/shared_ref.pasm                         [examples]
-examples/benchmarks/shared_ref.pl                           [examples]
 examples/benchmarks/stress.pasm                             [examples]
 examples/benchmarks/stress.pl                               [examples]
 examples/benchmarks/stress.rb                               [examples]
@@ -1078,8 +1081,6 @@
 lib/Parrot/Pmc2c/PMC/ParrotClass.pm                         [devel]lib
 lib/Parrot/Pmc2c/PMC/PrintTree.pm                           [devel]lib
 lib/Parrot/Pmc2c/PMC/RO.pm                                  [devel]lib
-lib/Parrot/Pmc2c/PMC/Ref.pm                                 [devel]lib
-lib/Parrot/Pmc2c/PMC/SharedRef.pm                           [devel]lib
 lib/Parrot/Pmc2c/PMC/default.pm                             [devel]lib
 lib/Parrot/Pmc2c/PMCEmitter.pm                              [devel]lib
 lib/Parrot/Pmc2c/Parser.pm                                  [devel]lib
@@ -1431,7 +1432,6 @@
 src/pmc/pmcproxy.pmc                                        [devel]src
 src/pmc/pointer.pmc                                         [devel]src
 src/pmc/random.pmc                                          [devel]src
-src/pmc/ref.pmc                                             [devel]src
 src/pmc/resizablebooleanarray.pmc                           [devel]src
 src/pmc/resizablefloatarray.pmc                             [devel]src
 src/pmc/resizableintegerarray.pmc                           [devel]src
@@ -1442,7 +1442,6 @@
 src/pmc/scalar.pmc                                          [devel]src
 src/pmc/scheduler.pmc                                       [devel]src
 src/pmc/schedulermessage.pmc                                [devel]src
-src/pmc/sharedref.pmc                                       [devel]src
 src/pmc/sockaddr.pmc                                        [devel]src
 src/pmc/socket.pmc                                          [devel]src
 src/pmc/string.pmc                                          [devel]src
@@ -1888,7 +1887,6 @@
 t/pmc/pointer.t                                             [test]
 t/pmc/prop.t                                                [test]
 t/pmc/random.t                                              [test]
-t/pmc/ref.t                                                 [test]
 t/pmc/resizablebooleanarray.t                               [test]
 t/pmc/resizablefloatarray.t                                 [test]
 t/pmc/resizableintegerarray.t                               [test]
@@ -1900,7 +1898,6 @@
 t/pmc/scalar.t                                              [test]
 t/pmc/scheduler.t                                           [test]
 t/pmc/schedulermessage.t                                    [test]
-t/pmc/sharedref.t                                           [test]
 t/pmc/signal.t                                              [test]
 t/pmc/sockaddr.t                                            [test]
 t/pmc/socket.t                                              [test]

Modified: branches/headercleanup/MANIFEST.SKIP
==============================================================================
--- branches/headercleanup/MANIFEST.SKIP	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/MANIFEST.SKIP	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,6 +1,6 @@
 # ex: set ro:
 # $Id$
-# generated by tools/dev/mk_manifest_and_skip.pl Wed Mar 18 18:07:29 2009 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Wed Apr 15 17:34:44 2009 UT
 #
 # This file should contain a transcript of the svn:ignore properties
 # of the directories in the Parrot subversion repository. (Needed for
@@ -41,6 +41,8 @@
 ^.*\.pdb/
 ^.*\.sln$
 ^.*\.sln/
+^.*\.sto$
+^.*\.sto/
 ^.*\.suo$
 ^.*\.suo/
 ^.*\.tmp$

Modified: branches/headercleanup/NEWS
==============================================================================
--- branches/headercleanup/NEWS	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/NEWS	Wed Apr 15 19:17:06 2009	(r38132)
@@ -7,8 +7,9 @@
   + Removed ops: gcd, exec, classname, need_finalize, runinterp, substr_r
   + Removed dynamic op: mul 
   + Removed .HLL_map directive; use interp's .hll_map() instead
-  + Removed PMCs: slice, bound_nci
+  + Removed PMCs: slice, bound_nci, ref
   + Removed Configure.pl option: --pmc
+  + Removed PMC union struct
 
 New in 1.0.0
 - Documentation

Modified: branches/headercleanup/PBC_COMPAT
==============================================================================
--- branches/headercleanup/PBC_COMPAT	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/PBC_COMPAT	Wed Apr 15 19:17:06 2009	(r38132)
@@ -27,6 +27,8 @@
 
 # please insert tab separated entries at the top of the list
 
+4.5	2009.04.10	cotto	removed Ref and SharedRef PMCs
+4.4	2009.04.07	pmichaud	find_caller_lex added
 4.3	2009.03.25	jonathan	socket opcodes added
 4.2	2009.03.21	cotto	removed Bound_NCI PMC
 4.1	2009.03.17	cotto	removed Slice PMC

Modified: branches/headercleanup/compilers/imcc/main.c
==============================================================================
--- branches/headercleanup/compilers/imcc/main.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/imcc/main.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -215,8 +215,9 @@
     "  Options:\n"
     "    -h --help\n"
     "    -V --version\n"
-    "    -I add path to include search\n"
-    "    -L add path to library search\n"
+    "    -I --include add path to include search\n"
+    "    -L --library add path to library search\n"
+    "    -X --dynext add path to dynamic extension search\n"
     "   <Run core options>\n"
     "    -R --runcore CORE\n"
     "    --bounds-checks|--slow-core\n"
@@ -296,11 +297,12 @@
     { 'D', 'D', OPTION_optional_FLAG, { "--parrot-debug" } },
     { 'E', 'E', (OPTION_flags)0, { "--pre-process-only" } },
     { 'G', 'G', (OPTION_flags)0, { "--no-gc" } },
-    { 'I', 'I', OPTION_required_FLAG, { NULL } },
-    { 'L', 'L', OPTION_required_FLAG, { NULL } },
+    { 'I', 'I', OPTION_required_FLAG, { "--include" } },
+    { 'L', 'L', OPTION_required_FLAG, { "--library" } },
     { 'O', 'O', OPTION_optional_FLAG, { "--optimize" } },
     { 'R', 'R', OPTION_required_FLAG, { "--runcore" } },
     { 'V', 'V', (OPTION_flags)0, { "--version" } },
+    { 'X', 'X', OPTION_required_FLAG, { "--dynext" } },
     { '\0', OPT_DESTROY_FLAG, (OPTION_flags)0,
                                  { "--leak-test", "--destroy-at-end" } },
     { '\0', OPT_GC_DEBUG, (OPTION_flags)0, { "--gc-debug" } },
@@ -539,6 +541,10 @@
                 Parrot_add_library_path_from_cstring(interp, opt.opt_arg,
                     PARROT_LIB_PATH_LIBRARY);
                 break;
+            case 'X':
+                Parrot_add_library_path_from_cstring(interp, opt.opt_arg,
+                    PARROT_LIB_PATH_DYNEXT);
+                break;
             default:
                 Parrot_ex_throw_from_c_args(interp, NULL, 1,
                     "main: Invalid flag '%s' used.\n\nhelp: parrot -h\n",

Modified: branches/headercleanup/compilers/imcc/parser_util.c
==============================================================================
--- branches/headercleanup/compilers/imcc/parser_util.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/imcc/parser_util.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -865,7 +865,7 @@
      * Continuations (this happens when something is the target of a :outer)
      * trying to return values using them when invoked. (See TT#500 for the
      * report of the bug this fixes). */
-    PMC *save_results = CONTEXT(interp)->current_results;
+    opcode_t *save_results = CONTEXT(interp)->current_results;
     CONTEXT(interp)->current_results = NULL;
     sub = imcc_compile(interp, s, 0, &error_message);
     CONTEXT(interp)->current_results = save_results;

Modified: branches/headercleanup/compilers/json/JSON.pir
==============================================================================
--- branches/headercleanup/compilers/json/JSON.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/json/JSON.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 # Copyright (C) 2005-2008, Parrot Foundation.
+# $Id$
 
 =head1 NAME
 

Modified: branches/headercleanup/compilers/json/test.pir
==============================================================================
--- branches/headercleanup/compilers/json/test.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/json/test.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,6 @@
 #!../../parrot
+# $Id$
+
 .sub main :main
   .param pmc argv
 

Modified: branches/headercleanup/compilers/ncigen/src/NCIGENAST.pir
==============================================================================
--- branches/headercleanup/compilers/ncigen/src/NCIGENAST.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/ncigen/src/NCIGENAST.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 NCIGENAST - NCIGEN abstract syntax tree

Modified: branches/headercleanup/compilers/ncigen/src/NCIPIR.pir
==============================================================================
--- branches/headercleanup/compilers/ncigen/src/NCIPIR.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/ncigen/src/NCIPIR.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 NCIPIR::Compiler - NCI PIR Compiler for NCIGENAST trees.

Modified: branches/headercleanup/compilers/nqp/bootstrap/nqp.pir
==============================================================================
--- branches/headercleanup/compilers/nqp/bootstrap/nqp.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/nqp/bootstrap/nqp.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 nqp.pir - A nqp compiler.

Modified: branches/headercleanup/compilers/nqp/src/builtins.pir
==============================================================================
--- branches/headercleanup/compilers/nqp/src/builtins.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/nqp/src/builtins.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 .namespace []
 
 =over 4

Modified: branches/headercleanup/compilers/pct/PCT.pir
==============================================================================
--- branches/headercleanup/compilers/pct/PCT.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/pct/PCT.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 PCT - Parrot compiler toolkit

Modified: branches/headercleanup/compilers/pct/src/PAST.pir
==============================================================================
--- branches/headercleanup/compilers/pct/src/PAST.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/pct/src/PAST.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 PAST - Parrot abstract syntax tree

Modified: branches/headercleanup/compilers/pct/src/PAST/Compiler.pir
==============================================================================
--- branches/headercleanup/compilers/pct/src/PAST/Compiler.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/pct/src/PAST/Compiler.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 PAST::Compiler - PAST Compiler

Modified: branches/headercleanup/compilers/pct/src/PAST/Node.pir
==============================================================================
--- branches/headercleanup/compilers/pct/src/PAST/Node.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/pct/src/PAST/Node.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 PAST - Parrot abstract syntax tree

Modified: branches/headercleanup/compilers/pct/src/PCT/HLLCompiler.pir
==============================================================================
--- branches/headercleanup/compilers/pct/src/PCT/HLLCompiler.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/pct/src/PCT/HLLCompiler.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 PCT::HLLCompiler - base class for compiler objects

Modified: branches/headercleanup/compilers/pct/src/PCT/Node.pir
==============================================================================
--- branches/headercleanup/compilers/pct/src/PCT/Node.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/pct/src/PCT/Node.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 PCT::Node - base class for PAST and POST nodes
@@ -197,10 +199,27 @@
 
 .sub 'node' :method
     .param pmc node
-     ## Do nothing for now.  When we're in a better position to
-     ## handle source line information (RT #43269 and others)
-     ## we'll figure out what to do here.
-    .return ()
+
+    if null node goto done
+    $I0 = isa node, ['PGE';'Match']
+    if $I0 goto node_match
+    $I0 = isa node, ['PCT';'Node']
+    if $I0 goto node_pct
+    $S0 = typeof node
+    $S0 = concat "Don't know how to save info from node of type ", $S0
+    die $S0
+  node_match:
+    .local pmc source, pos
+    source = getattribute node, '$.target'
+    pos    = node.'from'()
+    goto node_done
+  node_pct:
+    source = node['source']
+    pos    = node['pos']
+  node_done:
+    self['source'] = source
+    self['pos']    = pos
+  done:
 .end
 
 

Modified: branches/headercleanup/compilers/pct/src/POST/Compiler.pir
==============================================================================
--- branches/headercleanup/compilers/pct/src/POST/Compiler.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/pct/src/POST/Compiler.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 POST::Compiler - Compiler for POST trees
@@ -23,9 +25,6 @@
     $P1 = split ' ', 'pir evalpmc'
     cproto.'stages'($P1)
 
-    $P0 = new 'ResizablePMCArray'
-    set_global '@!subcode', $P0
-
     $P0 = new 'String'
     set_global '$?HLL', $P0
     null $P0
@@ -41,11 +40,11 @@
     .local pmc newself
     newself = new ['POST';'Compiler']
 
-    ##  start with empty code
-    .local pmc subcode, code
-    subcode = get_global '@!subcode'
-    code = new 'CodeString'
-    push subcode, code
+    .local pmc innerpir, line
+    innerpir = new 'CodeString'
+    .lex '$CODE', innerpir
+    line = box 0
+    .lex '$LINE', line
 
     ##  if the root node isn't a Sub, wrap it
     $I0 = isa post, ['POST';'Sub']
@@ -58,8 +57,7 @@
     newself.'pir'(post)
 
     ##  and return whatever code was generated
-    $P0 = pop subcode
-    .return ($P0)
+    .return (innerpir)
 .end
 
 
@@ -71,18 +69,25 @@
 
 .sub 'pir_children' :method
     .param pmc node
-    .local pmc code, iter
-    code = new 'CodeString'
+    .local pmc line
+    line = find_caller_lex '$LINE'
+    .lex '$LINE', line
+
+    .local pmc iter
     iter = node.'iterator'()
   iter_loop:
     unless iter goto iter_end
-    .local pmc cpost
+    .local pmc cpost, pos, source
     cpost = shift iter
-    $P0 = self.'pir'(cpost)
-    code .= $P0
+    pos = cpost['pos']
+    if null pos goto done_subline
+    source = cpost['source']
+    line = source.'lineof'(pos)
+    inc line
+  done_subline:
+    self.'pir'(cpost)
     goto iter_loop
   iter_end:
-    .return (code)
 .end
 
 
@@ -162,10 +167,15 @@
     goto pirop_emit
 
   pirop_emit:
-    .local pmc code
-    code = new 'CodeString'
-    code.'emit'(fmt, arglist :flat, 'r'=>result, 'n'=>name, 'i'=>invocant, 't'=>result)
-    .return (code)
+    .local pmc subpir, subline, line
+    subpir  = find_caller_lex '$SUBPIR'
+    subline = find_caller_lex '$SUBLINE'
+    line    = find_caller_lex '$LINE'
+    if subline == line goto done_line
+    subpir.'emit'('.annotate "line", %0', line)
+    assign subline, line
+  done_line:
+    subpir.'emit'(fmt, arglist :flat, 'r'=>result, 'n'=>name, 'i'=>invocant, 't'=>result)
 .end
 
 
@@ -177,12 +187,10 @@
 
 .sub 'pir' :method :multi(_, ['POST';'Label'])
     .param pmc node
-    .local string code, value
+    .local pmc subpir, value
     value = node.'result'()
-    code = '  '
-    code .= value
-    code .= ":\n"
-    .return (code)
+    subpir = find_caller_lex '$SUBPIR'
+    subpir.'emit'('  %0:', value)
 .end
 
 
@@ -197,13 +205,13 @@
 .sub 'pir' :method :multi(_, ['POST';'Sub'])
     .param pmc node
 
-    .local pmc subcode
-    subcode = get_global '@!subcode'
-    $P0 = new 'CodeString'
-    push subcode, $P0
-
-    .local pmc code
-    code = new 'CodeString'
+    .local pmc subpir, subline, innerpir
+    subpir = new 'CodeString'
+    .lex '$SUBPIR', subpir
+    subline = box -1
+    .lex '$SUBLINE', subline
+    innerpir = new 'CodeString'
+    .lex '$CODE', innerpir
 
     .local string name, pirflags
     name = node.'name'()
@@ -233,7 +241,7 @@
     if null outerpost goto pirflags_done
     unless outerpost goto pirflags_done
     outername = outerpost.'subid'()
-    $S0 = code.'escape'(outername)
+    $S0 = subpir.'escape'(outername)
     pirflags = concat pirflags, ' :outer('
     concat pirflags, $S0
     concat pirflags, ')'
@@ -255,7 +263,7 @@
     ns = $P0
   have_ns:
     set_global '$?NAMESPACE', ns
-    nskey = code.'key'(ns)
+    nskey = subpir.'key'(ns)
 
   subpir_start:
     $P0 = node.'compiler'()
@@ -266,17 +274,17 @@
     $P0 = new 'Hash'
   have_compiler_args:
     $P0 = self.'hll_pir'(node, 'name'=>name, 'namespace'=>ns, 'pirflags'=>pirflags, $P0 :named :flat)
-    code .= $P0
+    subpir .= $P0
     goto subpir_done
 
   subpir_post:
     unless hll goto subpir_ns
-    $P0 = code.'escape'(hll)
-    code.'emit'("\n.HLL %0", $P0)
+    $P0 = subpir.'escape'(hll)
+    subpir.'emit'("\n.HLL %0", $P0)
   subpir_ns:
-    code.'emit'("\n.namespace %0", nskey)
-    $S0 = code.'escape'(name)
-    code.'emit'(".sub %0 %1", $S0, pirflags)
+    subpir.'emit'("\n.namespace %0", nskey)
+    $S0 = subpir.'escape'(name)
+    subpir.'emit'(".sub %0 %1", $S0, pirflags)
     .local pmc paramlist
     paramlist = node['paramlist']
     if null paramlist goto paramlist_done
@@ -286,25 +294,21 @@
     unless iter goto paramlist_done
     $P0 = shift iter
     if null $P0 goto param_loop
-    code .= $P0
+    subpir .= $P0
     goto param_loop
   paramlist_done:
 
-    $P0 = self.'pir_children'(node)
-    code .= $P0
-    code.'emit'(".end\n\n")
+    self.'pir_children'(node)
+    subpir.'emit'(".end\n\n")
 
   subpir_done:
-    $P0 = pop subcode
-    code .= $P0
-    $P0 = subcode[-1]
-    $P0 .= code
+    .local pmc outerpir
+    outerpir = find_caller_lex '$CODE'
+    outerpir .= subpir
+    outerpir .= innerpir
 
     set_global '$?NAMESPACE', outerns
     set_global '$?HLL', outerhll
-
-    code = new 'CodeString'
-    .return (code)
 .end
 
 

Modified: branches/headercleanup/compilers/pct/src/POST/Node.pir
==============================================================================
--- branches/headercleanup/compilers/pct/src/POST/Node.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/pct/src/POST/Node.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 POST - Parrot opcode syntax tree

Modified: branches/headercleanup/compilers/pge/PGE.pir
==============================================================================
--- branches/headercleanup/compilers/pge/PGE.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/pge/PGE.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 PGE - the Parrot/Perl Grammar Engine

Modified: branches/headercleanup/compilers/pge/PGE/Exp.pir
==============================================================================
--- branches/headercleanup/compilers/pge/PGE/Exp.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/pge/PGE/Exp.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 PGE::Exp - base class for expressions

Modified: branches/headercleanup/compilers/pge/PGE/Match.pir
==============================================================================
--- branches/headercleanup/compilers/pge/PGE/Match.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/pge/PGE/Match.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 PGE::Match - implementation of PGE match objects

Modified: branches/headercleanup/compilers/pge/PGE/P5Regex.pir
==============================================================================
--- branches/headercleanup/compilers/pge/PGE/P5Regex.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/pge/PGE/P5Regex.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,4 @@
-
+# $Id$
 
 .namespace [ "PGE";"P5Regex" ]
 

Modified: branches/headercleanup/compilers/pge/PGE/Perl6Regex.pir
==============================================================================
--- branches/headercleanup/compilers/pge/PGE/Perl6Regex.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/pge/PGE/Perl6Regex.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 Perl6Regex - compiler and parser for Perl 6 regex

Modified: branches/headercleanup/compilers/pge/PGE/Regex.pir
==============================================================================
--- branches/headercleanup/compilers/pge/PGE/Regex.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/pge/PGE/Regex.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 Regex - base class for grammars and built-in rules

Modified: branches/headercleanup/compilers/pge/demo.pir
==============================================================================
--- branches/headercleanup/compilers/pge/demo.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/pge/demo.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 .include "errors.pasm"
 .sub _main
     .local string x

Modified: branches/headercleanup/compilers/pirc/src/bcgen.c
==============================================================================
--- branches/headercleanup/compilers/pirc/src/bcgen.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/pirc/src/bcgen.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -10,6 +10,7 @@
 
 #include "parrot/interpreter.h"
 #include "../../../src/pmc/pmc_sub.h"
+#include "../../../src/pmc/pmc_namespace.h"
 
 /* #include "parrot/embed.h" */
 
@@ -988,8 +989,9 @@
 
     switch (ns->entry_type) {
         case MULTI_TYPE_IDENT: {
-            PMC *namespace_pmc         = constant_pmc_new(bc->interp, enum_class_String);
-            PMC_str_val(namespace_pmc) = add_string_const_from_cstring(bc, ns->entry.ident);
+            PMC *namespace_pmc = constant_pmc_new(bc->interp, enum_class_String);
+            PARROT_NAMESPACE(namespace_pmc)->name =
+                add_string_const_from_cstring(bc, ns->entry.ident);
             break;
         }
         case MULTI_TYPE_KEYED:

Modified: branches/headercleanup/compilers/tge/TGE.pir
==============================================================================
--- branches/headercleanup/compilers/tge/TGE.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/tge/TGE.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 # Copyright (C) 2005-2009, Parrot Foundation.
+# $Id$
 
 =head1 NAME
 

Modified: branches/headercleanup/compilers/tge/TGE/Compiler.pir
==============================================================================
--- branches/headercleanup/compilers/tge/TGE/Compiler.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/tge/TGE/Compiler.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 # Copyright (C) 2005-2009, Parrot Foundation.
+# $Id$
 
 =head1 NAME
 

Modified: branches/headercleanup/compilers/tge/TGE/Grammar.pir
==============================================================================
--- branches/headercleanup/compilers/tge/TGE/Grammar.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/tge/TGE/Grammar.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 # Copyright (C) 2005-2008, Parrot Foundation.
+# $Id$
 
 =head1 NAME
 

Modified: branches/headercleanup/compilers/tge/TGE/Rule.pir
==============================================================================
--- branches/headercleanup/compilers/tge/TGE/Rule.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/tge/TGE/Rule.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 # Copyright (C) 2005-2008, Parrot Foundation.
+# $Id$
 
 =head1 NAME
 

Modified: branches/headercleanup/compilers/tge/TGE/Tree.pir
==============================================================================
--- branches/headercleanup/compilers/tge/TGE/Tree.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/tge/TGE/Tree.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 # Copyright (C) 2005-2008, Parrot Foundation.
+# $Id$
 
 =head1 NAME
 

Modified: branches/headercleanup/compilers/tge/tgc.pir
==============================================================================
--- branches/headercleanup/compilers/tge/tgc.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/compilers/tge/tgc.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 tgc.pir - The TGE rules compiler

Modified: branches/headercleanup/config/auto/pmc.pm
==============================================================================
--- branches/headercleanup/config/auto/pmc.pm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/config/auto/pmc.pm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -66,8 +66,6 @@
     lib/Parrot/Pmc2c/UtilFunctions.pm \\
     lib/Parrot/Pmc2c/PMC/default.pm \\
     lib/Parrot/Pmc2c/PMC/Null.pm \\
-    lib/Parrot/Pmc2c/PMC/Ref.pm \\
-    lib/Parrot/Pmc2c/PMC/SharedRef.pm \\
     lib/Parrot/Pmc2c/PMC/RO.pm
 END
 

Modified: branches/headercleanup/config/gen/call_list/misc.in
==============================================================================
--- branches/headercleanup/config/gen/call_list/misc.in	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/config/gen/call_list/misc.in	Wed Apr 15 19:17:06 2009	(r38132)
@@ -389,6 +389,7 @@
 
 # Testing Pointer PMC use
 v    V
+v    VVV
 
 # Testing SQLite
 i    tV

Modified: branches/headercleanup/config/gen/config_pm/config_lib_pasm.in
==============================================================================
--- branches/headercleanup/config/gen/config_pm/config_lib_pasm.in	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/config/gen/config_pm/config_lib_pasm.in	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 .pcc_sub main:
     get_params "(0)", P5
     set I10, P5     # argv
@@ -19,3 +21,9 @@
     freeze S0, P0
     print S0
     end
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/config/gen/makefiles/root.in
==============================================================================
--- branches/headercleanup/config/gen/makefiles/root.in	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/config/gen/makefiles/root.in	Wed Apr 15 19:17:06 2009	(r38132)
@@ -841,6 +841,7 @@
                            $(SRC_DIR)/pmc/timer.c     \
                            $(INC_DIR)/pbcversion.h
 
+$(IO_DIR)/socket_api$(O) : $(SRC_DIR)/pmc/socket.c
 $(IO_DIR)/socket_unix$(O) : $(INC_DIR)/pbcversion.h   \
                             $(SRC_DIR)/pmc/socket.c
 $(IO_DIR)/socket_win32$(O) : $(INC_DIR)/pbcversion.h   \
@@ -1054,12 +1055,12 @@
 
 $(SRC_DIR)/exec$(O) : $(GENERAL_H_FILES) @TEMP_exec_h@ $(SRC_DIR)/jit_emit.h
 
-$(SRC_DIR)/exec_dep$(O) : $(GENERAL_H_FILES) @TEMP_exec_h@ $(SRC_DIR)/jit_emit.h
+$(SRC_DIR)/exec_dep$(O) : $(GENERAL_H_FILES) @TEMP_exec_h@ $(SRC_DIR)/jit_emit.h $(SRC_DIR)/pmc/managedstruct.c
 
 $(SRC_DIR)/exec_cpu$(O) : $(GENERAL_H_FILES) @TEMP_exec_h@ $(SRC_DIR)/jit_emit.h
 
 $(SRC_DIR)/jit_defs$(O) : $(GENERAL_H_FILES) @TEMP_exec_h@ $(SRC_DIR)/jit_emit.h \
-	$(SRC_DIR)/pmc/pmc_fixedintegerarray.h $(SRC_DIR)/pmc/pmc_unmanagedstruct.h
+	$(SRC_DIR)/pmc/pmc_fixedintegerarray.h $(SRC_DIR)/pmc/pmc_unmanagedstruct.h $(SRC_DIR)/pmc/pmc_pointer.h
 
 $(INC_DIR)/extend_vtable.h $(SRC_DIR)/extend_vtable.c $(SRC_DIR)/vtable.h : src/vtable.tbl $(BUILD_TOOLS_DIR)/vtable_extend.pl lib/Parrot/Vtable.pm
 	$(PERL) $(BUILD_TOOLS_DIR)/vtable_extend.pl
@@ -1187,7 +1188,10 @@
 
 $(SRC_DIR)/exit$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/exit.c
 
-$(SRC_DIR)/nci$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/nci.c $(SRC_DIR)/nci.str
+$(SRC_DIR)/nci$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/nci.c $(SRC_DIR)/nci.str \
+        $(SRC_DIR)/pmc/pmc_managedstruct.h \
+        $(SRC_DIR)/pmc/pmc_nci.h \
+        $(SRC_DIR)/pmc/pmc_pointer.h
 
 $(SRC_DIR)/vtables$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/vtables.c
 

Modified: branches/headercleanup/config/gen/opengl.pm
==============================================================================
--- branches/headercleanup/config/gen/opengl.pm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/config/gen/opengl.pm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1006,7 +1006,7 @@
 /* Make sure that interp and sub are sane before running callback sub */
 /* XXXX: Should this do the moral equivalent of PANIC? */
 int
-is_safe(PARROT_INTERP, PMC *sub)
+is_safe(SHIM_INTERP, PMC *sub)
 {
     /* XXXX: Verify that interp still exists */
 

Modified: branches/headercleanup/config/gen/platform/generic/itimer.c
==============================================================================
--- branches/headercleanup/config/gen/platform/generic/itimer.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/config/gen/platform/generic/itimer.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -38,7 +38,7 @@
 */
 
 void
-start_sys_timer_ms(void *handle, int ms)
+start_sys_timer_ms(SHIM(void *handle), int ms)
 {
     struct itimerval its;
     memset(&its, 0, sizeof (its));

Modified: branches/headercleanup/config/gen/platform/generic/memexec.c
==============================================================================
--- branches/headercleanup/config/gen/platform/generic/memexec.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/config/gen/platform/generic/memexec.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -22,12 +22,18 @@
 */
 
 #ifdef PARROT_HAS_EXEC_PROTECT
+
+#  define PARROT_EXEC_PERMS PROT_READ|PROT_WRITE|PROT_EXEC
+
 /*
 
 =item C<void * mem_alloc_executable(size_t size)>
 
-Allocate executable memory
-Round up to page size because the whole page will be marked as executable
+Allocates executable memory.
+Rounds up to page size because the whole page will be marked as executable.
+
+Note, memory allocated with this interface *must* be freed with
+mem_free_executable, as it may have been mmapped rather than malloced.
 
 =cut
 
@@ -39,32 +45,46 @@
     void *p;
     size_t pagesize = sysconf(_SC_PAGESIZE);
     size = (size + pagesize - 1) & ~(pagesize-1);
+#  ifdef WIN32
     if (posix_memalign(&p, pagesize, size))
         return NULL;
-    mprotect(p, size, PROT_READ|PROT_WRITE|PROT_EXEC);
+    mprotect(p, size, PARROT_EXEC_PERMS);
+#  else /* !WIN32 */
+    p = mmap(NULL, size, PARROT_EXEC_PERMS, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+    if (!p)
+        return NULL;
+#  endif /* WIN32 */
     return p;
 }
 
 /*
 
-=item C<void mem_free_executable(void *p)>
+=item C<void mem_free_executable(void *p, size_t)>
+
+Free a buffer allocated with mem_alloc_executable().
 
 =cut
 
 */
 
 void
-mem_free_executable(void *p)
+mem_free_executable(void *p, size_t size)
 {
+#  ifdef WIN32
     free(p);
+#  else /* !WIN32 */
+    size_t pagesize = sysconf(_SC_PAGESIZE);
+    size = (size + pagesize - 1) & ~(pagesize-1);
+    munmap(p, size);
+#  endif /* WIN32 */
 }
 
 /*
 
-=item C<void * mem_realloc_executable(void* oldp, size_t newsize)>
+=item C<void * mem_realloc_executable(void* oldp, size_t oldsize, size_t newsize)>
 
-Reallocate executable memory
-Round up to page size because the whole page will be marked as executable
+Reallocate executable memory.
+Rounds up to page size because the whole page will be marked as executable.
 The intermediate temp is required because we don't know the old size
 
 =cut
@@ -72,11 +92,12 @@
 */
 
 void *
-mem_realloc_executable(void* oldp, size_t newsize)
+mem_realloc_executable(void* oldp, size_t oldsize, size_t newsize)
 {
-    void *temp;
     void *newp;
     size_t pagesize = sysconf(_SC_PAGESIZE);
+#  ifdef WIN32
+    void *temp;
     size_t roundup;
     temp = realloc(oldp, newsize);
     if (temp == NULL)
@@ -86,13 +107,18 @@
     if (posix_memalign(&newp, pagesize, roundup))
         newp = NULL;
     if (newp) {
-        mprotect(newp, roundup, PROT_READ|PROT_WRITE|PROT_EXEC);
+        mprotect(newp, roundup, PARROT_EXEC_PERMS);
         memcpy(newp, temp, newsize);
     }
     free(temp);
+#  else /* !WIN32 */
+    oldsize = (oldsize + pagesize - 1) & ~(pagesize-1);
+    newsize = (newsize + pagesize - 1) & ~(pagesize-1);
+    newp = mremap(oldp, oldsize, newsize, PARROT_EXEC_PERMS);
+#  endif /* WIN32 */
     return newp;
 }
-#endif
+#endif /* PARROT_HAS_EXEC_PROTECT */
 
 /*
 

Modified: branches/headercleanup/config/gen/platform/generic/stat.c
==============================================================================
--- branches/headercleanup/config/gen/platform/generic/stat.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/config/gen/platform/generic/stat.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -31,7 +31,7 @@
 */
 
 PMC *
-Parrot_stat_file(PARROT_INTERP, STRING *filename)
+Parrot_stat_file(SHIM_INTERP, SHIM(STRING *filename))
 {
     return NULL;
 }
@@ -46,7 +46,7 @@
 */
 
 PMC *
-Parrot_stat_info_pmc(PARROT_INTERP, STRING *filename, INTVAL thing)
+Parrot_stat_info_pmc(SHIM_INTERP, SHIM(STRING *filename), SHIM(INTVAL thing))
 {
     return NULL;
 }
@@ -189,7 +189,7 @@
 */
 
 FLOATVAL
-Parrot_stat_info_floatval(PARROT_INTERP, STRING *filename, INTVAL thing)
+Parrot_stat_info_floatval(SHIM_INTERP, SHIM(STRING *filename), SHIM(INTVAL thing))
 {
     return (FLOATVAL)-1;
 }
@@ -204,7 +204,7 @@
 */
 
 STRING *
-Parrot_stat_info_string(PARROT_INTERP, STRING *filename, INTVAL thing)
+Parrot_stat_info_string(SHIM_INTERP, SHIM(STRING *filename), SHIM(INTVAL thing))
 {
     return NULL;
 }

Modified: branches/headercleanup/config/gen/platform/openbsd/memexec.c
==============================================================================
--- branches/headercleanup/config/gen/platform/openbsd/memexec.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/config/gen/platform/openbsd/memexec.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -49,21 +49,23 @@
 
 /*
 
-=item C<void mem_free_executable(void *p)>
+=item C<void mem_free_executable(void *p, size_t size)>
+
+Free a buffer allocated with mem_alloc_executable().
 
 =cut
 
 */
 
 void
-mem_free_executable(void *p)
+mem_free_executable(void *p, size_t size)
 {
     free(p);
 }
 
 /*
 
-=item C<void * mem_realloc_executable(void* oldp, size_t newsize)>
+=item C<void * mem_realloc_executable(void* oldp, size_t oldsize, size_t newsize)>
 
 Reallocate executable memory
 Round up to page size because the whole page will be marked as executable
@@ -73,7 +75,7 @@
 */
 
 void *
-mem_realloc_executable(void* oldp, size_t newsize)
+mem_realloc_executable(void* oldp, size_t oldsize, size_t newsize)
 {
     size_t pagesize = sysconf(_SC_PAGESIZE);
     size_t roundup = (newsize + pagesize - 1) & ~(pagesize-1);

Modified: branches/headercleanup/config/gen/platform/platform_interface.h
==============================================================================
--- branches/headercleanup/config/gen/platform/platform_interface.h	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/config/gen/platform/platform_interface.h	Wed Apr 15 19:17:06 2009	(r38132)
@@ -40,12 +40,12 @@
 
 #ifdef PARROT_HAS_EXEC_PROTECT
 void *mem_alloc_executable(size_t);
-void mem_free_executable(void *);
-void *mem_realloc_executable(void *, size_t);
+void mem_free_executable(void *, size_t);
+void *mem_realloc_executable(void *, size_t, size_t);
 #else
 #  define mem_alloc_executable mem_sys_allocate
-#  define mem_free_executable mem_sys_free
-#  define mem_realloc_executable mem_sys_realloc
+#  define mem_free_executable(a, b) mem_sys_free(a)
+#  define mem_realloc_executable(a, b, c) mem_sys_realloc((a), (c))
 #endif
 
 void* Parrot_memcpy_aligned(void*, void*, size_t);

Modified: branches/headercleanup/docs/book/README
==============================================================================
--- branches/headercleanup/docs/book/README	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/docs/book/README	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,19 +1,23 @@
-The book will have the following chapters. Note that the number and order of
-intended chapters listed here may not directly correspond to the filenames in
-this folder:
+The book will have the following chapters.
 
- 1) Overview
- 2) Getting Started
- 3) High-Level Languages
- 4) Parrot Compiler Tools
- 5) Parrot Intermediate Representation (PIR)
- 6) Parrot Assembly Language (PASM)
- 7) Writing your own PMCs
- 8) Testing and Debugging
- 9) Standard Library (maybe)
+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
 
-This list will probably change as time goes on, as more topics need to be
-covered.
 
 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

Deleted: branches/headercleanup/docs/book/appX_patch_submission.pod
==============================================================================
--- branches/headercleanup/docs/book/appX_patch_submission.pod	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,133 +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 A<CHP-9-SECT-13>"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

Copied: branches/headercleanup/docs/book/appa_glossary.pod (from r38131, trunk/docs/book/appa_glossary.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/appa_glossary.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/appa_glossary.pod)
@@ -0,0 +1,321 @@
+=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

Copied: branches/headercleanup/docs/book/appb_patch_submission.pod (from r38131, trunk/docs/book/appb_patch_submission.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/appb_patch_submission.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/appb_patch_submission.pod)
@@ -0,0 +1,133 @@
+=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

Copied: branches/headercleanup/docs/book/appc_command_line_options.pod (from r38131, trunk/docs/book/appc_command_line_options.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/appc_command_line_options.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/appc_command_line_options.pod)
@@ -0,0 +1,318 @@
+=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 --bounds-checks
+
+Activate bounds checking. This also runs with the I<slow core> as a
+side effect.
+
+=item --fast-core
+
+Run with the I<fast core>.
+
+=item --computed-goto-core
+
+Run the I<computed goto core> (CGoto).
+
+=item --jit-core
+
+Run with the I<JIT core> if available.
+
+=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 --CGP-core
+
+Run with the I<CGoto-Prederefed> core.
+
+=item --switched-core
+
+Run with the I<Switched 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:

Copied: branches/headercleanup/docs/book/appd_build_options.pod (from r38131, trunk/docs/book/appd_build_options.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/appd_build_options.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/appd_build_options.pod)
@@ -0,0 +1,88 @@
+=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

Copied: branches/headercleanup/docs/book/appe_source_code.pod (from r38131, trunk/docs/book/appe_source_code.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/appe_source_code.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/appe_source_code.pod)
@@ -0,0 +1,67 @@
+=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

Copied: branches/headercleanup/docs/book/ch01_introduction.pod (from r38131, trunk/docs/book/ch01_introduction.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/ch01_introduction.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/ch01_introduction.pod)
@@ -0,0 +1,200 @@
+=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 notable advances
+including a register-based system rather than stack-based, and employing
+continuations as the core means of flow control.
+
+The name "Parrot" started with an April Fools' Day joke in 2001. Simon
+Cozens published an article titled "Programming Parrot", with 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>), inspired by Monty
+Python's Parrot sketch.
+
+=head2 Parrot Resources
+
+The starting point for all things related to Parrot is the main website
+U<http://www.parrot.org>. Many additional resources are listed there, as
+well as recent news and information about the project and foundation. 
+
+=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 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 just to see how things are progressing.
+
+=head3 Issue Tracking & Wiki
+
+X<trac.parrot.org website>
+X<issue tracking (trac.parrot.org)>
+
+Parrot's issue tracking is handled by a Trac site at
+U<https://trac.parrot.org>. In addition to submitting new tickets and
+tracking the status of existing tickets, this site includes a wiki used
+in project development, a source code browser, and the project roadmap.
+
+=head2 Parrot Development
+
+X<development cycles;Parrot>
+
+First released in September 2001, Parrot hit 1.0 in March 2009. The
+Parrot project makes releases on the third Tuesday of each month. Two
+releases a year are "supported" releases intended for production use,
+while the other ten releases are development releases. The supported
+releases happen in January and July.
+
+Development proceeds at a steady pace with bugs reported and fixed,
+patches submitted and applied, and features discussed and implemented.
+Activity tends to spike when a release is approaching to close tickets,
+fix bugs, clean up documentation, and prepare the supporting files for
+the release. Immediately after a release is generally a flurry of branch
+merges, feature additions, or removal of deprecated features, since the
+week after the release allows the maximum time for testing before the
+next release. Releases also encourage feedback as casual users and
+testers get their hands on the newest version.
+
+=head2 The Parrot Team
+
+Parrot is developed by a group of volunteers, broken down into several
+distinct roles, which people assume according to their skills and
+interests.
+
+=over 4
+
+=item Architect
+
+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 chief
+architect.
+
+=item Release Managers
+
+Release managers have responsibility for executing a product release
+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
+
+Metacommitters manage commit access to the Parrot repository. Once a
+contributor is selected for commit access, a metacommitter performs the
+necessary magic to give the new committer access to the SVN repository
+and the bugtracker. The architect is a metacommitter, but other team
+members may also hold this role.
+
+=item Committer
+
+X<Committers>
+Contributors who submit numerous, high-quality patches may be considered
+to become a committer. Committers have commit access to the full Parrot
+repository, but often specialize on particular parts of the project.
+Committer categories are described below. Contributors may be considered
+for commit access either by being nominated by another committer, or by
+requesting it.
+
+=item Core Developer
+
+Core developers develop and maintain core subsystems such as the I/O
+subsystem, the exceptions system, or the concurrency scheduler.
+
+=item Compiler Developer
+
+Compiler developers develop and maintain one or more Parrot front-end
+compilers such as IMCC, PIRC, PGE and TGE.
+
+=item High-Level Language Developer
+
+Developers who work on any of the high-level languages that target
+Parrot such as TCL, Lua or Perl 6, are high-level language developers.
+Some of these language projects are located in the Parrot repository,
+although most are maintained in separate locations.
+
+=item Build Manager
+
+Build managers maintain and extend configuration and build subsystems.
+They review smoke reports and attempt to extend platform support.
+
+=item Tester
+
+Developing, maintaining, and extending test suite coverage and testing
+tool are the key tasks for the testers. Testers are also
+responsible for testing goals, including complete coverage of core
+components on targeted platforms.
+
+=item Patch Monsters
+
+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, as they are affectionately known, are in charge of checking
+patches for conformance with coding standards and desirability of
+features.
+
+=item Cage Cleaners
+
+The cage cleaners ensure that coding standards are followed, that
+documentation is complete and accurate, that all tests are functioning
+properly, and that there are plenty of coding examples for new users to
+learn from. A class of tickets in the issue tracking system has been
+created especially for use by this group. This position encompasses
+tasks that run the gamut from entry-level to advanced, and is a good
+entry point for new users who want to get more familiar with Parrot
+internals.
+
+=item General Contributor
+
+Contributors are volunteers who write code or documentation patches,
+take part in email or online conversations, or contribute to the project
+in other important ways. All volunteer contributions are appreciated.
+
+=back
+
+=head2 Licensing
+
+The intellectual property for Parrot is held by the Parrot Foundation, a
+non-profit organization formed to support the Parrot development
+community. It is licensed 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/headercleanup/docs/book/ch01_overview.pod
==============================================================================
--- branches/headercleanup/docs/book/ch01_overview.pod	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,210 +0,0 @@
-=pod
-
-=head1 Project Overview
-
-The heart of Parrot is a language-neutral runtime environment for
-dynamic languages, such as Ruby, Python, PHP and Perl.
-
-The language-neutrality of the interpreter is partially a design
-decision for modularity. Keeping the implementation independent of the
-syntax makes the codebase cleaner and easier to maintain.
-Modular design also benefits future language designers, not just
-designers of current languages. Instead of targeting I<lex>/I<yacc> and
-reimplementing low-level features such as garbage collection and dynamic
-data types, designers can leave the details to Parrot and focus on the
-high-level features of their language: syntax, libraries, capabilities.
-Parrot does all the necessary bookkeeping, exposing a rich interface with
-capabilities that few languages can make full use of.
-
-A robust exceptions system, a capability to compile into
-platform-independent bytecode, and a clean extension and embedding
-mechanism would be just some of the necessary and standard features.
-
-
-
-Since Parrot would support the features of the major dynamic languages
-and wasn't biased to a particular syntax, it could run all these
-languages with little additional effort.  
-
-Language interoperability is another core goal. Different languages are
-suited to different tasks, and picking which language to use in a large
-software project is a common planning problem.  There's never a perfect
-fit, at least not for all jobs. Developers find themselves settling for
-the language with the most advantages and the least noticeable
-disadvantages. The ability to easily combine multiple languages within a
-single project opens up the potential of using well-tested libraries
-from one language, taking advantage of clean problem-domain expression
-in a second, while binding it together in a third that elegantly
-captures the overall architecture. It's about using languages according
-to their inherent strengths, and mitigating the cost of their
-weaknesses.
-
-The name "Parrot" started with an April Fools' Day joke in 2001. Simon
-CozensX<Cozens, Simon> published an article titled "Programming Parrot",
-with a fictional interview between Larry Wall and Guido van Rossum
-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 The Parrot Team
-
-The Parrot development team is broken down into several distinct roles,
-which people assume according to their merits and their talents. This is
-a list of those roles.
-
-=over 4
-
-=item Architect
-
-The architect has primary responsibility for setting overall direction
-of the project, and to facilitate team communication and understanding
-of architectural issues. The architect is primarily, but not solely,
-responsible for making design decisions and documenting them in Parrot
-Design Documents X<Parrot Design Documents>; responsibility for design
-and documentation of project subcomponents may be delegated to other
-members of the Project Team, or may be held jointly. The Architect also
-works with the Release Managers to develop and maintain the release
-schedule. Allison RandalX<Randal, Allison> currently leads the Parrot
-project as chief architect.
-
-=item Release Managers
-
-Release managers have responsibility for executing a product release
-according to the release schedule. The release schedule is developed
-and maintained jointly with the project Architect.
-
-=item Metacommitter
-
-All Metacommitters are responsible for managing commit access to the
-Parrot repository. Once a contributor is selected commit access, a
-Metacommitter performs the necessary magic to give the new committer
-access to the SVN repository and the bugtracker. The Architect is a
-Metacommitter, but other Project Team members may also hold this role.
-
-=item Committer
-
-X<Committers>
-Contributors who submit numerous, high-quality patches may be
-considered to become a Committer. Committers have commit access to the
-full Parrot repository, but generally work only on one or more
-subprojects; Committer categories are described below. Contributors may be
-considered for commit access either by being nominated by another
-Committer, or by requesting it.
-
-=item Core Developer
-
-Core Developers develop and maintain core subsystems such as the IO subsystem,
-the exceptions system, or the concurrency scheduler.
-
-=item Compiler Developer
-
-Compiler Developers develop and maintain one or more Parrot front-end
-compilers such as IMCC, PIRC, PGE and TGE.
-
-=item High-Level Language Developer
-
-Developers who work on any of the high-level languages that target
-Parrot such as TCL, Lua or Perl 6, are High-Level Language Developers.
-Some of these language projects are located in the Parrot repository,
-although most are maintained in separate locations.
-
-=item Build Manager
-
-Build Managers maintain and extend configuration and build subsystems.
-They review smoke reports and attempt to extend platform support.
-
-=item Tester
-
-Developing, maintaining, and extending test suite coverage and testing
-tool are the key tasks for the Testers. Testers are also
-responsible for testing goals, including complete coverage of core
-components on targeted platforms.
-
-=item Patch Monsters
-
-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, as they are affectionately known, are in charge of checking
-patches for conformance with coding standards and desirability of
-features.
-
-=item Cage Cleaners
-
-Parrot's cage, the development working environment, has a tendency to
-get messy and disorganized over time. It's the responsibility of the
-aptly-named Cage Cleaners to ensure that coding standards are followed, that
-documentation is complete and accurate, that all tests are functioning
-properly, and that there are plenty of coding examples for new users to
-learn from. A class of tickets in the issue tracking system has been
-created especially for use by this group. This position encompasses
-tasks that run the gamut from entry-level to advanced, and is a good
-entry point for new users who want to get more familiar with Parrot
-internals.
-
-=item General Contributor
-
-Contributors are volunteers who write code or documentation patches,
-take part in email or online conversations, or contribute to the project
-in other important ways. All volunteer contributions are appreciated.
-
-=back
-
-=head2 Development Cycles
-
-X<development cycles;Parrot>
-The Parrot development cycle centers on monthly releases. Most monthly releases
-are development releases, and two releases a year are production releases. The
-production releases are numbered X.0 and X.5, while the development releases
-take a major or minor version number between each production release.
-
-Development proceeds at a steady pace with bugs reported, patches
-submitted, patches applied, and all sorts of other regular development
-tasks performed. The pace isn't so much a result of careful planning as
-it is the law of averages; on any given day someone, somewhere, is
-working on Parrot. In periods of high activity there are often many more
-people working on Parrot N<Or related tools, or high-level language
-compilers, etc.> then just one. 
-
-Activity tends to spike when a release is approaching to close tickets, fix
-bugs, clean up documentation, and prepare the supporting files for the release.
-Immediately after the release, there is generally a flurry of branch merges,
-feature additions, or removal of deprecated features, since the week after the
-release allows the maximum time for testing before the next release. Releases
-also encourage feedback as casual users and testers get their hands on the
-newest version. These regular swells of activity are one of the major
-motivations for monthly releases.
-
-=head2 Getting Involved
-
-X<p2 (Parrot mailing list)>
-The first step to getting involved in the Parrot project, whether you
-want to hack code, write documentation, or help in other ways, is to
-join the mailing list. The topics on the list tend to
-revolve around practical matters: bug reports, notifications of
-changes committed to the subversion repository, questions on coding
-style, and how to implement particular features.
-
-The primary mailing list for Parrot is called "parrot-dev", and you can
-subscribe to it or view the archives through the web interface at
-U<http://lists.parrot.org/XXX>. The archives 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>.
-
-X<Parrot;sites>
-Parrot information and documentation can be accessed on the web in a
-variety of locations. The main website is U<http://www.parrot.org>,
-where you'll find recent news, and information about the project and
-foundation. The heart of development is U<http://trac.parrot.org>,
-Parrot's ticket submission and tracker, wiki, source code browser, and
-project roadmap.
-
-Parrot developers, volunteers, and well-wishers also 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 just to see how things are
-progressing.
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Modified: branches/headercleanup/docs/book/ch02_getting_started.pod
==============================================================================
--- branches/headercleanup/docs/book/ch02_getting_started.pod	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/docs/book/ch02_getting_started.pod	Wed Apr 15 19:17:06 2009	(r38132)
@@ -2,30 +2,50 @@
 
 =head1 Getting Started
 
-=head1 Building Parrot
+The first step before you start playing with Parrot 
 
-Z<CHP-2-SECT-2.2.2>
+=head2 Installing Parrot
 
-X<Parrot;source code>
-The first step before you start playing with Parrot is to get a copy of
-the source code and compile it. You can download the latest monthly
-release from U<http://www.parrot.org/release/current>.
+The simplest way to install Parrot is with pre-compiled binaries for
+your operating system or distribution. Packages are available for many
+packaging systems, including Debian, Fedora, Mandriva, FreeBSD, Cygwin,
+and MacPorts. A current list of available packages is maintained 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, you can download the latest
+supported release from U<http://www.parrot.org/release/supported>.
 
 To build Parrot you'll need a C compiler and a make utility. Generally,
 you'll use F<gcc> and F<make>, but many different versions of these
 tools are supported on different operation systems. Perl is also needed
-for parts of the configuration and build process. The following
-command-line instructions will build the core virtual machine and
-compiler toolkit, and run the standard test suite.
+for parts of the configuration and build process.
+
+The following command-line instructions build the core virtual machine
+and compiler toolkit, and run the standard test suite.
 
   $ perl Configure.pl
   $ make
   $ make test
+  $ make install
+
+If you're developing a language on Parrot, you'll also want to install
+the Parrot developer tools:
+
+  $ make install-dev
+
+By default, Parrot is installed in F</usr/local>, but you can
+specify a different location with the C<--prefix> flag to the
+configuration script.
+
+  $ perl Configure.pl --prefix=/home/me/parrot
 
-Once you've compiled Parrot, you can run your first small script. Create
-a test file in the main F<parrot> directory called F<fjord.pasm>. C<.pasm>
-files are written in primative Parrot Assembly Language (PASM) which is a
-low-level programming interface to Parrot.
+=head2 Running Parrot
+
+Once you've installed Parrot, you can run your first small script. Create
+a test file called F<fjord.pasm>. C<.pasm>
+files are written in Parrot Assembly Language (PASM) which is a
+low-level language native to the Parrot virtual machine.
 
 =begin PASM
 
@@ -36,12 +56,14 @@
 
 Now run this file with:
 
-  $ ./parrot fjord.pasm
+  $ parrot fjord.pasm
 
 which will print:
 
   He's pining for the fjords.
 
+=head2 Running a Language on Parrot
+
 Next, try out one of Parrot's high-level languages. Create a test file
 called F<hello.nqp>:
 
@@ -49,176 +71,96 @@
 
 Then run it as:
 
-  $ ./nqp hello.nqp
-  
-This will print, of course, the phrase "Hello, World". NQP stands for I<Not
-Quite Perl>, it's a mini language that's very similar to the Perl 6 programming
-language. NQP is part of the Parrot Compiler Tools (PCT) and is an integral
-part of building compilers for Parrot. We will talk more about NQP and the
-rest of the PCT tools, and how to use these for building compilers for Parrot
-in chapter 9.
-
-In the next few chapters we will discuss more aspects of Parrot programming
-using low-level PASM language, and a higher-level interface language called
-PIR. Chapters 3 and 4 will talk about PIR, which is the primary way to program
-Parrot directly. Chapter 5 will talk about PASM, and the low-level programming
-interface.
-
-=head2 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.
+  $ nqp hello.nqp
+
+which will print:
+
+  Hello, World!
+
+=head2 What Next?
+
+This book provides details on the components of Parrot relevant to
+various development tasks. You may pick and choose chapters based on
+your area of interest:
 
 =over 4
 
-=item * C Compiler
+=item Chapter 3, I<Parrot Intermediate Representation>
 
-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).
+Parrot Intermediate Representation (PIR) is a mid-level language native
+to the Parrot virtual machine. It's commonly used for writing extensions
+and tools for Parrot.
 
-=item * make
+=item Chapter 4, I<Compiler Tools>
 
-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.
+The Parrot Compiler Toolkit (PCT) provides a common infrastructure and
+set of utilities for implementing languages on Parrot.
 
-=item * Subversion
+=item Chapter 5, I<Grammar Engine>
 
-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.
+The Parrot Grammar Engine (PGE) is a next-generation regular expression
+engine and recursive descent parser. PGE is part of the compiler tools,
+and the first step to implementing a language on Parrot.
 
-=item * bison and flex
+=item Chapter 6, I<Grammar Actions>
 
-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.
+NQP (Not Quite Perl) is a lightweight language loosely inspired by the
+Perl 6 specification. NQP is part of the compiler tools and is an
+integral part of building language implementations on Parrot.
 
-=item * ICU
+=item Chapter 7, I<Dynamic C-Level Objects>
 
-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.
+Parrot allows dynamic extensions to Parrot's core data types. These are
+commonly used in more advanced language implementations. This chapter
+covers the details of writing and building these object extensions.
 
-=item * GMP
+=item Chapter 8, I<Dynamic Opcodes>
 
-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.
+Parrot allows dynamic extensions to the core instruction set. These are
+commonly used in more advanced language implementations. This chapter
+covers the details of writing and building these opcode extensions.
 
-=item * Readline
+=item Chapter 9, I<Parrot Assembly Language>
 
-The readline library allows some advanced behaviors on the command line such
-as command history.
+Parrot Assembly Language (PASM) is a low-level language native to the
+Parrot virtual machine. It serves as a plain-English representation of
+Parrot's bytecode format.
 
-=item * PCRE
+=item Appendix A, I<Glossary>
 
-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:
+A quick reference to common Parrot terms.
 
-  sudo apt-get install libpcre3-dev
+=item Appendix B, I<Command-Line Options>
 
-=item * GDBM
+Further details on running Parrot.
 
-=item * PQ
+=item Appendix C, I<Instruction Reference>
 
-=item * GLUT
+The standard instruction set for the Parrot virtual machine.
 
-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:
+=item Appendix D, I<Directive Reference>
 
-  sudo apt-get install libglut3-dev
+Out-of-band directives used within PIR/PASM code.
 
-=back
+=item Appendix E, I<Operator Reference>
+
+Operator syntax in PIR code.
+
+=item Appendix F, I<Build Options>
+
+Dependencies and additional options for building Parrot from source.
 
-In addition to these build requirements listed above, there are a number of
-Perl libraries needed to enable all 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
-
-
-=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
-also available from CPAN. The sure way to get the most recent release is at
-U<http://search.cpan.org/dist/parrot/> (or search for "parrot" in
-"Distributions"). If you want something a little more cutting edge than
-the packaged release, a new snapshot of the subversion repository is
-created every eight hours. The most recent snapshot is always available
-at U<http://cvs.perl.org/snapshots/parrot/parrot-latest.tar.gz>.
-
-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 A<CHP-11>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 A<CHP-3> Chapter 3, A<CHP-5> Chapter 5, and A<CHP-7> Chapter 7
-respectively.
+=item Appendix G, I<Source Code>
 
+Navigating the Parrot source tree.
+
+=item Appendix H, I<Patch Submission>
+
+How to submit a patch to Parrot.
+
+
+=back
+  
 =cut
 
 # Local variables:

Copied: branches/headercleanup/docs/book/ch03_pir.pod (from r38131, trunk/docs/book/ch03_pir.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/ch03_pir.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/ch03_pir.pod)
@@ -0,0 +1,2541 @@
+=pod
+
+=head1 Parrot Intermediate Representation
+
+Z<CHP-3>
+
+X<Parrot Intermediate Representation;;(see PIR)>
+X<PIR (Parrot intermediate representation)>
+The Parrot intermediate representation (PIR) is the primary way to program
+Parrot directly. It used to be an overlay on top of the far more primitive
+Parrot assembly language (PASM). However, PIR and PASM have since diverged
+semantically in a number of places and no longer are directly related to
+one another. PIR has many high-level features that will be familiar to
+programmers, such as basic operator syntax. However, it's still very
+low-level, and is closely tied to the underlying virtual machine. In fact,
+the Parrot developers specifically want to keep in that way for a
+number of reasons. PASM, the Parrot assembly language, is discussed in more
+detail in Chapter 5.
+
+X<.pir files>
+As a convention, files containing pure PIR code generally
+have a F<.pir> extension. PASM files typically end with F<.pasm>. Compiled
+Parrot Bytecode (PBC) files have a F<.pbc> extension. We'll talk more
+about PBC and PASM in later chapters.
+
+X<PIR (Parrot intermediate representation);documentation>
+PIR is well documented, both in traditional documentation and in
+instructional code examples. The project documentation in F<docs/> are good
+sources for information about the current syntax, semantics, and
+implementation.  The test suite in F<t/compilers/imcc/> shows examples
+of proper working code. In fact, the test suite is the definitive PIR
+resource, because it shows how PIR I<actually works>, even when the
+documentation may be out of date.
+
+=head2 Statements
+
+Z<CHP-3-SECT-1>
+
+X<statements (PIR)>
+X<PIR (Parrot intermediate representation);statements>
+The syntax of statements in PIR is much more flexible then is commonly
+found in assembly languages, but is more rigid and "close to the machine"
+then some higher-level languages like C are. PIR has a very close
+relationship with the Parrot assembly language, PASM. PASM instructions,
+with some small changes and caveats, are valid PIR instructions. PIR does
+add some extra syntactic options to help improve readability and
+programmability, however. The statement delimiter for both PIR and PASM is
+a newline C<\n>. Each statement has to be on its own line N<This isn't
+entirely true when you consider things like macros and heredocs, but we'll
+tackle those issues when we come to them.>, but empty whitespace lines
+between statements are okay. Statements may also start with a label, for
+use with jumps and branches. Comments are marked by a hash sign (C<#>),
+and continue until the end of the line. POD blocks may be used for
+multi-line documentation. We'll talk about all these issues in more detail
+as we go.
+
+To help with readability, PIR has some high-level constructs, including
+symbol operators:
+
+  $I1 = 5                       # set $I1, 5
+
+named variables:
+
+  .param int count
+  count = 5
+
+and complex statements built from multiple keywords and symbol
+operators:
+
+  if $I1 <= 5 goto LABEL        # le $I1, 5, LABEL
+
+We will get into all of these in more detail as we go. Notice that PIR
+does not, and will not, have high-level looping structures like C<while>
+or C<for> loops. PIR has some support for basic C<if> branching constructs,
+but will not support more complicated C<if>/C<then>/C<else> branch
+structures. Because of these omissions PIR can become a little bit messy
+and unwieldy for large programs. Luckily, there are a large group of
+high-level languages (HLL) that can be used to program Parrot instead. PIR
+is used primarily to write the compilers and libraries for these languages,
+while those languages can be used for writing larger and more complicated
+programs.
+
+=head2 Directives
+
+PIR has a number of directives, instructions which are handle specially by
+the parser to perform operations. Some directives specify actions that should
+be taken at compile-time. Some directives represent complex operations
+that require the generation of multiple PIR or PASM instructions. PIR also
+has a macro facility to create user-defined directives that are replaced
+at compile-time with the specified PIR code.
+
+Directives all start with a C<.> period. They take a variety of different
+forms, depending on what they are, what they do, and what arguments they
+take. We'll talk more about the various directives and about PIR macros in
+this and in later chapters.
+
+=head2 Variables and Constants
+
+Z<CHP-3-SECT-2>
+
+=head2 Parrot Registers
+
+Z<CHP-3-SECT-2.1>
+
+PIR code has a variety of ways to store values while you work with
+them. Actually, the only place to store values is in a Parrot register,
+but there are multiple ways to work with these registers. Register names
+in PIR always start with a dollar sign, followed by a single
+character that shows whether it is an integer (I), numeric (N), string
+(S), or PMC (P) register, and then the number of the register:
+
+  $S0 = "Hello, Polly.\n"
+  print $S0
+
+Integer (I) and Number (N) registers use platform-dependent sizes and
+limitations N<There are a few exceptions to this, we use platform-dependent
+behavior when the platforms behave sanely. Parrot will smooth out some of
+the bumps and inconsistencies so that behavior of PIR code will be the same
+on all platforms that Parrot supports>. Both I and N registers are treated
+as signed quantities internally for the purposes of arithmetic. Parrot's
+floating point values and operations are all IEEE 754 compliant.
+
+Strings (S) are buffers of data with a consistent formatting but a variable
+size. By far the most common use of S registers and variables is for storing
+text data. S registers may also be used in some circumstances as buffers
+for binary or other non-text data. However, this is an uncommon usage of
+them, and for most such data there will likely be a PMC type that is better
+suited to store and manipulate it. Parrot strings are designed to be very
+flexible and powerful, to account for all the complexity of human-readable
+(and computer-representable) text data.
+
+The final data type is the PMC, a complex and flexible data type. PMCs are,
+in the world of Parrot, similar to what classes and objects are in
+object-oriented languages. PMCs are the basis for complex data structures
+and object-oriented behavior in Parrot. We'll discuss them in more detail
+in this and in later chapters.
+
+=head2 Constants
+
+X<constants (PIR)>
+X<PIR (Parrot intermediate representation);constants>
+X<strings;in PIR>
+As we've just seen, Parrot has four primary data types: integers,
+floating-point numbers, strings, and PMCs. Integers and floating-point
+numbers can be specified in the code with numeric constants in a variety
+of formats:
+
+  $I0 = 42       # Integers are regular numeric constants
+  $I1 = -1       # They can be negative or positive
+  $I2 = 0xA5     # They can also be hexadecimal
+  $I3 = 0b01010  # ...or binary
+
+  $N0 = 3.14     # Numbers can have a decimal point
+  $N1 = 4        # ...or they don't
+  $N2 = -1.2e+4  # Numbers can also use scientific notation.
+
+String literals are enclosed in single or double-quotes:
+
+  $S0 = "This is a valid literal string"
+  $S1 = 'This is also a valid literal string'
+
+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'
+
+Here's a quick listing of the escape sequences supported by 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
+
+Or, if you need more flexibility, you can use a I<heredoc> string literal:
+
+  $S2 = << "End_Token"
+
+  This is a multi-line string literal. Notice that
+  it doesn't use quotation marks. The string continues
+  until the ending token (the thing in quotes next to
+  the << above) is found. The terminator must appear on
+  its own line, must appear at the beginning of the
+  line, and may not have any trailing whitespace.
+
+  End_Token
+
+=head3 Strings: Encodings and Charsets
+
+Strings are complicated. We showed three different ways to specify string
+literals in PIR code, but that wasn't the entire story. It used to be that
+all a computer system needed was to support the ASCII charset, a mapping of
+128 bit patterns to symbols and English-language characters. This was
+sufficient so long as all computer users could read and write English, and
+were satisfied with a small handful of punctuation symbols that were commonly
+used in English-speaking countries. However, this is a woefully insufficient
+system to use when we are talking about software portability between countries
+and continents and languages. Now we need to worry about several character
+encodings and charsets in order to make sense out of all the string data
+in the world.
+
+Parrot has a very flexible system for handling and manipulating strings.
+Every string is associated with an encoding and a character set (charset).
+The default for Parrot is 8-bit ASCII, which is simple to use and is almost
+universally supported. However, support is built in to have other formats as
+well.
+
+Double-quoted string constants, like the ones we've seen above, can have an
+optional prefix specifying the charset or both the encoding and charset of the
+string. 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 treated as raw unformatted binary"
+
+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 isn't
+treated as if it contains any readable characters. These kinds of strings
+are useful for library routines that return large amounts of binary data
+that doesn't easily fit into any other primitive data type.
+
+Notice that only double-quoted strings can have encoding and charset prefixes
+like this. Single-quoted strings do not support them.
+
+When two types of strings are combined together in some way, such as through
+concatenation, they must both use the same character set an encoding.
+Parrot will automatically upgrade one or both of the strings to use the next
+highest compatible format, if they aren't equal. ASCII strings will
+automatically upgrade to UTF-8 strings if needed, and UTF-8 will upgrade
+to UTF-16. Handling and maintaining these data and conversions all happens
+automatically inside Parrot, and 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>
+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.\n"
+  print hello
+
+This snippet defines a string variable named C<hello>, assigns it the
+value "Hello, Polly.\n", 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> N<Also, you can
+use any predefined PMC class name like C<BigNum> or C<LexPad>. We'll talk
+about classes and PMC object types in a little bit.>. 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,
+especially since the automatic code generators in use with the various
+high-level languages on parrot tend to generate very long identifier
+names in some situations. Of course, huge identifier names could
+cause all sorts of memory allocation problems or inefficiencies during
+lexical analysis and parsing. You should push the limits at your own risk.
+
+=head2 Register Allocator
+
+Now's a decent time to talk about Parrot's register allocator N<it's also
+sometimes humorously referred to as the "register alligator", due to an
+oft-repeated typo and the fact that the algorithm will bite you if you get
+too close to it>. When you use a register like C<$P5>, you aren't necessarily
+talking about the fifth register in memory. This is important since you can
+use a register named $P10000000 without forcing Parrot to allocate an array
+of ten million registers. Instead Parrot's compiler front-end uses an
+allocation algorithm which turns each individual register referenced in the
+PIR source code into a reference to an actual memory storage location. Here
+is a short example of how registers might be mapped:
+
+  $I20 = 5       # First register, I0
+  $I10000 = 6    # Second register, I1
+  $I13 = 7       # Third register, I2
+
+The allocator can also serve as a type of optimization. It performs a
+lifetime analysis on the registers to determine when they are being used and
+when they are not. When a register stops being used for one thing, it can
+be reused later for a different purpose. Register reuse helps to keep
+Parrot's memory requirements lower, because fewer unique registers need to
+be allocated. However, the downside of the register allocator is that it
+takes more time to execute during the compilation phase. Here's an example
+of where a register could be reused:
+
+=begin PIR
+
+  .sub main
+    $S0 = "hello "
+    print $S0
+    $S1 = "world!"
+    print $S1
+  .end
+
+=end PIR
+
+We'll talk about subroutines in more detail in the next chapter. For now,
+we can dissect this little bit of code to see what is happening. The C<.sub>
+and C<.end> directives demarcate the beginning and end of a subroutine
+called C<main>. This convention should be familiar to C and C++ programmers,
+although it's not required that the first subroutine N<or any subroutine
+for that matter> be named "main". In this code sequence, we assign the
+string C<"hello "> to the register C<$S0> and use the C<print> opcode to
+display it to the terminal. Then, we assign a second string C<"world!"> to
+a second register C<$S1>, and then C<print> that to the terminal as well.
+The resulting output of this small program is, of course, the well-worn
+salutation C<hello world!>.
+
+Parrot's compiler and register allocator are smart enough to realize that
+the two registers in the example above, C<$S0> and C<$S1> are used exclusively
+of one another. C<$S0> is assigned a value in line 2, and is read in line 3,
+but is never accessed after that. So, Parrot determines that its lifespan
+ends at line 3. The register C<$S1> is used first on line 4, and is accessed
+again on line 5. Since these two do not overlap, Parrot's compiler can
+determine that it can use only one register for both operations. This saves
+the second allocation. Notice that this code with only one register performs
+identically to the previous example:
+
+=begin PIR
+
+  .sub main
+    $S0 = "hello "
+    print $S0
+    $S0 = "world!"
+    print $S0
+  .end
+
+=end PIR
+
+In some situations it can be helpful to turn the allocator off and avoid
+expensive optimizations. Such situations are subroutines where there are a
+small fixed number of registers used, when variables are used throughout the
+subroutine and should never be reused, or when some kind of pointer reference
+needs to be made to the register N<this happens in some NCI calls that take
+pointers and return values>. To turn off the register allocator for certain
+variables, you can use the C<:unique_reg> modifier:
+
+  .local pmc MyUniquePMC :unique_reg
+
+Notice that C<:unique_reg> shouldn't affect the behavior of Parrot, but
+instead only changes the way registers are allocated. It's a trade off between
+using more memory in exchange for less time spent optimizing the subroutine.
+
+=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 'PerlString'     # This is how the Perl people do it
+  $P0 = "Hello, Polly.\n"
+  print $P0
+
+This example creates a C<PerlString> object, stores it in the PMC
+register C<$P0>, assigns the value "Hello, Polly.\n" to it, and prints
+it.  With named variables the type passed to the C<.local> directive is
+either the generic C<pmc> or a type compatible with the type passed to
+C<new>:
+
+  .local PerlString hello    # or .local pmc hello
+  hello = new 'PerlString'
+  hello = "Hello, Polly.\n"
+  print hello
+
+PIR is a dynamic language, and that dynamicism is readily displayed in
+the way PMC values are handled. Primitive registers like strings,
+numbers, and integers perform a special action called I<autoboxing>
+when they are assigned to a PMC. Autoboxing is when a primitive scalar
+type is automatically converted to a PMC object type. There are PMC
+classes for String, Number, and Integer which can be quickly converted
+to and from primitive int, number, and string types. Notice that the
+primitive types are in lower-case, while the PMC classes are
+capitalized. If you want to box a value explicitly, you can 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. However, 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 also have special custom methods available for performing various
+operations, they may be passed as PMCs to subroutines that only expect
+PMC arguments, and they can be subclassed by a user-defined type. We'll
+discuss all these complicated topics later in this chapter and in the next
+chapter. We will discuss PMC and all the details of their implementation and
+interactions in Chapter 11.
+
+=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's very similar
+to C<.local>, and requires a type and a name. The value of a constant
+must be assigned in the declaration statement. As with named
+variables, named constants are visible 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.\n"
+  print 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,
+although a way to do so may be added in later versions of Parrot.
+
+=head2 Symbol Operators
+
+Z<CHP-3-SECT-3>
+
+X<symbol operators in PIR>
+PIR has many other symbol 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
+  print sum
+  print "\n"
+
+The statement C<sum = $I42 + 5> translates to the equivalent statement
+C<add sum, $I42, 5>. This in turn will be translated to an equivalent
+PASM instruction which will be similar to C<add I0, I1, 5>. Notice that
+in the PASM instruction the register names do not have the C<$> symbol in
+front of them, and they've already been optimized into smaller numbers by
+the register allocator. The exact translation from PIR statement to PASM
+instruction isn't too important N<Unless you're hacking on the Parrot
+compiler!>, so we don't have to worry about it for now. We will talk more
+about PASM, its syntax and its instruction set in X<CHP-5> Chapter 5.
+Here are examples of some PIR symbolic operations:
+
+  $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
+
+We've mostly glossed over the behavior of the C<=> operator, although it's
+a very powerful and important operator in PIR. In it's most simple form,
+C<=> stores a value into one of the Parrot registers. We've seen cases where
+it can be used to assign a string value to a C<string> register, or an integer
+value to an C<int> register, or a floating point value into a C<number>
+register, etc. However, the C<=> operator can be used to assign any type
+of value into any type of register, and 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
+
+We've also seen an example earlier where a string literal was set into a
+PMC register that had a 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      # De-box. $I0 = 5
+
+  $P1 = new 'String'
+  $P1 = "5 birds"
+  $S1 = $P1      # De-box. $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      # De-box. $N2 = 3.14
+
+=head2 Labels
+
+Z<CHP-3-SECT-4>
+
+X<PIR (Parrot intermediate representation);labels>
+X<labels (PIR)>
+Any line in PIR can start with a label definition like C<LABEL:>,
+but label definitions can also stand alone on their own line. Labels are
+like flags or markers that the program can jump to or return to at different
+times. Labels and jump operations (which we will discuss a little bit
+later) are one of the primary methods to change control flow in PIR, so
+it is well worth understanding.
+
+Labels are most often used in branching instructions, which are used
+to implement high level control structures by our high-level language
+compilers.
+
+=head2 Compilation Units
+
+Z<CHP-3-SECT-4.1>
+
+X<PIR (Parrot intermediate representation);compilation units>
+X<compilation units (PIR)>
+Compilation units in PIR are roughly equivalent to the subroutines or
+methods of a high-level language. Though they will be explained in
+more detail later, we introduce them here because all code in a PIR
+source file must be defined in a compilation unit. We've already seen an
+example for the simplest syntax for a PIR compilation unit. It starts with
+the C<.sub> directive and ends with the C<.end> directive:
+
+=begin PIR
+
+  .sub main
+      print "Hello, Polly.\n"
+  .end
+
+=end PIR
+
+Again, we don't need to name the subroutine C<main>, it's just a common
+convention. This example defines a compilation unit named C<main> that
+prints a string C<"Hello, Polly.">. The first compilation unit in a file
+is normally executed first but you can flag any compilation unit as the
+first one to execute with the C<:main> marker.
+
+=begin PIR
+
+  .sub first
+      print "Polly want a cracker?\n"
+  .end
+
+  .sub second :main
+      print "Hello, Polly.\n"
+  .end
+
+=end PIR
+
+This code prints out "Hello, Polly." but not "Polly want a cracker?".
+This is because the function C<second> has the C<:main> flag, so it is
+executed first. The function C<first>, which doesn't have this flag
+is never executed. However, if we change around this example a little:
+
+=begin PIR
+
+  .sub first :main
+      print "Polly want a cracker?\n"
+  .end
+
+  .sub second
+      print "Hello, Polly.\n"
+  .end
+
+=end PIR
+
+The output now is "Polly want a cracker?". Execution in PIR starts
+at the C<:main> function and continues until the end of that function
+only. If you want to do more stuff if your program, you will need to
+call other functions explicitly.
+
+Chapter 4 goes into much more detail about compilation units
+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 is done entirely with conditional and unconditional
+branches to labels. This may seem simplistic and primitive, but
+remember that PIR is a thin overlay on the assembly language of a
+virtual processor, and is intended to be a simple target for the compilers
+of various. high-level languages. High level control structures are invariably linked
+to the language in which they are used, so any attempt by Parrot to
+provide these structures would work well for some languages but would
+require all sorts of messy translation in others. The only way to make
+sure all languages and their control structures can be equally
+accommodated is to simply give them the most simple and fundamental
+building blocks to work with. Language agnosticism is an important
+design goal in Parrot, and creates a very flexible and powerful
+development environment for our language developers.
+
+X<goto instruction (PIR)>
+The most basic branching instruction is the unconditional branch:
+C<goto>.
+
+=begin PIR
+
+  .sub _main
+      goto L1
+      print "never printed"
+  L1:
+      print "after branch\n"
+      end
+  .end
+
+=end PIR
+
+The first C<print> 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
+      print "never printed"
+  L1: print "after branch\n"
+      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 quite
+similar, but branches when the tested value is false. An undefined
+value, 0, or an empty string are all false values. Any other values
+are considered to be true values.
+
+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
+      print "never printed"
+  L1:
+      print "after branch\n"
+      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 PASM C<lt> branch operation.
+
+The rest of the comparison operators are summarized in
+"PIR Instructions" in Chapter 11.
+
+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
+
+      print $I0
+      print "\n"
+      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 then branches to the start of the loop.
+The loop ends when C<$I1> counts down to 0 so that the C<if> doesn't
+branch to C<REDO>. This is a I<do while>-style loop with the condition
+test at the end, so the code always runs the first time through.
+
+X<while-style loop (PIR)>
+For a I<while>-style loop with the condition test at the start, use a
+conditional branch together 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
+
+      print $I0
+      print "\n"
+      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 never
+executes.
+
+Any high-level flow control construct can be built from conditional
+and unconditional branches, because this is the way almost all computer
+hardware operates at the lowest-level, so all modern programming
+languages use branching constructs to implement their most complex
+flow control devices.
+
+Fortunately, libraries of macros have been developed that can implement
+more familiar syntax for many of these control structures. We will discuss
+these libraries in more detail in "PIR Standard Library".
+
+
+=head2 Subroutines
+
+Z<CHP-4>
+
+X<PIR (Parrot intermediate representation);subroutines>
+X<subroutines;in PIR>
+Code reuse has become a cornerstone of modern software engineering.
+Common tasks are routinely packaged as libraries for later reuse
+by other developers. The most basic building block of code reuse is
+the "function" or "subroutine". A calculation like "the factorial of
+a number", for example, may be used several times in a large program.
+Subroutines allow this kind of functionality to be abstracted into a
+single stand-alone unit for reuse. PIR is a subroutine-based language
+in that all code in PIR must exist in a subroutine. Execution starts,
+as we have seen, in the C<:main> subroutine, and others can be called
+to perform the tasks of a program. From subroutines we can construct
+more elaborate chunks of code reusability methods and objects. In
+this chapter we will talk about how subroutines work in PIR, and how
+they can be used by developers to create programs for Parrot.
+
+Parrot supports multiple high-level languages, and 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
+syntax for subroutines 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--by passing arguments, altering
+control flow, and returning results--is called the "Parrot Calling
+Conventions", or PCC. The details of PCC are generally hidden from the
+programmer, being partially implemented in C and being partially
+implemented in PASM. 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 of this can be largely
+ignored for developers who don't need it, but the power of this approach
+can be harnessed by those who do. We'll talk more about PCC and CPS in
+this and in later chapters as well.
+
+=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 a great deal of complexity. It generates a
+subroutine PMC object, creates a continuation PMC object to return
+control flow after the subroutine, passes the arguments, looks up the
+subroutine by name (and by signature if it's been overloaded), it calls
+the subroutine, and finally it assigns the results of the call to the
+given register variables. This is quite a lot of work for a single
+statement, and that's ignoring the computational logic that the
+subroutine itself implements.
+
+=head3 Expanded Subroutine Syntax
+
+The single line subroutine call is incredibly convenient, but it isn't
+always flexible enough. So PIR also has a more verbose call syntax
+that is still more convenient than manual calls. This example pulls
+the subroutine C<fact> out of the global symbol table into a PMC
+register 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, returns 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. Subroutines are defined with the C<.sub>
+directive, and end with the C<.end> directive. We've already seen
+this syntax in our earlier examples. The C<.param> defines input
+parameters and creates local named variables for them:
+
+  .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 compilation unit, 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
+     .local int count
+     .local int product
+     count = 5
+     product = 1
+
+     $I0 = 'fact'(count, product)
+
+     print $I0
+     print "\n"
+     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 passing the two variables as arguments. In the call, the
+two arguments are assigned to consecutive integer registers, because
+they're stored in typed integer variables. The C<fact> subroutine
+uses C<.param> and the C<.return> directives for retrieving parameters
+and returning results. The final printed result is 120.
+
+Execution of the program starts at the C<:main> subroutine or, if no
+subroutines are declared with C<:main> at the first subroutine in the file.
+If multiple subroutines are declared with C<:main>, the last of them is
+treated as the starting point. Eventually, declaring multiple subroutines
+with C<:main> might cause a syntax error or some other bad behavior, so it's
+not a good idea to rely on it now.
+
+=head3 Named Parameters
+
+Parameters that are passed in a strict order like we've seen above are
+called '''positional arguments'''. Positional arguments are
+differentiated from one another by their position in the function call.
+Putting positional arguments in a different order will produce different
+effects, or may cause errors. Parrot supports a second type of parameter,
+a '''named parameter'''. 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 = $S1 . " years old"
+    print $S0
+    print $S1
+ .end
+
+ .sub main :main
+    'MySub'("age" => 42, "name" => "Bob")
+ .end
+
+=end PIR
+
+In the example above, we could have easily reversed the order too:
+
+=begin PIR
+
+ .sub main :main
+    'MySub'("name" => "Bob", "age" => 42)    # Same!
+ .end
+
+=end PIR
+
+Named arguments can be a big help because you don't have to worry about
+the exact order of variables, especially as argument lists get very long.
+
+=head3 Optional Parameters
+
+Sometimes there are parameters to a function that don't always need to be
+passed, or values for a parameter which should be given a default value
+if a different value hasn't been explicitly provided. Parrot provides
+a mechanism for allowing optional parameters to be specified, so an
+error won't be raised if the parameter isn't provided. Parrot also
+provides a flag value that can be tested to determine if an optional
+parameter has been provided or not, so a default value can be supplied.
+
+Optional parameters are actually treated like two parameters: The value
+that may or may not be passed, and the flag value to determine if it
+has been or not. Here's an example declaration of an optional parameter:
+
+  .param string name :optional
+  .param int has_name :opt_flag
+
+The C<:optional> flag specifies that the given parameter is optional and
+does not necessarily need to be provided. The C<:opt_flag> specifies that
+an integer parameter contains a boolean flag. This flag is true if the
+value was passed, and false otherwise. This means we can use logic like
+this to provide a default value:
+
+  .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. When using them
+with positional parameters, they 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!
+    ...
+
+Optional parameters can also be mixed with named parameters:
+
+  .sub 'MySub'
+    .param int value :named("answer") :optional
+    .param int has_value :opt_flag
+    ...
+
+This could be called in two ways:
+
+  'MySub'("answer" => 42)  # with a value
+  'MySub'()                # without
+
+=head3 Sub PMCs
+
+Subroutines are a PMC type in Parrot, and references to them can be stored
+in PMC registers and manipulated like other PMC types. You can get a subroutine
+in the current namespace with the C<get_global> opcode:
+
+  $P0 = get_global "MySubName"
+
+Or, if you want to find a subroutine from a different namespace, you need
+to first select the namespace PMC and then pass that to C<get_global>:
+
+  $P0 = get_namespace "MyNamespace"
+  $P1 = get_global $P0, "MySubName"
+
+With a Sub PMC, there are lots of things you can do. You can obviously invoke
+it:
+
+  $P0(1, 2, 3)
+
+You can get its name or 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 1 if the sub has a slurpy parameter to eat up extra positional args
+
+=item * named_slurpy
+
+Returns 1 if the sub has a slurpy parameter to eat up extra named args
+
+=back
+
+Instead of getting the whole inspection hash, you can look for individual
+data items that you want:
+
+  $I0 = inspect $P0, "pos_required"
+
+If you want to get the total number of defined parameters to the Sub, you can
+call the C<arity> method:
+
+  $I0 = $P0.'arity'()
+
+To get the namespace PMC that the Sub was defined into, you can call the
+C<get_namespace> method:
+
+  $P1 = $P0.'get_namespace'()
+
+Subroutine PMCs are very useful things, and we will show more of their uses
+throughout this chapter.
+
+=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
+
+
+=head2 Continuation Passing Style
+
+Continuations are snapshots, a frozen image of the current execution
+state of the VM. Once we have a continuation we 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 N<there's actually
+no magic involved, just a lot of interesting ideas and involved code>.
+
+Continuations are not a new concept, they've been boggling the minds
+of Lisp and Scheme programmers for many years. However, despite all
+their power and flexibility they haven't been well-utilized in most
+modern programming languages or in their underlying libraries and
+virtual machines. Parrot aims to change that: In Parrot, almost every
+control flow manipulation including all subroutine, method, and
+coroutine calls, are performed using continuations. This mechanism
+is mostly hidden from developers who build applications on top of
+Parrot. The power and flexibility is available if people want to use
+it, but it's hidden behind more familiar constructs if not.
+
+Doing all sorts of flow control using continuations is called
+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
+
+In many cases, a subroutine will set up and call another subroutine,
+and then return the result of the second call directly. This is called
+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 used as the return value. C<add_one> is called
+and its result is immediately returned to the caller of C<add_two>, it is
+never stored in a local register or variable in C<add_two>, it's immediately
+returned. We can optimize this situation if we realize that the second call to
+C<add_one> is returning to the same place that C<add_two> is, and therefore
+can utilize the same return continuation as 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>
+In PIR code, we use the C<.tailcall> directive to make a tailcall like this,
+instead of the C<.return> directive. C<.tailcall> performs this optimization
+by reusing the return continuation of the parent function to make the
+tailcall. In PIR, we can write this example:
+
+=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 will print out the correct value "7".
+
+=head3 Creating and Using Continuations
+
+Most often continuations are used implicitly by the other control-flow
+operations in Parrot. However, they can also be created and used explicitly
+when required. Continuations are like any other PMC, and can be created
+using the C<new> keyword:
+
+  $P0 = new 'Continuation'
+
+The new continuation starts off in an undefined state. Attempting to invoke
+a new continuation after it's first been created will raise an exception. To
+prepare the continuation for use, a destination label must be assigned to it
+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 when the continuation was created, use the C<invoke> opcode
+or the C<()> notation:
+
+  invoke $P0  # Explicit using "invoke" opcode
+  $P0()       # Same, but nicer syntax
+
+Notice that even though you can use the subroutine notation C<$P0()> to
+invoke the continuation, it doesn't make any sense to try and pass arguments
+to it or to try and return values from it:
+
+  $P0 = new 'Continuation'
+  set_addr $P0, my_label
+
+  $P0(1, 2)      # WRONG!
+
+  $P1 = $P0()    # WRONG!
+
+=head2 Lexical Subroutines
+
+X<Lexical Subroutines>
+As we've mentioned above, Parrot offers support for lexical subroutines.
+What this means is that we can define a subroutine by name inside a
+larger subroutine, and our "inner" subroutine is only visible and callable
+from the "outer" outer. The "inner" subroutine inherits all the lexical
+variables from the outer subroutine, but is able to define its
+own lexical variables that cannot be seen or modified by the outer subroutine.
+This is important because PIR doesn't have anything corresponding to blocks
+or nested scopes like some other languages have. Lexical subroutines play
+the role of nested scopes when they are needed.
+
+If the subroutine is lexical, you can get its C<:outer> with the C<get_outer>
+method on the Sub PMC:
+
+  $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
+
+Let us diverge for a minute and start looking forward at the idea of X<High
+Level Languages;HLL> High Level Languages (HLLs) such as Perl, Python, and
+Ruby. All of these languages allow nested scopes, or blocks within blocks
+that can have their own lexical variables. Let's look back at the C
+programming language, where this kind of construct is not uncommon:
+
+  {
+      int x = 0;
+      int y = 1;
+      {
+          int z = 2;
+          // x, y, and z are all visible here
+      }
+      // only x and y are visible here
+  }
+
+The code above illustrates this idea perfectly without having to get into a
+detailed and convoluted example: In the inner block, we define the variable
+C<z> which is only visible inside that block. The outer block has no
+knowledge of C<z> at all. However, the inner block does have access to the
+variables C<x> and C<y>. This is an example of nested scopes where the
+visibility of different data items can change in a single subroutine. As
+we've discussed above, Parrot doesn't have any direct analog for this
+situation: If we tried to write the code above directly, we would end up
+with this PIR code:
+
+  .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
+
+In PIR, there is only one structure that supports scoping like this: the
+subroutine N<and objects that inherit from subroutines, such as methods,
+coroutines, and multisubs, which we will discuss later>. 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
+
+In the example above we put the word C<"visible"> in quotes. 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
+
+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 N<such is the case with
+multisubs, which we will discuss soon>, 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
+
+Information about lexical variables in a subroutine is stored in two different
+types of PMCs: The LexPad PMC that we already mentioned briefly, and the
+LexInfo PMCs which we haven't. Neither of these PMC types are really usable
+from PIR code, but are instead used by Parrot internally to store information
+about lexical variables.
+
+C<LexInfo> PMCs are used to store information about lexical variables at
+compile time. This is read-only information that is generated during
+compilation to represent what is known about lexical variables. Not all
+subroutines get a LexInfo PMC by default, you need to indicate to Parrot
+somehow that you require a LexInfo PMC to be created. One way to do this is
+with the C<.lex> directive that we looked at above. Of course, the C<.lex>
+directive only works for languages where the names of lexical variables are
+all known at compile time. For languages where this information isn't known,
+the subroutine can be flagged with C<:lex> instead.
+
+C<LexPad> PMCs are used to store run-time information about lexical variables.
+This includes their current values and their type information. LexPad PMCs are
+created at runtime for subs that have a C<LexInfo> PMC already. These are
+created each time the subroutine is invoked, which allows for recursive
+subroutine calls without overwriting variable names.
+
+With a Subroutine PMC, you can get access to the associated LexInfo PMC by
+calling the C<'get_lexinfo'> method:
+
+  $P0 = find_global "MySubroutine"
+  $P1 = $P0.'get_lexinfo'()
+
+Once you have the LexInfo PMC, there are a limited number of operations that
+you can call with it:
+
+  $I0 = elements $P1    # Get the number of lexical variables from it
+  $P0 = $P1["name"]     # Get the entry for lexical variable "name"
+
+There really isn't much else useful to do with LexInfo PMCs, they're mostly
+used by Parrot internally and aren't helpful to the PIR programmer.
+
+There is no easy way to get a reference to the current LexPad PMC in a given
+subroutine, but like LexInfo PMCs that doesn't matter because they aren't
+useful from PIR anyway. Remember that subroutines themselves can be lexical
+and that therefore the lexical environment of a given variable can extend to
+multiple subroutines and therefore multiple LexPads. The opcodes C<find_lex>
+and C<store_lex> automatically search through nested LexPads recursively to
+find the proper environment information about the given variables.
+
+=head2 Compilation Units Revisited
+
+Z<CHP-4-SECT-1.1>
+
+The term "compilation unit" is one that's been bandied about throughout the
+chapter and it's worth some amount of explanation here. A compilation unit
+is a section of code that forms a single unit. In some instances the term
+can be used to describe an entire file. In most other cases, it's used to
+describe a single subroutine. Our earlier example which created a C<'fact'>
+subroutine for calculating factorials could be considered to have used two
+separate compilation units: The C<main> subroutine and the C<fact> subroutine.
+Here is a way to rewrite that algorithm using only a single subroutine instead:
+
+=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 is different from how subroutines are normally
+invoked in PIR.
+
+Another disadvantage of this approach is that C<main> and C<fact> share the
+same compilation unit, so they're parsed and processed as one piece of code.
+They share registers. They would also share 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. This is a problem when trying to follow normal encapsulation guidelines.
+
+=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. We've seen some method calls in the examples
+above, especially when we were talking about the interfaces to certain PMC
+types. We've also seen a little bit of information about classes and objects
+in the previous chapter. PIR allows you to define your own classes, and with
+those classes you can define method interfaces to them. Method calls follow
+the same Parrot calling conventions that we have seen above, including all the
+various parameter configurations, lexical scoping, and other aspects we have
+already talked about.
+
+Classes can be defined in two ways: in C and compiled to machine code, and
+in PIR. The former is how the built-in PMC types are defined, like
+C<ResizablePMCArray>, or C<Integer>. These PMC types are either built with
+Parrot at compile time, or are compiled into a shared library called a
+I<dynpmc> and loaded into Parrot at runtime. We will talk about writing PMCs
+in C, and dealing with dynpmcs in chapter 11.
+
+The second type of class can be defined in PIR at runtime. We saw some
+examples of this in the last chapter using the C<newclass> and C<subclass>
+opcodes. We also talked about class attribute values. Now, we're going to talk
+about associating subroutines with these classes, and they're called
+I<methods>. Methods are just like other normal subroutines with two major
+changes: they are marked with the C<:method> flag, and they exist in a
+I<namespace>. Before we can talk about methods, we need to discuss
+namespaces first.
+
+=head3 Namespaces
+
+Z<CHP-4-SECT-2.1>
+
+X<Namespaces>
+X<.namespace>
+Namespaces provide a mechanism where names can be reused. This may not
+sound like much, but in large complicated systems, or systems with
+many included libraries, it can be very handy. Each namespace gets its
+own area for function names and global variables. This way you can have
+multiple functions named C<create> or C<new> or C<convert>, for
+instance, without having to use I<Multi-Method Dispatch> (MMD) which we
+will describe later. Namespaces are also vital for defining classes and their
+methods, which we already mentioned. We'll talk about all those uses here.
+
+Namespaces are specified with the C<.namespace []> directive. The brackets
+are not optional, but the keys inside them are. Here are some examples:
+
+  .namespace [ ]               # The root namespace
+  .namespace [ "Foo" ]         # The namespace "Foo"
+  .namespace [ "Foo" ; "Bar" ] # Namespace Foo::Bar
+  .namespace                   # WRONG! The [] are needed
+
+Using semicolons, namespaces can be nested to any arbitrary depth.
+Namespaces are special types of PMC, so we can access them and manipulate
+them just like other data objects. We can get the PMC for the root
+namespace using the C<get_root_namespace> opcode:
+
+  $P0 = get_root_namespace
+
+The current namespace, which might be different from the root namespace
+can be retrieved with the C<get_namespace> opcode:
+
+  $P0 = get_namespace             # get current namespace PMC
+  $P0 = get_namespace ["Foo"]     # get PMC for namespace "Foo"
+
+Namespaces are arranged into a large n-ary tree. There is the root namespace
+at the top of the tree, and in the root namespace are various special HLL
+namespaces. Each HLL compiler gets its own HLL namespace where it can store
+its data during compilation and runtime. Each HLL namespace may have a large
+hierarchy of other namespaces. We'll talk more about HLL namespaces and their
+significance in chapter 10.
+
+The root namespace is a busy place. Everybody could be lazy and use it to store
+all their subroutines and global variables, and then we would run into all
+sorts of collisions. One library would define a function "Foo", and then
+another library could try to create another subroutine with the same name.
+This is called I<namespace pollution>, because everybody is trying to put
+things into the root namespace, and those things are all unrelated to each
+other. Best practices requires that namespaces be used to hold private
+information away from public information, and to keep like things together.
+
+As an example, the namespace C<Integers> could be used to store subroutines
+that deal with integers. The namespace C<images> could be used to store
+subroutines that deal with creating and manipulating images. That way, when
+we have a subroutine that adds two numbers together, and a subroutine that
+performs additive image composition, we can name them both C<add> without any
+conflict or confusion. And within the C<image> namespace we could have sub
+namespaces for C<jpeg> and C<MRI> and C<schematics>, and each of these could
+have a C<add> method without getting into each other's way.
+
+The short version is this: use namespaces. There aren't any penalties to them,
+and they do a lot of work to keep things organized and separated.
+
+=head3 Namespace PMC
+
+The C<.namespace> directive that we've seen sets the current namespace. In
+PIR code, we have multiple ways to address a namespace:
+
+  # Get namespace "a/b/c" starting at the root namespace
+  $P0 = get_root_namespace ["a" ; "b" ; "c"]
+
+  # Get namespace "a/b/c" starting in the current HLL namespace.
+  $P0 = get_hll_namespace ["a" ; "b" ; "c"]
+  # Same
+  $P0 = get_root_namespace ["hll" ; "a" ; "b" ; "c"]
+
+  # Get namespace "a/b/c" starting in the current namespace
+  $P0 = get_namespace ["a" ; "b" ; "c"]
+
+Once we have a namespace PMC we can retrieve global variables and
+subroutine PMCs from it using the following functions:
+
+  $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
+
+We've seen above how to find a Namespace PMC. Once you have it, there are a
+few things you can do with it. You can find methods and variables that are
+stored in the namespace, or you can add new ones:
+
+  $P0 = get_namespace
+  $P0.'add_namespace'($P1)      # Add Namespace $P1 to $P0
+  $P1 = $P0.'find_namespace'("MyOtherNamespace")
+
+  # Find namespace "MyNamespace" in $P0, create it if it
+  #    doesn't exist
+  $P1 = $P0.'make_namespace'("MyNamespace")
+
+  $P0.'add_sub'("MySub", $P2)   # Add Sub PMC $P2 to the namespace
+  $P1 = $P0.'find_sub'("MySub") # Find it
+
+  $P0.'add_var'("MyVar", $P3)   # Add variable "MyVar" in $P3
+  $P1 = $P0.'find_var'("MyVar") # Find it
+
+  # Return the name of Namespace $P0 as a ResizableStringArray
+  $P3 = $P0.'get_name'()
+
+  # Find the parent namespace that contains this one:
+  $P5 = $P0.'get_parent'()
+
+  # Get the Class PMC associated with this namespace:
+  $P6 = $P0.'get_class'()
+
+There are a few other operations that can be done on Namespaces, but none
+as interesting as these. We'll talk about Namespaces throughout the rest
+of this chapter.
+
+=head3 Calling Methods
+
+Z<CHP-4-SECT-2.2>
+
+Now that we've discussed namespaces, we can start to discuss all the
+interesting things that namespaces enable, like object-oriented
+programming and method calls. Methods are just like subroutines, except
+they are invoked on a object PMC, and that PMC is passed as the c<self>
+parameter.
+
+The basic syntax for a method call is similar to the single line
+subroutine call above. It takes a variable for the invocant PMC and a
+string with the name of the method:
+
+  object."methodname"(arguments)
+
+Notice that the name of the method must be contained in quotes. If the
+name of the method is not contained in quotes, it's treated as a named
+variable that does. Here's an example:
+
+  .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
+
+Methods are defined like any other subroutine except with two major
+differences: They must be inside a namespace named after the class
+they are a part of, and they must use the C<:method> flag.
+
+  .namespace [ "MyClass"]
+
+  .sub "MyMethod" :method
+    ...
+
+Inside the method, the invocant object can be accessed using the C<self>
+keyword. 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 called "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
+    print "done\n"              # in the "Foo" namespace
+    end
+  .end
+
+  .namespace [ "Foo" ]          # start namespace "Foo"
+
+  .sub meth :method             # define Foo::meth global
+     print "in meth\n"
+     $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
+     print "in other_meth\n"    # as above 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.
+
+When a C<.sub> is declared as a C<:method>, it automatically creates a
+local variable named C<self> and assigns it the object passed in
+C<P2>. You don't need to write C<.param pmc self> to get it, it comes
+free with the method.
+
+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 subscribe to 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 PMC 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 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 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 N<this is one of the
+reasons for having multisubs in the first place!>. 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.
+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<or, 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 N<in addition to methods,
+which we will talk about in the next chapter> 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 compilation unit,
+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/headercleanup/docs/book/ch03_pir_basics.pod
==============================================================================
--- branches/headercleanup/docs/book/ch03_pir_basics.pod	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,1270 +0,0 @@
-=pod
-
-=head0 Parrot Intermediate Representation
-
-Z<CHP-3>
-
-X<Parrot Intermediate Representation;;(see PIR)>
-X<PIR (Parrot intermediate representation)>
-The Parrot intermediate representation (PIR) is the primary way to program
-Parrot directly. It used to be an overlay on top of the far more primitive
-Parrot assembly language (PASM). However, PIR and PASM have since diverged
-semantically in a number of places and no longer are directly related to
-one another. PIR has many high-level features that will be familiar to
-programmers, such as basic operator syntax. However, it's still very
-low-level, and is closely tied to the underlying virtual machine. In fact,
-the Parrot developers specifically want to keep in that way for a
-number of reasons. PASM, the Parrot assembly language, is discussed in more
-detail in A<CHP-5>Chapter 5.
-
-X<.pir files>
-As a convention, files containing pure PIR code generally
-have a F<.pir> extension. PASM files typically end with F<.pasm>. Compiled
-Parrot Bytecode (PBC) files have a F<.pbc> extension. We'll talk more
-about PBC and PASM in later chapters.
-
-X<PIR (Parrot intermediate representation);documentation>
-PIR is well documented, both in traditional documentation and in
-instructional code examples. The project documentation in F<docs/> are good
-sources for information about the current syntax, semantics, and
-implementation.  The test suite in F<t/compilers/imcc/> shows examples
-of proper working code. In fact, the test suite is the definitive PIR
-resource, because it shows how PIR I<actually works>, even when the
-documentation may be out of date.
-
-=head1 Statements
-
-Z<CHP-3-SECT-1>
-
-X<statements (PIR)>
-X<PIR (Parrot intermediate representation);statements>
-The syntax of statements in PIR is much more flexible then is commonly
-found in assembly languages, but is more rigid and "close to the machine"
-then some higher-level languages like C are. PIR has a very close
-relationship with the Parrot assembly language, PASM. PASM instructions,
-with some small changes and caveats, are valid PIR instructions. PIR does
-add some extra syntactic options to help improve readability and
-programmability, however. The statement delimiter for both PIR and PASM is
-a newline C<\n>. Each statement has to be on its own line N<This isn't
-entirely true when you consider things like macros and heredocs, but we'll
-tackle those issues when we come to them.>, but empty whitespace lines
-between statements are okay. Statements may also start with a label, for
-use with jumps and branches. Comments are marked by a hash sign (C<#>),
-and continue until the end of the line. POD blocks may be used for
-multi-line documentation. We'll talk about all these issues in more detail
-as we go.
-
-To help with readability, PIR has some high-level constructs, including
-symbol operators:
-
-  $I1 = 5                       # set $I1, 5
-
-named variables:
-
-  .param int count
-  count = 5
-
-and complex statements built from multiple keywords and symbol
-operators:
-
-  if $I1 <= 5 goto LABEL        # le $I1, 5, LABEL
-
-We will get into all of these in more detail as we go. Notice that PIR
-does not, and will not, have high-level looping structures like C<while>
-or C<for> loops. PIR has some support for basic C<if> branching constructs,
-but will not support more complicated C<if>/C<then>/C<else> branch
-structures. Because of these omissions PIR can become a little bit messy
-and unwieldy for large programs. Luckily, there are a large group of
-high-level languages (HLL) that can be used to program Parrot instead. PIR
-is used primarily to write the compilers and libraries for these languages,
-while those languages can be used for writing larger and more complicated
-programs.
-
-=head2 Directives
-
-PIR has a number of directives, instructions which are handle specially by
-the parser to perform operations. Some directives specify actions that should
-be taken at compile-time. Some directives represent complex operations
-that require the generation of multiple PIR or PASM instructions. PIR also
-has a macro facility to create user-defined directives that are replaced
-at compile-time with the specified PIR code.
-
-Directives all start with a C<.> period. They take a variety of different
-forms, depending on what they are, what they do, and what arguments they
-take. We'll talk more about the various directives and about PIR macros in
-this and in later chapters.
-
-=head1 Variables and Constants
-
-Z<CHP-3-SECT-2>
-
-=head2 Parrot Registers
-
-Z<CHP-3-SECT-2.1>
-
-PIR code has a variety of ways to store values while you work with
-them. Actually, the only place to store values is in a Parrot register,
-but there are multiple ways to work with these registers. Register names
-in PIR always start with a dollar sign, followed by a single
-character that shows whether it is an integer (I), numeric (N), string
-(S), or PMC (P) register, and then the number of the register:
-
-  $S0 = "Hello, Polly.\n"
-  print $S0
-
-Integer (I) and Number (N) registers use platform-dependent sizes and
-limitations N<There are a few exceptions to this, we use platform-dependent
-behavior when the platforms behave sanely. Parrot will smooth out some of
-the bumps and inconsistencies so that behavior of PIR code will be the same
-on all platforms that Parrot supports>. Both I and N registers are treated
-as signed quantities internally for the purposes of arithmetic. Parrot's
-floating point values and operations are all IEEE 754 compliant.
-
-Strings (S) are buffers of data with a consistent formatting but a variable
-size. By far the most common use of S registers and variables is for storing
-text data. S registers may also be used in some circumstances as buffers
-for binary or other non-text data. However, this is an uncommon usage of
-them, and for most such data there will likely be a PMC type that is better
-suited to store and manipulate it. Parrot strings are designed to be very
-flexible and powerful, to account for all the complexity of human-readable
-(and computer-representable) text data. 
-
-The final data type is the PMC, a complex and flexible data type. PMCs are,
-in the world of Parrot, similar to what classes and objects are in
-object-oriented languages. PMCs are the basis for complex data structures
-and object-oriented behavior in Parrot. We'll discuss them in more detail
-in this and in later chapters.
-
-=head2 Constants
-
-X<constants (PIR)>
-X<PIR (Parrot intermediate representation);constants>
-X<strings;in PIR>
-As we've just seen, Parrot has four primary data types: integers,
-floating-point numbers, strings, and PMCs. Integers and floating-point
-numbers can be specified in the code with numeric constants in a variety
-of formats:
-
-  $I0 = 42       # Integers are regular numeric constants
-  $I1 = -1       # They can be negative or positive
-  $I2 = 0xA5     # They can also be hexadecimal
-  $I3 = 0b01010  # ...or binary
-
-  $N0 = 3.14     # Numbers can have a decimal point
-  $N1 = 4        # ...or they don't
-  $N2 = -1.2e+4  # Numbers can also use scientific notation.
-
-String literals are enclosed in single or double-quotes:
-
-  $S0 = "This is a valid literal string"
-  $S1 = 'This is also a valid literal string'
-
-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'
-  
-Here's a quick listing of the escape sequences supported by 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
-
-Or, if you need more flexibility, you can use a I<heredoc> string literal:
-
-  $S2 = << "End_Token"
-
-  This is a multi-line string literal. Notice that
-  it doesn't use quotation marks. The string continues
-  until the ending token (the thing in quotes next to
-  the << above) is found. The terminator must appear on
-  its own line, must appear at the beginning of the
-  line, and may not have any trailing whitespace.
-
-  End_Token
-
-=head3 Strings: Encodings and Charsets
-
-Strings are complicated. We showed three different ways to specify string
-literals in PIR code, but that wasn't the entire story. It used to be that
-all a computer system needed was to support the ASCII charset, a mapping of
-128 bit patterns to symbols and English-language characters. This was
-sufficient so long as all computer users could read and write English, and
-were satisfied with a small handful of punctuation symbols that were commonly
-used in English-speaking countries. However, this is a woefully insufficient
-system to use when we are talking about software portability between countries
-and continents and languages. Now we need to worry about several character
-encodings and charsets in order to make sense out of all the string data
-in the world.
-
-Parrot has a very flexible system for handling and manipulating strings.
-Every string is associated with an encoding and a character set (charset).
-The default for Parrot is 8-bit ASCII, which is simple to use and is almost
-universally supported. However, support is built in to have other formats as
-well.
-
-Double-quoted string constants, like the ones we've seen above, can have an
-optional prefix specifying the charset or both the encoding and charset of the
-string. 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 treated as raw unformatted binary"
-
-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 isn't
-treated as if it contains any readable characters. These kinds of strings
-are useful for library routines that return large amounts of binary data
-that doesn't easily fit into any other primitive data type.
-
-Notice that only double-quoted strings can have encoding and charset prefixes
-like this. Single-quoted strings do not support them.
-
-When two types of strings are combined together in some way, such as through
-concatenation, they must both use the same character set an encoding.
-Parrot will automatically upgrade one or both of the strings to use the next
-highest compatible format, if they aren't equal. ASCII strings will
-automatically upgrade to UTF-8 strings if needed, and UTF-8 will upgrade
-to UTF-16. Handling and maintaining these data and conversions all happens
-automatically inside Parrot, and 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>
-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.\n"
-  print hello
-
-This snippet defines a string variable named C<hello>, assigns it the
-value "Hello, Polly.\n", 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> N<Also, you can 
-use any predefined PMC class name like C<BigNum> or C<LexPad>. We'll talk
-about classes and PMC object types in a little bit.>. 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,
-especially since the automatic code generators in use with the various
-high-level languages on parrot tend to generate very long identifier
-names in some situations. Of course, huge identifier names could
-cause all sorts of memory allocation problems or inefficiencies during
-lexical analysis and parsing. You should push the limits at your own risk.
-
-=head2 Register Allocator
-
-Now's a decent time to talk about Parrot's register allocator N<it's also
-sometimes humorously referred to as the "register alligator", due to an
-oft-repeated typo and the fact that the algorithm will bite you if you get
-too close to it>. When you use a register like C<$P5>, you aren't necessarily
-talking about the fifth register in memory. This is important since you can
-use a register named $P10000000 without forcing Parrot to allocate an array
-of ten million registers. Instead Parrot's compiler front-end uses an
-allocation algorithm which turns each individual register referenced in the
-PIR source code into a reference to an actual memory storage location. Here
-is a short example of how registers might be mapped:
-
-  $I20 = 5       # First register, I0
-  $I10000 = 6    # Second register, I1
-  $I13 = 7       # Third register, I2
-
-The allocator can also serve as a type of optimization. It performs a
-lifetime analysis on the registers to determine when they are being used and
-when they are not. When a register stops being used for one thing, it can
-be reused later for a different purpose. Register reuse helps to keep
-Parrot's memory requirements lower, because fewer unique registers need to
-be allocated. However, the downside of the register allocator is that it
-takes more time to execute during the compilation phase. Here's an example
-of where a register could be reused:
-
-=begin PIR
-  .sub main
-    $S0 = "hello "
-    print $S0
-    $S1 = "world!"
-    print $S1
-  .end
-=end PIR
-
-We'll talk about subroutines in more detail in the next chapter. For now,
-we can dissect this little bit of code to see what is happening. The C<.sub>
-and C<.end> directives demarcate the beginning and end of a subroutine
-called C<main>. This convention should be familiar to C and C++ programmers,
-although it's not required that the first subroutine N<or any subroutine
-for that matter> be named "main". In this code sequence, we assign the
-string C<"hello "> to the register C<$S0> and use the C<print> opcode to
-display it to the terminal. Then, we assign a second string C<"world!"> to
-a second register C<$S1>, and then C<print> that to the terminal as well.
-The resulting output of this small program is, of course, the well-worn
-salutation C<hello world!>.
-
-Parrot's compiler and register allocator are smart enough to realize that
-the two registers in the example above, C<$S0> and C<$S1> are used exclusively
-of one another. C<$S0> is assigned a value in line 2, and is read in line 3,
-but is never accessed after that. So, Parrot determines that its lifespan
-ends at line 3. The register C<$S1> is used first on line 4, and is accessed
-again on line 5. Sinec these two do not overlap, Parrot's compiler can
-determine that it can use only one register for both operations. This saves
-the second allocation. Notice that this code with only one register performs
-identically to the previous example:
-
-=begin PIR
-  .sub main
-    $S0 = "hello "
-    print $S0
-    $S0 = "world!"
-    print $S0
-  .end
-=end PIR
-
-In some situations it can be helpful to turn the allocator off and avoid
-expensive optimizations. Such situations are subroutines where there are a
-small fixed number of registers used, when variables are used throughout the
-subroutine and should never be reused, or when some kind of pointer reference
-needs to be made to the register N<this happens in some NCI calls that take
-pointers and return values>. To turn off the register allocator for certain
-variables, you can use the C<:unique_reg> modifier:
-
-  .local pmc MyUniquePMC :unique_reg
-
-Notice that C<:unique_reg> shouldn't affect the behavior of Parrot, but
-instead only changes the way registers are allocated. It's a trade off between
-using more memory in exchange for less time spent optimizing the subroutine.
-
-=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 'PerlString'     # This is how the Perl people do it
-  $P0 = "Hello, Polly.\n"
-  print $P0
-
-This example creates a C<PerlString> object, stores it in the PMC
-register C<$P0>, assigns the value "Hello, Polly.\n" to it, and prints
-it.  With named variables the type passed to the C<.local> directive is
-either the generic C<pmc> or a type compatible with the type passed to
-C<new>:
-
-  .local PerlString hello    # or .local pmc hello
-  hello = new 'PerlString'
-  hello = "Hello, Polly.\n"
-  print hello
-
-PIR is a dynamic language, and that dynamicism is readily displayed in
-the way PMC values are handled. Primitive registers like strings,
-numbers, and integers perform a special action called I<autoboxing>
-when they are assigned to a PMC. Autoboxing is when a primative scalar
-type is automatically converted to a PMC object type. There are PMC
-classes for String, Number, and Integer which can be quickly converted
-to and from primitive int, number, and string types. Notice that the
-primative types are in lower-case, while the PMC classes are
-capitalized. If you want to box a value explicitly, you can 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 primative types they represent. However, 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 also have special custom methods available for performing various
-operations, they may be passed as PMCs to subroutines that only expect
-PMC arguments, and they can be subclassed by a user-defined type. We'll
-discuss all these complicated topics later in this chapter and in the next
-chapter. We will discuss PMC and all the details of their implementation and
-interactions in A<CHP-11> Chapter 11.
-
-=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's very similar
-to C<.local>, and requires a type and a name. The value of a constant
-must be assigned in the declaration statement. As with named
-variables, named constants are visible 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.\n"
-  print 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,
-although a way to do so may be added in later versions of Parrot.
-
-=head1 Symbol Operators
-
-Z<CHP-3-SECT-3>
-
-X<symbol operators in PIR>
-PIR has many other symbol 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
-  print sum
-  print "\n"
-
-The statement C<sum = $I42 + 5> translates to the equivalent statement
-C<add sum, $I42, 5>. This in turn will be translated to an equivalent
-PASM instruction which will be similar to C<add I0, I1, 5>. Notice that
-in the PASM instruction the register names do not have the C<$> symbol in
-front of them, and they've already been optimized into smaller numbers by
-the register allocator. The exact translation from PIR statement to PASM
-instruction isn't too important N<Unless you're hacking on the Parrot
-compiler!>, so we don't have to worry about it for now. We will talk more
-about PASM, its syntax and its instruction set in X<CHP-5> Chapter 5.
-Here are examples of some PIR symbolic operations:
-
-  $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 A<CHP-13> Chapter 13.
-
-=head2 C<=> and Type Conversion
-
-We've mostly glossed over the behavior of the C<=> operator, although it's
-a very powerful and important operator in PIR. In it's most simple form,
-C<=> stores a value into one of the Parrot registers. We've seen cases where
-it can be used to assign a string value to a C<string> register, or an integer
-value to an C<int> register, or a floating point value into a C<number>
-register, etc. However, the C<=> operator can be used to assign any type
-of value into any type of register, and 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
-
-We've also seen an example earlier where a string literal was set into a
-PMC register that had a 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      # De-box. $I0 = 5
-
-  $P1 = new 'String'
-  $P1 = "5 birds"
-  $S1 = $P1      # De-box. $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      # De-box. $N2 = 3.14
-
-=head1 Labels
-
-Z<CHP-3-SECT-4>
-
-X<PIR (Parrot intermediate representation);labels>
-X<labels (PIR)>
-Any line in PIR can start with a label definition like C<LABEL:>,
-but label definitions can also stand alone on their own line. Labels are
-like flags or markers that the program can jump to or return to at different
-times. Labels and jump operations (which we will discuss a little bit
-later) are one of the primary methods to change control flow in PIR, so
-it is well worth understanding.
-
-Labels are most often used in branching instructions, which are used
-to implement high level control structures by our high-level language
-compilers.
-
-=head2 Compilation Units
-
-Z<CHP-3-SECT-4.1>
-
-X<PIR (Parrot intermediate representation);compilation units>
-X<compilation units (PIR)>
-Compilation units in PIR are roughly equivalent to the subroutines or
-methods of a high-level language. Though they will be explained in
-more detail later, we introduce them here because all code in a PIR
-source file must be defined in a compilation unit. We've already seen an
-example for the simplest syntax for a PIR compilation unit. It starts with
-the C<.sub> directive and ends with the C<.end> directive:
-
-=begin PIR
-  .sub main
-      print "Hello, Polly.\n"
-  .end
-=end PIR
-
-Again, we don't need to name the subroutine C<main>, it's just a common
-convention. This example defines a compilation unit named C<main> that
-prints a string C<"Hello, Polly.">. The first compilation unit in a file
-is normally executed first but you can flag any compilation unit as the
-first one to execute with the C<:main> marker.
-
-=begin PIR
-  .sub first
-      print "Polly want a cracker?\n"
-  .end
-
-  .sub second :main
-      print "Hello, Polly.\n"
-  .end
-=end PIR
-
-This code prints out "Hello, Polly." but not "Polly want a cracker?".
-This is because the function C<second> has the C<:main> flag, so it is
-executed first. The function C<first>, which doesn't have this flag
-is never executed. However, if we change around this example a little:
-
-=begin PIR
-  .sub first :main
-      print "Polly want a cracker?\n"
-  .end
-
-  .sub second
-      print "Hello, Polly.\n"
-  .end
-=end PIR
-
-The output now is "Polly want a cracker?". Execution in PIR starts
-at the C<:main> function and continues until the end of that function
-only. If you want to do more stuff if your program, you will need to
-call other functions explicitly.
-
-A<CHP-04>Chapter 4 goes into much more detail about compilation units
-and their uses.
-
-=head1 Flow Control
-
-Z<CHP-3-SECT-5>
-
-X<PIR (Parrot intermediate representation);flow control>
-X<flow control;in PIR>
-Flow control in PIR is done entirely with conditional and unconditional
-branches to labels. This may seem simplistic and primitive, but
-remember that PIR is a thin overlay on the assembly language of a
-virtual processor, and is intended to be a simple target for the compilers
-of various. high-level languages. High level control structures are invariably linked
-to the language in which they are used, so any attempt by Parrot to
-provide these structures would work well for some languages but would
-require all sorts of messy translation in others. The only way to make
-sure all languages and their control structures can be equally
-accommodated is to simply give them the most simple and fundamental
-building blocks to work with. Language agnosticism is an important
-design goal in Parrot, and creates a very flexible and powerful
-development environment for our language developers.
-
-X<goto instruction (PIR)>
-The most basic branching instruction is the unconditional branch:
-C<goto>.
-
-=begin PIR
-  .sub _main
-      goto L1
-      print "never printed"
-  L1:
-      print "after branch\n"
-      end
-  .end
-=end PIR
-
-The first C<print> 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
-      print "never printed"
-  L1: print "after branch\n"
-      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 quite
-similar, but branches when the tested value is false. An undefined
-value, 0, or an empty string are all false values. Any other values
-are considered to be true values.
-
-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
-      print "never printed"
-  L1:
-      print "after branch\n"
-      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 PASM C<lt> branch operation.
-
-The rest of the comparison operators are summarized in
-A<CHP-13-SECT-3>"PIR Instructions" in Chapter 11.
-
-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
-
-      print $I0
-      print "\n"
-      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 then branches to the start of the loop.
-The loop ends when C<$I1> counts down to 0 so that the C<if> doesn't
-branch to C<REDO>. This is a I<do while>-style loop with the condition
-test at the end, so the code always runs the first time through.
-
-X<while-style loop (PIR)>
-For a I<while>-style loop with the condition test at the start, use a
-conditional branch together 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
-
-      print $I0
-      print "\n"
-      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 never
-executes.
-
-Any high-level flow control construct can be built from conditional
-and unconditional branches, because this is the way almost all computer
-hardware operates at the lowest-level, so all modern programming
-languages use branching constructs to implement their most complex
-flow control devices.
-
-Fortunately, libraries of macros have been developed that can implement
-more familiar syntax for many of these control structures. We will discuss
-these libraries in more detail in A<CHP-6> "PIR Standard Library".
-
-=head1 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.
-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<or, 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 overriden 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 N<in addition to methods,
-which we will talk about in the next chapter> 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.
-
-=head1 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
-
-=head1 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 A<CHP-10>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 compilation unit,
-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:

Copied: branches/headercleanup/docs/book/ch04_compiler_tools.pod (from r38131, trunk/docs/book/ch04_compiler_tools.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/ch04_compiler_tools.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/ch04_compiler_tools.pod)
@@ -0,0 +1,189 @@
+=pod
+
+=head1 Parrot Compiler Tools
+
+Z<CHP-9>
+
+So far we've talked a lot about low-level Parrot programming with
+PIR and PASM. However, the true power of Parrot is its ability to
+host programs written in high level languages such as Perl 6,
+Python, Ruby, Tcl, and PHP. In order to write code in these languages
+developers need there to be compilers that convert from the language
+into PIR or PASM (or even directly convert to Parrot Bytecode).
+People who have worked on compilers before may be anticipating us
+to use terms like "Lex and Yacc" here, but we promise that we won't.
+
+Instead of traditional lexical analyzers and parser-generators that
+have been the mainstay of compiler designers for decades, Parrot
+uses an advanced set of parsing tools called the Parrot Compiler
+Tools (PCT)X<Parrot Compiler Tools>. PCT 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. Instead of using
+traditional low-level languages to write compilers, we can use a
+modern dynamic language like Perl 6 to write it instead. On a more
+interesting note, this means that the Perl 6 compiler is itself
+being written in Perl 6, a mind-boggling process known as
+C<bootstrapping>.
+
+The language-neutrality of the interpreter is partially a design
+decision for modularity. Keeping the implementation independent of the
+syntax makes the codebase cleaner and easier to maintain.
+Modular design also benefits future language designers, not just
+designers of current languages. Instead of targeting I<lex>/I<yacc> and
+reimplementing low-level features such as garbage collection and dynamic
+data types, designers can leave the details to Parrot and focus on the
+high-level features of their language: syntax, libraries, capabilities.
+Parrot does all the necessary bookkeeping, exposing a rich interface with
+capabilities that few languages can make full use of.
+
+A robust exceptions system, a capability to compile into
+platform-independent bytecode, and a clean extension and embedding
+mechanism would be just some of the necessary and standard features.
+
+Since Parrot would support the features of the major dynamic languages
+and wasn't biased to a particular syntax, it could run all these
+languages with little additional effort.  
+
+Language interoperability is another core goal. Different languages are
+suited to different tasks, and picking which language to use in a large
+software project is a common planning problem.  There's never a perfect
+fit, at least not for all jobs. Developers find themselves settling for
+the language with the most advantages and the least noticeable
+disadvantages. The ability to easily combine multiple languages within a
+single project opens up the potential of using well-tested libraries
+from one language, taking advantage of clean problem-domain expression
+in a second, while binding it together in a third that elegantly
+captures the overall architecture. It's about using languages according
+to their inherent strengths, and mitigating the cost of their
+weaknesses.
+
+=head2 PCT Overview
+
+PCT is a collection of classes which handle the creation of a
+compiler and driver program for a high-level language. The
+C<PCT::HLLCompiler> class handles building the compiler front end
+while the C<PCT::Grammar>  and C<PCT::Grammar::Actions> classes handle
+building the parser and lexical analyzer. Creating a new HLL compiler
+is as easy as subclassing these three entities with methods specific
+to that high-level language.
+
+=head3 Grammars and Action Files
+
+Creating a compiler using PCT requires three basic files, plus any
+additional files needed to implement the languages logic and library:
+
+=over 4
+
+=item * A main file
+
+The main file should contain the C<:main> function that is the driver
+program for the compiler. Here, a new C<PCT::HLLCompiler> object is
+instantiated, libraries are loaded, and necessary special global
+variables are created. The driver program is typically written in PIR,
+although thankfully they tend to be very short. Most of the action
+happens elsewhere.
+
+=item * A parser file
+
+The grammar for the high level language is specified using the Perl 6
+grammar engine (PGE) and is stored in a C<.pg> file. This file should
+subclass the C<PCT::Grammar> class and implement all the necessary
+rules to successfully parse the language.
+
+=item * An actions file
+
+Actions files are written in NQP. They take match objects generated by
+the grammar file and convert them into an Abstract Syntax Tree (AST)
+X<Abstract Syntax Tree;Parrot Abstract Syntax Tree;AST;PAST>
+which is converted by PCT into PIR for compiling and execution.
+The PIR implementation of these AST trees and nodes is called the
+Parrot Abstract Syntax Tree (PAST).
+
+=back
+
+=head3 C<make_language_shell.pl>
+
+The Parrot repository contains a number of helpful utilities for doing
+some common development and building tasks with Parrot. Many of these
+utilities are currently written in Perl 5, though some run on Parrot
+directly, and in future releases more will be migrated to Parrot.
+
+One of the tools of use to new compiler designers and language implementers
+is C<make_language_shell.pl>. C<make_language_shell.pl> is a tool for
+automatically creating all the necessary stub files for creating a new
+compiler for Parrot. It generates the driver file, parser grammar and
+actions files, builtin functions stub file, makefile, and test harness.
+All of these are demonstrative stubs and will obviously need to be
+edited furiously or even completely overwritten, but they give a good idea
+of what is needed to start on development of the compiler.
+
+C<make_language_shell.pl> is designed to be run from within the Parrot
+repository file structure. It creates a subfolder in C</languages/>
+with the name of your new language implementation. Typically a new
+implementation of an existing language is not simply named after the
+language, but is given some other descriptive name to let users know it
+is only one implementation available. Consider the way Perl 5 distributions
+are named things like "Active Perl" or "Strawberry Perl", or how Python
+distributions might be "IronPython" or "VPython". If, on the other hand,
+you are implementing an entirely new language, you don't need to give it
+a fancy distribution name.
+
+=head3 Parsing Fundamentals
+
+Compilers typically consist of three components: The lexical analyzer,
+the parser, and the code generator C<This is an oversimplification, 
+compilers also may have semantic analyzers, symbol tables, optimizers,
+preprocessors, data flow analyzers, dependency analyzers, and resource
+allocators, among other components. All these things are internal to
+Parrot and aren't the concern of the compiler implementer. Plus, these
+are all well beyond the scope of this book>. The lexical analyzer converts
+the HLL input file into individual tokens. A token may consist of an
+individual punctuation mark("+"), an identifier ("myVar"), or a keyword
+("while"), or any other artifact that cannot be sensibly broken down. The
+parser takes a stream of these input tokens, and attempts to match them
+against a given pattern, or grammar. The matching process orders the input
+tokens into an abstract syntax tree (AST), which is a form that
+the computer can easily work with. This AST is passed to the code
+generator which converts it into code of the target language. For
+something like the GCC C compiler, the target language is machine code.
+For PCT and Parrot, the target language is PIR and PBC.
+
+Parsers come in two general varieties: Top-down and bottom-up. Top-down
+parsers start with a top-level rule, a rule which is supposed to
+represent the entire input. It attempts to match various combination of
+subrules until the entire input is matched. Bottom-down parsers, on the
+other hand, 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 itself is a top-down parser, although it also contains a bottom-up
+I<operator precedence> parser, for things like mathematical expressions
+where bottom-up methods are more efficient. We'll discuss both, and the
+methods for switching between the two, throughout this chapter.
+
+=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. Most commandline options are handled by PCT, but
+there are some behaviors that the driver program will want to
+override.
+
+PCT programs can, by default, be run in two ways: Interactive mode,
+which is run one statement at a time in the console, and file mode which
+loads and runs an entire file. For interactive mode, it is necessary
+to specify information about the prompt that's used and the environment
+that's expected. Help and error messages need to be written for the user
+too. 
+
+=head3 C<HLLCompiler> class
+
+
+=cut
+
+# Local variables:
+#   c-file-style: "parrot"
+# End:
+# vim: expandtab shiftwidth=4:

Deleted: branches/headercleanup/docs/book/ch04_pir_subroutines.pod
==============================================================================
--- branches/headercleanup/docs/book/ch04_pir_subroutines.pod	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,1251 +0,0 @@
-=pod
-
-=head1 Subroutines
-
-Z<CHP-4>
-
-X<PIR (Parrot intermediate representation);subroutines>
-X<subroutines;in PIR>
-Code reuse has become a cornerstone of modern software engineering.
-Common tasks are routinely packaged as libraries for later reuse
-by other developers. The most basic building block of code reuse is
-the "function" or "subroutine". A calculation like "the factorial of
-a number", for example, may be used several times in a large program.
-Subroutines allow this kind of functionality to be abstracted into a
-single stand-alone unit for reuse. PIR is a subroutine-based language
-in that all code in PIR must exist in a subroutine. Execution starts,
-as we have seen, in the C<:main> subroutine, and others can be called
-to perform the tasks of a program. From subroutines we can construct
-more elaborate chunks of code reusability methods and objects. In
-this chapter we will talk about how subroutines work in PIR, and how
-they can be used by developers to create programs for Parrot.
-
-Parrot supports multiple high-level languages, and 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
-syntax for subroutines 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--by passing arguments, altering
-control flow, and returning results--is called the "Parrot Calling
-Conventions", or PCC. The details of PCC are generally hidden from the
-programmer, being partially implemented in C and being partially
-implemented in PASM. 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 of this can be largely
-ignored for developers who don't need it, but the power of this approach
-can be harnessed by those who do. We'll talk more about PCC and CPS in
-this and in later chapters as well.
-
-=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 a great deal of complexity. It generates a
-subroutine PMC object, creates a continuation PMC object to return
-control flow after the subroutine, passes the arguments, looks up the
-subroutine by name (and by signature if it's been overloaded), it calls
-the subroutine, and finally it assigns the results of the call to the
-given register variables. This is quite a lot of work for a single
-statement, and that's ignoring the computational logic that the
-subroutine itself implements.
-
-=head3 Expanded Subroutine Syntax
-
-The single line subroutine call is incredibly convenient, but it isn't
-always flexible enough. So PIR also has a more verbose call syntax
-that is still more convenient than manual calls. This example pulls
-the subroutine C<fact> out of the global symbol table into a PMC
-register 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, returns 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. Subroutines are defined with the C<.sub>
-directive, and end with the C<.end> directive. We've already seen
-this syntax in our earlier examples. The C<.param> defines input
-parameters and creates local named variables for them:
-
-  .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 compilation unit, 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
-     .local int count
-     .local int product
-     count = 5
-     product = 1
-
-     $I0 = 'fact'(count, product)
-
-     print $I0
-     print "\n"
-     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 passing the two variables as arguments. In the call, the
-two arguments are assigned to consecutive integer registers, because
-they're stored in typed integer variables. The C<fact> subroutine
-uses C<.param> and the C<.return> directives for retrieving parameters
-and returning results. The final printed result is 120.
-
-Execution of the program starts at the C<:main> subroutine or, if no
-subroutines are declared with C<:main> at the first subroutine in the file.
-If multiple subroutines are declared with C<:main>, the last of them is
-treated as the starting point. Eventually, declaring multiple subroutines
-with C<:main> might cause a syntax error or some other bad behavior, so it's
-not a good idea to rely on it now.
-
-=head3 Named Parameters
-
-Parameters that are passed in a strict order like we've seen above are
-called '''positional arguments'''. Positional arguments are
-differentiated from one another by their position in the function call.
-Putting positional arguments in a different order will produce different
-effects, or may cause errors. Parrot supports a second type of parameter,
-a '''named parameter'''. 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 = $S1 . " years old"
-    print $S0
-    print $S1
- .end
-
- .sub main :main
-    'MySub'("age" => 42, "name" => "Bob")
- .end
-
-=end PIR
-
-In the example above, we could have easily reversed the order too:
-
-=begin PIR
-
- .sub main :main
-    'MySub'("name" => "Bob", "age" => 42)    # Same!
- .end
-
-=end PIR
-
-Named arguments can be a big help because you don't have to worry about
-the exact order of variables, especially as argument lists get very long.
-
-=head3 Optional Parameters
-
-Sometimes there are parameters to a function that don't always need to be
-passed, or values for a parameter which should be given a default value
-if a different value hasn't been explicitly provided. Parrot provides
-a mechanism for allowing optional parameters to be specified, so an
-error won't be raised if the parameter isn't provided. Parrot also
-provides a flag value that can be tested to determine if an optional
-parameter has been provided or not, so a default value can be supplied.
-
-Optional parameters are actually treated like two parameters: The value
-that may or may not be passed, and the flag value to determine if it
-has been or not. Here's an example declaration of an optional parameter:
-
-  .param string name :optional
-  .param int has_name :opt_flag
-
-The C<:optional> flag specifies that the given parameter is optional and
-does not necessarily need to be provided. The C<:opt_flag> specifies that
-an integer parameter contains a boolean flag. This flag is true if the
-value was passed, and false otherwise. This means we can use logic like
-this to provide a default value:
-
-  .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. When using them
-with positional parameters, they 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!
-    ...
-
-Optional parameters can also be mixed with named parameters:
-
-  .sub 'MySub'
-    .param int value :named("answer") :optional
-    .param int has_value :opt_flag
-    ...
-
-This could be called in two ways:
-
-  'MySub'("answer" => 42)  # with a value
-  'MySub'()                # without
-
-=head3 Sub PMCs
-
-Subroutines are a PMC type in Parrot, and references to them can be stored
-in PMC registers and manipulated like other PMC types. You can get a subroutine
-in the current namespace with the C<get_global> opcode:
-
-  $P0 = get_global "MySubName"
-
-Or, if you want to find a subroutine from a different namespace, you need
-to first select the namespace PMC and then pass that to C<get_global>:
-
-  $P0 = get_namespace "MyNamespace"
-  $P1 = get_global $P0, "MySubName"
-
-With a Sub PMC, there are lots of things you can do. You can obviously invoke
-it:
-
-  $P0(1, 2, 3)
-
-You can get its name or 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 1 if the sub has a slurpy parameter to eat up extra positional args
-
-=item * named_slurpy
-
-Returns 1 if the sub has a slurpy parameter to eat up extra named args
-
-=back
-
-Instead of getting the whole inspection hash, you can look for individual
-data items that you want:
-
-  $I0 = inspect $P0, "pos_required"
-
-If you want to get the total number of defined parameters to the Sub, you can
-call the C<arity> method:
-
-  $I0 = $P0.'arity'()
-
-To get the namespace PMC that the Sub was defined into, you can call the
-C<get_namespace> method:
-
-  $P1 = $P0.'get_namespace'()
-
-Subroutine PMCs are very useful things, and we will show more of their uses
-throughout this chapter.
-
-=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
-
-
-=head2 Continuation Passing Style
-
-Continuations are snapshots, a frozen image of the current execution
-state of the VM. Once we have a continuation we 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 N<there's actually
-no magic involved, just a lot of interesting ideas and involved code>.
-
-Continuations are not a new concept, they've been boggling the minds
-of Lisp and Scheme programmers for many years. However, despite all
-their power and flexibility they haven't been well-utilized in most
-modern programming languages or in their underlying libraries and
-virtual machines. Parrot aims to change that: In Parrot, almost every
-control flow manipulation including all subroutine, method, and
-coroutine calls, are performed using continuations. This mechanism
-is mostly hidden from developers who build applications on top of
-Parrot. The power and flexibility is available if people want to use
-it, but it's hidden behind more familiar constructs if not.
-
-Doing all sorts of flow control using continuations is called
-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
-
-In many cases, a subroutine will set up and call another subroutine,
-and then return the result of the second call directly. This is called
-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 used as the return value. C<add_one> is called
-and its result is immediately returned to the caller of C<add_two>, it is
-never stored in a local register or variable in C<add_two>, it's immediately
-returned. We can optimize this situation if we realize that the second call to
-C<add_one> is returning to the same place that C<add_two> is, and therefore
-can utilize the same return continuation as 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>
-In PIR code, we use the C<.tailcall> directive to make a tailcall like this,
-instead of the C<.return> directive. C<.tailcall> performs this optimization
-by reusing the return continuation of the parent function to make the
-tailcall. In PIR, we can write this example:
-
-=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 will print out the correct value "7".
-
-=head3 Creating and Using Continuations
-
-Most often continuations are used implicitly by the other control-flow
-operations in Parrot. However, they can also be created and used explicitly
-when required. Continuations are like any other PMC, and can be created
-using the C<new> keyword:
-
-  $P0 = new 'Continuation'
-
-The new continuation starts off in an undefined state. Attempting to invoke
-a new continuation after it's first been created will raise an exception. To
-prepare the continuation for use, a destination label must be assigned to it
-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 when the continuation was created, use the C<invoke> opcode
-or the C<()> notation:
-
-  invoke $P0  # Explicit using "invoke" opcode
-  $P0()       # Same, but nicer syntax
-
-Notice that even though you can use the subroutine notation C<$P0()> to
-invoke the continuation, it doesn't make any sense to try and pass arguments
-to it or to try and return values from it:
-
-  $P0 = new 'Continuation'
-  set_addr $P0, my_label
-
-  $P0(1, 2)      # WRONG!
-
-  $P1 = $P0()    # WRONG!
-
-=head2 Lexical Subroutines
-
-X<Lexical Subroutines>
-As we've mentioned above, Parrot offers support for lexical subroutines.
-What this means is that we can define a subroutine by name inside a
-larger subroutine, and our "inner" subroutine is only visible and callable
-from the "outer" outer. The "inner" subroutine inherits all the lexical
-variables from the outer subroutine, but is able to define its
-own lexical variables that cannot be seen or modified by the outer subroutine.
-This is important because PIR doesn't have anything corresponding to blocks
-or nested scopes like some other languages have. Lexical subroutines play
-the role of nested scopes when they are needed.
-
-If the subroutine is lexical, you can get its C<:outer> with the C<get_outer>
-method on the Sub PMC:
-
-  $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
-
-Let us diverge for a minute and start looking forward at the idea of X<High
-Level Languages;HLL> High Level Languages (HLLs) such as Perl, Python, and
-Ruby. All of these languages allow nested scopes, or blocks within blocks
-that can have their own lexical variables. Let's look back at the C
-programming language, where this kind of construct is not uncommon:
-
-  {
-      int x = 0;
-      int y = 1;
-      {
-          int z = 2;
-          // x, y, and z are all visible here
-      }
-      // only x and y are visible here
-  }
-
-The code above illustrates this idea perfectly without having to get into a
-detailed and convoluted example: In the inner block, we define the variable
-C<z> which is only visible inside that block. The outer block has no
-knowledge of C<z> at all. However, the inner block does have access to the
-variables C<x> and C<y>. This is an example of nested scopes where the
-visibility of different data items can change in a single subroutine. As
-we've discussed above, Parrot doesn't have any direct analog for this
-situation: If we tried to write the code above directly, we would end up
-with this PIR code:
-
-  .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
-
-In PIR, there is only one structure that supports scoping like this: the
-subroutine N<and objects that inherit from subroutines, such as methods,
-coroutines, and multisubs, which we will discuss later>. 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
-
-In the example above we put the word C<"visible"> in quotes. 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
-
-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 N<such is the case with
-multisubs, which we will discuss soon>, 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
-
-Information about lexical variables in a subroutine is stored in two different
-types of PMCs: The LexPad PMC that we already mentioned briefly, and the
-LexInfo PMCs which we haven't. Neither of these PMC types are really usable
-from PIR code, but are instead used by Parrot internally to store information
-about lexical variables.
-
-C<LexInfo> PMCs are used to store information about lexical variables at
-compile time. This is read-only information that is generated during
-compilation to represent what is known about lexical variables. Not all
-subroutines get a LexInfo PMC by default, you need to indicate to Parrot
-somehow that you require a LexInfo PMC to be created. One way to do this is
-with the C<.lex> directive that we looked at above. Of course, the C<.lex>
-directive only works for languages where the names of lexical variables are
-all known at compile time. For languages where this information isn't known,
-the subroutine can be flagged with C<:lex> instead.
-
-C<LexPad> PMCs are used to store run-time information about lexical variables.
-This includes their current values and their type information. LexPad PMCs are
-created at runtime for subs that have a C<LexInfo> PMC already. These are
-created each time the subroutine is invoked, which allows for recursive
-subroutine calls without overwriting variable names.
-
-With a Subroutine PMC, you can get access to the associated LexInfo PMC by
-calling the C<'get_lexinfo'> method:
-
-  $P0 = find_global "MySubroutine"
-  $P1 = $P0.'get_lexinfo'()
-
-Once you have the LexInfo PMC, there are a limited number of operations that
-you can call with it:
-
-  $I0 = elements $P1    # Get the number of lexical variables from it
-  $P0 = $P1["name"]     # Get the entry for lexical variable "name"
-
-There really isn't much else useful to do with LexInfo PMCs, they're mostly
-used by Parrot internally and aren't helpful to the PIR programmer.
-
-There is no easy way to get a reference to the current LexPad PMC in a given
-subroutine, but like LexInfo PMCs that doesn't matter because they aren't
-useful from PIR anyway. Remember that subroutines themselves can be lexical
-and that therefore the lexical environment of a given variable can extend to
-multiple subroutines and therefore multiple LexPads. The opcodes C<find_lex>
-and C<store_lex> automatically search through nested LexPads recursively to
-find the proper environment information about the given variables.
-
-=head2 Compilation Units Revisited
-
-Z<CHP-4-SECT-1.1>
-
-The term "compilation unit" is one that's been bandied about throughout the
-chapter and it's worth some amount of explanation here. A compilation unit
-is a section of code that forms a single unit. In some instances the term
-can be used to describe an entire file. In most other cases, it's used to
-describe a single subroutine. Our earlier example which created a C<'fact'>
-subroutine for calculating factorials could be considered to have used two
-separate compilation units: The C<main> subroutine and the C<fact> subroutine.
-Here is a way to rewrite that algorithm using only a single subroutine instead:
-
-=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 is different from how subroutines are normally
-invoked in PIR.
-
-Another disadvantage of this approach is that C<main> and C<fact> share the
-same compilation unit, so they're parsed and processed as one piece of code.
-They share registers. They would also share 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. This is a problem when trying to follow normal encapsulation guidelines.
-
-=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. We've seen some method calls in the examples
-above, especially when we were talking about the interfaces to certain PMC
-types. We've also seen a little bit of information about classes and objects
-in the previous chapter. PIR allows you to define your own classes, and with
-those classes you can define method interfaces to them. Method calls follow
-the same Parrot calling conventions that we have seen above, including all the
-various parameter configurations, lexical scoping, and other aspects we have
-already talked about.
-
-Classes can be defined in two ways: in C and compiled to machine code, and
-in PIR. The former is how the built-in PMC types are defined, like
-C<ResizablePMCArray>, or C<Integer>. These PMC types are either built with
-Parrot at compile time, or are compiled into a shared library called a
-I<dynpmc> and loaded into Parrot at runtime. We will talk about writing PMCs
-in C, and dealing with dynpmcs in chapter 11.
-
-The second type of class can be defined in PIR at runtime. We saw some
-examples of this in the last chapter using the C<newclass> and C<subclass>
-opcodes. We also talked about class attribute values. Now, we're going to talk
-about associating subroutines with these classes, and they're called
-I<methods>. Methods are just like other normal subroutines with two major
-changes: they are marked with the C<:method> flag, and they exist in a
-I<namespace>. Before we can talk about methods, we need to discuss
-namespaces first.
-
-=head3 Namespaces
-
-Z<CHP-4-SECT-2.1>
-
-X<Namespaces>
-X<.namespace>
-Namespaces provide a mechanism where names can be reused. This may not
-sound like much, but in large complicated systems, or systems with
-many included libraries, it can be very handy. Each namespace get's its
-own area for function names and global variables. This way you can have
-multiple functions named C<create> or C<new> or C<convert>, for
-instance, without having to use I<Multi-Method Dispatch> (MMD) which we
-will describe later. Namespaces are also vital for defining classes and their
-methods, which we already mentioned. We'll talk about all those uses here.
-
-Namespaces are specified with the C<.namespace []> directive. The brackets
-are not optional, but the keys inside them are. Here are some examples:
-
-  .namespace [ ]               # The root namespace
-  .namespace [ "Foo" ]         # The namespace "Foo"
-  .namespace [ "Foo" ; "Bar" ] # Namespace Foo::Bar
-  .namespace                   # WRONG! The [] are needed
-
-Using semicolons, namespaces can be nested to any arbitrary depth.
-Namespaces are special types of PMC, so we can access them and manipulate
-them just like other data objects. We can get the PMC for the root
-namespace using the C<get_root_namespace> opcode:
-
-  $P0 = get_root_namespace
-
-The current namespace, which might be different from the root namespace
-can be retrieved with the C<get_namespace> opcode:
-
-  $P0 = get_namespace             # get current namespace PMC
-  $P0 = get_namespace ["Foo"]     # get PMC for namespace "Foo"
-
-Namespaces are arranged into a large n-ary tree. There is the root namespace
-at the top of the tree, and in the root namespace are various special HLL
-namespaces. Each HLL compiler gets its own HLL namespace where it can store
-its data during compilation and runtime. Each HLL namespace may have a large
-hierarchy of other namespaces. We'll talk more about HLL namespaces and their
-significance in chapter 10.
-
-The root namespace is a busy place. Everybody could be lazy and use it to store
-all their subroutines and global variables, and then we would run into all
-sorts of collisions. One library would define a function "Foo", and then
-another library could try to create another subroutine with the same name.
-This is called I<namespace pollution>, because everybody is trying to put
-things into the root namespace, and those things are all unrelated to each
-other. Best practices requires that namespaces be used to hold private
-information away from public information, and to keep like things together.
-
-As an example, the namespace C<Integers> could be used to store subroutines
-that deal with integers. The namespace C<images> could be used to store
-subroutines that deal with creating and manipulating images. That way, when
-we have a subroutine that adds two numbers together, and a subroutine that
-performs additive image composition, we can name them both C<add> without any
-conflict or confusion. And within the C<image> namespace we could have sub
-namespaces for C<jpeg> and C<MRI> and C<schematics>, and each of these could
-have a C<add> method without getting into each other's way.
-
-The short version is this: use namespaces. There aren't any penalties to them,
-and they do a lot of work to keep things organized and separated.
-
-=head3 Namespace PMC
-
-The C<.namespace> directive that we've seen sets the current namespace. In
-PIR code, we have multiple ways to address a namespace:
-
-  # Get namespace "a/b/c" starting at the root namespace
-  $P0 = get_root_namespace ["a" ; "b" ; "c"]
-
-  # Get namespace "a/b/c" starting in the current HLL namespace.
-  $P0 = get_hll_namespace ["a" ; "b" ; "c"]
-  # Same
-  $P0 = get_root_namespace ["hll" ; "a" ; "b" ; "c"]
-
-  # Get namespace "a/b/c" starting in the current namespace
-  $P0 = get_namespace ["a" ; "b" ; "c"]
-
-Once we have a namespace PMC we can retrieve global variables and
-subroutine PMCs from it using the following functions:
-
-  $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
-
-We've seen above how to find a Namespace PMC. Once you have it, there are a
-few things you can do with it. You can find methods and variables that are
-stored in the namespace, or you can add new ones:
-
-  $P0 = get_namespace
-  $P0.'add_namespace'($P1)      # Add Namespace $P1 to $P0
-  $P1 = $P0.'find_namespace'("MyOtherNamespace")
-
-  # Find namespace "MyNamespace" in $P0, create it if it
-  #    doesn't exist
-  $P1 = $P0.'make_namespace'("MyNamespace")
-
-  $P0.'add_sub'("MySub", $P2)   # Add Sub PMC $P2 to the namespace
-  $P1 = $P0.'find_sub'("MySub") # Find it
-
-  $P0.'add_var'("MyVar", $P3)   # Add variable "MyVar" in $P3
-  $P1 = $P0.'find_var'("MyVar") # Find it
-
-  # Return the name of Namespace $P0 as a ResizableStringArray
-  $P3 = $P0.'get_name'()
-
-  # Find the parent namespace that contains this one:
-  $P5 = $P0.'get_parent'()
-
-  # Get the Class PMC associated with this namespace:
-  $P6 = $P0.'get_class'()
-
-There are a few other operations that can be done on Namespaces, but none
-as interesting as these. We'll talk about Namespaces throughout the rest
-of this chapter.
-
-=head3 Calling Methods
-
-Z<CHP-4-SECT-2.2>
-
-Now that we've discussed namespaces, we can start to discuss all the
-interesting things that namespaces enable, like object-oriented
-programming and method calls. Methods are just like subroutines, except
-they are invoked on a object PMC, and that PMC is passed as the c<self>
-parameter.
-
-The basic syntax for a method call is similar to the single line
-subroutine call above. It takes a variable for the invocant PMC and a
-string with the name of the method:
-
-  object."methodname"(arguments)
-
-Notice that the name of the method must be contained in quotes. If the
-name of the method is not contained in quotes, it's treated as a named
-variable that does. Here's an example:
-
-  .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
-
-Methods are defined like any other subroutine except with two major
-differences: They must be inside a namespace named after the class
-they are a part of, and they must use the C<:method> flag.
-
-  .namespace [ "MyClass"]
-
-  .sub "MyMethod" :method
-    ...
-
-Inside the method, the invocant object can be accessed using the C<self>
-keyword. 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:
-
-=begin PIR - See TT #483
-
-  .sub "MyMethod" :method
-    $S0 = self                    # Already defined as "self"
-    say $S0
-  .end
-
-  .sub "MyMethod2" :method
-    .param pmc item :invocant     # "self" is now called "item"
-    $S0 = item
-    say $S0
-  .end
-
-=end PIR - See TT #483
-
-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
-    print "done\n"              # in the "Foo" namespace
-    end
-  .end
-
-  .namespace [ "Foo" ]          # start namespace "Foo"
-
-  .sub meth :method             # define Foo::meth global
-     print "in meth\n"
-     $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
-     print "in other_meth\n"    # as above 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.
-
-When a C<.sub> is declared as a C<:method>, it automatically creates a
-local variable named C<self> and assigns it the object passed in
-C<P2>. You don't need to write C<.param pmc self> to get it, it comes
-free with the method.
-
-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 subscribe to 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 PMC 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 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 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 N<this is one of the
-reasons for having multisubs in the first place!>. 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.
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/headercleanup/docs/book/ch05_pasm.pod
==============================================================================
--- branches/headercleanup/docs/book/ch05_pasm.pod	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,3289 +0,0 @@
-=pod
-
-=head0 Parrot Assembly Language
-
-Z<CHP-5>
-
-X<Parrot Assembly Language;;(see PASM)>
-X<PASM (Parrot assembly language)>
-Parrot assembly (PASM) is an assembly language written for Parrot's
-virtual CPU. Basic register operations or branches in PASM generally
-translate into a single CPU instruction. N<This means the JIT run time
-has a performance of up to one PASM instruction per processor cycle.>
-On the other hand, because it's designed to implement dynamic
-high-level languages, it has support for many advanced features such as
-lexical and global variables, objects, garbage collection,
-continuations, coroutines, and much more. PASM is very similar in
-many respects to PIR which we've already discussed, and in almost all
-cases PIR should be used instead of using PASM directly. However, all
-PASM syntax is also valid PIR syntax, so it's helpful to have an
-understanding of the underlying operations in PASM.
-
-X<.pasm files> A file with a F<.pasm> extension is treated as pure PASM
-code by Parrot, as is any file run with the C<-a> command-line option.
-This mode is mainly used for running pure PASM tests from the test suite,
-and is not likely to be useful for most developers.
-
-Some people may ask why we have PASM at all, especially with PIR which
-has much nicer syntax. The answer is that PASM, like all assembly languages
-has a one-to-one correspondence with the underlying Parrot Bytecode (PBC).
-This makes it easy to translate from PBC to human-readable PASM code in
-a disassembler program. PIR code is basically just a thin wrapper over
-PASM, and you can write PASM code seamlessly in PIR files. It's always
-around, and it's good to be familiar with it.
-
-=head1 Basics
-
-Z<CHP-5-SECT-2>
-
-X<PASM (Parrot assembly language);overview>
-PASM has a simple syntax that will be familiar to people who have experience
-programming other assembly languages. Each statement stands on its own line
-and there is no end-of-line delimiter like is used in many other languages.
-Statements begin with a Parrot instruction, commonly referred to
-as an "opcode"N<More accurately, it should probably be referred to as a
-"mnemonic">. The arguments follow, separated by commas:
-
-  [label] opcode dest, source, source ...
-
-If the opcode returns a result, it is stored in the first argument.
-Sometimes the first register is both a source value and the
-destination of the result, this is the case when we want to modify a
-value in place, without consuming a new Parrot register to hold the
-value. The arguments can be either registers or constants, although the
-destination argument cannot be constant.
-
-=begin PASM
-
-  LABEL:
-      print "The answer is: "
-      print 42
-      print "\n"
-      end                # halt the interpreter
-
-=end PASM
-
-X<PASM (Parrot assembly language);labels>
-A label names a line of code so other instructions can refer to it.
-Label names consist of letters, numbers, and underscores, exactly the
-same syntax as is used for labels in PIR. Simple labels are often all
-capital letters to make them stand out from the rest of the source code
-more clearly. A label definition is simply the name of the label
-followed by a colon. It can be on its own line N<In fact, we recommend
-that it be on its own line, for readability.>:
-
-=begin PASM
-
-  LABEL:
-      print "Norwegian Blue\n"
-
-=end PASM
-
-or before a statement on the same line:
-
-=begin PASM
-
-  LABEL: print "Norwegian Blue\n"
-
-=end PASM
-
-X<PASM (Parrot assembly language);comments>
-POD (plain old documentation) is also allowed in PASM like it is in PIR.
-An equals sign in the first column marks the start of a POD block, and
-a C<=cut> marker signals the end of a POD block.
-
-=begin PASM
-
-=head1
-
-  This is POD documentation, and is treated like a
-  comment. The PASM interpreter ignores this.
-
-=cut
-
-=end PASM
-
-Besides POD, there are also ordinary 1-line comments using the # sign,
-which is the same in PIR:
-
-=begin PASM
-
-  LABEL:                        # This is a comment for a label
-    print "Norwegian Blue\n"    # Print a color
-
-=end PASM
-
-=head2 Constants
-
-Z<CHP-5-SECT-2.1>
-
-X<PASM (Parrot assembly language);constants>
-Integer constants are signed integers.N<The size of integers is
-defined when Parrot is configured. It's typically 32 bits on 32-bit
-machines (a range of -2G<31> to +2G<31>-1) and twice that size on
-64-bit processors.> Decimal integer constants can have a positive (C<+>) or
-negative (C<->) sign in front. Binary integers are preceded by C<0b>
-or C<0B>, and hexadecimal integers are preceded by C<0x> or C<0X>:
-
-=begin PASM
-
-  print 42         # Decimalinteger constant
-  print +144       # integer constant
-  print 0x2A       # hexadecimal integer
-  print 0b1101     # binary integer
-
-=end PASM
-
-Floating-point constants can also be positive or negative. Scientific
-notation provides an exponent, marked with C<e> or C<E> (the sign of
-the exponent is optional):
-
-=begin PASM
-
-  print 3.14159    # floating point constant
-  print 1.e6       # scientific notation
-  print -1.23e+45
-
-=end PASM
-
-String constants are wrapped in single or double quotation marks.
-Quotation marks inside the string must be escaped by a backslash.
-Other special characters also have escape sequences. These are the
-same as for Perl 5's C<qq()> operator: C<\t> (tab), C<\n> (newline),
-C<\r> (return), C<\f> (form feed), C<\\> (literal slash), C<\">
-(literal double quote), etc.
-
-=begin PASM
-
-  print "string\n"    # string constant with escaped newline
-  print "\\"          # a literal backslash
-  print 'a\n'         # three chars: 'a', a backslash, and a 'n'
-
-=end PASM
-
-=head2 Working with Registers
-
-Z<CHP-5-SECT-2.2>
-
-X<PASM (Parrot assembly language);registers>
-X<registers;Parrot;;(see PASM, registers)>
-Parrot is a register-based virtual machine. It has 4 typed register
-sets: integers, floating-point numbers, strings, and Parrot objects
-(called PMCs). Register names consist of a capital letter indicating
-the register set type and the number of the register. Register numbers
-are non-negative (zero and positive numbers), and do not have a
-pre-defined upper limit N<At least not a restrictive limit. Parrot
-registers are stored internally as an array, and the register number is
-an index to that array. If you call C<N2000> you are implicitly creating
-a register array with 2000 entries. This can carry a performance
-penalty>. For example:
-
-  I0   integer register #0
-  N11  number or floating point register #11
-  S2   string register #2
-  P33  PMC register #33
-
-Integer and number registers hold values, while string and PMC
-registers contain pointers to allocated memory for a string header or
-a Parrot object.
-
-In Chapter 3 we mentioned that a register name was a dollar-sign followed
-by a type identifier and then a number. Now we're naming registers with
-only a letter and number, not a dollar sign. Why the difference? The
-dollar sign indicates to Parrot that the register names are not literal,
-and that the register allocator should assign the identifier to a
-physical memory location. Without the dollar sign, the register number
-is an actual offset into the register array. C<N2000> is going to point
-to the two thousandth register, while C<$N2000> can point to any
-memory location that the register allocator determines to be free. Since
-PIR attempts to protect the programmer from some of the darkest details,
-Parrot requires that registers in PIR use the C<$> form. In PASM you can
-use either form, but we still recommend using the C<$> form so you don't
-have to worry about register allocations (and associated performance
-penalties) yourself.
-
-=head3 Register assignment
-
-Z<CHP-5-SECT-2.2.1>
-
-X<PASM (Parrot assembly language);registers;assignment>
-The most basic operation on registers is assignment using the C<set>
-opcode:
-
-=begin PASM
-
-  set I0, 42        # set integer register #0 to the integer value 42
-  set N3, 3.14159   # set number register #3 to an approximation of E<#x3C0>
-  set I1, I0        # set register I1 to what I0 contains
-  set I2, N3        # truncate the floating point number to an integer
-
-=end PASM
-
-PASM uses registers where a high-level language would use variables.
-The C<exchange> opcode swaps the contents of two registers of the same
-type:
-
-=begin PASM
-
-  exchange I1, I0   # set register I1 to what I0 contains
-                    # and set register I0 to what I1 contains
-=end PASM
-
-As we mentioned before, string and PMC registers are slightly
-different because they hold a pointer instead of directly holding a
-value. Assigning one string register to another:
-
-=begin PASM
-
-  set S0, "Ford"
-  set S1, S0
-  set S0, "Zaphod"
-  print S1                # prints "Ford"
-  end
-
-=end PASM
-
-doesn't make a copy of the string; it makes a copy of the pointer.
-N<Strings in Parrot use Copy-On-Write (COW) optimizations. When we
-call C<set S1, S0> we copy the pointer only, so both registers point
-to the same string memory. We don't actually make a copy of the string
-until one of two registers is modified.> Just after C<set> C<S1>, C<S0>,
-both C<S0> and C<S1> point to the same string. But assigning a constant
-string to a string register allocates a new string. When "Zaphod" is
-assigned to C<S0>, the pointer changes to point to the location of the
-new string, leaving the old string untouched. So strings act like simple
-values on the user level, even though they're implemented as pointers.
-
-Unlike strings, assignment to a PMC doesn't automatically create a new
-object; it only calls the PMC's VTABLE method for assignment N<and depending
-on implementation the VTABLE assignment operation might not actually
-assign anything. For now though, we can assume most VTABLE interfaces
-do what they say they do.>. So, rewriting the same example using a PMC
-has a completely different result:
-
-=begin PASM
-
-  new P0, "String"
-  set P0, "Ford"
-  set P1, P0
-  set P0, "Zaphod"
-  print P1                # prints "Zaphod"
-  end
-
-=end PASM
-
-The C<new> opcode creates an instance of the C<.String> class. The
-class's vtable methods define how the PMC in C<P0> operates.  The
-first C<set> statement calls C<P0>'s vtable method
-C<set_string_native>, which assigns the string "Ford" to the PMC. When
-C<P0> is assigned to C<P1>:
-
-=begin PASM
-
-  set P1, P0
-
-=end PASM
-
-it copies the pointer, so C<P1> and C<P0> are both aliases to the same
-PMC. Then, assigning the string "Zaphod" to C<P0> changes the
-underlying PMC, so printing C<P1> or C<P0> prints "Zaphod".N<Contrast
-this with C<assign> in A<-CHP-5-SECT-3.2>"PMC Assignment" later in
-this chapter.>
-
-=head3 PMC object types
-
-Z<CHP-5-SECT-2.2.2>
-
-X<PMCs (Polymorphic Containers);object types>
-Internally, PMC types are represented by positive integers, and
-built-in types by negative integers. PASM provides two opcodes to deal
-with types. Use C<typeof> to look up the name of a type from its
-integer value or to look up the named type of a PMC. Use C<find_type>
-to look up the integer value of a named type.
-
-When the source argument is a PMC and the destination is a string
-register, C<typeof> returns the name of the type:
-
-=begin PASM
-
-  new P0, "String"
-  typeof S0, P0               # S0 is "String"
-  print S0
-  print "\n"
-  end
-
-=end PASM
-
-In this example, C<typeof> returns the type name "String".
-
-X<PMCs (Polymorphic Containers);inheritance>
-X<Parrot;classes;inheritance>
-X<inheritance;with PMCs>
-All Parrot classes inherit from the class C<default>. The
-C<default>X<default PMC> class provides some
-default functionality, but mainly throws exceptions when the default
-variant of a method is called (meaning the subclass didn't define the
-method).
-
-=head3 Autoboxing
-
-Z<CHP-5-SECT-2.2.3>
-
-X<Auboboxing>
-As we've seen in the previous chapters about PIR, we can convert between
-primitive string, integer, and number types and PMCs. PIR used the C<=>
-operator to make these conversions. PASM doesn't have any symbolic operators
-so we have to use the underlying opcodes directly. In this case, the C<set>
-opcode is used to perform data copying and data conversions automatically.
-
-Assigning a primitive data type to a PMC of a String, Integer, or Float type
-converts that PMC to the new type. So, assigning a string to a Number PMC
-converts it into a String PMC. Assigning an integer value converts it to a
-C<Integer>, and assigning C<undef> morphs it to C<Undef>:
-
-=begin PASM
-
-  new P0, "String"
-  set P0, "Ford\n"
-  print P0           # prints "Ford\n"
-  set P0, 42
-  print P0           # prints 42
-  print "\n"
-  typeof S0, P0
-  print S0           # prints "Integer"
-  print "\n"
-  end
-
-=end PASM
-
-C<P0> starts as a C<String>, but when C<set> assigns it an integer
-value 42 (replacing the old string value C<"Ford">), it changes type
-to C<Integer>. This behavior only works for the wrapper PMC types for the
-primitive values string, int, and num. Other PMC classes will have different
-behaviors when you try to assign a primitive value to them.
-
-=head2 Math Operations
-
-Z<CHP-5-SECT-2.3>
-
-X<PASM (Parrot assembly language);math operations>
-PASM has a full set of math instructions. These work with integers,
-floating-point numbers, and PMCs that implement the vtable methods of
-a numeric object. Most of the major math opcodes have two- and
-three-argument forms:
-
-=begin PASM
-
-  add I0, I1              # I0 += I1
-  add I10, I11, I2        # I10 = I11 + I2
-
-=end PASM
-
-The three-argument form of C<add>X<add opcode (PASM)> stores the sum
-of the last two registers in the first register. The two-argument form
-adds the first register to the second and stores the result back in
-the first register.
-
-The source arguments can be Parrot registers or constants, but they
-must be compatible with the type of the destination register.
-Generally, "compatible" means that the source and destination have to
-be the same type, but there are a few exceptions:
-
-=begin PASM
-
-  sub P0, P1, 2          # P0 = P1 - 2
-  sub P0, P1, 1.5        # P0 = P1 - 1.5
-
-=end PASM
-
-If the destination register is an integer register, like C<I0>, the
-other arguments must be integer registers or integer constants. A
-floating-point destination, like C<N0>, usually requires
-floating-point arguments, but many math opcodes also allow the final
-argument to be an integer. Opcodes with a PMC destination register may
-take an integer, floating-point, or PMC final argument:
-
-=begin PASM
-
-  mul P0, P1             # P0 *= P1
-  mul P0, I1
-  mul P0, N1
-  mul P0, P1, P2         # P0 = P1 * P2
-  mul P0, P1, I2
-  mul P0, P1, N2
-
-=end PASM
-
-X<PMCs (Polymorphic Containers);operations on>
-Operations on a PMC are implemented by the vtable method of the
-destination (in the two-argument form) or the left source argument (in
-the three argument form). The result of an operation is entirely
-determined by the PMC.  A class implementing imaginary number
-operations might return an imaginary number, for example.
-
-We won't list every math opcode here, but we'll list some of the most
-common ones. You can get a complete list in A<CHP-11-SECT-1>"PASM
-Opcodes" in Chapter 11.
-
-=head3 Unary math opcodes
-
-Z<CHP-5-SECT-2.3.1>
-
-The unary opcodes have either a destination argument and a source
-argument, or a single argument as destination and source. Some of the
-most common unary math opcodes are C<inc> (increment), C<dec>
-(decrement), C<abs> (absolute value), C<neg> (negate), and C<fact>
-(factorial):
-
-=begin PASM
-
-  abs N0, -5.0  # the absolute value of -5.0 is 5.0
-  fact I1, 5    # the factorial of 5 is 120
-  inc I1        # 120 incremented by 1 is 121
-
-=end PASM
-
-=head3 Binary math opcodes
-
-Z<CHP-5-SECT-2.3.2>
-
-X<PASM (Parrot assembly language);math operations;binary>
-Binary opcodes have two source arguments and a destination argument.
-As we mentioned before, most binary math opcodes have a two-argument
-form in which the first argument is both a source and the destination.
-Parrot provides C<add>X<add opcode (PASM)> (addition),
-C<sub>X<sub opcode (PASM)> (subtraction), C<mul>X<mul opcode (PASM)>
-(multiplication), C<div>X<div opcode (PASM)> (division), and C<pow>X<pow
-opcode (PASM)> (exponent) opcodes, as well as two different modulus
-operations. C<mod>X<mod opcode (PASM)> is Parrot's implementation of
-modulus, and C<cmod>X<cmod opcode (PASM)> is the C<%> operator from
-the C library. It also provides C<gcd>X<gcd opcode (PASM)> (greatest
-common divisor) and C<lcm>X<lcm opcode (PASM)> (least common
-multiple).
-
-=begin PASM
-
-  div I0, 12, 5   # I0 = 12 / 5
-  mod I0, 12, 5   # I0 = 12 % 5
-
-=end PASM
-
-=head3 Floating-point operations
-
-Z<CHP-5-SECT-2.3.3>
-
-X<PASM (Parrot assembly language);math operations;floating-point>
-Although most of the math operations work with both floating-point
-numbers and integers, a few require floating-point destination
-registers. Among these are C<ln> (natural log), C<log2> (log base 2),
-C<log10> (log base 10), and C<exp> (I<e>G<x>), as well as a full set
-of trigonometric opcodes such as C<sin> (sine), C<cos> (cosine),
-C<tan> (tangent), C<sec> (secant), C<cosh> (hyperbolic cosine),
-C<tanh> (hyperbolic tangent), C<sech> (hyperbolic secant), C<asin>
-(arc sine), C<acos> (arc cosine), C<atan> (arc tangent), C<asec> (arc
-secant), C<exsec> (exsecant), C<hav> (haversine), and C<vers>
-(versine). All angle arguments for the
-X<trigonometric functions (PASM)> trigonometric functions are in
-radians:
-
-=begin PASM
-
-  sin N1, N0
-  exp N1, 2
-
-=end PASM
-
-The majority of the floating-point operations have a single source
-argument and a single destination argument. Even though the
-destination must be a floating-point register, the source can be
-either an integer or floating-point number.
-
-The C<atan>X<atan opcode (PASM)> opcode also has a three-argument
-variant that implements C's C<atan2()>:
-
-=begin PASM
-
-  atan N0, 1, 1
-
-=end PASM
-
-=head2 Working with Strings
-
-Z<CHP-5-SECT-2.4>
-
-X<PASM (Parrot assembly language);string operations>
-String operations work with string registers and with PMCs that implement a
-string class. String operations on PMC registers require all their string
-arguments to be String PMCs.
-
-=head3 Concatenating strings
-
-Z<CHP-5-SECT-2.4.1>
-
-X<PASM (Parrot assembly language);string operations;concatenation>
-Use the C<concat>X<concat opcode (PASM)> opcode to concatenate
-strings. With string register or string constant arguments, C<concat>
-has both a two-argument and a three-argument form. The first argument
-is a source and a destination in the two-argument form:
-
-=begin PASM
-
-  set S0, "ab"
-  concat S0, "cd"     # S0 has "cd" appended
-  print S0            # prints "abcd"
-  print "\n"
-
-  concat S1, S0, "xy" # S1 is the string S0 with "xy" appended
-  print S1            # prints "abcdxy"
-  print "\n"
-  end
-
-=end PASM
-
-The first C<concat> concatenates the string "cd" onto the string "ab"
-in C<S0>. It generates a new string "abcd" and changes C<S0> to point
-to the new string. The second C<concat> concatenates "xy" onto the
-string "abcd" in C<S0> and stores the new string in C<S1>.
-
-X<PMCs (Polymorphic Containers);concatenation>
-For PMC registers, C<concat> has only a three-argument form with
-separate registers for source and destination:
-
-=begin PASM
-
-  new P0, "String"
-  new P1, "String"
-  new P2, "String"
-  set P0, "ab"
-  set P1, "cd"
-  concat P2, P0, P1
-  print P2            # prints abcd
-  print "\n"
-  end
-
-=end PASM
-
-Here, C<concat> concatenates the strings in C<P0> and C<P1> and stores
-the result in C<P2>.
-
-=head3 Repeating strings
-
-Z<CHP-5-SECT-2.4.2>
-
-X<PASM (Parrot assembly language);string operations;repeating strings>
-The C<repeat>X<repeat opcode (PASM)> opcode repeats a string a certain
-number of times:
-
-=begin PASM
-
-  set S0, "x"
-  repeat S1, S0, 5  # S1 = S0 x 5
-  print S1          # prints "xxxxx"
-  print "\n"
-  end
-
-=end PASM
-
-In this example, C<repeat> generates a new string with "x" repeated
-five times and stores a pointer to it in C<S1>.
-
-=head3 Length of a string
-
-Z<CHP-5-SECT-2.4.3>
-
-X<PASM (Parrot assembly language);string operations;length>
-The C<length>X<length opcode (PASM)> opcode returns the length of a
-string in characters. This won't be the same as the length in bytes
-for multibyte encoded strings:
-
-=begin PASM
-
-  set S0, "abcd"
-  length I0, S0                # the length is 4
-  print I0
-  print "\n"
-  end
-
-=end PASM
-
-C<length> doesn't have an equivalent for PMC strings.
-
-=head3 Substrings
-
-Z<CHP-5-SECT-2.4.4>
-
-X<PASM (Parrot assembly language);string operations;substrings>
-The simplest version of the C<substr>X<substr opcode (PASM)> opcode
-takes four arguments: a destination register, a 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 PASM
-
-  substr S0, "abcde", 1, 2        # S0 is "bc"
-
-=end PASM
-
-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. So an offset of -1 starts at the last character of the
-string.
-
-C<substr> also has a five-argument form, where the fifth argument is a
-string to replace the substring. This modifies the second argument and
-returns the removed substring in the destination register.
-
-=begin PASM
-
-  set S1, "abcde"
-  substr S0, S1, 1, 2, "XYZ"
-  print S0                        # prints "bc"
-  print "\n"
-  print S1                        # prints "aXYZde"
-  print "\n"
-  end
-
-=end PASM
-
-This replaces the substring "bc" in C<S1> with the string "XYZ", and
-returns "bc" in C<S0>.
-
-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 C<concat> opcode. If the replacement string is an
-empty string, the characters are just removed from the original
-string.
-
-When you don't need to capture the replaced string, there's an
-optimized version of C<substr> that just does a replace without
-returning the removed substring.
-
-=begin PASM
-
-  set S1, "abcde"
-  substr S1, 1, 2, "XYZ"
-  print S1                        # prints "aXYZde"
-  print "\n"
-  end
-
-=end PASM
-
-The PMC versions of C<substr> are not yet implemented.
-
-=head3 Chopping strings
-
-Z<CHP-5-SECT-2.4.5>
-
-X<PASM (Parrot assembly language);string operations;chopping strings>
-The C<chopn>X<chopn opcode (PASM)> opcode removes characters from the
-end of a string. It takes two arguments: the string to modify and the
-count of characters to remove.
-
-=begin PASM
-
-  set S0, "abcde"
-  chopn S0, 2
-  print S0         # prints "abc"
-  print "\n"
-  end
-
-=end PASM
-
-This example removes two characters from the end of C<S0>. If the
-count is negative, that many characters are kept in the string:
-
-=begin PASM
-
-  set S0, "abcde"
-  chopn S0, -2
-  print S0         # prints "ab"
-  print "\n"
-  end
-
-=end PASM
-
-This keeps the first two characters in C<S0> and removes the rest.
-C<chopn> also has a three-argument version that stores the chopped
-string in a separate destination register, leaving the original string
-untouched:
-
-=begin PASM
-
-  set S0, "abcde"
-  chopn S1, S0, 1
-  print S1         # prints "abcd"
-  print "\n"
-  end
-
-=end PASM
-
-=head3 Copying strings
-
-Z<CHP-5-SECT-2.4.6>
-
-X<PASM (Parrot assembly language);string operations;copying>
-The C<clone>X<clone opcode (PASM)> opcode makes a deep copy of a
-string or PMC. Instead of just copying the pointer, as normal
-assignment would, it recursively copies the string or object
-underneath.
-
-=begin PASM
-
-  new P0, "String"
-  set P0, "Ford"
-  clone P1, P0
-  set P0, "Zaphod"
-  print P1        # prints "Ford"
-  end
-
-=end PASM
-
-This example creates an identical, independent clone of the PMC in
-C<P0> and puts a pointer to it in C<P1>. Later changes to C<P0> have
-no effect on C<P1>.
-
-With simple strings, the copy created by C<clone>, as well as the
-results from C<substr>, are copy-on-write (COW). These are rather
-cheap in terms of memory usage because the new memory location is only
-created when the copy is assigned a new value. Cloning is rarely
-needed with ordinary string registers since they always create a new
-memory location on assignment.
-
-=head3 Converting characters
-
-Z<CHP-5-SECT-2.4.7>
-
-X<PASM (Parrot assembly language);string operations;converting strings>
-The C<chr>X<chr opcode (PASM)> opcode takes an integer value and
-returns the corresponding character as a one-character string, while
-the C<ord>X<ord opcode (PASM)> opcode takes a single character string
-and returns the integer that represents that character in the string's
-encoding:
-
-=begin PASM
-
-  chr S0, 65                # S0 is "A"
-  ord I0, S0                # I0 is 65
-
-=end PASM
-
-C<ord> has a three-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 PASM
-
-  ord I0, "ABC", 2        # I0 is 67
-
-=end PASM
-
-A negative offset counts backward from the end of the string, so -1 is
-the last character.
-
-=begin PASM
-
-  ord I0, "ABC", -1        # I0 is 67
-
-=end PASM
-
-=head3 Formatting strings
-
-Z<CHP-5-SECT-2.4.8>
-
-X<PASM (Parrot assembly language);string operations;formatting
-strings> The C<sprintf>X<sprintf opcode (PASM)> opcode generates a
-formatted string from a series of values. It takes three arguments:
-the destination register, a string specifying the format, and an
-ordered aggregate PMC (like a C<Array>) containing the values to
-be formatted. The format string and the destination register can be
-either strings or PMCs:
-
-=begin PASM
-
-  sprintf S0, S1, P2
-  sprintf P0, P1, P2
-
-=end PASM
-
-The format string is similar to the one for C's C<sprintf> function,
-but with some extensions for Parrot data types. Each format field in
-the string starts with a C<%>
-X<% (percent sign);% format strings for sprintf opcode (PASM)> and
-ends with a character specifying the output format. The output format
-characters are listed in A<CHP-5-TABLE-1>Table 5-1.
-
-=begin table picture Format characters
-
-Z<CHP-5-TABLE-1>
-
-=headrow
-
-=row
-
-=cell Format
-
-=cell Meaning
-
-=bodyrows
-
-=row
-
-=cell C<%c>
-
-=cell A 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 either 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 can be specified with several options: R<flags>,
-R<width>, R<precision>, and R<size>. The format flags are listed in
-A<CHP-5-TABLE-2>Table 5-2.
-
-=begin table picture Format flags
-
-Z<CHP-5-TABLE-2>
-
-=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.
-The flags are listed in A<CHP-5-TABLE-3>Table 5-3.
-
-=begin table picture Size flags
-
-Z<CHP-5-TABLE-3>
-
-=headrow
-
-=row
-
-=cell Character
-
-=cell Meaning
-
-=bodyrows
-
-=row
-
-=cell C<h>
-
-=cell short or float
-
-=row
-
-=cell C<l>
-
-=cell long
-
-=row
-
-=cell C<H>
-
-=cell huge value (long long or long double)
-
-=row
-
-=cell C<v>
-
-=cell INTVAL or FLOATVAL
-
-=row
-
-=cell C<O>
-
-=cell opcode_t
-
-=row
-
-=cell C<P>
-
-=cell C<PMC>
-
-=row
-
-=cell C<S>
-
-=cell string
-
-=end table
-
-The values in the aggregate PMC must have a type compatible with the
-specified R<size>.
-
-Here's a short illustration of string formats:
-
-=begin PASM
-
-  new P2, "Array"
-  new P0, "Int"
-  set P0, 42
-  push P2, P0
-  new P1, "Num"
-  set P1, 10
-  push P2, P1
-  sprintf S0, "int %#Px num %+2.3Pf\n", P2
-  print S0     # prints "int 0x2a num +10.000"
-  print "\n"
-  end
-
-=end PASM
-
-The first eight lines create a C<Array> with two elements: a
-C<Int> and a C<Num>. The format string of the C<sprintf> has
-two format fields. The first, C<%#Px>, takes a PMC argument from the
-aggregate (C<P>) 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/src/sprintf.t> have many more
-examples of format strings.
-
-=head3 Testing for substrings
-
-Z<CHP-5-SECT-2.4.9>
-
-X<PASM (Parrot assembly language);string operations;testing for substrings>
-The C<index>X<index opcode (PASM)> 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 PASM
-
-  index I0, "Beeblebrox", "eb"
-  print I0                       # prints 2
-  print "\n"
-  index I0, "Beeblebrox", "Ford"
-  print I0                       # prints -1
-  print "\n"
-  end
-
-=end PASM
-
-C<index> also has a four-argument version, where the fourth argument
-defines an offset position for starting the search:
-
-=begin PASM
-
-  index I0, "Beeblebrox", "eb", 3
-  print I0                         # prints 5
-  print "\n"
-  end
-
-=end PASM
-
-This finds the second "eb" in "Beeblebrox" instead of the first,
-because the search skips the first three characters in the
-string.
-
-=head3 Joining strings
-
-The C<join> opcode joins the elements of an array PMC into a single
-string. The second argument separates the individual elements of the
-PMC in the final string result.
-
-=begin PASM
-
-  new P0, "Array"
-  push P0, "hi"
-  push P0, 0
-  push P0, 1
-  push P0, 0
-  push P0, "parrot"
-  join S0, "__", P0
-  print S0              # prints "hi__0__1__0__parrot"
-  end
-=end PASM
-
-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, and stores it in C<S0>.
-
-=head3 Splitting strings
-
-Splitting a string yields a new array containing the resulting
-substrings of the original string.
-
-=begin PASM
-
-  split P0, "", "abc"
-  set P1, P0[0]
-  print P1              # 'a'
-  set P1, P0[2]
-  print P1              # 'c'
-  end
-
-=end PASM
-
-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. For now, the split pattern (the second
-argument to the opcode) is ignored except for a test to make sure that
-its length is zero.
-
-=head2 Logical and Bitwise Operations
-
-Z<CHP-5-SECT-2.6>
-
-X<PASM (Parrot assembly language);bitwise operations>
-X<PASM (Parrot assembly language);logical operations>
-The X<logical opcodes> logical opcodes evaluate the truth of their
-arguments. They're often used to make decisions on control flow.
-Logical operations are implemented for integers and PMCs. Numeric
-values 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 method (PASM)> vtable method returns a
-nonzero value.
-
-The C<and>X<and opcode (PASM)> opcode returns the second argument if
-it's false and the third argument otherwise:
-
-=begin PASM
-
-  and I0, 0, 1  # returns 0
-  and I0, 1, 2  # returns 2
-
-=end PASM
-
-The C<or>X<or opcode (PASM)> opcode returns the second argument if
-it's true and the third argument otherwise:
-
-=begin PASM
-
-  or I0, 1, 0  # returns 1
-  or I0, 0, 2  # returns 2
-
-  or P0, P1, P2
-
-=end PASM
-
-Both C<and> and C<or> are short-circuiting. If they can determine what
-value to return from the second 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 (PASM)> opcode returns the second argument if
-it is the only true value, returns the third argument if it is the
-only true value, and returns false if both values are true or both are
-false:
-
-=begin PASM
-
-  xor I0, 1, 0  # returns 1
-  xor I0, 0, 1  # returns 1
-  xor I0, 1, 1  # returns 0
-  xor I0, 0, 0  # returns 0
-
-=end PASM
-
-The C<not>X<not opcode (PASM)> opcode returns a true value when the
-second argument is false, and a false value if the second argument is
-true:
-
-=begin PASM
-
-  not I0, I1
-  not P0, P1
-
-=end PASM
-
-The X<bitwise;opcodes (PASM)> bitwise opcodes operate on their values
-a single bit at a time. C<band>X<band opcode (PASM)>,
-C<bor>X<bor opcode (PASM)>, and C<bxor>X<bxor opcode (PASM)> return a
-value that is the logical AND, OR, or XOR of each bit in the source
-arguments. They each take a destination register and two source
-registers. They also have two-argument forms where the destination is
-also a source.  C<bnot>X<bnot opcode (PASM)> is the logical NOT of
-each bit in a single source argument.
-
-=begin PASM
-
-  bnot I0, I1
-  band P0, P1
-  bor I0, I1, I2
-  bxor P0, P1, I2
-
-=end PASM
-
-X<bitwise;string opcodes>
-The bitwise opcodes also have string variants for AND, OR, and XOR:
-C<bors>X<bors opcode (PASM)>, C<bands>X<bands opcode (PASM)>, and
-C<bxors>X<bxors opcode (PASM)>. These take string register or PMC
-string source arguments and perform the logical operation on each byte
-of the strings to produce the final string.
-
-=begin PASM
-
-  bors S0, S1
-  bands P0, P1
-  bors S0, S1, S2
-  bxors P0, P1, S2
-
-=end PASM
-
-The bitwise string opcodes only have meaningful results when they're
-used with simple ASCII strings because the bitwise operation is done
-per byte.
-
-The logical and arithmetic shift operations shift their values by a
-specified number of bits:
-
-=begin PASM
-
-  shl  I0, I1, I2        # shift I1 left by count I2 giving I0
-  shr  I0, I1, I2        # arithmetic shift right
-  lsr  P0, P1, P2        # logical shift right
-
-=end PASM
-
-=head1 Working with PMCs
-
-Z<CHP-5-SECT-3>
-
-In most of the examples we've shown so far, X<PMCs (Polymorphic
-Containers);working with> PMCs just duplicate the functionality of
-integers, numbers, and strings. They wouldn't be terribly useful if
-that's all they did, though. PMCs offer several advanced features,
-each with its own set of operations.
-
-=head2 Aggregates
-
-Z<CHP-5-SECT-3.1>
-
-PMCs can define complex types that hold multiple values. These are
-commonly called "X<PMCs (Polymorphic Containers);aggregate>
-X<aggregate PMCs> aggregates." The most important feature added for
-aggregates is keyed access. Elements within an aggregate PMC can be
-stored and retrieved by a numeric or string key. PASM also offers a
-full set of operations for manipulating aggregate data types.
-
-Since PASM is intended to implement Perl, the two most fully featured
-aggregates already in operation are arrays and hashes. Any aggregate
-defined for any language could take advantage of the features
-described here.
-
-=head3 Arrays
-
-Z<CHP-5-SECT-3.1.1>
-
-X<PMCs (Polymorphic Containers);arrays>
-The C<Array>X<Array PMC> PMC is an ordered aggregate with
-zero-based integer keys. The syntax for X<keyed access to PMCs> keyed access to a
-PMC puts the key in square brackets after the register name:
-
-=begin PASM
-
-  new P0, "Array"     # obtain a new array object
-  set P0, 2           # set its length
-  set P0[0], 10       # set first element to 10
-  set P0[1], I31      # set second element to I31
-  set I0, P0[0]       # get the first element
-  set I1, P0          # get array length
-
-=end PASM
-
-A key on the destination register of a C<set> operation sets a value
-for that key in the aggregate. A key on the source register of a
-C<set> returns the value for that key. If you set C<P0> without a key,
-you set the length of the array, not one of its values.N<C<Array>
-is an autoextending array, so you never need to set its length. Other
-array types may require the length to be set explicitly.> And if you
-assign the C<Array> to an integer, you get the length of the
-array.
-
-By the time you read this, the syntax for getting and setting the
-length of an array may have changed. The change would separate array
-allocation (how much storage the array provides) from the actual
-element count. The currently proposed syntax uses C<set> to set or
-retrieve the allocated size of an array, and an C<elements>
-X<elements opcode (PASM)> opcode to retrieve the count of
-elements stored in the array.
-
-=begin PASM
-
-  set P0, 100         # allocate store for 100 elements
-  set I0, P0          # obtain current allocation size
-  elements I0, P0     # get element count
-
-=end PASM
-
-Some other useful instructions for working with arrays are C<push>,
-C<pop>, C<shift>, and C<unshift> (you'll find them in
-A<CHP-11-SECT-1>"PASM Opcodes" in Chapter 11).
-
-=head3 Hashes
-
-Z<CHP-5-SECT-3.1.2>
-
-X<PMCs (Polymorphic Containers);hashes>
-The C<Hash>X<Hash PMC> PMC is an unordered aggregate with
-string keys:
-
-=begin PASM
-
-  new P1, "Hash"      # generate a new hash object
-  set P1["key"], 10   # set key and value
-  set I0, P1["key"]   # obtain value for key
-  set I1, P1          # number of entries in hash
-
-=end PASM
-
-The C<exists>X<exists opcode (PASM)> opcode tests whether a keyed
-value exists in an aggregate. It returns 1 if it finds the key in the
-aggregate, and returns 0 if it doesn't. It doesn't care if the value
-itself is true or false, only that the key has been set:
-
-=begin PASM
-
-  new P0, "Hash"
-  set P0["key"], 0
-  exists I0, P0["key"] # does a value exist at "key"
-  print I0             # prints 1
-  print "\n"
-  end
-
-=end PASM
-
-The C<delete>X<delete opcode (PASM)> opcode is also useful for working
-with hashes: it removes a key/value pair.
-
-=head3 Iterators
-
-Z<CHP-5-SECT-3.1.3>
-
-Iterators extract values from an aggregate PMC. You create an iterator
-by creating a new C<Iterator> PMC, and passing the array to C<new> as
-an additional parameter:
-
-=begin PASM
-
-      new P1, "Iterator", P2
-
-=end PASM
-
-The include file F<iterator.pasm> defines some constants for working
-with iterators. The C<.ITERATE_FROM_START> and C<.ITERATE_FROM_END>
-constants are used to select whether an array iterator starts from the
-beginning or end of the array. The C<shift> opcode extracts values
-from the array. An iterator PMC is true as long as it still has values
-to be retrieved (tested by C<unless> below).
-
-=begin PASM
-
-  .include "iterator.pasm"
-      new P2, "Array"
-      push P2, "a"
-      push P2, "b"
-      push P2, "c"
-      new P1, "Iterator", P2
-      set P1, .ITERATE_FROM_START
-
-  iter_loop:
-      unless P1, iter_end
-      shift P5, P1
-      print P5                        # prints "a", "b", "c"
-      branch iter_loop
-  iter_end:
-      end
-
-=end PASM
-
-Hash iterators work similarly to array iterators, but they extract
-keys. With hashes it's only meaningful to iterate in one direction,
-since they don't define any order for their keys.
-
-=begin PASM
-
-  .include "iterator.pasm"
-      new P2, "Hash"
-      set P2["a"], 10
-      set P2["b"], 20
-      set P2["c"], 30
-      new P1, "Iterator", P2
-      set P1, .ITERATE_FROM_START_KEYS
-
-  iter_loop:
-      unless P1, iter_end
-      shift S5, P1                    # one of the keys "a", "b", "c"
-      set I9, P2[S5]
-      print I9                        # prints e.g. 20, 10, 30
-      branch iter_loop
-  iter_end:
-      end
-
-=end PASM
-
-=head3 Data structures
-
-Z<CHP-5-SECT-3.1.4>
-
-X<PMCs (Polymorphic Containers);data structures>
-Arrays and hashes can hold any data type, including other aggregates.
-Accessing elements deep within nested data structures is a common
-operation, so PASM 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 PASM
-
-  new P0, "Hash"
-  new P1, "Array"
-  set P1[2], 42
-  set P0["answer"], P1
-  set I1, 2
-  set I0, P0["answer";I1]        # $i = %hash{"answer"}[2]
-  print I0
-  print "\n"
-  end
-
-=end PASM
-
-This example builds up a data structure of a hash containing an array.
-The complex key C<P0["answer";I1]> retrieves an element of the array
-within the hash. You can also set a value using a complex key:
-
-=begin PASM
-
-  set P0["answer";0], 5   # %hash{"answer"}[0] = 5
-
-=end PASM
-
-The individual keys are integers or strings, or registers with integer
-or string values.
-
-=head2 PMC Assignment
-
-Z<CHP-5-SECT-3.2>
-
-We mentioned before that C<set> on two X<PMCs (Polymorphic
-Containers);assignment> PMCs simply aliases them both to the same object,
-and that C<clone> creates a complete duplicate object. But if you just
-want to assign the value of one PMC to another PMC, you need the
-C<assign>X<assign opcode (PASM)> opcode:
-
-=begin PASM
-
-  new P0, "Int"
-  new P1, "Int"
-  set P0, 42
-  set P2, P0
-  assign P1, P0     # note: P1 has to exist already
-  inc P0
-  print P0          # prints 43
-  print "\n"
-  print P1          # prints 42
-  print "\n"
-  print P2          # prints 43
-  print "\n"
-  end
-
-=end PASM
-
-This example creates two C<Int> PMCs: C<P0> and C<P1>. It gives
-C<P0> a value of 42. It then uses C<set> to give the same value to
-C<P2>, but uses C<assign> to give the value to C<P1>. When C<P0> is
-incremented, C<P2> also changes, but C<P1> doesn't. The destination
-register for C<assign> must have an existing object of the right type
-in it, since C<assign> doesn't create a new object (as with C<clone>)
-or reuse the source object (as with C<set>).
-
-=head2 Properties
-
-Z<CHP-5-SECT-3.3>
-
-X<PMCs (Polymorphic Containers);properties>
-PMCs can have additional values attached to them as "properties" of
-the PMC. What these properties do is entirely up to the language being
-implemented. Perl 6 uses them to store extra information about a
-variable: whether it's a constant, if it should always be interpreted
-as a true value, etc.
-
-The C<setprop>X<setprop opcode (PASM)> opcode sets the value of a
-named property on a PMC. It takes three arguments: the PMC to be set
-with a property, the name of the property, and a PMC containing the
-value of the property. The C<getprop>X<getprop opcode (PASM)> opcode
-returns the value of a property. It also takes three arguments: the
-PMC to store the property's value, the name of the property, and the
-PMC from which the property value is to be retrieved:
-
-=begin PASM
-
-  new P0, "String"
-  set P0, "Zaphod"
-  new P1, "Int"
-  set P1, 1
-  setprop P0, "constant", P1        # set a property on P0
-  getprop P3, "constant", P0        # retrieve a property on P0
-  print P3                          # prints 1
-  print "\n"
-  end
-
-=end PASM
-
-This example creates a C<String> object in C<P0>, and a C<Int>
-object with the value 1 in C<P1>. C<setprop> sets a property named
-"constant" on the object in C<P0> and gives the property the value in
-C<P1>.N<The "constant" property is ignored by PASM, but is significant
-to the Perl 6 code running on top of it.> C<getprop> retrieves the
-value of the property "constant" on C<P0> and stores it in C<P3>.
-
-Properties are kept in a separate hash for each PMC. Property values
-are always PMCs, but only references to the actual PMCs. Trying to
-fetch the value of a property that doesn't exist returns a
-C<Undef>.
-
-C<delprop>X<delprop opcode (PASM)> deletes a property from a PMC.
-
-=begin PASM
-
-  delprop P1, "constant"  # delete property
-
-=end PASM
-
-You can also return a complete hash of all properties on a PMC with
-C<prophash>X<prophash opcode (PASM)>.
-
-=begin PASM
-
-  prophash P0, P1         # set P0 to the property hash of P1
-
-=end PASM
-
-=head1 Flow Control
-
-Z<CHP-5-SECT-4>
-
-X<PASM (Parrot assembly language);flow control>
-Although it has many advanced features, at heart PASM is an assembly
-language. All flow control in PASM--as in most assembly languages--is
-done with branches and jumps.
-
-Branch instructions transfer control to a relative offset from the
-current instruction. The rightmost argument to every branch opcode is
-a label, which the assembler converts to the integer value of the
-offset. You can also branch on a literal integer value, but there's
-rarely any need to do so. The simplest branch instruction is
-C<branch>:
-
-=begin PASM
-
-    branch L1                # branch 4
-    print "skipped\n"
-  L1:
-    print "after branch\n"
-    end
-
-=end PASM
-
-This example unconditionally branches to the location of the label
-C<L1>, skipping over the first C<print> statement.
-
-Jump instructions transfer control to an absolute address. The C<jump>
-opcode doesn't calculate an address from a label, so it's used
-together with C<set_addr>:
-
-=begin PASM
-
-    set_addr I0, L1
-    jump I0
-    print "skipped\n"
-    end
-  L1:
-    print "after jump\n"
-    end
-
-=end PASM
-
-The C<set_addr>X<set_addr opcode (PASM)> opcode takes a label or an
-integer offset and returns an absolute address.
-
-You've probably noticed the C<end>X<end opcode (PASM)> opcode as the
-last statement in many examples above. This terminates the execution
-of the current run loop. Terminating the main bytecode segment (the
-first run loop) stops the interpreter. Without the C<end> statement,
-execution just falls off the end of the bytecode segment, with a good
-chance of crashing the interpreter.
-
-=head2 Conditional Branches
-
-Z<CHP-5-SECT-4.1>
-
-X<PASM (Parrot assembly language);conditional branches>
-X<conditional branches in PASM>
-Unconditional jumps and branches aren't really enough for flow
-control. What you need to implement the control structures of
-high-level languages is the ability to select different actions based
-on a set of conditions. PASM has opcodes that conditionally branch
-based on the truth of a single value or the comparison of two values.
-The following example has C<if>X<if (conditional);opcode (PASM)> and
-C<unless>X<unless (conditional);opcode (PASM)> conditional branches:
-
-=begin PASM
-
-    set I0, 0
-    if I0, TRUE
-    unless I0, FALSE
-    print "skipped\n"
-    end
-  TRUE:
-    print "shouldn't happen\n"
-    end
-  FALSE:
-    print "the value was false\n"
-    end
-
-=end PASM
-
-C<if> branches if its first argument is a true value, and C<unless>
-branches if its first argument is a false value. In this case, the
-C<if> doesn't branch because C<I0> is false, but the C<unless> does
-branch.
-The comparison branching opcodes compare two values and branch if the
-stated relation holds true. These are
-C<eq>X<eq (equal);opcode (PASM)> (branch when equal),
-C<ne>X<ne (not equal);opcode (PASM)> (when not equal),
-C<lt>X<lt (less than);opcode (PASM)> (when less than),
-C<gt>X<gt (greater than);opcode (PASM)> (when greater than),
-C<le>X<le (less than or equal);opcode (PASM)> (when less than or
-equal), and C<ge>X<ge (greater than or equal);opcode (PASM)> (when
-greater than or equal). The two compared arguments must be the same
-register type:
-
-=begin PASM
-
-    set I0, 4
-    set I1, 4
-    eq I0, I1, EQUAL
-    print "skipped\n"
-    end
-  EQUAL:
-    print "the two values are equal\n"
-    end
-
-=end PASM
-
-This compares two integers, C<I0> and C<I1>, and branches if they're
-equal. Strings of different character sets or encodings are converted
-to Unicode before they're compared. PMCs have a C<cmp> vtable method.
-This gets called on the left argument to perform the comparison of the
-two objects.
-
-The comparison opcodes don't specify if a numeric or string comparison
-is intended. The type of the register selects for integers, floats,
-and strings. With PMCs, the vtable method C<cmp> or C<is_equal> of the
-first argument is responsible for comparing the PMC meaningfully with
-the other operand. If you need to force a numeric or string comparison
-on two PMCs, use the alternate comparison opcodes that end in the
-C<_num> and C<_str> suffixes.
-
-=begin PASM
-
-  eq_str P0, P1, label     # always a string compare
-  gt_num P0, P1, label     # always numerically
-
-=end PASM
-
-Finally, the C<eq_addr> opcode branches if two PMCs or strings are
-actually the same object (have the same address):
-
-=begin PASM
-
-  eq_addr P0, P1, same_pmcs_found
-
-=end PASM
-
-=head2 Iteration
-
-Z<CHP-5-SECT-4.2>
-
-X<iteration;in PASM>
-X<PASM (Parrot assembly language);iteration>
-PASM doesn't define high-level loop constructs. These are built up
-from a combination of conditional and unconditional branches. A
-I<do-while>X<do-while style loop;(PASM)> style loop can be constructed
-with a single conditional branch:
-
-=begin PASM
-
-    set I0, 0
-    set I1, 10
-  REDO:
-    inc I0
-    print I0
-    print "\n"
-    lt I0, I1, REDO
-    end
-
-=end PASM
-
-This example prints out the numbers 1 to 10. The first time through,
-it executes all statements up to the C<lt> statement.  If the
-condition evaluates as true (C<I0> is less than C<I1>) it branches to
-the C<REDO> label and runs the three statements in the loop body
-again. The loop ends when the condition evaluates as false.
-
-Conditional and unconditional branches can build up quite complex
-looping constructs, as follows:
-
-=begin PASM
-
-    # loop ($i=1; $i<=10; $i++) {
-    #    print "$i\n";
-    # }
-  loop_init:
-    set I0, 1
-    branch loop_test
-  loop_body:
-    print I0
-    print "\n"
-    branch loop_continue
-  loop_test:
-    le I0, 10, loop_body
-    branch out
-  loop_continue:
-    inc I0
-    branch loop_test
-  out:
-    end
-
-=end PASM
-
-X<loops;PASM>
-X<PASM (Parrot assembly language);loops>
-This example emulates a X<counter-controlled loop> counter-controlled
-loop like Perl 6's C<loop> keyword or C's C<for>. The first time
-through the loop it sets the initial value of the counter in
-C<loop_init>, tests that the loop condition is met in C<loop_test>,
-and then executes the body of the loop in C<loop_body>. If the test
-fails on the first iteration, the loop body will never execute. The
-end of C<loop_body> branches to C<loop_continue>, which increments the
-counter and then goes to C<loop_test> again. The loop ends when the
-condition fails, and it branches to C<out>. The example is more
-complex than it needs to be just to count to 10, but it nicely shows
-the major components of a
-loop.
-
-=head1 Lexicals and Globals
-
-Z<CHP-5-SECT-6>
-
-So far, we've been treating Parrot registers like the variables of a
-high-level language. This is fine, as far as it goes, but it isn't the
-full picture. The dynamic nature and introspective features of
-languages like Perl make it desirable to manipulate variables by name,
-instead of just by register or stack location. These languages also
-have global variables, which are visible throughout the entire
-program. Storing a global variable in a register would either tie up
-that register for the lifetime of the program or require some unwieldy way
-to shuffle the data into and out of registers.
-
-Parrot provides structures for storing both global and lexically
-scoped named variables. Lexical and global variables must be PMC
-values. PASM provides instructions for storing and retrieving
-variables from these structures so the PASM opcodes can operate on
-their values.
-
-=head2 Globals
-
-Z<CHP-5-SECT-6.1>
-
-X<PASM (Parrot assembly language);global variables>
-Global variables are stored in a C<Hash>, so every variable name
-must be unique.  PASM has two opcodes for globals, C<set_global> and
-C<get_global>:
-
-=begin PASM
-
-  new P10, "Int"
-  set P10, 42
-  set_global "$foo", P10
-  # ...
-  get_global P0, "$foo"
-  print P0                        # prints 42
-  end
-
-=end PASM
-
-The first two statements create a C<Int> in the PMC register
-C<P10> and give it the value 42. In the third statement,
-C<set_global> stores that PMC as the named global variable C<$foo>.
-At some later point in the program, C<get_global> retrieves the PMC
-from the global variable by name, and stores it in C<P0> so it can be
-printed.
-
-The C<set_global> opcode only stores a reference to the object. If
-we add an increment statement:
-
-=begin PASM
-
-  inc P10
-
-=end PASM
-
-after the C<set_global> it increments the stored global, printing 43.
-If that's not what you want, you can C<clone> the PMC before you store
-it. Leaving the global variable as an alias does have advantages,
-though. If you retrieve a stored global into a register and modify it
-as follows:
-
-=begin PASM
-
-  get_global P0, "varname"
-  inc P0
-
-=end PASM
-
-the value of the stored global is directly modified, so you don't need
-to call C<set_global> again.
-
-The two-argument forms of C<set_global> and C<get_global> store or
-retrieve globals from the outermost namespace (what Perl users will
-know as the "main" namespace). A simple flat global namespace isn't
-enough for most languages, so Parrot also needs to support
-hierarchical namespaces for separating packages (classes and modules
-in Perl 6). Use C<set_rootglobal> and
-C<get_root_global> add an argument to select a nested namespace:
-
-=begin PASM
-
-  set_root_global ["Foo"], "var", P0 # store P0 as var in the Foo namespace
-  get_root_global P1, ["Foo"], "var"  # get Foo::var
-
-=end PASM
-
-Eventually the global opcodes will have variants that take a PMC to
-specify the namespace, but the design and implementation of these
-aren't finished yet.
-
-=head2 Lexicals
-
-Z<CHP-5-SECT-6.2>
-
-X<PASM (Parrot assembly language);lexical variables>
-Lexical variables are stored in a lexical scratchpad. There's one pad
-for each lexical scope. Every pad has both a hash and an array, so
-elements can be stored either by name or by numeric index.
-
-=head3 Basic instructions
-
-Z<CHP-5-SECT-6.2.1>
-
-To store a lexical variable in the current scope pad, use C<store_lex>.
-Likewise, use C<find_lex> to retrieve a variable from the current pad.
-
-=begin PASM
-
-  new P0, "Int"            # create a variable
-  set P0, 10               # assign value to it
-  store_lex "foo", P0      # store the var with the variable name "foo"
-  # ...
-  find_lex P1, "foo"       # get the var "foo" into P1
-  print P1
-  print "\n"               # prints 10
-  end
-
-=end PASM
-
-=head1 Subroutines
-
-Z<CHP-5-SECT-7>
-
-X<subroutines>
-Subroutines and methods are the basic building blocks of larger
-programs. At the heart of every subroutine call are two fundamental
-actions: it has to store the current location so it can come back to
-it, and it has to transfer control to the subroutine. The
-C<bsr>X<bsr opcode (PASM)> opcode does both. It pushes the address of the
-next instruction onto the control stack, and then branches to a label
-that marks the subroutine:
-
-=begin PASM
-
-    print "in main\n"
-    bsr _sub
-    print "and back\n"
-    end
-  _sub:
-    print "in sub\n"
-    ret
-
-=end PASM
-
-At the end of the subroutine, the C<ret> instruction pops a location
-back off the control stack and goes there, returning control to the
-caller. The C<jsr>X<jsr opcode (PASM)> opcode pushes the current location
-onto the call stack and jumps to a subroutine. Just like the C<jump>
-opcode, it takes an absolute address in an integer register, so the
-address has to be calculated first with the C<set_addr>X<set_addr
-opcode (PASM)> opcode:
-
-=begin PASM
-
-    print "in main\n"
-    set_addr I0, _sub
-    jsr I0
-    print "and back\n"
-    end
-  _sub:
-    print "in sub\n"
-    ret
-
-=end PASM
-
-=head2 Calling Conventions
-
-Z<CHP-5-SECT-7.1>
-
-X<registers;usage for subroutine calls>
-X<subroutines;register usage>
-X<subroutines;calling conventions>
-A C<bsr> or C<jsr> is fine for a simple subroutine call, but few
-subroutines are quite that simple. Who is responsible for saving and
-restoring the registers, however, so that they don't get overwritten when
-we perform a c<bsr> or C<jsr>? How are arguments passed? Where are the
-subroutine's return values stored? A number of different answers are
-possible. You've seen how many ways Parrot has of storing values. The
-critical point is that the caller and the called subroutine have to
-agree on all the answers.
-
-=head3 Parrot calling conventions
-
-Z<CHP-5-SECT-7.1.2>
-
-Internal subroutines can use whatever calling convention serves them
-best. Externally visible subroutines and methods need stricter rules.
-Since these routines may be called as part of an included library or
-module and even from a different high level language, it's important
-to have a consistent interface.
-
-The C<.sub> directive defines globally accessible subroutine
-objects.
-
-Subroutine objects of all kinds can be called with the
-C<invoke>X<invoke opcode (PASM)> opcode. There is also an C<invoke>
-C<PR<x>> instruction for calling objects held in a different register.
-
-The C<invokecc>X<invokecc opcode (PASM)> opcode is like C<invoke>, but it
-also creates and stores a new return continuation. When the
-called subroutine invokes this return continuation, it returns control
-to the instruction after the function call. This kind of call is known
-as Continuation Passing Style (CPS).
-X<CPS (Continuation Passing Style)>
-X<Continuation Passing Style (CPS)>
-
-=head2 Native Call Interface
-
-Z<CHP-5-SECT-7.2>
-
-X<subroutines;calling conventions;NCI>
-A special version of the Parrot calling conventions are used by the
-X<NCI (Native Call Interface)> Native Call Interface (NCI) for calling
-subroutines with a known prototype in shared libraries. This is not
-really portable across all libraries, but it's worth a short example.
-This is a simplified version of the first test in F<t/pmc/nci.t>:
-
-=begin PASM TODO
-
-    loadlib P1, "libnci"          # get library object for a shared lib
-    print "loaded\n"
-    dlfunc P0, P1, "nci_dd", "dd" # obtain the function object
-    print "dlfunced\n"
-    set I0, 1                     # prototype used - unchecked
-    set N5, 4.0                   # first argument
-    invoke                        # call nci_dd
-    ne N5, 8.0, nok_1             # the test functions returns 2*arg
-    print "ok 1\n"
-    end
-  nok_1:
-    #...
-
-=end PASM TODO
-
-This example shows two new instructions: C<loadlib> and C<dlfunc>. The
-C<loadlib>X<loadlib opcode (PASM)> 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 C<.so> or C<.dll>. Which extensions it
-tries depends on the OS Parrot is running on.
-
-The C<dlfunc>X<dlfunc opcode (PASM)> 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. The
-characters used in X<NCI (Native Call Interface);function signatures>
-NCI function signatures are listed in A<CHP-5-TABLE-5>Table 5-5.
-
-=begin table picture Function signature letters
-
-Z<CHP-5-TABLE-5>
-
-=headrow
-
-=row
-
-=cell Character
-
-=cell Register set
-
-=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
-
-For more information on callback functions, read the documentation in
-F<docs/pdds/pdd16_native_call.pod> and F<docs/pmc/struct.pod>.
-
-=head2 Coroutines
-
-Z<CHP-5-SECT-7.4>
-
-As we mentioned in the previous chapter, coroutines are
-X<subroutines;coroutines> subroutines that
-can suspend themselves and return control to the caller--and then pick
-up where they left off the next time they're called, as if they never
-left.
-
-X<coroutines>
-In PASM, coroutines are subroutine-like objects:
-
-=begin PASM TODO
-
-  newsub P0, .Coroutine, _co_entry
-
-=end PASM TODO
-
-The C<Coroutine> object has its own user stack, register frame stacks,
-control stack, and pad stack. The pad stack is inherited from the
-caller. The coroutine's control stack has the caller's control stack
-prepended, but is still distinct. When the coroutine invokes itself,
-it returns to the caller and restores the caller's context (basically
-swapping all stacks). The next time the coroutine is invoked, it
-continues to execute from the point at which it previously returned:
-
-=begin PASM TODO
-
-    new_pad 0                # push a new lexical pad on stack
-    new P0, "Int"            # save one variable in it
-    set P0, 10
-    store_lex -1, "var", P0
-
-    newsub P0, .Coroutine, _cor
-                             # make a new coroutine object
-    saveall                  # preserve environment
-    invoke                   # invoke the coroutine
-    restoreall
-    print "back\n"
-    saveall
-    invoke                   # invoke coroutine again
-    restoreall
-    print "done\n"
-    pop_pad
-    end
-
-  _cor:
-    find_lex P1, "var"       # inherited pad from caller
-    print "in cor "
-    print P1
-    print "\n"
-    inc P1                   # var++
-    saveall
-    invoke                   # yield(  )
-    restoreall
-    print "again "
-    branch _cor              # next invocation of the coroutine
-
-=end PASM TODO
-
-This prints out the result:
-
-  in cor 10
-  back
-  again in cor 11
-  done
-
-X<invoke opcode (PASM);coroutines and>
-The C<invoke> inside the coroutine is commonly referred to as
-I<yield>. The coroutine never ends. When it reaches the bottom, it
-branches back up to C<_cor> and executes until it hits C<invoke>
-again.
-
-The interesting part about this example is that the coroutine yields
-in the same way that a subroutine is called. This means that the
-coroutine has to preserve its own register values. This example uses
-C<saveall> but it could have only stored the registers the coroutine
-actually used. Saving off the registers like this works because
-coroutines have their own register frame stacks.
-
-=head2 Continuations
-
-Z<CHP-5-SECT-7.5>
-
-X<continuations>
-X<subroutines;continuations>
-A continuation is a subroutine that gets a complete copy of the
-caller's context, including its own copy of the call stack. Invoking a
-continuation starts or restarts it at the entry point:
-
-=begin PASM XXX
-
-    new P1, "Int"
-    set P1, 5
-
-    newsub P0, .Continuation, _con
-  _con:
-    print "in cont "
-    print P1
-    print "\n"
-    dec P1
-    unless P1, done
-    invoke                        # P0
-  done:
-    print "done\n"
-    end
-
-=end PASM XXX
-
-This prints:
-
-  in cont 5
-  in cont 4
-  in cont 3
-  in cont 2
-  in cont 1
-  done
-
-=head2 Evaluating a Code String
-
-Z<CHP-5-SECT-7.6>
-
-X<code strings, evaluating>
-This isn't really a subroutine operation, but it does produce a code
-object that can be invoked. In this case, it's a X<bytecode segment
-object> bytecode segment object.
-
-The first step is to get an assembler or compiler for the target
-language:
-
-=begin PASM
-
-  compreg P1, "PASM"
-
-=end PASM
-
-Within the Parrot interpreter there are currently three registered
-languages: C<PASM>, C<PIR>, and C<PASM1>. The first two are for parrot
-assembly language and parrot intermediate representation code. The third
-is for evaluating single statements in PASM. Parrot automatically adds
-an C<end> opcode at the end of C<PASM1> strings before they're
-compiled.
-
-This example places a bytecode segment object into the destination
-register C<P0> and then invokes it with C<invoke>:
-
-=begin PASM TODO
-
-  compreg P1, "PASM1"                # get compiler
-  set S1, "in eval\n"
-  compile P0, P1, "print S1"
-  invoke                             # eval code P0
-  print "back again\n"
-  end
-
-=end PASM TODO
-
-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.
-These compilers may be written in PASM or reside in shared libraries.
-
-=begin PASM
-
-  compreg "MyLanguage", P10
-
-=end PASM
-
-In this example the C<compreg> opcode registers the subroutine-like
-object C<P10> as a compiler for the language "MyLanguage". See
-F<examples/compilers> and F<examples/japh/japh16.pasm> for an external
-compiler in a shared library.
-
-=head1 Exceptions and Exception Handlers
-
-Z<CHP-5-SECT-8>
-
-X<exceptions>
-X<exception handlers>
-Exceptions provide a way of calling a piece of code outside the normal
-flow of control. They are mainly used for error reporting or cleanup
-tasks, but sometimes exceptions are just a funny way to branch from
-one code location to another one. The design and implementation of
-exceptions in Parrot isn't complete yet, but this section will give
-you an idea where we're headed.
-
-Exceptions are objects that hold all the information needed to handle
-the exception: the error message, the severity and type of the error,
-etc. The class of an exception object indicates the kind of exception
-it is.
-
-Exception handlers are derived from continuations. They are ordinary
-subroutines that follow the Parrot calling conventions, but are never
-explicitly called from within user code. User code pushes an exception
-handler onto the control stack with the C<set_eh>X<set_eh opcode (PASM)>
-opcode. The system calls the installed exception handler only when an
-exception is thrown (perhaps because of code that does division by
-zero or attempts to retrieve a global that wasn't stored.)
-
-=begin PASM TODO
-
-    newsub P20, .ExceptionHandler, _handler
-    set_eh P20                  # push handler on control stack
-    null P10                    # set register to null
-    get_global P10, "none"     # may throw exception
-    clear_eh                    # pop the handler off the stack
-    #...
-
-  _handler:                     # if not, execution continues here
-    is_null P10, not_found      # test P10
-    #...
-
-=end PASM TODO
-
-This example creates a new exception handler subroutine with the
-C<newsub> opcode and installs it on the control stack with the
-C<set_eh> opcode. It sets the C<P10> register to a null value (so it
-can be checked later) and attempts to retrieve the global variable
-named C<none>. If the global variable is found, the next statement
-(C<clear_eh>) pops the exception handler off the control stack and
-normal execution continues. If the C<get_global> call doesn't find
-C<none> it throws an exception by pushing an exception object onto the
-control stack. When Parrot sees that it has an exception, it pops it
-off the control stack and calls the exception handler C<_handler>.
-
-The first exception handler in the control stack sees every exception
-thrown. The handler has to examine the exception object and decide
-whether it can handle it (or discard it) or whether it should
-C<rethrow> the exception to pass it along to an exception handler
-deeper in the stack. The C<rethrow>X<rethrow opcode (PASM)> opcode is only
-valid in exception handlers. It pushes the exception object back onto
-the control stack so Parrot knows to search for the next exception
-handler in the stack. The process continues until some exception
-handler deals with the exception and returns normally, or until there
-are no more exception handlers on the control stack. When the system
-finds no installed exception handlers it defaults to a final action,
-which normally means it prints an appropriate message and terminates
-the program.
-
-When the system installs an exception handler, it creates a return
-continuation with a snapshot of the current interpreter context. If
-the exception handler just returns (that is, if the exception is
-cleanly caught) the return continuation restores the control stack
-back to its state when the exception handler was called, cleaning up
-the exception handler and any other changes that were made in the
-process of handling the exception.
-
-Exceptions thrown by standard Parrot opcodes (like the one thrown by
-C<get_global> above or by the C<throw> opcode) are always resumable,
-so when the exception handler function returns normally it continues
-execution at the opcode immediately after the one that threw the
-exception. Other exceptions at the run-loop level are also generally
-resumable.
-
-=begin PASM
-
-  new P10, 'Exception'    # create new Exception object
-  set P10, 'I die'        # set message attribute
-  throw P10               # throw it
-
-=end PASM
-
-Exceptions are designed to work with the Parrot calling conventions.
-Since the return addresses of C<bsr> subroutine calls and exception
-handlers are both pushed onto the control stack, it's generally a bad
-idea to combine the two.
-
-=head1 Events
-
-Z<CHP-5-SECT-9>
-
-An event is a notification that something has happened: a timer
-expired, an IO operation finished, a thread sent a message to
-another thread, or the user pressed C<Ctrl-C> to interrupt program
-execution.
-
-What all of these events have in common is that they arrive
-asynchronously. It's generally not safe to interrupt program flow at an
-arbitrary point and continue at a different position, so the event is
-placed in the
-interpreter's task queue. The run loops code regularly checks whether
-an event needs to be handled. Event handlers may be an internal piece
-of code or a user-defined event handler subroutine.
-
-Events are still experimental in Parrot, so the implementation and
-design is subject to change.
-
-=head2 Timers
-
-Z<CHP-5-SECT-9.1>
-
-C<Timer> objects are the replacement for Perl 5's C<alarm> handlers.
-They are also a significant improvement. Timers can fire once or
-repeatedly, and multiple timers can run independently. The precision
-of a timer is limited by the OS Parrot runs on, but it is always more
-fine-grained then a whole second. The final syntax isn't yet fixed, so
-please consult the documentation for examples.
-
-=head2 Signals
-
-Z<CHP-5-SECT-9.2>
-
-Signal handling is related to events. When Parrot gets a signal it
-needs to handle from the OS, it converts that signal into an event and
-broadcasts it to all running threads. Each thread independently
-decides if it's interested in this signal and, if so, how to respond to it.
-
-=begin PASM TODO
-
-    newsub P20, .ExceptionHandler, _handler
-    set_eh P20                  # establish signal handler
-    print "send SIGINT:\n"
-    sleep 2                     # press ^C after you saw start
-    print "no SIGINT\n"
-    end
-  _handler:
-    .include "signal.pasm"      # get signal definitions
-    print "caught "
-    set I0, P5["type"]         # if _type is negative, the ...
-    neg I0, I0                  # ... negated type is the signal
-    ne I0, .SIGINT, nok
-    print "SIGINT\n"
-  nok:
-    end
-
-=end PASM TODO
-
-This example creates a signal handler and pushes it on to the control
-stack. It then prompts the user to send a C<SIGINT> from the shell
-(this is usually C<Ctrl-C>, but it varies in different shells), and
-waits for 2 seconds. If the user doesn't send a SIGINT in 2 seconds
-the example just prints "no SIGINT" and ends. If the user does send a
-SIGINT, the signal handler catches it, prints out "caught SIGINT" and
-ends.N<Currently, only Linux installs a C<SIGINT> C<sigaction>
-handler, so this example won't work on other platforms.>
-
-=head1 Threads
-
-Z<CHP-5-SECT-10>
-
-Threads allow multiple pieces of code to run in parallel. This is
-useful when you have multiple physical CPUs to share the load of
-running individual threads. With a single processor, threads still
-provide the feeling of parallelism, but without any improvement in
-execution time. Even worse, sometimes using threads on a single
-processor will actually slow down your program.
-
-Still, many algorithms can be expressed more easily in terms of
-parallel running pieces of code and many applications profit from
-taking advantage of multiple CPUs. Threads can vastly simplify
-asynchronous programs like internet servers: a thread splits off,
-waits for some IO to happen, handles it, and relinquishes the
-processor again when it's done.
-
-Parrot compiles in thread support by default (at least, if the
-platform provides some kind of support for it). Unlike Perl 5,
-compiling with threading support doesn't impose any execution time
-penalty for a non-threaded program. Like exceptions and events,
-threads are still under development, so you can expect significant
-changes in the near future.
-
-As outlined in the previous chapter, Parrot implements three different
-threading models. (B<Note>:  As of version 1.0, the C<TQueue> PMC will be
-deprecated, rendering the following discussion obsolete.) The following
-example uses the third model, which takes advantage of shared data. It uses a
-C<TQueue> (thread-safe queue) object to synchronize the two parallel running
-threads. This is only a simple example to illustrate threads, not a typical
-usage of threads (no-one really wants to spawn two threads just to print out a
-simple string).
-
-=begin PASM TODO
-
-    get_global P5, "_th1"              # locate thread function
-    new P2, "ParrotThread"              # create a new thread
-    find_method P0, P2, "thread3"       # a shared thread's entry
-    new P7, "TQueue"                    # create a Queue object
-    new P8, "Int"                       # and a Int
-    push P7, P8                         # push the Int onto queue
-    new P6, "String"                    # create new string
-    set P6, "Js nte artHce\n"
-    set I3, 3                           # thread function gets 3 args
-    invoke                              # _th1.run(P5,P6,P7)
-    new P2, "ParrotThread"              # same for a second thread
-    get_global P5, "_th2"
-    set P6, "utaohrPro akr"             # set string to 2nd thread's
-    invoke                              # ... data, run 2nd thread too
-    end                                 # Parrot joins both
-
-  .pcc_sub _th1:                        # 1st thread function
-  w1: sleep 0.001                       # wait a bit and schedule
-    defined I1, P7                      # check if queue entry is ...
-    unless I1, w1                       # ... defined, yes: it's ours
-    set S5, P6                          # get string param
-    substr S0, S5, I0, 1                # extract next char
-    print S0                            # and print it
-    inc I0                              # increment char pointer
-    shift P8, P7                        # pull item off from queue
-    if S0, w1                           # then wait again, if todo
-    invoke P1                           # done with string
-
-  .pcc_sub _th2:                        # 2nd thread function
-  w2: sleep 0.001
-    defined I1, P7                      # if queue entry is defined
-    if I1, w2                           # then wait
-    set S5, P6
-    substr S0, S5, I0, 1                # if not print next char
-    print S0
-    inc I0
-    new P8, "Int"                       # and put a defined entry
-    push P7, P8                         # onto the queue so that
-    if S0, w2                           # the other thread will run
-    invoke P1                           # done with string
-
-=end PASM TODO
-
-This example creates a C<ParrotThread> object and calls its C<thread3>
-method, passing three arguments: a PMC for the C<_th1> subroutine in
-C<P5>, a string argument in C<P6>, and a C<TQueue> object in C<P7>
-containing a single integer. Remember from the earlier section
-A<CHP-5-SECT-7.1.3>"Parrot calling conventions" that registers 5-15
-hold the arguments for a subroutine or method call and C<I3> stores
-the number of arguments. The thread object is passed in C<P2>.
-
-This call to the C<thread3> method spawns a new thread to run the
-C<_th1> subroutine. The main body of the code then creates a second
-C<ParrotThread> object in C<P2>, stores a different subroutine in
-C<P5>, sets C<P6> to a new string value, and then calls the C<thread3>
-method again, passing it the same C<TQueue> object as the first
-thread. This method call spawns a second thread. The main body of code
-then ends, leaving the two threads to do the work.
-
-At this point the two threads have already started running. The first
-thread (C<_th1>) starts off by sleeping for a 1000th of a second. It
-then checks if the C<TQueue> object contains a value. Since it
-contains a value when the thread is first called, it goes ahead and
-runs the body of the subroutine. The first thing this does is shift
-the element off the C<TQueue>. It then pulls one character off a copy
-of the string parameter using C<substr>, prints the character,
-increments the current position (C<I0>) in the string, and loops back
-to the C<w1> label and sleeps. Since the queue doesn't have any
-elements now, the subroutine keeps sleeping.
-
-Meanwhile, the second thread (C<_th2>) also starts off by sleeping for
-a 1000th of a second. It checks if the shared C<TQueue> object
-contains a defined value but unlike the first thread it only continues
-sleeping if the queue does contain a value. Since the queue contains a
-value when the second thread is first called, the subroutine loops
-back to the C<w2> label and continues sleeping. It keeps sleeping
-until the first thread shifts the integer off the queue, then runs the
-body of the subroutine. The body pulls one character off a copy of the
-string parameter using C<substr>, prints the character, and increments
-the current position in the string. It then creates a new
-C<Int>, pushes it onto the shared queue, and loops back to the
-C<w2> label again to sleep. The queue has an element now, so the
-second thread keeps sleeping, but the first thread runs through its
-loop again.
-
-The two threads alternate like this, printing a character and marking
-the queue so the next thread can run, until there are no more
-characters in either string. At the end, each subroutine invokes the
-return continuation in C<P1> which terminates the thread. The
-interpreter waits for all threads to terminate in the cleanup phase
-after the C<end> in the main body of code.
-
-The final printed result (as you might have guessed) is:
-
-  Just another Parrot Hacker
-
-The syntax for threads isn't carved in stone and the implementation
-still isn't finished but as this example shows, threads are working
-now and already useful.
-
-Several methods are useful when working with threads. The C<join>
-method belongs to the C<ParrotThread> class. When it's called on a
-C<ParrotThread> object, the calling code waits until the thread
-terminates.
-
-=begin PASM TODO
-
-    new P2, "ParrotThread"      # create a new thread
-    set I5, P2                  # get thread ID
-
-    find_method P0, P2, "join"  # get the join method...
-    invoke                      # ...and join (wait for) the thread
-    set P16, P5                 # the return result of the thread
-
-=end PASM TODO
-
-C<kill> and C<detach> are interpreter methods, so you have to grab the
-current interpreter object before you can look up the method object.
-
-=begin PASM TODO
-
-    set I5, P2                  # get thread ID of thread P2
-    getinterp P3                # get this interpreter object
-    find_method P0, P3, "kill"  # get kill method
-    invoke                      # kill thread with ID I5
-
-    find_method P0, P3, "detach"
-    invoke                      # detach thread with ID I5
-
-=end PASM TODO
-
-By the time you read this, some of these combinations of statements
-and much of the threading syntax above may be reduced to a simpler set
-of opcodes.
-
-=head1 Loading Bytecode
-
-Z<CHP-5-SECT-11>
-
-In addition to running Parrot bytecode on the command-line, you can
-also load pre-compiled bytecode directly into your PASM source file.
-The C<load_bytecode>X<load_bytecode opcode (PASM)> opcode takes a single
-argument: the name of the bytecode file to load. So, if you create a
-file named F<file.pasm> containing a single subroutine:
-
-=begin PASM TODO
-
-  # file.pasm
-  .sub _sub2:               # .sub stores a global sub
-     print "in sub2\n"
-     invoke P1
-
-=end PASM TODO
-
-and compile it to bytecode using the C<-o> command-line switch:
-
-  $ parrot -o file.pbc file.pasm
-
-You can then load the compiled bytecode into F<main.pasm> and directly
-call the subroutine defined in F<file.pasm>:
-
-=begin PASM TODO
-
-  # main.pasm
-  main:
-    load_bytecode "file.pbc"    # compiled file.pasm
-    get_global P0, "_sub2"
-    invokecc
-    end
-
-=end PASM TODO
-
-The C<load_bytecode> opcode also works with source files, as long as
-Parrot has a compiler registered for that type of file:
-
-=begin PASM TODO
-
-  # main2.pasm
-  main:
-    load_bytecode "file.pasm"  # PASM source code
-    set_global P0, "_sub2"
-    invokecc
-    end
-
-=end PASM TODO
-
-Subroutines marked with C<:load> run as soon as they're loaded (before
-C<load_bytecode> returns), rather than waiting to be called. A
-subroutine marked with C<:main> will always run first, no matter what
-name you give it or where you define it in the file.
-
-=begin PASM TODO
-
-  # file3.pasm
-  .sub :load                    # mark the sub as to be run
-    print "file3\n"
-    invoke P1                   # return
-
-  # main3.pasm
-  first:                        # first is never invoked
-    print "never\n"
-    invoke P1
-
-  .sub :main                    # because _main is marked as the
-    print "main\n"              # MAIN entry of program execution
-    load_bytecode "file3.pasm"
-    print "back\n"
-    end
-
-=end PASM TODO
-
-This example uses both C<:load> and C<:main>. Because the C<main>
-subroutine is defined with C<:main> it will execute first even though
-another subroutine comes before it in the file. C<main> prints a
-line, loads the PASM source file, and then prints another line.
-Because C<_entry> in F<file3.pasm> is marked with C<:load> it runs
-before C<load_bytecode> returns, so the final output is:
-
-  main
-  file3
-  back
-
-=head1 Classes and Objects
-
-Z<CHP-5-SECT-12>
-
-This section revolves around one complete example that defines a
-class, instantiates objects, and uses them. The whole example is
-included at the end of the section.
-
-=head2 Class declaration
-
-Z<CHP-5-SECT-12.1>
-
-X<classes;in PASM>
-The C<newclass>X<newclass opcode (PASM)> opcode defines a new class.
-It takes two arguments, the name of the class and the destination
-register for the class PMC. All classes (and objects) inherit from the
-C<ParrotClass> PMCX<ParrotClass PMC>, which is the core of the Parrot
-object system.
-
-=begin PASM
-
-    newclass P1, "Foo"
-
-=end PASM
-
-To instantiate a new object of a particular class, you first look up
-the integer value for the class type with the C<find_type> opcode,
-then create an object of that type with the C<new> opcode:
-
-=begin PASM TODO
-
-    find_type I1, "Foo"
-    new P3I I1
-
-=end PASM TODO
-
-The C<new> opcode also checks to see if the class defines a
-method named "__init" and calls it if it exists.
-
-=head2 Attributes
-
-Z<CHP-5-SECT-12.2>
-
-X<attributes;in PASM>
-X<classes;attributes>
-The C<addattribute> opcode creates a slot in the class for an
-attribute (sometimes known as an I<instance variable>) and associates
-it with a name:
-
-=begin PASM
-
-    addattribute P1, ".i"                # Foo.i
-
-=end PASM
-
-This chunk of code
-from the C<__init> method looks up the position of the first
-attribute, creates a C<Int> PMC, and stores it as the first
-attribute:
-
-=begin PASM TODO
-
-    classoffset I0, P2, "Foo"     # first "Foo" attribute of object P2
-    new P6, "Int"                 # create storage for the attribute
-    setattribute P2, I0, P6       # store the first attribute
-
-=end PASM TODO
-
-The C<classoffset> opcodeX<classoffset opcode (PASM)> takes a PMC
-containing an object and the name of its class, and returns an integer
-index for the position of the first attribute. The C<setattribute>
-opcode uses the integer index to store a PMC value in one of the
-object's attribute slots. This example initializes the first
-attribute. The second attribute would be at C<I0 + 1>, the third
-attribute at C<I0 + 2>, etc:
-
-=begin PASM TODO
-
-    inc I0
-    setattribute P2, I0, P7       # store next attribute
-    #...
-
-=end PASM TODO
-
-There is also support for named parameters with fully qualified
-parameter names (although this is a little bit slower than getting
-the class offset once and accessing several attributes by index):
-
-=begin PASM
-
-    new P6, "Int"
-    setattribute P2, "Foo\x0.i", P6   # store the attribute
-
-=end PASM
-
-You use the same integer index to retrieve the value of an attribute.
-The C<getattribute>X<getattribute opcode (PASM)> opcode takes an object and
-an index as arguments and returns the attribute PMC at that position:
-
-=begin PASM TODO
-
-    classoffset I0, P2, "Foo"         # first "Foo" attribute of object P2
-    getattribute P10, P2, I0          # indexed get of attribute
-
-=end PASM TODO
-
-or
-
-=begin PASM
-
-    getattribute P10, P2, "Foo\x0.i"  # named get
-
-=end PASM
-
-To set the value of an attribute PMC, first retrieve it with
-C<getattribute> and then assign to the returned PMC. Because PMC
-registers are only pointers to values, you don't need to store the PMC
-again after you modify its value:
-
-=begin PASM TODO
-
-    getattribute P10, P2, I0
-    set P10, I5
-
-=end PASM TODO
-
-=head2 Methods
-
-Z<CHP-5-SECT-12.3>
-
-X<methods;in PASM>
-X<classes;methods>
-X<classes;namespaces>
-Methods in PASM are just subroutines installed in the namespace of the
-class. You define a method with the C<.pcc_sub> directive before the
-label:
-
-=begin PASM TODO
-
-  .pcc_sub _half:                 # I5 = self."_half"()
-    classoffset I0, P2, "Foo"
-    getattribute P10, P2, I0
-    set I5, P10                   # get value
-    div I5, 2
-    invoke P1
-
-=end PASM TODO
-
-This routine returns half of the value of the first attribute of the
-object. Method calls use the Parrot calling conventions so they always
-pass the I<invocant> object (often called I<self>) in C<P2>. Invoking
-the return continuation in C<P1> returns control to the caller.
-
-The C<.pcc_sub> directive automatically stores the subroutine as a
-global in the current namespace. The C<.namespace> directive sets the
-current namespace:
-
-=begin PASM
-
-  .namespace [ "Foo" ]
-
-=end PASM
-
-If the namespace is explicitly set to an empty string or key, then the
-subroutine is stored in the outermost namespace.
-
-The C<callmethodcc>X<callmethodcc opcode (PASM)> opcode makes a method
-call. It follows the Parrot calling conventions, so it expects to
-find the invocant object in C<P2>, the method object in C<P0>, etc. It
-adds one bit of magic, though. If you pass the name of the method in
-C<S0>, C<callmethodcc> looks up that method name in the invocant
-object and stores the method object in C<P0> for you:
-
-=begin PASM TODO
-
-    set S0, "_half"             # set method name
-    set P2, P3                  # the object
-    callmethodcc                # create return continuation, call
-    print I5                    # result of method call
-    print "\n"
-
-=end PASM TODO
-
-The C<callmethodcc> opcode also generates a return continuation and
-stores it in C<P1>. The C<callmethod> opcode doesn't generate a return
-continuation, but is otherwise identical to C<callmethodcc>. Just like
-ordinary subroutine calls, you have to preserve and restore any
-registers you want to keep after a method call. Whether you store
-individual registers, register frames, or half register frames is up
-to you.
-
-=head3 Overriding vtable functions
-
-Z<CHP-5-SECT-12.3.1>
-
-Every object inherits a default set of I<vtable> functions from the
-C<ParrotObject> PMC, but you can also override them with your own
-methods. The vtable functions have predefined names that start with a
-double underscore "__". The following code defines a method named
-C<__init> in the C<Foo> class that initializes the first attribute of
-the object with an integer:
-
-=begin PASM TODO
-
-  .sub __init:
-    classoffset I0, P2, "Foo"     # lookup first attribute position
-    new P6, "Int"                 # create storage for the attribute
-    setattribute P2, I0, P6       # store the first attribute
-    invoke P1                     # return
-
-=end PASM TODO
-
-Ordinary methods have to be called explicitly, but the vtable
-functions are called implicitly in many different contexts. Parrot
-saves and restores registers for you in these calls. The C<__init>
-method is called whenever a new object is constructed:
-
-=begin PASM TODO
-
-    find_type I1, "Foo"
-    new P3, I1          # call __init if it exists
-
-=end PASM TODO
-
-A few other vtable functions in the complete code example for this
-section are C<__set_integer_native>, C<__add>, C<__get_integer>,
-C<__get_string>, and C<__increment>. The C<set> opcode calls Foo's
-C<__set_integer_native> vtable function when its destination register
-is a C<Foo> object and the source register is a native integer:
-
-=begin PASM
-
-    set P3, 30          # call __set_integer_native method
-
-=end PASM
-
-The C<add> opcode calls Foo's C<__add> vtable function when it adds
-two C<Foo> objects:
-
-=begin PASM TODO
-
-    new P4, I1          # same with P4
-    set P4, 12
-    new P5, I1          # create a new store for add
-
-    add P5, P3, P4      # __add method
-
-=end PASM TODO
-
-The C<inc> opcode calls Foo's C<__increment> vtable function when it
-increments a C<Foo> object:
-
-=begin PASM
-
-    inc P3              # __increment
-
-=end PASM
-
-Foo's C<__get_integer> and C<__get_string> vtable functions are called
-whenever an integer or string value is retrieved from a C<Foo> object:
-
-=begin PASM
-
-    set I10, P5         # __get_integer
-    #...
-    print P5            # calls __get_string, prints 'fortytwo'
-
-=end PASM
-
-
-=head2 Inheritance
-
-Z<CHP-5-SECT-12.4>
-
-X<inheritance;in PASM>
-X<classes;inheritance>
-The C<subclass>X<subclass opcode (PASM)> opcode creates a new class that
-inherits methods and attributes from another class. It takes 3
-arguments: the destination register for the new class, a register
-containing the parent class, and the name of the new class:
-
-=begin PASM
-
-    subclass P3, P1, "Bar"
-
-=end PASM
-
-X<multiple inheritance; in PASM>
-For multiple inheritance, the C<addparent>X<addparent opcode (PASM)>
-opcode adds additional parents to a subclass.
-
-=begin PASM
-
-  newclass P4, "Baz"
-  addparent P3, P4
-
-=end PASM
-
-To override an inherited method, define a method with the same name in
-the namespace of the subclass. The following code overrides Bar's
-C<__increment> method so it decrements the value instead of
-incrementing it:
-
-=begin PASM TODO
-
-  .namespace [ "Bar" ]
-
-  .sub __increment:
-    classoffset I0, P2, "Foo"     # get Foo's attribute slot offset
-    getattribute P10, P2, I0      # get the first Foo attribute
-    dec P10                       # the evil line
-    invoke P1
-
-=end PASM TODO
-
-Notice that the attribute inherited from C<Foo> can only be looked up
-with the C<Foo> class name, not the C<Bar> class name. This preserves
-the distinction between attributes that belong to the class and
-inherited attributes.
-
-Object creation for subclasses is the same as for ordinary classes:
-
-=begin PASM TODO
-
-    find_type I1, "Bar"
-    new P5, I1
-
-=end PASM TODO
-
-Calls to inherited methods are just like calls to methods defined in
-the class:
-
-=begin PASM TODO
-
-    set P5, 42                  # inherited __set_integer_native
-    inc P5                      # overridden __increment
-    print P5                    # prints 41 as Bar's __increment decrements
-    print "\n"
-
-    set S0, "_half"             # set method name
-    set P2, P5                  # the object
-    callmethodcc                # create return continuation, call
-    print I5
-    print "\n"
-
-=end PASM TODO
-
-=head2 Additional Object Opcodes
-
-Z<CHP-5-SECT-12.5>
-
-The C<isa> and C<can> opcodes are also useful when working with
-objects. C<isa>X<isa opcode (PASM)> checks whether an object belongs to or
-inherits from a particular class. C<can>X<can opcode (PASM)> checks whether
-an object has a particular method. Both return a true or false value.
-
-=begin PASM
-
-    isa I0, P3, "Foo"           # 1
-    isa I0, P3, "Bar"           # 1
-    can I0, P3, "__add"         # 1
-
-=end PASM
-
-=head2 Complete Example
-
-Z<CHP-5-SECT-12.6>
- 
-=begin PASM TODO
-
-    newclass P1, "Foo"
-    addattribute P1, "$.i"                # Foo.i
-
-    find_type I1, "Foo"
-    new P3, I1          # call __init if it exists
-    set P3, 30          # call __set_integer_native method
-
-    new P4, I1          # same with P4
-    set P4, 12
-    new P5, I1          # create a new LHS for add
-
-    add P5, P3, P4      # __add method
-    set I10, P5         # __get_integer
-    print I10
-    print "\n"
-    print P5            # calls __get_string prints 'fortytwo'
-    print "\n"
-
-    inc P3              # __increment
-    add P5, P3, P4
-    print P5            # calls __get_string prints '43'
-    print "\n"
-
-    subclass P3, P1, "Bar"
-
-    find_type I1, "Bar"
-    new P3, I1
-
-    set P3, 100
-    new P4, I1
-    set P4, 200
-    new P5, I1
-
-    add P5, P3, P4
-    print P5                    # prints 300
-    print "\n"
-
-    set P5, 42
-    print P5                    # prints 'fortytwo'
-    print "\n"
-
-    inc P5
-    print P5                    # prints 41 as Bar's
-    print "\n"                  # __increment decrements
-
-    set S0, "_half"             # set method name
-    set P2, P3                  # the object
-    callmethodcc                # create return continuation, call
-    print I5                    # prints 50
-    print "\n"
-
-    end
-
-  .namespace [ "Foo" ]
-
-  .sub __init:
-    classoffset I0, P2, "Foo"     # lookup first attribute position
-    new P6, "Int"                 # create a store for the attribute
-    setattribute P2, I0, P6       # store the first attribute
-    invoke P1                     # return
-
-  .sub __set_integer_native:
-    classoffset I0, P2, "Foo"
-    getattribute P10, P2, I0
-    set P10, I5                   # assign passed in value
-    invoke P1
-
-  .sub __get_integer:
-    classoffset I0, P2, "Foo"
-    getattribute P10, P2, I0
-    set I5, P10                   # return value
-    invoke P1
-
-  .sub __get_string:
-    classoffset I0, P2, "Foo"
-    getattribute P10, P2, I0
-    set I5, P10
-    set S5, P10                   # get stringified value
-    ne I5, 42, ok
-    set S5, "fortytwo"            # or return modified one
-  ok:
-    invoke P1
-
-  .sub __increment:
-    classoffset I0, P2, "Foo"
-    getattribute P10, P2, I0      # as with all aggregates, this
-    inc P10                       # has reference semantics - no
-    invoke P1                     # setattribute needed
-
-  .sub __add:
-    classoffset I0, P2, "Foo"
-    getattribute P10, P2, I0      # object
-    getattribute P11, P5, I0      # argument
-    getattribute P12, P6, I0      # destination
-    add P12, P10, P11
-    invoke P1
-
-  .sub _half:                 # I5 = _half(self)
-    classoffset I0, P2, "Foo"
-    getattribute P10, P2, I0
-    set I5, P10                   # get value
-    div I5, 2
-    invoke P1
-
-
-  .namespace [ "Bar" ]
-
-  .sub __increment:
-    classoffset I0, P2, "Foo"     # get Foo's attribute slot offset
-    getattribute P10, P2, I0      # get the first Foo attribute
-    dec P10                       # the evil line
-    invoke P1
-
-=end PASM TODO
-
-This example prints out:
-
-  42
-  fortytwo
-  43
-  300
-  fortytwo
-  41
-  50
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Copied: branches/headercleanup/docs/book/ch05_pge.pod (from r38131, trunk/docs/book/ch05_pge.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/ch05_pge.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/ch05_pge.pod)
@@ -0,0 +1,1486 @@
+=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 for the
+syntax specified by those rules. PGE rules provide the full power of
+recursive descent parsing and operator precedence parsing, but are
+comfortably useful even if you don't know anything about parsing theory.
+In the usual case, all you'll ever need to know is that rules are
+patterns for matching text.
+
+=head2 Grammars
+
+A grammar is a collection of rules, in much the same way that a class is a collection of methods.N<In fact, 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 piece of text. The basic matching syntax for rules is likely to be somewhat familiar to anyone who has worked with regular expressions.
+
+  rule id { \d+ }
+
+Larger rules are composed from smaller rules:
+
+  rule record { <id> <name> <phone> }
+
+And a grammar holds a group of rules that work together:
+
+  grammar Contacts;
+
+  rule name { 'John' | 'Bob ' | 'Fred' }
+  
+  rule id   { \d+ }
+
+  rule record { <id> <name> }
+
+  ...
+
+
+=head3 Rules and Tokens
+
+There are two different kinds of rules, each declared with a different keyword: C<rule> or C<token>. A C<rule> does smart whitespace matching between the various pieces of the pattern. So, the C<record> rule above would match "6355 John" or "6355      John" but not "6355John".
+
+A C<token> only matches whitespace if you specifically request it. To get the same effect with a token, you'd have to add a C<\s> pattern to the rule:
+
+  token record { <id> \s+ <name> }
+
+=head3 The Start Rule
+
+A recursive descent parser is a top-down parser. This means it starts at the highest-level rule and works its way down through individual rules to match an entire string or file. In PGE, this top-level rule is called C<TOP> by convention.N<The top-level rule can be called anything, but some of the compiler tools expect it to be called C<TOP>.>
+
+  rule TOP { <record> }
+
+This rule matches a single record in a string or file. Once the parser has matched the entire string or file passed to the start rule, the parse is considered successful and a raw parse tree is returned.
+
+=head3 Testing a Grammar
+
+You might want to try out the examples in this chapter as you read along. To compile a simple example, save it 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 with the following command:
+
+  $ parrot Perl6Grammar.pbc --output=Contacts.pir Contacts.pg
+
+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:
+
+  $ ./parrot runtime/parrot/library/PGE/Perl6Grammar.pbc --output=Contacts.pir Contacts.pg
+
+Next, create a small PIR script to run your grammar. You can save it as F<grammar_test.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
+      .local pmc top, grammar, match
+
+      source = "3 John"
+      top = get_hll_global ['Contacts'], 'TOP'
+      grammar = get_class 'Contacts'
+      match = top(source, 'grammar' => grammar)
+      _dumper(match, "match")
+  .end
+
+When you run the test script:
+
+  $ 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 rule in the grammar corresponds to a node in the tree. This output shows that the top-level match variable contains one child named "record", that "record" contains two children named "id" and "name", and that "id" contains the number 3, and "name" contains the string "John". Exactly what we would expect from our simple grammar.
+
+=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<.> matches any single character, even a newline character.
+The C<^> and C<$> metacharacters are zero-width
+matches on the beginning and end of a string. They each have doubled
+alternates C<^^> and C<$$> that match at the beginning and end of
+every line within a string.
+
+The C<|>, C<&>, C<\>, C<#>, and C<:=> metacharacters are all syntax
+structure elements. The C<|> is an alternation between two options. The
+C<&> matches two patterns simultaneously (the patterns must be the same
+length). The C<\> turns literal characters into metacharacters (the
+escape sequences). The
+C<#> marks a comment to the end of the line. You can start a comment at
+any point on any line in a rule. The C<:=> binds a hypothetical variable to
+the result of a subrule or grouped pattern. Hypotheticals are covered
+in L<Hypothetical Variables> later in this chapter.
+
+The metacharacters C<()>, C<[]>, C<{}> and C<E<lt>E<gt>> are bracketing
+pairs. The pairs always have to be balanced within the rule, unless they
+are literal characters (escaped with a C<\>). The C<()> and C<[]> pairs group patterns to match as a single atom. They're often used to
+capture a result, mark the boundaries of an alternation, or mark a group
+of patterns with a quantifier. Parentheses C<()> are
+capturing and square brackets C<[]> are non-capturing. 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. Assertions are covered
+in L<Assertions> later in this chapter.
+
+Table 7-2 summarizes the basic set of 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.
+X<^ (caret);^^ beginning of line (rules)>
+
+=row 
+
+=cell C<$$>
+
+=cell Match the end of a line.
+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)>
+The escape sequences are literal characters acting as metacharacters,
+marked with the C<\> escape. Some escape sequences represent single
+characters that are difficult to represent literally, like C<\t> for
+tab, or C<\x[...]> for a character specified by a hexadecimal number.
+Some represent limited character classes, like C<\d> for digits or C<\w>
+for word characters. Some represent zero-width positions in a match,
+like C<\b> for a word boundary. With all the escape sequences that use
+brackets, C<()>, C<{}>, and C<E<lt>E<gt>> work in place of C<[]>. 
+
+X<variable interpolation in rules>
+X<rules;variable interpolation>
+Note that since an ordinary variable now interpolates as a literal
+string 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 plus "_").
+
+=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. A range with three trailing
+dots (C<E<lt>2...E<gt>>) is shorthand for C<E<lt>R<n>..InfE<gt>> and
+matches as many times as possible.
+
+Each quantifier has a minimal alternate form, marked with a trailing
+C<?>, that matches the shortest possible sequence first.
+
+
+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>
+In general, an assertion simply states that some condition or state is
+true and the match fails when that assertion is false. Many different
+constructs with many different purposes use assertion syntax. 
+
+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. You have to enclose a variable in assertion delimiters to get it
+to interpolate as an anonymous rule or rules. 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. In the simplest case, a bare hash in a pattern matches a word
+(C<\w+>) and tries to find that word as one of its keys.N<The effect is
+much as if it matched the keys as a series of alternates, but you're
+guaranteed to match the longest possible key, instead of just the first
+one it hits in random order.>, while a hash in assertion brackets does
+the same, but then 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, which is immediately matched.
+
+An assertion with parentheses C<E<lt>(...)E<gt>> is similar to a bare
+closure in a pattern in that it allows you to include straight Perl code
+within a rule. The difference is that C<E<lt>(...)E<gt>> evaluates the
+return value of the closure in boolean context. The match succeeds if
+the return value is true and fails if the return value is false.
+
+Assertions match character classes, both named and enumerated. A named
+rule character class is often more accurate than an enumerated character
+class. For example, C<E<lt>[a-zA-Z]E<gt>> is commonly used to match
+alphabetic characters, but generally what's really needed is the
+built-in rule C<E<lt>alphaE<gt>> which matches the full set of Unicode
+alphabetic characters.
+
+A<CHP-7-TABLE-5>Table 7-5 shows the syntax for 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 (which is 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 the pattern syntax. 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 }
+
+The single-character modifiers can be grouped, but the others must be
+separated by a colon:
+
+  m:wig/ zaphod /                        # OK
+  m:words:ignorecase:globally / zaphod / # OK
+  m:wordsignorecaseglobally / zaphod /   # Not OK
+
+Most of the modifiers can also go inside the rule, attached to the
+rule delimiters or to grouping delimiters. Internal modifiers are
+lexically scoped to their enclosing delimiters, so you get a temporary
+alteration of the pattern:
+
+  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>)
+can't be lexically scoped, because they alter the return value of the
+entire rule.
+
+The C<:R<N>x> modifier matches the rule a counted number of times. If
+the modifier expects more matches than the string has, the match fails.
+It has an alternate form C<:x(R<N>)> that 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, but 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>)>--can
+take a variable in place of the number. The other forms--C<:R<N>st>,
+C<:R<N>nd>, and C<:R<N>rd>--are for cases where it's more natural to
+write C<:1st>, C<:2nd>, C<:3rd> than it is to write C<:1th>, C<:2th>,
+C<:3th>. Either way is valid, so pick the one that's most comfortable
+for you.
+
+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.
+
+There are no modifiers to alter whether the matched string is treated as
+a single line or multiple lines. That's why the "beginning of string"
+and "end of string" metasymbols have "beginning of line" and "end of
+line" counterparts.
+
+A<CHP-7-TABLE-6>Table 7-6 shows the current list of 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 Only match the pattern once.
+
+=row 
+
+=cell C<:g>
+
+=cell C<:globally>
+
+=cell Match the pattern as many times as possible, but only possibilities
+that don't overlap.
+
+=row 
+
+=cell C<:e>
+
+=cell C<:exhaustive>
+
+=cell Match every possible occurrence of a pattern, even 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>
+A number of named rules are provided by default, 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 (so it's always
+true) 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 you're I<before> a pattern.
+
+=row 
+
+=cell C<E<lt>after ...E<gt>>
+
+=cell Zero-width lookbehind. Assert that you're I<after> 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> 
+Backtracking is triggered whenever part of the pattern fails to match.
+You can also explicitly trigger backtracking by calling the C<fail>
+function within a closure. A<CHP-7-TABLE-8>Table 7-8 shows some
+metacharacters and built-in rules relevant to backtracking.
+
+=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, 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, 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, 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, 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 is considered successful and the generated AST is
+delivered to the code generator for conversion into PIR.
+
+
+We haven't covered actions yet, but it's still important now to talk
+about how we will call them when we are ready. We call an action
+by inserting the C<{*}> token into the rule. When the C<{*}> rule is
+encountered, PGE calls the associated action method with the current
+match object as an argument. Let's take our C<persons_name> rule
+from above, and sprinkle 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 had a chance to match 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. Notice that
+if the match fails halfway through, we still call the actions where
+we succeeded, but do not call the actions after the failure. So, if
+we try to match the string "Leia", the action is called before the
+name and after the first name. When the rule tries to match the last
+name, it fails because no last name is provided, and the third action
+method call is never made.
+
+=head3 Alternations and Keys
+
+In addition to sub-rules, groups, and quantifiers, we also are able to
+take alternations between options that are either-or. The vertical bar
+token "|" can be used to distinguish between options where only one
+may match, Here's an example:
+
+ rule hero {
+    ['Luke' | 'Leia'] 'Skywalker'
+ }
+
+This rule will match either "Luke Skywalker" or "Leia Skywalker" but
+won't match "Luke Leia Skywalker" N<or anything else, for that matter>.
+With things like alternations, if we want to call an action method it's
+helpful to distinguish which combination we 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
+got matched.
+
+=head3 Warning: Left Recursion
+
+Getting into all the nitty-gritty theory behind parsers is well beyond
+the scope of this book. However, there is one potential pitfall that
+developers should be made aware of that is not immediately obvious.
+Like functions in ordinary procedural or functional languages, the
+methods in the PGE parser grammar can call themselves recursively.
+Consider the following 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>* '}'
+ }
+
+Notice that 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 called
+I<recursion> X<Recursion>, and is part of where the "Recursive Descent"
+algorithm gets its name from.
+
+Now, let's look at a more direct example of a comma-separated list of
+integer digits to form an array. We can define this recursively as
+follows:
+
+ rule list {
+     <list> ',' <digit> | <digit>
+ }
+
+The intention is that if there is only one digit, we match the second
+option in the alternation, and if there are more digits we can match
+them recursively in the first alternation. However, take a close look
+at the insidious result. The recursive descent parser enters the C<list>
+rule. It's first option is to enter the list rule again, so it does.
+Recursive descent is a depth-first algorithm, and it will continue to
+descent down a particular path until it finds a successful match or a
+match failure. In this case, it matches C<list> and then it matches
+C<list> again, then it matches C<list> again, and so on and so forth.
+What we have created is an infinite loop pattern called I<left recursion>.
+
+Left recursion is caused when the left-most item of the left-most
+alternation is a recursion. The rule above can be easily resolved
+by writing:
+
+ rule list {
+    <digit> | <list> ',' <digit>
+ }
+
+Or even
+
+ rule list {
+    <digit> ',' <list> | <digit>
+ }
+
+Both of these two options make sure the left-most item in our rule is not
+a recursion, therefore preventing left recursion.
+
+Here is a more tricky example where the left recursion is hidden from
+view:
+
+ rule term {
+    <expression> '*' <term> | <digit>
+ }
+
+ rule expression {
+    <term> '+' <expression> | <term>
+ }
+
+This is a very limited subset of mathematical equations that we might like
+to write, and even in this small subset we have this 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> ...
+
+Left recursion is not the only problem you can run into with a recursive
+descent grammar, but it's one that's likely going to come up relatively
+often for new language designers, and one that is not always likely to
+generate useful error messages.
+
+=head3 Operator Precedence Parser
+
+Places where there are lots of little tokens in a statement, and where
+there are lots of possible options that a top-down parser will have to
+attempt can become relatively inefficient using PCT's recursive descent
+parser. Specifically, mathematical expressions are very open-ended and
+have forms that are difficult to anticipate. Consider the expression:
+
+ a + b * c + d
+
+The recursive descent parser is going to have to recognize through
+significant trial and error how this statement should be parsed. For tasks
+like this, recursive descent parsers are not ideal, although a type of
+bottom-up parser called an I<operator precedence>
+X<Parser, Operator precedence> parser is. 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. The "things" in an
+equation are split into two subtypes: I<terms> and I<operators>. Operators
+themselves are split into a number of types 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. In the example above,
+the expression is parsed
+
+ a + (b * c) + d
+
+This is because the C<*> operator has a higher precedence and therefore binds
+more tightly then the C<+> operator.
+
+To switch from the top-down recursive descent parser to the bottom-up
+operator precedence parser, a rule must be defined that is an C<optable>
+X<Parser, optable>:
+
+ rule expression is optable { ... }
+
+The C<...> ellipses aren't an editorial shortcut, it's the Perl 6 operator
+that is used to define a function signature. The C<...> indicates that
+this is just a signature and that the actual guts of it will be filled in
+somewhere else. In this case, that "somewhere else" is in the definition of
+the optable role.
+
+=head3 Protofunction Definitions
+
+Protofunctions are used to define operators in the optable in the same way that
+rules and tokens are used throughout the rest of the grammar. A proto is a way
+of saying that the rule is overridable dynamically, and that it might be defined
+somewhere else. In this case, PCT takes information from the proto declaration
+and fills in the details for us. On another note, this also means that the HLL
+itself can modify its own grammar at run time, by overriding the proto
+definitions for its operator table. Some languages call this process "operator
+overloading".
+
+A proto is defined like this, taking some of our grammar rules above:
+
+ 'proto' <proto_name> [ 'is' <property> ] '{' '...' '}'
+
+The name of the operator, listed as C<< <proto_name> >> above, contains both a
+location part and an identifier part. The location is one of the places where
+the operator can be located, 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. Some examples of
+this are:
+
+ 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
+
+Protofunction definitions are function signatures which can be overridden via
+multimethod dispatch. This means functions can be written I<with the same name>
+as the rule to implement the behavior of the operator:
+
+ rule infix:"+" { ... }
+
+And in a PIR file for built-in functions:
+
+ .sub 'infix:+'
+    .param pmc a
+    .param pmc b
+    .local pmc c
+    c = a + b
+    .return(c)
+ .end
+
+The question to ask then is "Why have an C<is subname()> property, if all
+operators can be defined as subroutines?" The answer is that 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 duplicating functionality, is there?
+
+The great thing about protos being overloadable is that you can specify
+different functions to call with different signatures:
+
+ .sub 'infix:+' :multi('Integer', 'Integer')
+    ...
+ .end
+
+ .sub 'infix:+' :multi('CLispRatio', 'Number')
+    ...
+ .end
+
+ .sub 'infix:+' :multi('Perl6Double', 'PythonInteger')
+    ...
+ .end
+
+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 for us all, this isn't the
+case because all these data types have those VTABLE interfaces that we can
+use. 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. This example was only a demonstration of the flexibility
+of the method.
+
+
+=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. The values stored in these variables
+will be kept if the match is successful, but thrown away if the match
+fails (hence the term "hypothetical"). 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<:=>. These variables must already be defined in the lexical
+scope surrounding the rule:
+
+  my $person;
+  "Zaphod's just this guy." ~~ / ^ $person := (\w+) /;
+  print $person; # prints Zaphod
+
+Repeated matches can be captured into an array:
+
+  my @words;
+  "feefifofum" ~~ / @words := (f<-[f]>+)* /;
+  # @words contains ("fee", "fi", "fo", "fum")
+
+Pairs of repeated matches can be captured 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 /;
+
+
+When a rule matches a sequence of input tokens, an associated method
+in NQP is called to convert that match into an AST node. This node
+is then inserted into the I<parse tree>.
+
+=head3 Basic Rules
+
+Let's start off with a simple rule:
+
+ rule persons_name {
+    <first_name> <last_name>
+ }
+
+We also define the two name tokens as:
+
+ 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 "+" after the
+C<< <alpha> >> tag is a short way of saying "one or more". Our rule
+C<persons_name> would match something like C<Darth Vader> N<Actually,
+it matches a lot of things that aren't people's names>but wouldn't
+match something like C<C 3P0>. Notice that the rule above would match
+C<Jar Jar Binks>, but not the way you would expect: It would match the
+first "Jar" as C<< <first_name> >> and the second "Jar" as
+C<< <last_name> >> and wouldn't match "Binks" at all.
+
+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/headercleanup/docs/book/ch06_library.pod
==============================================================================
--- branches/headercleanup/docs/book/ch06_library.pod	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,107 +0,0 @@
-=pod
-
-Z<CHP-6>
-
-=head1 PIR Standard Library
-
-PIR and PASM are both very low-level languages by any programming
-standards, even though they support some important features of
-high-level dynamic languages,and PIR has some symbolic syntax features.
-Important re-occurring programming tasks in these languages have been
-extracted out into a series of runtime libraries to help make these
-tasks easier. Libraries written in PIR or PASM can be easily included
-and used from any of the high-level language compilers that target
-Parrot, in addition to being used in the Parrot test suite and
-PIR/PASM code generators like PCT.
-
-Some modules, such as F<pcre.pir> and F<postgres.pir> are NCI wrappers
-for common compiled shared libraries.
-
-From the Parrot repository, there are a number of premade libraries in
-F<runtime/library/>, and several generated libraries in F<runtime/include>
-that can be used by Parrot hackers and HLL-implementers alike, if needed.
-This chapter is going to give a brief overview of some of these libraries
-and how they are used.
-
-=head1 Loading and Using Libraries
-
-Libraries are precompiled code files that can be loaded into Parrot. There
-are ways to load a library into Parrot, each with a slightly different
-mechanism. The C<.loadlib> PIR directive causes the library file to be loaded
-at compile-time. The C<load_lib> obcode causes the library to be loaded
-dynamically at runtime.
-
-=head1 General Parrot Libraries
-
-=head2 F<Config.fpmc>
-
-C<Config.fpmc> is generated during the build process. The file defines a
-hash PMC that contains information about the system where Parrot was
-built. By accessing the data in this PMC, you can determine how Parrot
-was compiled and what features and libraries it has available.
-
-=head1 Perl-Inspired Libraries
-
-Since the Parrot project started as the internals of the Perl 6 development
-project, and since a number of Perl hackers are very active in Parrot,
-several libraries in the Parrot runtime are based on common Perl 5 libraries.
-
-=head2 F<Dumper.pir> and F<Data/Dumper.pir>
-
-Perl 5 had C<Data::Dumper>, that would print out the complete contents and
-structure of any arbitrary complex data type. This is useful in a number of
-cases, with debugging not the least of them. It's good to verify that
-complicated nested data structures are being composed and accessed in the
-manner that the programmer intends.
-
-=head1 NCI Wrapper Libraries
-
-Parrot does not intend to reinvent any wheels, and there is lots of important
-functionality encapsulated in various libraries that Parrot does not copy.
-Instead of having to reimplement all sorts of libraries for Parrot, Parrot
-provides the NCI interface to work with these libraries directly. PIR or
-PASM wrapper libraries are provided to create an interface that programs
-running on Parrot can use to access functionality in these libraries.
-
-Notice that these libraries are depending on having the compiled libraries
-they reference already installed on your system. Many of these are detected
-during the configuration process. If you do not have these libraries
-installed, you cannot call the modules discussed here. We will give some
-information about how to find and install the libraries, however.
-
-Notice that this is only a partial list of wrapper libraries that come
-bundled with the Parrot repository. Additional library wrappers may be
-added to the repository at a later date, or may be available from other
-sources.
-
-=head2 PCRE
-
-PCRE is a library that implements regular expressions using Perl 5 syntax.
-
-
-=head2 NCurses
-
-NCurses is a library for manipulating the console and the cursor.
-
-=head2 OpenGL
-
-OpenGL is a 3D graphics library.
-
-=head2 Postgres SQL
-
-=head2 SDL
-
-=head1 Mod_Parrot and CGI libraries
-
-Parrot is also available, through a related but separate development effort
-as a module for the Apache web server, Mod_Parrot. Mod_Parrot allows
-Parrot and the high-level languages which target it to be used in Apache
-to generate web content. Several libraries are available in the Parrot
-repository that can help manage these requests.
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Copied: branches/headercleanup/docs/book/ch06_nqp.pod (from r38131, trunk/docs/book/ch06_nqp.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/ch06_nqp.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/ch06_nqp.pod)
@@ -0,0 +1,169 @@
+=pod
+
+=head1 Grammar Actions
+
+Protofunction signatures aren't the only way to apply functions to rules
+matched by the parser. In fact, they might be the most primitive because
+they use PIR code to implement the operator logic. Another way has been made
+available, by programming function actions in a language that's almost, but
+Not Quite Perl (NQP).
+
+NQP is a small language that's implemented as a subset of Perl 6 syntax and
+semantics. It's represents almost the smallest subset of the Perl 6 language
+necessary to implement the logic of a parser, although some developers have
+complained enough to get a few extra syntactic features added in above the
+bare minimum. NQP also happens to be a Perl 6 subset that's not entirely
+dissimilar from Perl 5, so Perl 5 programmers should not be too lost when
+writing NQP.
+
+=head2 NQP Basics
+
+Like Perl, NQP uses sigils to differentiate different types of variables.
+The C<$> sigil is used for scalars, C<@> is used for arrays, and C<%> is
+used for hashes N<Perl 6 aficionados will know that this isn't entirely
+true, but an in-depth look at Perl 6's context awareness is another topic
+for another book>. A "scalar" is really any single value, and can
+interchangeably be given a string value, or an integer value, or an object.
+In NQP we can write things like this:
+
+ $scalar := "This is a string"
+ $x      := 123
+ $pi     := 3.1415      # rounding
+
+Wait a minute, what's that weird C<:=> symbol? Why don't we just use the
+plain old vanilla C<=> sign? The problem is that I<NQP doesn't have it>.
+Remember how we mentioned that NQP was a minimal subset or Perl 6? The
+C<:=> operator is the I<bind> operator, that makes one value an alias
+C<C programmers and the like may call it a "reference"> for another. In
+most cases you can ignore the distinction between the two, but be warned
+that it's not a regular variable assignment.
+
+With hashes and arrays, it might be tempting to do a list assignment like
+we've all grown familiar with in Perl 5 and other dynamic languages:
+
+ @small_integers := (1, 2, 3, 4);                        # WRONG!
+ %leading_ladies := ("Leia" => "Starwars",
+                    "Trillian" => "Hitchhikers Guide"); # WRONG!
+
+Here's another little gotcha, NQP doesn't have list or hash context! If
+it's necessary to initialize a whole list at once, you can write:
+
+ @small_integers[0] := 1;
+ @small_integers[1] := 2;
+ # ... And so on, and so forth ...
+
+It's also possible to assign a list in I<scalar context> as follows:
+
+ $array_but_a_scalar := (1, 2, 3, 4)
+
+Remember how we said NQP was a bare-bones subset of Perl 6? If NQP had too
+many features, people would use it instead of Perl 6!
+
+=head3 Calling Actions From Rules
+
+When talking about grammar rules, we discussed the funny little C<{*}>
+symbol that calls an action. The action in question is an NQP method
+with the same name as the rule that calls it. NQP rules can be called
+with two different function signatures:
+
+ method name ($/) { ... }
+
+And with a key:
+
+ method name($/, $key) { ... }
+
+Here's an example that shows how the keys are used:
+
+ rule cavepeople {
+      'Fred'  {*}    #= Caveman
+    | 'Wilma' {*}    #= Cavewoman
+    | 'Dino'  {*}    #= Dinosaur
+ }
+
+And here is the rule that tells us 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 just a string that contains whatever text is on the line after
+the C<#=> symbol. If we don't have a C<#=> we don't use a C<$key> in our
+method.
+
+=head3 The Match Object C<$/>
+
+The match object C<$/> may have a funny-looking name, but it's a data
+structure that's all business. It's both a hash and an array. Plus,
+since it's a special variable it also gets a special shortcut syntax
+that can be used to save a few keystrokes:
+
+ $/('Match_item')   is the same as  $<Match_item>
+ $/[0]              is the same as  $[0]
+
+In the match object, each item in the hash is named after one of the items
+that we matched in the rule. So, if we have a file with input "C<X + 5>"
+and a rule:
+
+ rule introductions {
+    <variable> <operator> <number>
+ }
+
+Our match object is going to look like this: C<$/ = ("variable" => "x",
+"operator" => "+", "number" => "5")>
+
+If we have multiple values with the same name, or items with quantifiers
+C<*> or C<+> on it, those members of the match object may be arrays. So,
+if we have the input "A A A B B", and the following rule:
+
+ rule letters {
+    <vowel>* <consonant>*
+ }
+
+The match object will look like this (in Perl 5 syntax):
+
+ $/ = ("vowel" => ["A", "A", "A"], "consonant" => ["B", "B"])
+
+We can get the number of matches in each group by casting it to a scalar
+using the C<$( )> operator:
+
+ $($<vowel>) == 3
+
+=head3 Inline PIR
+
+Now that we know what the match object is, we can talk about the inline
+PIR functionality. In a PGE rule, we can use the C<{{ }}> double curly
+brackets to go into inline-PIR mode. Inside these brackets arbitrary
+PIR code can be executed to affect the operation of the parser. We can
+access the variable C<$/> directly in the grammar without having to
+jump into NQP, and actually examine and affect the values in it.
+
+=head3 PAST Nodes
+
+The job of NQP is to make abstract syntax trees, and the PCT implementation
+of syntax trees is implemented in the PAST class. There are many different
+types of objects in the PAST class, each of which represents a
+particular program construct. These constructs are relatively common and
+simple, but there are powerful levels of configuration that allow complicated
+programming structures to be represented.
+
+=head3 Making Trees
+
+Every action has the ability to create a PAST node that represents that
+action N<and additional PAST nodes, that are children of that node>. Calling
+the C<make> command on that node adds it into the growing PAST tree that
+PCT maintains. Once the C<TOP> rule matches successfully and returns,
+PCT takes that tree and starts the process of optimizing it and converting
+it into PIR and PBC code for execution.
+
+=cut
+
+# Local variables:
+#   c-file-style: "parrot"
+# End:
+# vim: expandtab shiftwidth=4:

Copied: branches/headercleanup/docs/book/ch07_dynpmcs.pod (from r38131, trunk/docs/book/ch07_dynpmcs.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/ch07_dynpmcs.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/ch07_dynpmcs.pod)
@@ -0,0 +1,237 @@
+=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/headercleanup/docs/book/ch07_testing_and_debugging.pod
==============================================================================
--- branches/headercleanup/docs/book/ch07_testing_and_debugging.pod	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,128 +0,0 @@
-=pod
-
-=head0 Testing and Debugging
-
-Z<CHP-7>
-
-Programming languages and the virtual machines on which they run are just
-one small part of the total programming ecosystem. Programmers require not
-just development tools, but also maintenance and management tools. Critical
-to development and maintenance of code are comprehensive testing tools and
-code debugging tools. Luckily, Parrot supports both. This chapter is going
-to discuss the testing frameworks available for HLLs written on Parrot,
-and the Parrot debugger which can be used for live debugging of software
-written in any of the HLLs that Parrot supports.
-
-=head1 Writing Tests
-
-Z<CHP-7-SECT-1>
-
-X<testing Parrot>
-Parrot is volunteer-driven, and contributions from new users are always
-welcome. Contributing tests is a good place for a new developer to start.
-You don't have to understand the code behind a PASM opcodeN<Or PIR
-instruction, or whatever.> to test it, you only have to understand
-the desired behavior. If you're working on some code and it doesn't do
-what the documentation claims, you can isolate the problem in a test or
-series of tests and send them to the bug tracking system. There's a
-good chance the problem will be fixed before the next release. Writing
-tests makes it a lot easier for the developer to know when they've solved
-your problem--it's solved when your tests pass. It also prevents that
-problem from appearing again, because it's checked every time anyone
-runs C<make> C<test>. As you move along, you'll want to write tests
-for every bug you fix or new feature you add.
-
-X<Test::Builder>
-X<Parrot::Test module>
-The Perl 5 testing framework is at the core of Parrot tests,
-particularly F<Test::Builder>. Parrot's F<Parrot::Test> module is an
-interface to F<Test::Builder> and implements the extra features needed
-for testing Parrot, like the fact that PASM and PIR code has to be
-compiled to bytecode before it runs. F<Parrot::Test> handles the
-compilation and running of the test code, and collects the output for
-verification.
-
-The main Parrot tests are in the top-level F<t/> directory of the
-Parrot source tree. F<t/op> contains tests for basic opcodes and
-F<t/pmc> has tests for PMCs. The names of the test files indicate the
-functionality tested, like F<integer.t>, F<number.t>, and F<string.t>.
-Part of the F<make test> target is the command F<perl t/harness>,
-which runs all the F<.t> files in the subdirectories under F</t>. You
-can run individual test files by passing their names to the F<harness>
-script:
-
-  $ perl t/harness t/op/string.t t/op/integer.t
-
-X<set opcode (PASM);test example>
-Here's a simple example that tests the C<set> opcode with integer
-registers, taken from F<t/op/integer.t>:
-
-  output_is(E<lt>E<lt>CODE, E<lt>E<lt>OUTPUT, "set_i");
-      set     I0, 42
-      set     I1, I0
-      print   I1
-      print   "\\n"
-      end
-  CODE
-  42
-  OUTPUT
-
-The code here sets integer register C<I0> to the value 42, sets C<I1>
-to the value of C<I0>, and then prints the value in C<I1>. The test
-passes if the value printed was 42, and fails otherwise.
-
-The C<output_is> subroutine takes three strings: the code to run, the
-expected output, and a description of the test. The first two strings
-can be quite long, so the convention is to use Perl 5 here-documents.
-If you look into the code section, you'll see that the literal C<\n>
-has to be escaped as C<\\n>. Many tests use the non-interpolating
-(C<E<lt>E<lt>'CODE>') form of here-document to avoid that problem. The
-description can be any text.  In this case, it's the fully qualified
-name of the C<set> opcode for integer registers, but it could have
-been "set a native integer register."
-
-If you look up at the top of F<integer.t>, you'll see the line:
-
-  use Parrot::Test tests => 38;
-
-(although the actual number may be larger if more tests have been added
-since this book went to press).
-
-The C<use> line for the F<Parrot::Test> module imports a set of
-subroutines into the test file, including C<output_is>. The end of the
-line gives the number of tests contained in the file.
-
-The C<output_is> subroutine looks for an exact match between the
-expected result and the actual output of the code. When the test
-result can't be compared exactly, you want C<output_like> instead. It
-takes a Perl 5 regular expression for the expected output:
-
-  output_like(<<'CODE', <<'OUTPUT', "testing for text match");
-  ...
-  CODE
-  /^Output is some \d+ number\n$/
-  OUTPUT
-
-F<Parrot::Test> also exports C<output_isnt>, which tests that the
-actual output of the code I<doesn't> match a particular value.
-
-There are a few guidelines to follow when you're writing a test for a
-new opcode or checking that an existing opcode has full test coverage.
-Tests should cover the opcode's standard operation, corner cases, and
-illegal input. The first tests should always cover the basic
-functionality of an opcode. Further tests can cover more complex
-operations and the interactions between opcodes. If the test program
-is complex or obscure, it helps to add comments. Tests should be
-self-contained to make it easy to identify where and why a test is
-failing.
-
-=head1 The Parrot Debugger
-
-Z<CHP-7-SECT-2>
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/headercleanup/docs/book/ch08_architecture.pod
==============================================================================
--- branches/headercleanup/docs/book/ch08_architecture.pod	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,1272 +0,0 @@
-=pod
-
-=head0 Parrot Internals
-
-Z<CHP-8>
-
-This chapter details the architecture and internal workings of Parrot,
-and attempts to explain how Parrot has been designed and how it operates.
-As we've mentioned before, Parrot is a register-based, bytecode-driven,
-object-oriented, multithreaded, dynamically typed, self-modifying,
-asynchronous interpreter. That may seem awfully confusing when you first
-look at it, but the design fits together remarkably well.
-
-=head1 Core Design Principles
-
-Z<CHP-8-SECT-1>
-
-X<Parrot;internals>
-Three main principles drive the design of
-X<Parrot;core design principles> Parrot: speed, abstraction, and
-stability.
-
-I<Speed> is a paramount concern. Parrot absolutely must be as fast as
-possible, since the engine effectively imposes an upper limit on the
-speed of any program running on it. It doesn't matter how efficient
-your program is or how clever your program's algorithms are if the
-engine it runs on limps slowly along. While Parrot can't make a poorly
-written program run fast, it could make a well-written program run
-slowly, a possibility we find entirely unacceptable.
-
-Speed encompasses more than just raw execution time. It extends to
-resource usage. It's irrelevant how fast the engine can run through
-its bytecode if it uses so much memory in the process that the system
-spends half its time swapping to disk. While we're not averse to using
-resources to gain speed benefits, we try not to use more than we need,
-and to share what we do use.
-
-I<Abstraction> indicates that things are designed such that there's a
-limit to what anyone needs to keep in their head at any one time. This
-is very important because Parrot is conceptually very large, as you'll
-see when you read the rest of the chapter. There's a lot going on, too
-much to keep the whole thing in mind at once. The design is such that
-you don't have to remember what everything does, and how it all works.
-This is true regardless of whether you're writing code that runs on
-top of Parrot or working on one of its internal subsystems.
-
-Parrot also uses abstraction boundaries as places to cheat for speed.
-As long as it I<looks> like an abstraction is being completely
-fulfilled, it doesn't matter if it actually I<is> being fulfilled,
-something we take advantage of in many places within the engine. For
-example, variables are required to be able to return a string
-representation of themselves, and each variable type has a "give me
-your string representation" function we can call.  That lets each
-class have custom stringification code, optimized for that particular
-type. The engine has no idea what goes on beneath the covers and
-doesn't care--it just knows to call that function when it needs the
-string value of a variable. Objects are another good case in
-point--while they look like nice, clean black boxes on the surface,
-under the hood we cheat profoundly.
-
-I<Stability> is important for a number of reasons.  We're building the
-Parrot engine to be a good backend for many language compilers to
-target. We must maintain a stable interface so compiled programs can
-continue to run as time goes by. We're also working hard to make
-Parrot a good interpreter for embedded languages, so we must have a
-stable interface exposed to anyone who wants to embed us. Finally, we
-want to avoid some of the problems that Perl 5 has had over the years
-that forced C extensions written to be recompiled after an upgrade.
-Recompiling C extensions is annoying during the upgrade and
-potentially fraught with danger. Such backward-incompatible changes
-have sometimes been made to Perl itself.
-
-=head1 Parrot's Architecture
-
-Z<CHP-8-SECT-2>
-
-The X<architecture;Parrot>
-X<Parrot;architecture>
-Parrot system is divided into four main parts, each with its own
-specific task. The diagram in A<CHP-7-FIG-1>Figure 7-1 shows
-the parts, and the way source code and control flows through Parrot.
-Each of the four parts of Parrot are covered briefly here, with the
-features and parts of the interpreter covered in more detail
-afterward.
-
-=begin figure Parrot's flow
-
-Z<CHP-8-FIG-1>
-F<figs/p6e_0801.png>
-
-=end figure
-
-The flow starts with source code, which is passed into the parser
-module. The parser processes that source into a form that the compiler
-module can handle. The compiler module takes the processed source and
-emits bytecode, which Parrot can directly execute. That bytecode is
-passed into the optimizer module, which processes the bytecode and
-produces bytecode that is hopefully faster than what the compiler
-emitted. Finally, the bytecode is handed off to the interpreter
-module, which interprets the bytecode. Since compilation and execution
-are so tightly woven in dynamic languages such as Perl and Python, the
-control may well flow back to the parser to parse more code.
-
-X<Parrot;compiler module>
-Parrot's compiler module also has the capability to freeze bytecode to
-disk and read that frozen bytecode back again, bypassing the parser
-and compilation phases entirely. The bytecode can be directly
-executed, or handed to the optimizer to work on before execution. This
-may happen if you've loaded in a precompiled library and want Parrot
-to optimize the combination of your code and the library code.  The
-bytecode loader is interesting in its own right, and also warrants a
-small section.
-
-=head2 Parser
-
-Z<CHP-8-SECT-2.1>
-
-X<parser, Parrot>
-X<Parrot;parser module>
-The parser module is responsible for source code in PASM, PIR, or one of
-the high-level languages, and turning it into an X<AST (Abstract Syntax
-Tree)> X<Abstract Syntax Tree (AST)> Abstract Syntax Tree (AST). An AST
-is a digested form of the program, one that's much easier for Parrot to
-work with. In some systems this task is split into two parts--the
-lexing and the parsing--but since the tasks are so closely bound, Parrot
-combines them into a single module.
-
-X<lexing>
-Lexing (or X<tokenizing> tokenizing) turns a stream of characters into a
-stream of tokens. It doesn't assign any meaning to those tokens--that's
-the job of the parser--but it is smart enough to see that an input line
-such as C<$a = 1 + 2;> is composed of 6 tokens (C<$>, C<a>, C<=>, C<1>,
-C<+>, and C<2>).
-
-Parsing is the task of taking the tokens that the lexer has found and
-assigning some meaning to them. Individual tokens from the lexer are
-combined by the parser into larger and more complex tokens, which
-represent common programming constructs like statements, subroutines,
-and programs. When the input source code has been completely converted
-into these complex data structures, the parsing stage is complete.
-Sometimes the parsed output can be directly executed by the interpreter,
-sometimes it is compiled first.
-
-Parsing can be a chore as anyone who's done it before knows. In some
-cases it can be downright maddening--Perl 5's parser has over ten
-thousand lines of C code. Special utility programs such as I<lex>
-and I<yacc> are often used to automate the generation of parser code.
-Perl 5 itself uses a I<yacc>-based grammar to handle parts of the
-processing task.N<I<yacc> can handle only part of the task, though.
-As the quote goes, "The task of parsing Perl is divided between
-I<lex>, I<yacc>, smoke, and mirrors."> Rather than going with a
-custom-built parser for each language, Parrot provides a
-general-purpose parser built on top of Perl 6's grammar engine, with
-hooks for calling out to special-purpose code where necessary. Perl 6
-grammars are designed to be powerful enough to handle parsing Perl, so
-it made good sense to leverage the engine as a general-purpose parser.
-Parrot provides some utility code to transform a I<yacc> grammar into a
-Perl 6 grammar, so languages that already use I<yacc> can be moved over
-to Parrot's parser with a minimum amount of fuss. This allows you to use
-a I<yacc> grammar instead of a Perl 6 grammar to describe the language
-being parsed, both because many languages already have their grammars
-described with I<yacc> and because a I<yacc> grammar is sometimes a more
-appropriate way to describe things.
-
-Parrot does support independent parsers for cases where the Perl 6
-grammar engine isn't the appropriate choice. A language might already
-have an existing parser available, or different techniques might be in
-order. The quirky parsing engines such as the one for Perl 5 may get
-embedded this way, as it's easier to embed some quirky parsers than it
-is to recreate all the quirks in a new parser.
-
-=head2 Compiler
-
-Z<CHP-8-SECT-2.2>
-
-
-X<Parrot;compiler module>
-X<compiler module, Parrot>
-The parser outputs data in a form called an Abstract Syntax Tree (AST).
-The compiler module takes this AST and converts it into bytecode that the
-interpreter engine can execute. This translation is very straightforward
-and isn't too expensive in terms of operating time and resources. The
-tree is flattened, and is passed into a series of substitutions and
-transformations. The compiler is the least interesting part or Parrot,
-little more than a simple rule-based filter module. It is simple, but
-it's a necessary part of Parrot.
-
-For many languages the parser and compiler are essentially a single
-unit. Like the parser, the compiler is modular, so you can load
-in your own compiler if needed. Parrot itself comes with two compiler
-modules for Parrot assembly and PIR. Instead of emitting bytecode
-directly, many HLL compilers emit PIR code, and that is compiled by
-Parrot into bytecode.
-
-=head2 Optimizer
-
-Z<CHP-8-SECT-2.3>
-
-X<Parrot;optimizer module>
-X<optimizer>
-The optimizer module takes the AST from the parser and the bytecode
-from the compiler, and transforms the bytecode to make it run faster.
-X<optimizing code for dynamic languages>
-Optimizing code for dynamic languages such as Perl, Python, and Ruby
-is an interesting task. The languages are so dynamic that the
-optimizer can't be sure how a program will actually run. For example,
-the code:
-
-  $a = 0;
-  for (1..10000) {
-      $a++;
-  }
-
-looks straightforward enough. The variable C<$a> starts at 0, gets
-incremented ten thousand times, and has an end value of 10000. A
-standard optimizer would turn that code into the single line:
-
-  $a = 10000;
-
-and remove the loop entirely. Unfortunately, that's not necessarily
-appropriate for these dynamic languages. C<$a> could easily be an
-active value, which creates side effects when it is accessed or
-incremented. If incrementing the variable ten thousand times causes
-a hardware stepper motor to rotate smoothly, then just assigning a
-value of 10000 to the variable might not only be incorrect but actually
-dangerous to bystanders. An active variable like this might also keep
-track of the number of times it has been accessed or modified. Either
-way, optimizing the loop away changes the semantics of the program in
-ways the original programmer didn't want.
-
-Because of the potential for active or tied data, especially for
-languages as dynamically typed as Perl, Python, Ruby, and PHP,
-optimizing is a non-trivial task. Other languages, such as C or Pascal,
-are more statically typed and lack active data, so an aggressive
-optimizer is in order for them. Breaking out the optimizer into a
-separate module allows us to add in optimizations piecemeal without
-affecting the compiler.  There's a lot of exciting work going into
-the problem of optimizing dynamic languages, and we fully expect to
-take advantage of it where we can.
-
-Optimization is potentially an expensive operation, which is another
-good reason to have it in a separate module. Spending ten seconds
-optimizing a program that will run in five seconds is a huge waste of
-time. On the other hand, spending ten seconds to optimize a program
-makes sense if you save the optimized version to disk and use it over
-and over again. Even if you save only one second per program run, it
-doesn't take long for the ten-second optimization time to pay off. The
-default is to optimize heavily when freezing bytecode to disk and
-lightly when running directly, but this can be changed with a
-command-line switch.
-
-Perl, Python, and Ruby all lack a robust optimizer (outside their
-regular expression engines), so any optimizations we add will increase
-their performance. In fact, optimizations that we add might
-help improve the performance of all high-level languages that run on
-Parrot. This, we feel, is a good thing.
-
-=head2 Interpreter
-
-Z<CHP-8-SECT-2.4>
-
-The interpreter module is the part of the engine that executes the
-generated bytecode. Calling it an interpreter is something of a
-misnomer, since Parrot's core includes both a traditional bytecode
-interpreter module as well as a high-performance just-in-time (JIT)
-compiler engine, but that's a detail of the implementation that we
-don't need to discuss here at length N<At least, we won't discuss it
-yet>.
-
-All the interesting things happen inside the interpreter, and the
-remainder of the chapter is dedicated to the interpreter and the
-functions it provides. It's not out of line to consider the
-interpreter as the real core of Parrot, and to consider the parser,
-compiler, and optimizer as utility modules whose ultimate purpose is
-to feed bytecode to the interpreter.
-
-=head2 Bytecode Loader
-
-Z<CHP-8-SECT-2.5>
-
-X<Parrot;bytecode loader>
-X<bytecode, Parrot;loader>
-The bytecode loader isn't part of our block diagram, but it is
-interesting 
-enough to warrant brief coverage.
-
-The bytecode loader handles loading in bytecode that's been frozen to
-disk. The Parrot bytecode loader is clever enough to handle loading in
-Parrot bytecode regardless of the sort of system that it was saved on,
-so we have cross-platform portability. You can generate bytecode on a
-32-bit x86 system and load it up on a 64-bit Alpha or SPARC system
-without any problems.
-
-The bytecode loading system also has a heuristic engine built into it,
-so it can identify the bytecode format it's reading. This means Parrot
-can not only tell what sort of system Parrot bytecode was generated on
-so it can properly process it, but also allows it to identify bytecode
-generated for other bytecode driven systems, such as .NET, the JVM,
-and the Z-machine.N<The Z-machine is the interpreter for
-Infocom text adventures, such as Zork and The Lurking Horror.>
-
-In addition to loading in bytecode, the loader is sufficiently clever
-to recognize source files for any language that has a registered
-compiler. It loads and compiles that source as if it were frozen
-bytecode.
-
-X<Parrot;loadable opcode library system>
-Together with Parrot's loadable opcode library system (something we'll
-talk about later), this gives Parrot the capability to load in foreign
-bytecode formats and transform them into something Parrot can execute.
-With a sophisticated enough loader, Parrot can load and execute Java and
-.NET bytecode and present Java and .NET library code to languages that
-generate native Parrot bytecode. This is something of a happy accident.
-The original purpose of the architecture was to allow Parrot to load and
-execute Z-machine bytecode, but happy accidents are the best kind.
-
-=head1 The Interpreter
-
-Z<CHP-8-SECT-3>
-
-The X<interpreter, Parrot>
-interpreter is the engine that actually runs the code emitted by the
-parser, compiler, and optimizer modules.  The Parrot execution engine
-is a virtual CPU done completely in software. We've drawn on research
-in CPU and interpreter design over the past forty years to try and
-build the best engine to run dynamic languages.
-
-That emphasis on dynamic languages is important. We are not trying to
-build the fastest C, Forth, Lisp, or Prolog engine. Each class of
-languages has its own quirks and emphasis, and no single engine will
-handle all the different types of languages well. Trying to design an
-engine that works equally well for all languages will get you an
-engine that executes all of them poorly.
-
-That doesn't mean that we've ignored languages outside our area of
-primary focus--far from it. We've worked hard to make sure that we can
-accommodate as many languages as possible without compromising the
-performance of our core language set. We feel that even though we may
-not run Prolog or Scheme code as fast as a dedicated engine would, the
-flexibility Parrot provides to mix and match languages more than makes
-up for that.
-
-Parrot's core design is that of a register-rich CISC CPU, like many of
-the CISC machines of the past such as the VAX, Motorola 68000, and IBM
-System/3x0. It also bears some resemblance to modern RISC CPUs such as
-the IBM Power series and Intel Alpha,N<Formerly HP, formerly Compaq,
-formerly Digital Alpha.> as it does all its operations on data in
-registers. Using a core design similar to older systems gives us
-decades of compiler research to draw on. Most compiler research since
-the early 1970s deals with targeting register systems of one sort or
-another.
-
-Using a register architecture as the basis for Parrot goes against the
-current trends in virtual machines, which favor stack-based
-approaches. While a stack approach is simpler to implement, a register
-system provides a richer set of semantics.  It's also just more
-pleasant for us assembly old-timers to write code for. Combined with
-the decades of sophisticated compiler research, we feel that it's the
-correct design decision.
-
-=head2 Registers
-
-Z<CHP-8-SECT-3.1>
-
-X<interpreter, Parrot;registers>
-As we've seen in previous chapters, Parrot has four basic types of
-registers: PMC, string, integer, and floating-point numbers, one for
-each of the core data types. We separate the register types for ease
-of implementation, garbage collection, and space efficiency. Since
-PMCs and strings are garbage-collectable entities, restricting what
-can access them--strings in string registers and PMCs in PMC registers
---makes the garbage collector a bit faster and simpler. Integers and
-floats map directly to low-level machine data types and can be stored
-in sequential arrays to save space and increase access speed.
-
-=head2 Strings
-
-Z<CHP-8-SECT-3.3>
-
-X<strings;Parrot>
-X<interpreter, Parrot;strings>
-Text data is deceptively complex, so Parrot has strings as a
-fundamental data type and tackles the problems head-on. We do this
-out of sheer practicality, because we know how complex and error-prone
-strings can get. We implement them one, and all languages that target
-Parrot can share that same implementation.
-
-The big problem with text is the vast number of human languages and
-the variety of conventions around the world for dealing with it. Long
-ago, 7-bit ASCII with 127 characters was sufficient N<And if that wasn't
-sufficient, too bad. It's all you had.>. Computers were limited and
-mostly used in English, regardless of the user's native language. These
-heavy restrictions were acceptable because the machines of the day were
-so limited that any other option was too slow. Also, most people using
-computers at the time were fluent in English either as their native or
-comfortable second language.
-
-That day passed quite a few years ago. Many different ways of
-representing text have sprung up, from the various multibyte Japanese
-and Chinese representations--designed for languages with many thousands
-of characters--to a half dozen or so European representations, which
-take only a byte but disagree on what characters fit into that byte.
-The Unicode consortium has been working for years on the Unicode standard
-to try and unify all the different schemes, but full unification is still
-years away, if it ever happens.
-
-In the abstract, strings are a series of integers with meaning
-attached to them, but getting from real-world data to abstract
-integers isn't as simple as you might want. There are three important
-things associated with string data--encoding, character set, and
-language--and Parrot's string system knows how to deal with them.
-
-X<strings;encoding>
-A string's I<encoding> says how to turn data from a stream of bytes to a
-stream of characters represented by integers. Something like ASCII data
-is simple to deal with, since each character is a single byte, and
-characters range in value from 0 to 255. UTF-8, one of the Unicode
-encodings, is more complex--a single character can take anywhere from 1
-to 6 bytes.
-
-X<strings;character set>
-The I<character set> for a string tells Parrot what each of the integers
-actually represents. Parrot won't get too far if it doesn't know that 65
-is a capital "A" in an ASCII or Unicode character stream, for example.
-
-X<strings;language>
-Finally, the I<language> for a string determines how the string behaves
-in some contexts. Different languages have different rules for sorting
-and case-folding characters. Whether an accented character keeps its
-accent when upper-cased or lowercased, for instance, depends on the
-language that the string came from.
-
-The capability of translating strings from one encoding to another and
-one character set to another, and to determine when it's needed, is
-built into Parrot. The I/O and regular expression systems fully
-exploit Parrot's core string capabilities, so any language that uses
-Parrot's built-in string functionality gets this for free. Since
-properly implementing even a single system like Unicode is fraught
-with peril, this makes the job of people writing languages that target
-Parrot much easier.
-
-While Parrot provides these facilities, languages aren't required to
-make use of them. Perl 6, for example, generally mandates that all
-strings will be treated as if they are Unicode. In this case Parrot's
-multi-lingual capabilities mainly act as filters to translate to and
-from Unicode. Parrot presents all the data as if it were Unicode, but
-only translates non-Unicode data to Unicode in situations where your
-program may notice.
-
-Unicode is Parrot's character set of last resort when it needs one.
-We use IBM's ICU Unicode library to do all the heavy lifting, since
-writing a properly done Unicode library is a non-trivial undertaking.
-It makes more sense to use a well-tested and debugged library than it
-does to try and reimplement Unicode again.
-
-=head2 Variables
-
-Z<CHP-8-SECT-3.4>
-
-X<variables;Parrot interpreter and>
-X<interpreter, Parrot;variables>
-Variables are a fundamental construct in almost all computer
-languages.N<With the exception of functional languages, though they
-can be useful there as well.> With low-level languages such as C,
-variables are straightforward--they are either basic hardware
-constructs like a 32-bit integer, a 64-bit IEEE floating-point number,
-or the address of some location in memory, or they're a structure
-containing basic hardware constructs. Exchanging variables between
-low-level languages is simple because all the languages operate on
-essentially the same things.
-
-Once you get to higher-level languages, variables get more
-interesting. OO languages have the concept of the object as a
-fundamental construct, but no two OO languages seem to agree on
-exactly how objects should behave or how they should be implemented.
-Then there are higher-level languages like Perl, with complex
-constructs like hashes, arrays, and polymorphic scalars as fundamental
-constructs.
-
-The first big issue that Parrot had to face was implementing these
-constructs. The second was doing it in a way that allowed Perl code to
-use Ruby objects, Ruby code to use Python objects, and Lisp code to
-use both.N<Or vice-versa> Parrot's solution is the PMC datatype.
-
-A PMC, as we've seen in previous chapters, is an abstract variable type.
-The languages we're working to support--Perl, Python, and Ruby for
-example--have base variables that are far more complex than just an
-integer or floating-point number.  If we want them to exchange any
-sort of real data, they must have a common base variable type. Parrot
-provides that with the PMC construct. Each language can build on this
-common base. More importantly, each language can make sure that their
-variables behave properly regardless of which language is using them.
-
-When you think about it, there is a large list of things that a
-variable should be able to do. You should, for example, be able to
-load or store a value, add or subtract it from another variable, call
-a method or set a property on it, get its integer or floating-point
-representation, and so on. What we did was make a list of these
-functions and turn them into a mandatory interface called the VTABLE.
-
-Each PMC has a VTABLE attached to it. This table of function pointers
-is fixed--the list of functions, and where they are in the table, is
-the same for each PMC. All the common operations a program might
-perform on a variable, as well as all the operators that might be
-overloaded for a PMC, have VTABLE entries.
-
-=head2 Bytecode
-
-Z<CHP-8-SECT-3.5>
-
-Like any CPU, software, or hardware, Parrot needs a set of
-instructions to tell it what to do. For hardware, this is a stream of
-executable code or machine language. For Parrot, this is bytecode.
-Calling it bytecode isn't strictly accurate, since the individual
-instructions are 32 bits each rather than 8 bits each, but since it's
-the common term for most other virtual machines, it's the term we use.
-
-Each instruction--also known as an X<opcode> I<opcode>--tells the
-interpreter engine what to do. Some opcodes are very low level, such as
-the one to add two integers together.  Others are significantly more
-complex, like the opcode to take a continuation.
-
-X<bytecode, Parrot>
-X<Parrot;bytecode>
-Parrot's bytecode is designed to be directly executable. The code on
-disk can be run by the interpreter without needing any translation.
-This gets us a number of benefits. Loading is much faster, of course,
-since we don't have to do much (if any) processing on the bytecode as
-it's loaded. It also means we can use some special OS calls that map a
-file directly into the memory space of a process. Because of the way
-this is handled by the operating system,N<Conveniently, this works the
-same way for all the flavors of Unix, Windows, and VMS.> the bytecode
-file will be loaded into the system's memory only once, no matter how
-many processes use the file. This can save a significant amount of
-real RAM on server systems. Files loaded this way also get their parts
-loaded on demand. Since we don't need to process the bytecode in any
-way to execute it, if you map in a large bytecode library file, only
-those bits of the file your program actually executes will get read in
-from disk. This can save a lot of time.
-
-Parrot creates bytecode in a format optimized for the platform it's
-built on, since the most common case by far is executing bytecode that's
-been built on the system you're using. This means that floating-point
-numbers are stored in the current platform's native format, integers
-are in the native size, and both are stored in the byte order for the
-current platform. Parrot does have the capability of executing
-bytecode that uses 32-bit integers and IEEE floating-point numbers on
-any platform, so you can build and ship bytecode that can be run by
-anyone with a Parrot interpreter.
-
-If you do use a bytecode file that doesn't match the current
-platform's requirements (perhaps the integers are a different size),
-Parrot automatically translates the bytecode file as it reads it in.
-In this case, Parrot does have to read in the entire file and process
-it. The sharing and load speed benefits are lost, but it's a small
-price to pay for the portability. Parrot ships with a utility to turn
-a portable bytecode file into a native format bytecode file if the
-overhead is too onerous.
-X<Parrot;interpreter;;(see interpreter, Parrot)>
-
-=head1 I/O, Events, and Threads
-
-Z<CHP-8-SECT-4>
-
-Parrot has comprehensive support for I/O, threads, and events. These
-three systems are interrelated, so we'll treat them together. The
-systems we talk about in this section are less mature than other parts
-of the engine, so they may change by the time we roll out the final
-design and implementation.
-
-=head2 I/O
-
-Z<CHP-8-SECT-4.1>
-
-Parrot's base X<I/O;Parrot> I/O system is fully X<asynchronous I/O>
-asynchronous with callbacks and per-request private data. Since this
-is massive overkill in many cases, we have a plain vanilla synchronous
-I/O layer that programs can use if they don't need the extra power.
-
-Asynchronous I/O is conceptually pretty simple. Your program makes an
-I/O request. The system takes that request and returns control to your
-program, which keeps running. Meanwhile the system works on satisfying
-the I/O request. Once satisfied, the system notifies your program in
-some way. Since there can be multiple requests outstanding, and you can't
-be sure exactly what your program will be doing when a request is
-satisfied, programs that make use of asynchronous I/O can become very
-complex.
-
-X<synchronous I/O>
-Synchronous I/O is even simpler. Your program makes a request to the
-system and then waits until that request is done. There can be only
-one request in process at a time, and you always know what you're
-doing (waiting) while the request is being processed. It makes your
-program much simpler, since you don't have to do any sort of
-coordination or synchronization.
-
-The big benefit of asynchronous I/O systems is that they generally
-have a much higher throughput than a synchronous system. They move
-data around much faster--in some cases three or four times faster.
-This is because the system can be busy moving data to or from disk
-while your program is busy processing the next set of data.
-
-For disk devices, having multiple outstanding requests--especially on
-a busy system--allows the system to order read and write requests to
-take better advantage of the underlying hardware. For example, many
-disk devices have built-in track buffers. No matter how small a
-request you make to the drive, it always reads a full track. With
-synchronous I/O, if your program makes two small requests to the same
-track, and they're separated by a request for some other data, the
-disk will have to read the full track twice. With asynchronous I/O, on
-the other hand, the disk may be able to read the track just once, and
-satisfy the second request from the track buffer.
-
-Parrot's I/O system revolves around a request. A request has three
-parts: a buffer for data, a completion routine, and a piece of data
-private to the request. Your program issues the request, then goes about
-its business. When the request is completed, Parrot will call the
-completion routine, passing it the request that just finished. The
-completion routine extracts out the buffer and the private data, and
-does whatever it needs to do to handle the request. If your request
-doesn't have a completion routine, then your program will have to
-explicitly check to see if the request was satisfied.
-
-Your program can choose to sleep and wait for the request to finish,
-essentially blocking. Parrot will continue to process events while
-your program is waiting, so it isn't completely unresponsive. This is
-how Parrot implements synchronous I/O--it issues the asynchronous
-request, then immediately waits for that request to complete.
-
-The reason we made Parrot's I/O system asynchronous by default was
-sheer pragmatism. Network I/O is all asynchronous, as is GUI
-programming, so we knew we had to deal with asynchrony in some form.
-It's also far easier to make an asynchronous system pretend to be
-synchronous than it is the other way around. We could have decided to
-treat GUI events, network I/O, and file I/O all separately, but there
-are plenty of systems around that demonstrate what a bad idea that is.
-
-=head2 Events
-
-Z<CHP-8-SECT-4.2>
-
-An X<events, Parrot> event is a notification that something has
-happened: the user has manipulated a GUI element, an I/O request has
-completed, a signal has been triggered, or a timer has expired.  Most
-systems these days have an event handler,N<Often two or three, which is
-something of a problem.> because handling events is so fundamental to
-modern GUI programming. Unfortunately, most event handling systems are
-not integrated, or poorly integrated, with the I/O system. This leads
-to nasty code and unpleasant workarounds to try and make a program
-responsive to network, file, and GUI events simultaneously. Parrot,
-on the other hand, presents a unified event handling system integrated
-with its I/O system; this makes it possible to write cross-platform
-programs that work well in a complex environment.
-
-Parrot's events are fairly simple. An event has an event type, some
-event data, an event handler, and a priority. Each thread has an event
-queue, and when an event occurs it is put into the queue for the correct
-thread. Once in the queue, events must wait until an event handler gets
-a chance to process it. If there is no clear destination thread for the
-event, it is put into a default queue where it can be processed.
-
-Any operation that would potentially block normal operation, such as a
-C<sleep> command or the cleanup operations that Parrot calls when it exits
-a subroutine, causes the event handlers to process through the events
-in the queue. In this way, when your program thinks it is just waiting,
-it is actually getting a lot of work done in the background. Parrot
-doesn't check an outstanding event to handle during every opcode. This
-is a pure performance consideration: All those checks would get expensive
-very quickly. Parrot generally ensures timely event handling, and events
-shouldn't ever be ignored for more then a few milliseconds. N<Unless
-asynchronous event handling is explicitly disabled, and then events will
-stay ignored for as long as the programmer wants.>.
-
-When Parrot does extract an event from the event queue, it calls that
-event's event handler, if it has one. If an event doesn't have a
-handler, Parrot instead looks for a generic handler for the event type
-and calls it instead. If for some reason there's no handler for the
-event type Parrot falls back to the generic event handler which
-throws an exception as a last resort. You can override the generic event
-handler if you want Parrot to do something else with unhandled events,
-perhaps silently discard them instead.
-
-Because events are handled in mainline code, they don't have the
-restrictions commonly associated with interrupt-level code. It's safe
-and acceptable for an event handler to throw an exception, allocate
-memory, or manipulate thread or global state safely. Event handlers
-can even acquire locks if they need to. Even though event handlers have
-all these capabilities, it doesn't mean they should be used with
-impunity. An event handler blocking on a lock can easily deadlock a
-program that hasn't been properly designed. Parrot gives you plenty of
-rope, it's up to the programmer not to trip on it.
-
-Parrot uses the priority on events for two purposes. First, the
-priority is used to order the events in the event queue. Events for a
-particular priority are handled in a FIFO manner, but higher-priority
-events are always handled before lower-priority events. Parrot also
-allows a user program or event handler to set a minimum event priority
-that it will handle. If an event with a priority lower than the
-current minimum arrives, it won't be handled, instead sitting in the
-queue until the minimum priority level is dropped. This allows an
-event handler that's dealing with a high-priority event to ignore
-lower-priority events.
-
-User code generally doesn't need to deal with prioritized events, so
-programmers should adjust event priorities with care. Adjusting the
-default priority of an event, or adjusting the current minimum
-priority level, is a rare occurrence.  It's almost always a mistake to
-change them, but the capability is there for those rare occasions
-where it's the correct thing to do.
-
-=head2 Signals
-
-Z<CHP-8-SECT-4.3>
-
-X<signals, Parrot>
-Signals are a special form of event, based on the standard Unix signal
-mechanism. Even though signals are occasionally described as being
-special in some way, under the hood they're treated like any other event.
-The primary difference between a signal and an event is that signals
-have names that Unix and Linux programmers will recognize. This can be
-a little confusing, especially when the Parrot signal doesn't use exactly
-the same semantics as the Unix signal does.
-
-The Unix signaling mechanism is something of a mash, having been
-extended and worked on over the years by a small legion of ambitious but
-underpaid programmers. There are generally two types of signals to deal
-with: those that are fatal, and those that are not.
-
-X<fatal signals> 
-Fatal signals are things like X<SIGKILL>
-SIGKILL, which unconditionally kills a process, or X<SIGSEGV> SIGSEGV,
-which indicates that the process has tried to access memory that isn't
-part of your process. Most programmers will better know SIGSEGV as a
-"segmentation fault", something that should be avoided at all costs.
-There's no good way for Parrot to catch and handle these signals, since
-they occur at a lower level in the operating system and are typically
-presented to Parrot long after anything can be done about it. These
-signals will therefore always kill Parrot and whatever programs were
-running on it. On some systems it's possible to catch some of
-N<sometimes> the fatal signals, but Parrot code itself operates at too
-high a level for a user program to do anything with them. Any handlers
-for these kinds of signals would have to be written at the lowest levels
-in C or a similar language, something that cannot be accessed directly
-from PIR, PASM, or any of the high-level languages that run on Parrot.
-Parrot itself may try to catch these signals in special circumstances for
-its own use, but that functionality isn't exposed to a user program.
-
-X<non-fatal signals>
-Non-fatal signals are things like X<SIGCHLD> SIGCHLD, indicating that a
-child process has died, or X<SIGINT> SIGINT, indicating that the user
-has hit C<^C> on the keyboard. Parrot turns these signals into events
-and puts them in the event queue.  Your program's event handler for the
-signal will be called as soon as Parrot gets to the event in the queue,
-and your code can do what it needs to with it.
-
-SIGALRM, the timer expiration signal, is treated specially by
-Parrot. Generated by an expiring alarm() system call, this signal is
-normally used to provide timeouts for system calls that would
-otherwise block forever, which is very useful. The big downside to
-this is that on most systems there can only be one outstanding
-alarm() request, and while you can get around this somewhat with the
-setitimer call (which allows up to three pending alarms) it's still
-quite limited.
-
-Since Parrot's IO system is fully asynchronous and never blocks--even
-what looks like a blocking request still drains the event queue--the
-alarm signal isn't needed for this. Parrot instead grabs SIGALRM for
-its own use, and provides a fully generic timer system which allows
-any number of timer events, each with their own callback functions
-and private data, to be outstanding.
-
-=head2 Threads
-
-Z<CHP-8-SECT-4.4>
-
-X<threads, Parrot>
-Threads are a means of splitting a process into multiple pieces that
-execute simultaneously.  It's a relatively easy way to get some
-parallelism without too much work. Threads don't solve all the
-parallelism problems your program may have N<And in fact, threading
-can cause its own parallelism problems, if you aren't careful>.
-Sometimes multiple processes on a single system, multiple processes
-on a cluster, or processes on multiple separate systems are better
-for parallelized tasks then using threads.
-
-All the resources in a threaded process are shared between threads.
-This is simultaneously the great strength and great weakness of the
-method. Easy sharing is fast sharing, making it far faster to
-exchange data between threads or access shared global data than to
-share data between processes on a single system or on multiple
-systems. Easy sharing of data can be dangerous, though, since data can
-be corrupted if the threads don't coordinate between themselves somehow.
-And, because all the threads are contained within a single process, if
-any one of them causes a fatal error, Parrot and all the programs and
-threads running on top of it dies.
-
-With a low-level language such as C, these issues are manageable. The
-core data types, integers, floats, and pointers are all small enough
-to be handled atomically. You never have to worry that two threads will
-try to write a value to the same integer variable, and the result will
-be a corrupted combination of the two. It will be one or the other value,
-depending on which thread wrote to the memory location last. Composite
-data structures, on the other hand, are not handled atomically. Two
-threads both accessing a large data structure can write incompatible data
-into different fields. To avoid this, these structures can be protected
-with special devices called mutexes. Mutexes N<depending on the exact
-implementation and semantics, Mutexes can also be known as locks,
-spinlocks, semaphores, or critical sections.> are special structures that
-a thread can get exclusive access to. Like a baton in a relay race, only
-one thread can own a mutex at a time, and by convention only the thread
-with the mutex can access the associated data. The composite data
-elements that need protecting can each have their own mutex, and when a
-thread tries to touch the data it must acquires the mutex first. If
-another thread already has the mutex, all other threads must wait before
-they can get the mutex and access the data. By default there's very
-little data that must be shared between threads, so it's relatively easy
-to write thread-safe code if a little thought is given to the program
-structure. Thread safety is far too big a topic to cover in this book,
-but trust us when we say it's something worth being concerned with.
-
-X<Parrot;native data type;;(see PMCs)>
-X<PMCs (Polymorphic Containers);Parrot's native data type> 
-PMCs are complex structures, even the simplest ones. We can't count on
-the hardware or even the operating system to provide us atomic access.
-Parrot has to provide that atomicity itself, which is expensive. Getting
-and releasing a mutex is an inexpensive operations by itself, and has
-been heavily optimized by platform vendors because they want threaded
-code to run quickly. It's not free, though, and when you consider that
-Parrot must access hundreds or even thousands of PMCs for some programs,
-any operations that get performed for all accesses can impose a huge
-performance penalty.
-
-=head3 External Libraries
-
-Even if your program is thread-safe, and Parrot itself is thread-safe,
-that doesn't mean there is no danger. Many libraries that Parrot uses
-or that your program taps into through NCI may not be thread safe, and
-may crash your program if you attempt to use them in a threaded
-environment. Parrot cannot make existing unsafe libraries any safer
-N<We can send nagging bug reports to the library developers.>, but at
-least Parrot itself won't introduce new problems. Whenever you're using
-an external library, you should double-check that it's safe to use with
-threading environments. If you aren't using threading in your programs,
-you don't need to worry about it.
-
-=head3 Threading Models
-
-When you think about it, there are really three different threading
-models. In the first one, multiple threads have no interaction among
-themselves. This essentially does with threads the same thing that's
-done with processes. This works very well in Parrot, with the
-isolation between interpreters helping to reduce the overhead of this
-scheme. There's no possibility of data sharing at the user level, so
-there's no need to lock anything.
-
-In the second threading model, multiple threads run and pass messages
-back and forth amongst themselves. Parrot supports this as well, via
-the event mechanism. The event queues are thread-safe, so one thread
-can safely inject an event into another thread's event queue. This is
-similar to a multiple-process model of programming, except that
-communication between threads is much faster, and it's easier to pass
-around structured data.
-
-In the third threading model, multiple threads run and share data
-among themselves directly. While Parrot can't guarantee that data at
-the user level remains consistent, it can make sure that access to shared
-data is at least safe. We do this with two mechanisms.
-
-First, Parrot presents an advisory lock system to user code. Any piece
-of user code running in a thread can lock a variable. Any attempt to
-lock a variable that another thread has locked will block until the
-lock is released. Locking a variable only blocks other lock attempts.
-It does I<not> block access. This may seem odd, but it's the same scheme
-used by threading systems that obey the POSIX thread standard, and has
-been well tested in practice.
-
-Secondly, Parrot forces all shared PMCs to be marked as such, and all
-access to shared PMCs must first acquire that PMC's private lock. This
-is done by installing an alternate VTABLE for shared PMCs, one that
-acquires locks on all its parameters. These locks are held only for
-the duration of the VTABLE interface call, but ensure that the PMCs
-affected by the operation aren't altered by another thread while the
-VTABLE operation is in progress.
-
-=head1 Objects
-
-Z<CHP-8-SECT-5>
-
-X<objects;Parrot>
-Perl 5, Perl 6, Python, and Ruby are all object-oriented languages in
-some form or other, so Parrot has to have core support for objects and
-classes. Unfortunately, all these languages have somewhat different
-object systems, which made the design of Parrot's object system
-somewhat tricky. It turns out that if you draw the abstraction lines
-in the right places, support for the different systems is easily
-possible. This is especially true if you provide core support for things
-like method dispatch that the different object systems can use and
-override.
-
-=head2 Generic Object Interfacing
-
-Z<CHP-8-SECT-5.1>
-
-X<PMCs (Polymorphic Containers);handling method calls>
-Parrot's object system is very simple--in fact, a PMC only has to handle
-method calls to be considered an object. Just handling methods covers
-well over 90% of the object functionality that most programs use, since
-the vast majority of object access is via method calls. This means that
-user code that does the following:
-
-  object = some_constructor(1, 2, "foo");  
-  object.bar(12);
-
-will work just fine, no matter what language the class that backs
-C<object> is written in, if C<object> even has a class backing it. It
-could be Perl 5, Perl 6, Python, Ruby, or even Java, C#, or Common
-Lisp; it doesn't matter.
-
-Objects may override other functionality as well. For example, Python
-objects use the basic PMC property mechanism to implement object
-attributes. Both Python and Perl 6 mandate that methods and properties
-share the same namespace, with methods overriding properties of the
-same name.
-
-=head2 Parrot Objects
-
-Z<CHP-8-SECT-5.2>
-
-X<objects;Parrot>
-X<Parrot;objects>
-When we refer to Parrot objects we're really talking about Parrot's
-default base object system. Any PMC can have methods called on it and
-act as an object, and Parrot is sufficiently flexible to allow for
-alternate object systems, such as the one Perl 5 uses. In this
-section, though, we're talking about what we provide in our standard
-object system. Parrot's standard object system is pretty
-traditional--it's a class-based system with multiple inheritance,
-interface declarations, and slot-based objects.
-
-X<inheritance;in Parrot>
-Each object is a member of a class, which defines how the object
-behaves. Each class in an object's hierarchy can have one or more
-attributes--that is, named slots that are guaranteed to be in each
-object of that class. The names are all class-private so there's no
-chance of collision. Objects are essentially little fixed-sized
-arrays that know what class they belong to. Most of the "smarts" for
-an object lives in that object's class. Parrot allows you to add
-attributes at run time to a class. If you do, then all objects with
-that class in their inheritance hierarchy will get the new attribute
-added into it. While this is potentially expensive it's a very useful
-feature for languages that may extend a class at run time.
-
-X<multiple inheritance; in Parrot>
-Parrot uses a multiple inheritance scheme for classes. Each class can
-have two or more parent classes, and each of those classes can have
-multiple parents. A class has control over how methods are searched
-for, but the default search is a left-most, depth-first search, the
-same way that Perl 5 does it. Individual class implementers may
-change this if they wish, but only the class an object is instantiated
-into controls the search order. Parrot also fully supports correct
-method redispatch, so a method may properly call the next method in
-the hierarchy even in the face of multiple parents. One limitation we
-place on inheritance is that a class is only instantiated in the
-hierarchy once, no matter how many times it appears in class and
-parent class inheritance lists.
-
-Each class has its own vtableX<vtable>, which all objects of that
-class share. This means that with the right vtable methods every
-object can behave like a basic PMC type in addition to an object.  For
-unary operations such as load or store, the default class vtable first
-looks for the appropriately named method in the class hierarchy.  For
-binary operators such as addition and subtraction, it first looks in
-the multimethod dispatch table. This is only the default, and
-individual languages may make different choices. Objects that
-implement the proper methods can also act as arrays or hashes.
-
-Finally, Parrot implements an interface declaration scheme. You may
-declare that a class C<does> one or more named interfaces, and later
-query objects at run time to see if they implement an interface. This
-doesn't put any methods in a class. For that you need to either inherit
-from a class that does or implement them by hand. All it does is make a
-declaration of what your class does. Interface declarations are
-inheritable as well, so if one of your parent classes declares that it
-implements an interface then your class will as well. This is used in
-part to implement Perl 6's roles.
-
-=head2 Mixed Class-Type Support
-
-Z<CHP-8-SECT-5.3>
-
-X<mixed class-type support in Parrot>
-X<classes;Parrot;mixed class support>
-The final piece of Parrot's object system is the support for
-inheriting from classes of different types. This could be a Perl 6
-class inheriting from a Perl 5 class, or a Ruby class inheriting from
-a .NET class. It could even involve inheriting from a fully compiled
-language such as C++ or Objective C, if proper wrapping is
-established.N<Objective C is particularly simple, as it has a fully
-introspective class system that allows for run-time class creation.
-Inheritance can go both ways between it and Parrot.> As we talked
-about earlier, as long as a class either descends from the base Parrot
-class or has a small number of required properties, Parrot can
-subclass it. This potentially goes both ways, as any class system that
-knows how to subclass from Parrot's base class can inherit from it.
-
-Allowing classes to inherit from other classes of a different base
-type does present some interesting technical issues. The inheritance
-isn't 100% invisible, though you have to head off into the corner
-cases to find the cracks. It's an important feature to design into
-Parrot, so we can subclass Perl 5 style classes, and they can subclass
-Parrot classes. Being able to subclass C++ and Objective C classes is
-a potential bonus. Python, Ruby, and Perl 6 all share a common (but
-hidden) base class in Parrot's base object type, so they can inherit
-from each other without difficulty.
-
-=head1 Advanced Features
-
-Z<CHP-8-SECT-6>
-
-Since the languages Parrot targets (like Perl and Ruby) have
-sophisticated concepts as core features, it's in Parrot's best
-interest to have core support for them. This section covers some (but
-not all) of these features.
-
-=head2 Garbage Collection
-
-Z<CHP-8-SECT-6.1>
-
-X<garbage collection;Parrot>
-It's expected that modern languages have garbage collection built in.
-The programmer shouldn't have to worry about explicitly cleaning up
-after dead variables, or even identifying them. For interpreted
-languages, this requires support from the interpreter engine, so
-Parrot provides that support.
-
-Parrot has two separate allocation systems built into it. Each
-allocation system has its own garbage collection scheme. Parrot also
-has some strict rules over what can be referenced and from where.
-This allows it to have a more efficient garbage collection system.
-
-X<PMCs (Polymorphic Containers);garbage collection and>
-X<garbage collection;Parrot;PMC and>
-The first allocation system is responsible for PMC and string
-structures. These are fixed-sized objects that Parrot allocates out of
-arenas, which are pools of identically sized things. Using arenas makes
-it easy for Parrot to find and track them, and speeds up the detection
-of dead objects.
-
-X<Parrot;dead object detection system>
-Parrot's dead object detection system works by first running through
-all the arenas and marking all strings and PMCs as dead. It then runs
-through the stacks and registers, marking all strings and PMCs they
-reference as alive.  Next, it iteratively runs through all the live
-PMCs and strings and marks everything they reference as alive.
-Finally, it sweeps through all the arenas looking for newly dead PMCs
-and strings, which it puts on the free list. At this point, any PMC
-that has a custom destruction routine, such as an object with a
-C<DESTROY>X<DESTROY method> method, has
-its destruction routine called. The dead object detector is triggered
-whenever Parrot runs out of free objects, and can be explicitly
-triggered by running code.  Often a language compiler will force a
-dead object sweep when leaving a block or subroutine.
-
-Parrot's memory allocation system is used to allocate space for the
-contents of strings and PMCs. Allocations don't have a fixed size;
-they come from pools of memory that Parrot maintains. Whenever Parrot
-runs out of memory in its memory pools, it makes a compacting
-run--squeezing out unused sections from the pools. When it's done, one
-end of each pool is entirely actively used memory, and the other end
-is one single chunk of free memory. This makes allocating memory from
-the pools faster, as there's no need to walk a free list looking for a
-segment of memory large enough to satisfy the request for memory. It
-also makes more efficient use of memory, as there's less overhead than
-in a traditional memory allocation system.
-
-Splitting memory pool compaction from dead object detection has a nice
-performance benefit for Perl and languages like it. For most Perl
-programs, the interpreter allocates and reallocates far more memory
-for string and variable contents than it does actual string and
-variable structures. The structures are reused over and over as their
-contents change. With a traditional single-collector system, each time
-the interpreter runs out of memory it has to do a full scan for dead
-objects and compact the pools after. With a split system, Parrot can
-just sweep through the variables it thinks are live and compact their
-contents. This does mean that Parrot will sometimes move data for
-variables and strings that are really dead because it hasn't found
-that out yet. That expense is normally much less than the expense of
-doing a full tracing run to find out which variables are actually
-dead.
-
-Parrot's allocation and collection systems have some compromises that
-make interfacing with low-level code easier. The structure that
-describes a PMC or string is guaranteed not to move over the lifetime
-of the string or variable. This allows C code to store pointers to
-variables in internal structures without worrying that what they're
-referencing may move. It also means that the garbage collection system
-doesn't have to worry about updating pointers that C code might hold,
-which it would have to do if PMC or string structures could move.
-
-=head2 Multimethod Dispatching
-
-Z<CHP-8-SECT-6.2>
-
-X<multimethod;dispatching>
-Multimethod dispatching (also known as signature-based dispatching) is
-a powerful technique that uses the parameters of a function or method
-call to help decide at run time what function or method Parrot should
-call. This is one of the new features being built into Perl 6. It
-allows you to have two or more subroutines or methods with the same
-name that differ only in the types of their arguments.
-
-In a standard dispatch system, each subroutine or method name must be
-unique within a namespace. Attempting to create a second routine with
-the same name either throws an error or overlays the original one. This
-is certainly straightforward, but in some circumstances it leads to
-code that looks like:
-
-  sub foo {
-      my ($self, $arg) = @_;
-      if ($arg->isa("Foo")) {
-          # Do something with a Foo arg
-      } elsif ($arg->isa("Bar")) {
-          # Do something with a Bar arg
-      } elsif ($arg->isa("Baz")) {
-          # Do something with a Baz arg
-      } else {
-          #...
-      }
-  }
-
-This method effectively dispatches both on the type of the object and
-on the type of the argument to the method. This sort of thing is common,
-especially in operator overloading functions. Manually checking the
-types of the arguments to select an action is both error-prone and
-difficult to extend. Multimethod dispatch solves this problem.
-
-With multimethod dispatch, there can be more than one method or
-subroutine with the same name as long as each variant has different
-parameters in its declaration. When code calls a method or subroutine
-that participates in multiple dispatch, the system chooses the variant
-that most closely matches the types of the parameters in the call.
-
-One very notable thing about subs and methods that do multimethod
-dispatch is that the named subroutines and methods live outside of any
-namespace. By default, when searching for a method or subroutine,
-Parrot first looks for an explicit sub or method of that name in the
-current namespace (or the inheritance hierarchy of an object), then
-for the default subroutine or method (AUTOLOAD or its equivalent) in
-the inheritance hierarchy, and only when those fail will it look for a
-multimethod dispatch version of the subroutine or method. Since Parrot
-allows individual PMC classes to control how their dispatching is
-done, this sequence may be changed on a per-class basis if need be.
-
-Parrot itself makes heavy use of multimethod dispatch, with most of
-the core PMC classes using it to provide operator overloading. The
-only reason we don't use it for all our operator dispatching is that
-some of the languages we're interested in require a left-side wins
-scheme. It's so heavily used for operator overloading, in fact, that
-we actually have two separate versions of multiple dispatch built
-into Parrot, one specially tailored to operator overloading and a more
-general version for normal subroutine and method dispatch.
-
-=head2 Continuations
-
-Z<CHP-8-SECT-6.3>
-
-X<continuations>
-Continuations are possibly the most powerful high-level flow control
-construct. Originating with lambda calculus, and built into Lisp over
-thirty years ago, continuations can be thought of as a closure for
-control flow. They not only capture their lexical scope, which gets
-restored when they're invoked, but also capture their call stack, so
-when they're invoked it's as if you never left the spot where they were
-created. Like closures, though, while they capture the variables in
-scope when the continuation is taken, they don't capture the values of
-the variables. When you invoke a continuation it's not like rolling back
-a transaction.
-
-Continuations are phenomenally powerful, and have the undeserved
-reputation of being bizarre and mind-warping things. This turns out
-not to be the case. Originally we put continuations into Parrot to
-support Ruby, which has them. This decision turned out to be
-fortuitous.
-
-In a simple call/return system, which many languages use, when you
-make a subroutine call the return address is pushed onto a stack
-somewhere. When the subroutine is done it takes the address off the
-stack and returns there. This is a simple and straightforward
-operation, and quite fast. The one disadvantage is that with a secure
-system the calling routine needs to preserve any information that is
-important before making the call and restore it on return.
-
-An alternative calling scheme is called Continuation Passing Style, or
-CPS. With CPS, rather than pushing a return address onto the stack
-you create a return continuation and pass that into the subroutine as
-a parameter. When the subroutine is done it invokes the return
-continuation, effectively returning to the caller with the caller's
-environment automatically restored. This includes not only things like
-the call stack and lexical variables, but also meta-information like
-security credentials.
-
-When we were originally designing Parrot we'd planned on the simpler
-call/return style, with the caller preserving everything important
-before the call, and restoring it afterwards. Three things soon became
-clear: we were saving and restoring a lot of individual pieces; we were
-going to have to add new pieces in the future; and there wasn't any
-difference between what we were doing for a call and what we were
-doing for a continuation, except that the call was a lot more manual.
-
-The future-proofing was what finally made the decision. Parrot is
-making a strong guarantee of backwards compatibility, which means that
-code compiled to Parrot bytecode once we've released will run safely
-and unchanged on all future version of Parrot. If we require all
-the individual pieces of the environment (registers, lexical pads,
-nested namespaces, opcode libraries, stack pointers, exception
-handlers, and assorted things) to be saved manually for a subroutine
-call, it means that we can't add any new pieces in the future, as then
-old code would no longer work properly. We briefly toyed with the idea
-of an opcode to package up the entire environment in one go. Then we
-realized that package was a continuation, and as such we might as well
-just go all the way and use them.
-
-As a result, Parrot implements a full CPS system internally, and uses
-it for all subroutine and method calls. We also have the simpler
-call/return style of flow control available for languages that don't
-need the heavier-weight call system, as well as for compilers to use
-for internal processing and optimization. We do go to some lengths to
-hide the continuations. PIR code, for example, allows compiler writers
-to create subroutines and methods (and calls to them) that conform to
-Parrot's CPS mechanism without ever touching continuations directly.
-We then have the benefits of what appears to be a simple calling
-scheme, secure future-proofing, and the full power of continuations
-for languages that want them.
-
-=head2 Coroutines
-
-Z<CHP-8-SECT-6.4>
-
-X<coroutines>
-A coroutine is a subroutine or method that can suspend itself partway
-through, then later pick up where it left off. This isn't quite the
-same thing as a continuation, though it may seem so at first.
-Coroutines are often used to implement iterators and generators, as
-well as threads on systems that don't have native threading support.
-Since they are so useful, and since Perl 6 and Python provide them
-either directly or as generators, Parrot has support for them built
-in.
-
-Coroutines present some interesting technical challenges. Calling into
-an existing coroutine requires reestablishing not only the lexical
-state and potentially the hypothetical state of variables, but also
-the control state for just the routine. In the presence of exceptions
-they're a bit more complex than plain subroutines and continuations,
-but they're still very useful things and as such we've full support
-for them.
-
-=head1 Conclusion
-
-Z<CHP-8-SECT-7>
-
-We've touched on much of Parrot's core functionality, but certainly
-not all. Hopefully we've given you enough of a feel for how Parrot
-works to expand your knowledge with the Parrot documentation and
-source.
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:
-

Copied: branches/headercleanup/docs/book/ch08_dynops.pod (from r38131, trunk/docs/book/ch08_dynops.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/ch08_dynops.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/ch08_dynops.pod)
@@ -0,0 +1,233 @@
+=pod
+
+=head1 Dynamic Opcodes
+
+Z<CHP-12>
+
+The smallest executable component is not the compilation unit or even the
+subroutine, but is actually the 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". Of course the list of things
+that qualify as "low-level" in Parrot can be pretty advanced compared to the
+functionality supplied by regular assembly language 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. The difference is that Parrot's opcodes can perform some
+very complex and high-level tasks that each may take many execution cycles
+for the average hardware processor. Also, Parrot's opcodes can be
+dynamically loaded in from a special library file called a I<dynop
+library>. We'll talk about dynops a little bit later.
+
+=head3 Opcode naming
+
+To the PIR and PASM programmers, opcodes appear to be polymorphic. That
+is, some opcodes appear to have multiple argument formats. This is just an
+illusion, however. Parrot opcodes are not polymorphic, although certain
+features enable it to appear that way. Different argument list formats
+are detected during parsing and translated into separate, and unique,
+opcode names. 
+
+=head3 Opcode Multiple Dispatch
+
+=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. This script is very similar to that used to
+define PMCs. The C<INTERP> constant, for instance, is always available
+in the opcodes like they are in VTABLE and METHOD declarations. Unlike
+VTABLEs and METHODs, opcodes are 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 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
+
+=item * NUM
+
+=item * STR
+
+=item * PMC
+
+=item * KEY
+
+=item * INTKEY
+
+=item * LABEL
+
+=back
+
+In addition to these types, you need to specify the direction that data is
+moving through that parameter:
+
+=over 4
+
+=item * in
+
+=item * out
+
+=item * inout
+
+=item * invar
+
+=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()
+
+If C<NEXT> contains the address of the next opcode in memory. You don't
+need to call C<goto NEXT()>, however, because the default behavior for
+all opcodes is to automatically jump to the next opcode in the program
+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:

Copied: branches/headercleanup/docs/book/ch09_pasm.pod (from r38131, trunk/docs/book/ch09_pasm.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/ch09_pasm.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/ch09_pasm.pod)
@@ -0,0 +1,3291 @@
+=pod
+
+=head1 Parrot Assembly Language
+
+Z<CHP-5>
+
+X<Parrot Assembly Language;;(see PASM)>
+X<PASM (Parrot assembly language)>
+Parrot assembly (PASM) is an assembly language written for Parrot's
+virtual CPU. Basic register operations or branches in PASM generally
+translate into a single CPU instruction. N<This means the JIT run time
+has a performance of up to one PASM instruction per processor cycle.>
+On the other hand, because it's designed to implement dynamic
+high-level languages, it has support for many advanced features such as
+lexical and global variables, objects, garbage collection,
+continuations, coroutines, and much more. PASM is very similar in
+many respects to PIR which we've already discussed, and in almost all
+cases PIR should be used instead of using PASM directly. However, all
+PASM syntax is also valid PIR syntax, so it's helpful to have an
+understanding of the underlying operations in PASM.
+
+X<.pasm files> A file with a F<.pasm> extension is treated as pure PASM
+code by Parrot, as is any file run with the C<-a> command-line option.
+This mode is mainly used for running pure PASM tests from the test suite,
+and is not likely to be useful for most developers.
+
+Some people may ask why we have PASM at all, especially with PIR which
+has much nicer syntax. The answer is that PASM, like all assembly languages
+has a one-to-one correspondence with the underlying Parrot Bytecode (PBC).
+This makes it easy to translate from PBC to human-readable PASM code in
+a disassembler program. PIR code is basically just a thin wrapper over
+PASM, and you can write PASM code seamlessly in PIR files. It's always
+around, and it's good to be familiar with it.
+
+=head2 Basics
+
+Z<CHP-5-SECT-2>
+
+X<PASM (Parrot assembly language);overview>
+PASM has a simple syntax that will be familiar to people who have experience
+programming other assembly languages. Each statement stands on its own line
+and there is no end-of-line delimiter like is used in many other languages.
+Statements begin with a Parrot instruction, commonly referred to
+as an "opcode"N<More accurately, it should probably be referred to as a
+"mnemonic">. The arguments follow, separated by commas:
+
+  [label] opcode dest, source, source ...
+
+If the opcode returns a result, it is stored in the first argument.
+Sometimes the first register is both a source value and the
+destination of the result, this is the case when we want to modify a
+value in place, without consuming a new Parrot register to hold the
+value. The arguments can be either registers or constants, although the
+destination argument cannot be constant.
+
+=begin PASM
+
+  LABEL:
+      print "The answer is: "
+      print 42
+      print "\n"
+      end                # halt the interpreter
+
+=end PASM
+
+X<PASM (Parrot assembly language);labels>
+A label names a line of code so other instructions can refer to it.
+Label names consist of letters, numbers, and underscores, exactly the
+same syntax as is used for labels in PIR. Simple labels are often all
+capital letters to make them stand out from the rest of the source code
+more clearly. A label definition is simply the name of the label
+followed by a colon. It can be on its own line N<In fact, we recommend
+that it be on its own line, for readability.>:
+
+=begin PASM
+
+  LABEL:
+      print "Norwegian Blue\n"
+
+=end PASM
+
+or before a statement on the same line:
+
+=begin PASM
+
+  LABEL: print "Norwegian Blue\n"
+
+=end PASM
+
+X<PASM (Parrot assembly language);comments>
+POD (plain old documentation) is also allowed in PASM like it is in PIR.
+An equals sign in the first column marks the start of a POD block, and
+a C<=cut> marker signals the end of a POD block.
+
+=begin PASM
+
+  =head2
+
+  This is POD documentation, and is treated like a
+  comment. The PASM interpreter ignores this.
+
+  =cut
+
+=end PASM
+
+Besides POD, there are also ordinary 1-line comments using the # sign,
+which is the same in PIR:
+
+=begin PASM
+
+  LABEL:                        # This is a comment for a label
+    print "Norwegian Blue\n"    # Print a color
+
+=end PASM
+
+=head3 Constants
+
+Z<CHP-5-SECT-2.1>
+
+X<PASM (Parrot assembly language);constants>
+Integer constants are signed integers.N<The size of integers is
+defined when Parrot is configured. It's typically 32 bits on 32-bit
+machines (a range of -2G<31> to +2G<31>-1) and twice that size on
+64-bit processors.> Decimal integer constants can have a positive (C<+>) or
+negative (C<->) sign in front. Binary integers are preceded by C<0b>
+or C<0B>, and hexadecimal integers are preceded by C<0x> or C<0X>:
+
+=begin PASM
+
+  print 42         # Decimalinteger constant
+  print +144       # integer constant
+  print 0x2A       # hexadecimal integer
+  print 0b1101     # binary integer
+
+=end PASM
+
+Floating-point constants can also be positive or negative. Scientific
+notation provides an exponent, marked with C<e> or C<E> (the sign of
+the exponent is optional):
+
+=begin PASM
+
+  print 3.14159    # floating point constant
+  print 1.e6       # scientific notation
+  print -1.23e+45
+
+=end PASM
+
+String constants are wrapped in single or double quotation marks.
+Quotation marks inside the string must be escaped by a backslash.
+Other special characters also have escape sequences. These are the
+same as for Perl 5's C<qq()> operator: C<\t> (tab), C<\n> (newline),
+C<\r> (return), C<\f> (form feed), C<\\> (literal slash), C<\">
+(literal double quote), etc.
+
+=begin PASM
+
+  print "string\n"    # string constant with escaped newline
+  print "\\"          # a literal backslash
+  print 'a\n'         # three chars: 'a', a backslash, and a 'n'
+
+=end PASM
+
+=head3 Working with Registers
+
+Z<CHP-5-SECT-2.2>
+
+X<PASM (Parrot assembly language);registers>
+X<registers;Parrot;;(see PASM, registers)>
+Parrot is a register-based virtual machine. It has 4 typed register
+sets: integers, floating-point numbers, strings, and Parrot objects
+(called PMCs). Register names consist of a capital letter indicating
+the register set type and the number of the register. Register numbers
+are non-negative (zero and positive numbers), and do not have a
+pre-defined upper limit N<At least not a restrictive limit. Parrot
+registers are stored internally as an array, and the register number is
+an index to that array. If you call C<N2000> you are implicitly creating
+a register array with 2000 entries. This can carry a performance
+penalty>. For example:
+
+  I0   integer register #0
+  N11  number or floating point register #11
+  S2   string register #2
+  P33  PMC register #33
+
+Integer and number registers hold values, while string and PMC
+registers contain pointers to allocated memory for a string header or
+a Parrot object.
+
+In Chapter 3 we mentioned that a register name was a dollar-sign followed
+by a type identifier and then a number. Now we're naming registers with
+only a letter and number, not a dollar sign. Why the difference? The
+dollar sign indicates to Parrot that the register names are not literal,
+and that the register allocator should assign the identifier to a
+physical memory location. Without the dollar sign, the register number
+is an actual offset into the register array. C<N2000> is going to point
+to the two thousandth register, while C<$N2000> can point to any
+memory location that the register allocator determines to be free. Since
+PIR attempts to protect the programmer from some of the darkest details,
+Parrot requires that registers in PIR use the C<$> form. In PASM you can
+use either form, but we still recommend using the C<$> form so you don't
+have to worry about register allocations (and associated performance
+penalties) yourself.
+
+=head4 Register assignment
+
+Z<CHP-5-SECT-2.2.1>
+
+X<PASM (Parrot assembly language);registers;assignment>
+The most basic operation on registers is assignment using the C<set>
+opcode:
+
+=begin PASM
+
+  set I0, 42        # set integer register #0 to the integer value 42
+  set N3, 3.14159   # set number register #3 to an approximation of E<#x3C0>
+  set I1, I0        # set register I1 to what I0 contains
+  set I2, N3        # truncate the floating point number to an integer
+
+=end PASM
+
+PASM uses registers where a high-level language would use variables.
+The C<exchange> opcode swaps the contents of two registers of the same
+type:
+
+=begin PASM
+
+  exchange I1, I0   # set register I1 to what I0 contains
+                    # and set register I0 to what I1 contains
+
+=end PASM
+
+As we mentioned before, string and PMC registers are slightly
+different because they hold a pointer instead of directly holding a
+value. Assigning one string register to another:
+
+=begin PASM
+
+  set S0, "Ford"
+  set S1, S0
+  set S0, "Zaphod"
+  print S1                # prints "Ford"
+  end
+
+=end PASM
+
+doesn't make a copy of the string; it makes a copy of the pointer.
+N<Strings in Parrot use Copy-On-Write (COW) optimizations. When we
+call C<set S1, S0> we copy the pointer only, so both registers point
+to the same string memory. We don't actually make a copy of the string
+until one of two registers is modified.> Just after C<set> C<S1>, C<S0>,
+both C<S0> and C<S1> point to the same string. But assigning a constant
+string to a string register allocates a new string. When "Zaphod" is
+assigned to C<S0>, the pointer changes to point to the location of the
+new string, leaving the old string untouched. So strings act like simple
+values on the user level, even though they're implemented as pointers.
+
+Unlike strings, assignment to a PMC doesn't automatically create a new
+object; it only calls the PMC's VTABLE method for assignment N<and depending
+on implementation the VTABLE assignment operation might not actually
+assign anything. For now though, we can assume most VTABLE interfaces
+do what they say they do.>. So, rewriting the same example using a PMC
+has a completely different result:
+
+=begin PASM
+
+  new P0, "String"
+  set P0, "Ford"
+  set P1, P0
+  set P0, "Zaphod"
+  print P1                # prints "Zaphod"
+  end
+
+=end PASM
+
+The C<new> opcode creates an instance of the C<.String> class. The
+class's vtable methods define how the PMC in C<P0> operates.  The
+first C<set> statement calls C<P0>'s vtable method
+C<set_string_native>, which assigns the string "Ford" to the PMC. When
+C<P0> is assigned to C<P1>:
+
+=begin PASM
+
+  set P1, P0
+
+=end PASM
+
+it copies the pointer, so C<P1> and C<P0> are both aliases to the same
+PMC. Then, assigning the string "Zaphod" to C<P0> changes the
+underlying PMC, so printing C<P1> or C<P0> prints "Zaphod".N<Contrast
+this with C<assign> in "PMC Assignment" later in
+this chapter.>
+
+=head4 PMC object types
+
+Z<CHP-5-SECT-2.2.2>
+
+X<PMCs (Polymorphic Containers);object types>
+Internally, PMC types are represented by positive integers, and
+built-in types by negative integers. PASM provides two opcodes to deal
+with types. Use C<typeof> to look up the name of a type from its
+integer value or to look up the named type of a PMC. Use C<find_type>
+to look up the integer value of a named type.
+
+When the source argument is a PMC and the destination is a string
+register, C<typeof> returns the name of the type:
+
+=begin PASM
+
+  new P0, "String"
+  typeof S0, P0               # S0 is "String"
+  print S0
+  print "\n"
+  end
+
+=end PASM
+
+In this example, C<typeof> returns the type name "String".
+
+X<PMCs (Polymorphic Containers);inheritance>
+X<Parrot;classes;inheritance>
+X<inheritance;with PMCs>
+All Parrot classes inherit from the class C<default>. The
+C<default>X<default PMC> class provides some
+default functionality, but mainly throws exceptions when the default
+variant of a method is called (meaning the subclass didn't define the
+method).
+
+=head4 Autoboxing
+
+Z<CHP-5-SECT-2.2.3>
+
+X<Autoboxing>
+As we've seen in the previous chapters about PIR, we can convert between
+primitive string, integer, and number types and PMCs. PIR used the C<=>
+operator to make these conversions. PASM doesn't have any symbolic operators
+so we have to use the underlying opcodes directly. In this case, the C<set>
+opcode is used to perform data copying and data conversions automatically.
+
+Assigning a primitive data type to a PMC of a String, Integer, or Float type
+converts that PMC to the new type. So, assigning a string to a Number PMC
+converts it into a String PMC. Assigning an integer value converts it to a
+C<Integer>, and assigning C<undef> morphs it to C<Undef>:
+
+=begin PASM
+
+  new P0, "String"
+  set P0, "Ford\n"
+  print P0           # prints "Ford\n"
+  set P0, 42
+  print P0           # prints 42
+  print "\n"
+  typeof S0, P0
+  print S0           # prints "Integer"
+  print "\n"
+  end
+
+=end PASM
+
+C<P0> starts as a C<String>, but when C<set> assigns it an integer
+value 42 (replacing the old string value C<"Ford">), it changes type
+to C<Integer>. This behavior only works for the wrapper PMC types for the
+primitive values string, int, and num. Other PMC classes will have different
+behaviors when you try to assign a primitive value to them.
+
+=head3 Math Operations
+
+Z<CHP-5-SECT-2.3>
+
+X<PASM (Parrot assembly language);math operations>
+PASM has a full set of math instructions. These work with integers,
+floating-point numbers, and PMCs that implement the vtable methods of
+a numeric object. Most of the major math opcodes have two- and
+three-argument forms:
+
+=begin PASM
+
+  add I0, I1              # I0 += I1
+  add I10, I11, I2        # I10 = I11 + I2
+
+=end PASM
+
+The three-argument form of C<add>X<add opcode (PASM)> stores the sum
+of the last two registers in the first register. The two-argument form
+adds the first register to the second and stores the result back in
+the first register.
+
+The source arguments can be Parrot registers or constants, but they
+must be compatible with the type of the destination register.
+Generally, "compatible" means that the source and destination have to
+be the same type, but there are a few exceptions:
+
+=begin PASM
+
+  sub P0, P1, 2          # P0 = P1 - 2
+  sub P0, P1, 1.5        # P0 = P1 - 1.5
+
+=end PASM
+
+If the destination register is an integer register, like C<I0>, the
+other arguments must be integer registers or integer constants. A
+floating-point destination, like C<N0>, usually requires
+floating-point arguments, but many math opcodes also allow the final
+argument to be an integer. Opcodes with a PMC destination register may
+take an integer, floating-point, or PMC final argument:
+
+=begin PASM
+
+  mul P0, P1             # P0 *= P1
+  mul P0, I1
+  mul P0, N1
+  mul P0, P1, P2         # P0 = P1 * P2
+  mul P0, P1, I2
+  mul P0, P1, N2
+
+=end PASM
+
+X<PMCs (Polymorphic Containers);operations on>
+Operations on a PMC are implemented by the vtable method of the
+destination (in the two-argument form) or the left source argument (in
+the three argument form). The result of an operation is entirely
+determined by the PMC.  A class implementing imaginary number
+operations might return an imaginary number, for example.
+
+We won't list every math opcode here, but we'll list some of the most
+common ones. You can get a complete list in "PASM
+Opcodes" in Chapter 11.
+
+=head4 Unary math opcodes
+
+Z<CHP-5-SECT-2.3.1>
+
+The unary opcodes have either a destination argument and a source
+argument, or a single argument as destination and source. Some of the
+most common unary math opcodes are C<inc> (increment), C<dec>
+(decrement), C<abs> (absolute value), C<neg> (negate), and C<fact>
+(factorial):
+
+=begin PASM
+
+  abs N0, -5.0  # the absolute value of -5.0 is 5.0
+  fact I1, 5    # the factorial of 5 is 120
+  inc I1        # 120 incremented by 1 is 121
+
+=end PASM
+
+=head4 Binary math opcodes
+
+Z<CHP-5-SECT-2.3.2>
+
+X<PASM (Parrot assembly language);math operations;binary>
+Binary opcodes have two source arguments and a destination argument.
+As we mentioned before, most binary math opcodes have a two-argument
+form in which the first argument is both a source and the destination.
+Parrot provides C<add>X<add opcode (PASM)> (addition),
+C<sub>X<sub opcode (PASM)> (subtraction), C<mul>X<mul opcode (PASM)>
+(multiplication), C<div>X<div opcode (PASM)> (division), and C<pow>X<pow
+opcode (PASM)> (exponent) opcodes, as well as two different modulus
+operations. C<mod>X<mod opcode (PASM)> is Parrot's implementation of
+modulus, and C<cmod>X<cmod opcode (PASM)> is the C<%> operator from
+the C library. It also provides C<gcd>X<gcd opcode (PASM)> (greatest
+common divisor) and C<lcm>X<lcm opcode (PASM)> (least common
+multiple).
+
+=begin PASM
+
+  div I0, 12, 5   # I0 = 12 / 5
+  mod I0, 12, 5   # I0 = 12 % 5
+
+=end PASM
+
+=head4 Floating-point operations
+
+Z<CHP-5-SECT-2.3.3>
+
+X<PASM (Parrot assembly language);math operations;floating-point>
+Although most of the math operations work with both floating-point
+numbers and integers, a few require floating-point destination
+registers. Among these are C<ln> (natural log), C<log2> (log base 2),
+C<log10> (log base 10), and C<exp> (I<e>G<x>), as well as a full set
+of trigonometric opcodes such as C<sin> (sine), C<cos> (cosine),
+C<tan> (tangent), C<sec> (secant), C<cosh> (hyperbolic cosine),
+C<tanh> (hyperbolic tangent), C<sech> (hyperbolic secant), C<asin>
+(arc sine), C<acos> (arc cosine), C<atan> (arc tangent), C<asec> (arc
+secant), C<exsec> (exsecant), C<hav> (haversine), and C<vers>
+(versine). All angle arguments for the
+X<trigonometric functions (PASM)> trigonometric functions are in
+radians:
+
+=begin PASM
+
+  sin N1, N0
+  exp N1, 2
+
+=end PASM
+
+The majority of the floating-point operations have a single source
+argument and a single destination argument. Even though the
+destination must be a floating-point register, the source can be
+either an integer or floating-point number.
+
+The C<atan>X<atan opcode (PASM)> opcode also has a three-argument
+variant that implements C's C<atan2()>:
+
+=begin PASM
+
+  atan N0, 1, 1
+
+=end PASM
+
+=head3 Working with Strings
+
+Z<CHP-5-SECT-2.4>
+
+X<PASM (Parrot assembly language);string operations>
+String operations work with string registers and with PMCs that implement a
+string class. String operations on PMC registers require all their string
+arguments to be String PMCs.
+
+=head4 Concatenating strings
+
+Z<CHP-5-SECT-2.4.1>
+
+X<PASM (Parrot assembly language);string operations;concatenation>
+Use the C<concat>X<concat opcode (PASM)> opcode to concatenate
+strings. With string register or string constant arguments, C<concat>
+has both a two-argument and a three-argument form. The first argument
+is a source and a destination in the two-argument form:
+
+=begin PASM
+
+  set S0, "ab"
+  concat S0, "cd"     # S0 has "cd" appended
+  print S0            # prints "abcd"
+  print "\n"
+
+  concat S1, S0, "xy" # S1 is the string S0 with "xy" appended
+  print S1            # prints "abcdxy"
+  print "\n"
+  end
+
+=end PASM
+
+The first C<concat> concatenates the string "cd" onto the string "ab"
+in C<S0>. It generates a new string "abcd" and changes C<S0> to point
+to the new string. The second C<concat> concatenates "xy" onto the
+string "abcd" in C<S0> and stores the new string in C<S1>.
+
+X<PMCs (Polymorphic Containers);concatenation>
+For PMC registers, C<concat> has only a three-argument form with
+separate registers for source and destination:
+
+=begin PASM
+
+  new P0, "String"
+  new P1, "String"
+  new P2, "String"
+  set P0, "ab"
+  set P1, "cd"
+  concat P2, P0, P1
+  print P2            # prints abcd
+  print "\n"
+  end
+
+=end PASM
+
+Here, C<concat> concatenates the strings in C<P0> and C<P1> and stores
+the result in C<P2>.
+
+=head4 Repeating strings
+
+Z<CHP-5-SECT-2.4.2>
+
+X<PASM (Parrot assembly language);string operations;repeating strings>
+The C<repeat>X<repeat opcode (PASM)> opcode repeats a string a certain
+number of times:
+
+=begin PASM
+
+  set S0, "x"
+  repeat S1, S0, 5  # S1 = S0 x 5
+  print S1          # prints "xxxxx"
+  print "\n"
+  end
+
+=end PASM
+
+In this example, C<repeat> generates a new string with "x" repeated
+five times and stores a pointer to it in C<S1>.
+
+=head4 Length of a string
+
+Z<CHP-5-SECT-2.4.3>
+
+X<PASM (Parrot assembly language);string operations;length>
+The C<length>X<length opcode (PASM)> opcode returns the length of a
+string in characters. This won't be the same as the length in bytes
+for multibyte encoded strings:
+
+=begin PASM
+
+  set S0, "abcd"
+  length I0, S0                # the length is 4
+  print I0
+  print "\n"
+  end
+
+=end PASM
+
+C<length> doesn't have an equivalent for PMC strings.
+
+=head4 Substrings
+
+Z<CHP-5-SECT-2.4.4>
+
+X<PASM (Parrot assembly language);string operations;substrings>
+The simplest version of the C<substr>X<substr opcode (PASM)> opcode
+takes four arguments: a destination register, a 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 PASM
+
+  substr S0, "abcde", 1, 2        # S0 is "bc"
+
+=end PASM
+
+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. So an offset of -1 starts at the last character of the
+string.
+
+C<substr> also has a five-argument form, where the fifth argument is a
+string to replace the substring. This modifies the second argument and
+returns the removed substring in the destination register.
+
+=begin PASM
+
+  set S1, "abcde"
+  substr S0, S1, 1, 2, "XYZ"
+  print S0                        # prints "bc"
+  print "\n"
+  print S1                        # prints "aXYZde"
+  print "\n"
+  end
+
+=end PASM
+
+This replaces the substring "bc" in C<S1> with the string "XYZ", and
+returns "bc" in C<S0>.
+
+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 C<concat> opcode. If the replacement string is an
+empty string, the characters are just removed from the original
+string.
+
+When you don't need to capture the replaced string, there's an
+optimized version of C<substr> that just does a replace without
+returning the removed substring.
+
+=begin PASM
+
+  set S1, "abcde"
+  substr S1, 1, 2, "XYZ"
+  print S1                        # prints "aXYZde"
+  print "\n"
+  end
+
+=end PASM
+
+The PMC versions of C<substr> are not yet implemented.
+
+=head4 Chopping strings
+
+Z<CHP-5-SECT-2.4.5>
+
+X<PASM (Parrot assembly language);string operations;chopping strings>
+The C<chopn>X<chopn opcode (PASM)> opcode removes characters from the
+end of a string. It takes two arguments: the string to modify and the
+count of characters to remove.
+
+=begin PASM
+
+  set S0, "abcde"
+  chopn S0, 2
+  print S0         # prints "abc"
+  print "\n"
+  end
+
+=end PASM
+
+This example removes two characters from the end of C<S0>. If the
+count is negative, that many characters are kept in the string:
+
+=begin PASM
+
+  set S0, "abcde"
+  chopn S0, -2
+  print S0         # prints "ab"
+  print "\n"
+  end
+
+=end PASM
+
+This keeps the first two characters in C<S0> and removes the rest.
+C<chopn> also has a three-argument version that stores the chopped
+string in a separate destination register, leaving the original string
+untouched:
+
+=begin PASM
+
+  set S0, "abcde"
+  chopn S1, S0, 1
+  print S1         # prints "abcd"
+  print "\n"
+  end
+
+=end PASM
+
+=head4 Copying strings
+
+Z<CHP-5-SECT-2.4.6>
+
+X<PASM (Parrot assembly language);string operations;copying>
+The C<clone>X<clone opcode (PASM)> opcode makes a deep copy of a
+string or PMC. Instead of just copying the pointer, as normal
+assignment would, it recursively copies the string or object
+underneath.
+
+=begin PASM
+
+  new P0, "String"
+  set P0, "Ford"
+  clone P1, P0
+  set P0, "Zaphod"
+  print P1        # prints "Ford"
+  end
+
+=end PASM
+
+This example creates an identical, independent clone of the PMC in
+C<P0> and puts a pointer to it in C<P1>. Later changes to C<P0> have
+no effect on C<P1>.
+
+With simple strings, the copy created by C<clone>, as well as the
+results from C<substr>, are copy-on-write (COW). These are rather
+cheap in terms of memory usage because the new memory location is only
+created when the copy is assigned a new value. Cloning is rarely
+needed with ordinary string registers since they always create a new
+memory location on assignment.
+
+=head4 Converting characters
+
+Z<CHP-5-SECT-2.4.7>
+
+X<PASM (Parrot assembly language);string operations;converting strings>
+The C<chr>X<chr opcode (PASM)> opcode takes an integer value and
+returns the corresponding character as a one-character string, while
+the C<ord>X<ord opcode (PASM)> opcode takes a single character string
+and returns the integer that represents that character in the string's
+encoding:
+
+=begin PASM
+
+  chr S0, 65                # S0 is "A"
+  ord I0, S0                # I0 is 65
+
+=end PASM
+
+C<ord> has a three-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 PASM
+
+  ord I0, "ABC", 2        # I0 is 67
+
+=end PASM
+
+A negative offset counts backward from the end of the string, so -1 is
+the last character.
+
+=begin PASM
+
+  ord I0, "ABC", -1        # I0 is 67
+
+=end PASM
+
+=head4 Formatting strings
+
+Z<CHP-5-SECT-2.4.8>
+
+X<PASM (Parrot assembly language);string operations;formatting
+strings> The C<sprintf>X<sprintf opcode (PASM)> opcode generates a
+formatted string from a series of values. It takes three arguments:
+the destination register, a string specifying the format, and an
+ordered aggregate PMC (like a C<Array>) containing the values to
+be formatted. The format string and the destination register can be
+either strings or PMCs:
+
+=begin PASM
+
+  sprintf S0, S1, P2
+  sprintf P0, P1, P2
+
+=end PASM
+
+The format string is similar to the one for C's C<sprintf> function,
+but with some extensions for Parrot data types. Each format field in
+the string starts with a C<%>
+X<% (percent sign);% format strings for sprintf opcode (PASM)> and
+ends with a character specifying the output format. The output format
+characters are listed in Table 5-1.
+
+=begin table picture Format characters
+
+Z<CHP-5-TABLE-1>
+
+=headrow
+
+=row
+
+=cell Format
+
+=cell Meaning
+
+=bodyrows
+
+=row
+
+=cell C<%c>
+
+=cell A 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 either 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 can be specified with several options: R<flags>,
+R<width>, R<precision>, and R<size>. The format flags are listed in
+Table 5-2.
+
+=begin table picture Format flags
+
+Z<CHP-5-TABLE-2>
+
+=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.
+The flags are listed in Table 5-3.
+
+=begin table picture Size flags
+
+Z<CHP-5-TABLE-3>
+
+=headrow
+
+=row
+
+=cell Character
+
+=cell Meaning
+
+=bodyrows
+
+=row
+
+=cell C<h>
+
+=cell short or float
+
+=row
+
+=cell C<l>
+
+=cell long
+
+=row
+
+=cell C<H>
+
+=cell huge value (long long or long double)
+
+=row
+
+=cell C<v>
+
+=cell INTVAL or FLOATVAL
+
+=row
+
+=cell C<O>
+
+=cell opcode_t
+
+=row
+
+=cell C<P>
+
+=cell C<PMC>
+
+=row
+
+=cell C<S>
+
+=cell string
+
+=end table
+
+The values in the aggregate PMC must have a type compatible with the
+specified R<size>.
+
+Here's a short illustration of string formats:
+
+=begin PASM
+
+  new P2, "Array"
+  new P0, "Int"
+  set P0, 42
+  push P2, P0
+  new P1, "Num"
+  set P1, 10
+  push P2, P1
+  sprintf S0, "int %#Px num %+2.3Pf\n", P2
+  print S0     # prints "int 0x2a num +10.000"
+  print "\n"
+  end
+
+=end PASM
+
+The first eight lines create a C<Array> with two elements: a
+C<Int> and a C<Num>. The format string of the C<sprintf> has
+two format fields. The first, C<%#Px>, takes a PMC argument from the
+aggregate (C<P>) 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/src/sprintf.t> have many more
+examples of format strings.
+
+=head4 Testing for substrings
+
+Z<CHP-5-SECT-2.4.9>
+
+X<PASM (Parrot assembly language);string operations;testing for substrings>
+The C<index>X<index opcode (PASM)> 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 PASM
+
+  index I0, "Beeblebrox", "eb"
+  print I0                       # prints 2
+  print "\n"
+  index I0, "Beeblebrox", "Ford"
+  print I0                       # prints -1
+  print "\n"
+  end
+
+=end PASM
+
+C<index> also has a four-argument version, where the fourth argument
+defines an offset position for starting the search:
+
+=begin PASM
+
+  index I0, "Beeblebrox", "eb", 3
+  print I0                         # prints 5
+  print "\n"
+  end
+
+=end PASM
+
+This finds the second "eb" in "Beeblebrox" instead of the first,
+because the search skips the first three characters in the
+string.
+
+=head4 Joining strings
+
+The C<join> opcode joins the elements of an array PMC into a single
+string. The second argument separates the individual elements of the
+PMC in the final string result.
+
+=begin PASM
+
+  new P0, "Array"
+  push P0, "hi"
+  push P0, 0
+  push P0, 1
+  push P0, 0
+  push P0, "parrot"
+  join S0, "__", P0
+  print S0              # prints "hi__0__1__0__parrot"
+  end
+
+=end PASM
+
+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, and stores it in C<S0>.
+
+=head4 Splitting strings
+
+Splitting a string yields a new array containing the resulting
+substrings of the original string.
+
+=begin PASM
+
+  split P0, "", "abc"
+  set P1, P0[0]
+  print P1              # 'a'
+  set P1, P0[2]
+  print P1              # 'c'
+  end
+
+=end PASM
+
+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. For now, the split pattern (the second
+argument to the opcode) is ignored except for a test to make sure that
+its length is zero.
+
+=head3 Logical and Bitwise Operations
+
+Z<CHP-5-SECT-2.6>
+
+X<PASM (Parrot assembly language);bitwise operations>
+X<PASM (Parrot assembly language);logical operations>
+The X<logical opcodes> logical opcodes evaluate the truth of their
+arguments. They're often used to make decisions on control flow.
+Logical operations are implemented for integers and PMCs. Numeric
+values 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 method (PASM)> vtable method returns a
+nonzero value.
+
+The C<and>X<and opcode (PASM)> opcode returns the second argument if
+it's false and the third argument otherwise:
+
+=begin PASM
+
+  and I0, 0, 1  # returns 0
+  and I0, 1, 2  # returns 2
+
+=end PASM
+
+The C<or>X<or opcode (PASM)> opcode returns the second argument if
+it's true and the third argument otherwise:
+
+=begin PASM
+
+  or I0, 1, 0  # returns 1
+  or I0, 0, 2  # returns 2
+
+  or P0, P1, P2
+
+=end PASM
+
+Both C<and> and C<or> are short-circuiting. If they can determine what
+value to return from the second 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 (PASM)> opcode returns the second argument if
+it is the only true value, returns the third argument if it is the
+only true value, and returns false if both values are true or both are
+false:
+
+=begin PASM
+
+  xor I0, 1, 0  # returns 1
+  xor I0, 0, 1  # returns 1
+  xor I0, 1, 1  # returns 0
+  xor I0, 0, 0  # returns 0
+
+=end PASM
+
+The C<not>X<not opcode (PASM)> opcode returns a true value when the
+second argument is false, and a false value if the second argument is
+true:
+
+=begin PASM
+
+  not I0, I1
+  not P0, P1
+
+=end PASM
+
+The X<bitwise;opcodes (PASM)> bitwise opcodes operate on their values
+a single bit at a time. C<band>X<band opcode (PASM)>,
+C<bor>X<bor opcode (PASM)>, and C<bxor>X<bxor opcode (PASM)> return a
+value that is the logical AND, OR, or XOR of each bit in the source
+arguments. They each take a destination register and two source
+registers. They also have two-argument forms where the destination is
+also a source.  C<bnot>X<bnot opcode (PASM)> is the logical NOT of
+each bit in a single source argument.
+
+=begin PASM
+
+  bnot I0, I1
+  band P0, P1
+  bor I0, I1, I2
+  bxor P0, P1, I2
+
+=end PASM
+
+X<bitwise;string opcodes>
+The bitwise opcodes also have string variants for AND, OR, and XOR:
+C<bors>X<bors opcode (PASM)>, C<bands>X<bands opcode (PASM)>, and
+C<bxors>X<bxors opcode (PASM)>. These take string register or PMC
+string source arguments and perform the logical operation on each byte
+of the strings to produce the final string.
+
+=begin PASM
+
+  bors S0, S1
+  bands P0, P1
+  bors S0, S1, S2
+  bxors P0, P1, S2
+
+=end PASM
+
+The bitwise string opcodes only have meaningful results when they're
+used with simple ASCII strings because the bitwise operation is done
+per byte.
+
+The logical and arithmetic shift operations shift their values by a
+specified number of bits:
+
+=begin PASM
+
+  shl  I0, I1, I2        # shift I1 left by count I2 giving I0
+  shr  I0, I1, I2        # arithmetic shift right
+  lsr  P0, P1, P2        # logical shift right
+
+=end PASM
+
+=head2 Working with PMCs
+
+Z<CHP-5-SECT-3>
+
+In most of the examples we've shown so far, X<PMCs (Polymorphic
+Containers);working with> PMCs just duplicate the functionality of
+integers, numbers, and strings. They wouldn't be terribly useful if
+that's all they did, though. PMCs offer several advanced features,
+each with its own set of operations.
+
+=head3 Aggregates
+
+Z<CHP-5-SECT-3.1>
+
+PMCs can define complex types that hold multiple values. These are
+commonly called "X<PMCs (Polymorphic Containers);aggregate>
+X<aggregate PMCs> aggregates." The most important feature added for
+aggregates is keyed access. Elements within an aggregate PMC can be
+stored and retrieved by a numeric or string key. PASM also offers a
+full set of operations for manipulating aggregate data types.
+
+Since PASM is intended to implement Perl, the two most fully featured
+aggregates already in operation are arrays and hashes. Any aggregate
+defined for any language could take advantage of the features
+described here.
+
+=head4 Arrays
+
+Z<CHP-5-SECT-3.1.1>
+
+X<PMCs (Polymorphic Containers);arrays>
+The C<Array>X<Array PMC> PMC is an ordered aggregate with
+zero-based integer keys. The syntax for X<keyed access to PMCs> keyed access to a
+PMC puts the key in square brackets after the register name:
+
+=begin PASM
+
+  new P0, "Array"     # obtain a new array object
+  set P0, 2           # set its length
+  set P0[0], 10       # set first element to 10
+  set P0[1], I31      # set second element to I31
+  set I0, P0[0]       # get the first element
+  set I1, P0          # get array length
+
+=end PASM
+
+A key on the destination register of a C<set> operation sets a value
+for that key in the aggregate. A key on the source register of a
+C<set> returns the value for that key. If you set C<P0> without a key,
+you set the length of the array, not one of its values.N<C<Array>
+is an autoextending array, so you never need to set its length. Other
+array types may require the length to be set explicitly.> And if you
+assign the C<Array> to an integer, you get the length of the
+array.
+
+By the time you read this, the syntax for getting and setting the
+length of an array may have changed. The change would separate array
+allocation (how much storage the array provides) from the actual
+element count. The currently proposed syntax uses C<set> to set or
+retrieve the allocated size of an array, and an C<elements>
+X<elements opcode (PASM)> opcode to retrieve the count of
+elements stored in the array.
+
+=begin PASM
+
+  set P0, 100         # allocate store for 100 elements
+  set I0, P0          # obtain current allocation size
+  elements I0, P0     # get element count
+
+=end PASM
+
+Some other useful instructions for working with arrays are C<push>,
+C<pop>, C<shift>, and C<unshift> (you'll find them in
+"PASM Opcodes" in Chapter 11).
+
+=head4 Hashes
+
+Z<CHP-5-SECT-3.1.2>
+
+X<PMCs (Polymorphic Containers);hashes>
+The C<Hash>X<Hash PMC> PMC is an unordered aggregate with
+string keys:
+
+=begin PASM
+
+  new P1, "Hash"      # generate a new hash object
+  set P1["key"], 10   # set key and value
+  set I0, P1["key"]   # obtain value for key
+  set I1, P1          # number of entries in hash
+
+=end PASM
+
+The C<exists>X<exists opcode (PASM)> opcode tests whether a keyed
+value exists in an aggregate. It returns 1 if it finds the key in the
+aggregate, and returns 0 if it doesn't. It doesn't care if the value
+itself is true or false, only that the key has been set:
+
+=begin PASM
+
+  new P0, "Hash"
+  set P0["key"], 0
+  exists I0, P0["key"] # does a value exist at "key"
+  print I0             # prints 1
+  print "\n"
+  end
+
+=end PASM
+
+The C<delete>X<delete opcode (PASM)> opcode is also useful for working
+with hashes: it removes a key/value pair.
+
+=head4 Iterators
+
+Z<CHP-5-SECT-3.1.3>
+
+Iterators extract values from an aggregate PMC. You create an iterator
+by creating a new C<Iterator> PMC, and passing the array to C<new> as
+an additional parameter:
+
+=begin PASM
+
+      new P1, "Iterator", P2
+
+=end PASM
+
+The include file F<iterator.pasm> defines some constants for working
+with iterators. The C<.ITERATE_FROM_START> and C<.ITERATE_FROM_END>
+constants are used to select whether an array iterator starts from the
+beginning or end of the array. The C<shift> opcode extracts values
+from the array. An iterator PMC is true as long as it still has values
+to be retrieved (tested by C<unless> below).
+
+=begin PASM
+
+  .include "iterator.pasm"
+      new P2, "Array"
+      push P2, "a"
+      push P2, "b"
+      push P2, "c"
+      new P1, "Iterator", P2
+      set P1, .ITERATE_FROM_START
+
+  iter_loop:
+      unless P1, iter_end
+      shift P5, P1
+      print P5                        # prints "a", "b", "c"
+      branch iter_loop
+  iter_end:
+      end
+
+=end PASM
+
+Hash iterators work similarly to array iterators, but they extract
+keys. With hashes it's only meaningful to iterate in one direction,
+since they don't define any order for their keys.
+
+=begin PASM
+
+  .include "iterator.pasm"
+      new P2, "Hash"
+      set P2["a"], 10
+      set P2["b"], 20
+      set P2["c"], 30
+      new P1, "Iterator", P2
+      set P1, .ITERATE_FROM_START_KEYS
+
+  iter_loop:
+      unless P1, iter_end
+      shift S5, P1                    # one of the keys "a", "b", "c"
+      set I9, P2[S5]
+      print I9                        # prints e.g. 20, 10, 30
+      branch iter_loop
+  iter_end:
+      end
+
+=end PASM
+
+=head4 Data structures
+
+Z<CHP-5-SECT-3.1.4>
+
+X<PMCs (Polymorphic Containers);data structures>
+Arrays and hashes can hold any data type, including other aggregates.
+Accessing elements deep within nested data structures is a common
+operation, so PASM 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 PASM
+
+  new P0, "Hash"
+  new P1, "Array"
+  set P1[2], 42
+  set P0["answer"], P1
+  set I1, 2
+  set I0, P0["answer";I1]        # $i = %hash{"answer"}[2]
+  print I0
+  print "\n"
+  end
+
+=end PASM
+
+This example builds up a data structure of a hash containing an array.
+The complex key C<P0["answer";I1]> retrieves an element of the array
+within the hash. You can also set a value using a complex key:
+
+=begin PASM
+
+  set P0["answer";0], 5   # %hash{"answer"}[0] = 5
+
+=end PASM
+
+The individual keys are integers or strings, or registers with integer
+or string values.
+
+=head3 PMC Assignment
+
+Z<CHP-5-SECT-3.2>
+
+We mentioned before that C<set> on two X<PMCs (Polymorphic
+Containers);assignment> PMCs simply aliases them both to the same object,
+and that C<clone> creates a complete duplicate object. But if you just
+want to assign the value of one PMC to another PMC, you need the
+C<assign>X<assign opcode (PASM)> opcode:
+
+=begin PASM
+
+  new P0, "Int"
+  new P1, "Int"
+  set P0, 42
+  set P2, P0
+  assign P1, P0     # note: P1 has to exist already
+  inc P0
+  print P0          # prints 43
+  print "\n"
+  print P1          # prints 42
+  print "\n"
+  print P2          # prints 43
+  print "\n"
+  end
+
+=end PASM
+
+This example creates two C<Int> PMCs: C<P0> and C<P1>. It gives
+C<P0> a value of 42. It then uses C<set> to give the same value to
+C<P2>, but uses C<assign> to give the value to C<P1>. When C<P0> is
+incremented, C<P2> also changes, but C<P1> doesn't. The destination
+register for C<assign> must have an existing object of the right type
+in it, since C<assign> doesn't create a new object (as with C<clone>)
+or reuse the source object (as with C<set>).
+
+=head3 Properties
+
+Z<CHP-5-SECT-3.3>
+
+X<PMCs (Polymorphic Containers);properties>
+PMCs can have additional values attached to them as "properties" of
+the PMC. What these properties do is entirely up to the language being
+implemented. Perl 6 uses them to store extra information about a
+variable: whether it's a constant, if it should always be interpreted
+as a true value, etc.
+
+The C<setprop>X<setprop opcode (PASM)> opcode sets the value of a
+named property on a PMC. It takes three arguments: the PMC to be set
+with a property, the name of the property, and a PMC containing the
+value of the property. The C<getprop>X<getprop opcode (PASM)> opcode
+returns the value of a property. It also takes three arguments: the
+PMC to store the property's value, the name of the property, and the
+PMC from which the property value is to be retrieved:
+
+=begin PASM
+
+  new P0, "String"
+  set P0, "Zaphod"
+  new P1, "Int"
+  set P1, 1
+  setprop P0, "constant", P1        # set a property on P0
+  getprop P3, "constant", P0        # retrieve a property on P0
+  print P3                          # prints 1
+  print "\n"
+  end
+
+=end PASM
+
+This example creates a C<String> object in C<P0>, and a C<Int>
+object with the value 1 in C<P1>. C<setprop> sets a property named
+"constant" on the object in C<P0> and gives the property the value in
+C<P1>.N<The "constant" property is ignored by PASM, but is significant
+to the Perl 6 code running on top of it.> C<getprop> retrieves the
+value of the property "constant" on C<P0> and stores it in C<P3>.
+
+Properties are kept in a separate hash for each PMC. Property values
+are always PMCs, but only references to the actual PMCs. Trying to
+fetch the value of a property that doesn't exist returns a
+C<Undef>.
+
+C<delprop>X<delprop opcode (PASM)> deletes a property from a PMC.
+
+=begin PASM
+
+  delprop P1, "constant"  # delete property
+
+=end PASM
+
+You can also return a complete hash of all properties on a PMC with
+C<prophash>X<prophash opcode (PASM)>.
+
+=begin PASM
+
+  prophash P0, P1         # set P0 to the property hash of P1
+
+=end PASM
+
+=head2 Flow Control
+
+Z<CHP-5-SECT-4>
+
+X<PASM (Parrot assembly language);flow control>
+Although it has many advanced features, at heart PASM is an assembly
+language. All flow control in PASM--as in most assembly languages--is
+done with branches and jumps.
+
+Branch instructions transfer control to a relative offset from the
+current instruction. The rightmost argument to every branch opcode is
+a label, which the assembler converts to the integer value of the
+offset. You can also branch on a literal integer value, but there's
+rarely any need to do so. The simplest branch instruction is
+C<branch>:
+
+=begin PASM
+
+    branch L1                # branch 4
+    print "skipped\n"
+  L1:
+    print "after branch\n"
+    end
+
+=end PASM
+
+This example unconditionally branches to the location of the label
+C<L1>, skipping over the first C<print> statement.
+
+Jump instructions transfer control to an absolute address. The C<jump>
+opcode doesn't calculate an address from a label, so it's used
+together with C<set_addr>:
+
+=begin PASM
+
+    set_addr I0, L1
+    jump I0
+    print "skipped\n"
+    end
+  L1:
+    print "after jump\n"
+    end
+
+=end PASM
+
+The C<set_addr>X<set_addr opcode (PASM)> opcode takes a label or an
+integer offset and returns an absolute address.
+
+You've probably noticed the C<end>X<end opcode (PASM)> opcode as the
+last statement in many examples above. This terminates the execution
+of the current run loop. Terminating the main bytecode segment (the
+first run loop) stops the interpreter. Without the C<end> statement,
+execution just falls off the end of the bytecode segment, with a good
+chance of crashing the interpreter.
+
+=head3 Conditional Branches
+
+Z<CHP-5-SECT-4.1>
+
+X<PASM (Parrot assembly language);conditional branches>
+X<conditional branches in PASM>
+Unconditional jumps and branches aren't really enough for flow
+control. What you need to implement the control structures of
+high-level languages is the ability to select different actions based
+on a set of conditions. PASM has opcodes that conditionally branch
+based on the truth of a single value or the comparison of two values.
+The following example has C<if>X<if (conditional);opcode (PASM)> and
+C<unless>X<unless (conditional);opcode (PASM)> conditional branches:
+
+=begin PASM
+
+    set I0, 0
+    if I0, TRUE
+    unless I0, FALSE
+    print "skipped\n"
+    end
+  TRUE:
+    print "shouldn't happen\n"
+    end
+  FALSE:
+    print "the value was false\n"
+    end
+
+=end PASM
+
+C<if> branches if its first argument is a true value, and C<unless>
+branches if its first argument is a false value. In this case, the
+C<if> doesn't branch because C<I0> is false, but the C<unless> does
+branch.
+The comparison branching opcodes compare two values and branch if the
+stated relation holds true. These are
+C<eq>X<eq (equal);opcode (PASM)> (branch when equal),
+C<ne>X<ne (not equal);opcode (PASM)> (when not equal),
+C<lt>X<lt (less than);opcode (PASM)> (when less than),
+C<gt>X<gt (greater than);opcode (PASM)> (when greater than),
+C<le>X<le (less than or equal);opcode (PASM)> (when less than or
+equal), and C<ge>X<ge (greater than or equal);opcode (PASM)> (when
+greater than or equal). The two compared arguments must be the same
+register type:
+
+=begin PASM
+
+    set I0, 4
+    set I1, 4
+    eq I0, I1, EQUAL
+    print "skipped\n"
+    end
+  EQUAL:
+    print "the two values are equal\n"
+    end
+
+=end PASM
+
+This compares two integers, C<I0> and C<I1>, and branches if they're
+equal. Strings of different character sets or encodings are converted
+to Unicode before they're compared. PMCs have a C<cmp> vtable method.
+This gets called on the left argument to perform the comparison of the
+two objects.
+
+The comparison opcodes don't specify if a numeric or string comparison
+is intended. The type of the register selects for integers, floats,
+and strings. With PMCs, the vtable method C<cmp> or C<is_equal> of the
+first argument is responsible for comparing the PMC meaningfully with
+the other operand. If you need to force a numeric or string comparison
+on two PMCs, use the alternate comparison opcodes that end in the
+C<_num> and C<_str> suffixes.
+
+=begin PASM
+
+  eq_str P0, P1, label     # always a string compare
+  gt_num P0, P1, label     # always numerically
+
+=end PASM
+
+Finally, the C<eq_addr> opcode branches if two PMCs or strings are
+actually the same object (have the same address):
+
+=begin PASM
+
+  eq_addr P0, P1, same_pmcs_found
+
+=end PASM
+
+=head3 Iteration
+
+Z<CHP-5-SECT-4.2>
+
+X<iteration;in PASM>
+X<PASM (Parrot assembly language);iteration>
+PASM doesn't define high-level loop constructs. These are built up
+from a combination of conditional and unconditional branches. A
+I<do-while>X<do-while style loop;(PASM)> style loop can be constructed
+with a single conditional branch:
+
+=begin PASM
+
+    set I0, 0
+    set I1, 10
+  REDO:
+    inc I0
+    print I0
+    print "\n"
+    lt I0, I1, REDO
+    end
+
+=end PASM
+
+This example prints out the numbers 1 to 10. The first time through,
+it executes all statements up to the C<lt> statement.  If the
+condition evaluates as true (C<I0> is less than C<I1>) it branches to
+the C<REDO> label and runs the three statements in the loop body
+again. The loop ends when the condition evaluates as false.
+
+Conditional and unconditional branches can build up quite complex
+looping constructs, as follows:
+
+=begin PASM
+
+    # loop ($i=1; $i<=10; $i++) {
+    #    print "$i\n";
+    # }
+  loop_init:
+    set I0, 1
+    branch loop_test
+  loop_body:
+    print I0
+    print "\n"
+    branch loop_continue
+  loop_test:
+    le I0, 10, loop_body
+    branch out
+  loop_continue:
+    inc I0
+    branch loop_test
+  out:
+    end
+
+=end PASM
+
+X<loops;PASM>
+X<PASM (Parrot assembly language);loops>
+This example emulates a X<counter-controlled loop> counter-controlled
+loop like Perl 6's C<loop> keyword or C's C<for>. The first time
+through the loop it sets the initial value of the counter in
+C<loop_init>, tests that the loop condition is met in C<loop_test>,
+and then executes the body of the loop in C<loop_body>. If the test
+fails on the first iteration, the loop body will never execute. The
+end of C<loop_body> branches to C<loop_continue>, which increments the
+counter and then goes to C<loop_test> again. The loop ends when the
+condition fails, and it branches to C<out>. The example is more
+complex than it needs to be just to count to 10, but it nicely shows
+the major components of a
+loop.
+
+=head2 Lexicals and Globals
+
+Z<CHP-5-SECT-6>
+
+So far, we've been treating Parrot registers like the variables of a
+high-level language. This is fine, as far as it goes, but it isn't the
+full picture. The dynamic nature and introspective features of
+languages like Perl make it desirable to manipulate variables by name,
+instead of just by register or stack location. These languages also
+have global variables, which are visible throughout the entire
+program. Storing a global variable in a register would either tie up
+that register for the lifetime of the program or require some unwieldy way
+to shuffle the data into and out of registers.
+
+Parrot provides structures for storing both global and lexically
+scoped named variables. Lexical and global variables must be PMC
+values. PASM provides instructions for storing and retrieving
+variables from these structures so the PASM opcodes can operate on
+their values.
+
+=head3 Globals
+
+Z<CHP-5-SECT-6.1>
+
+X<PASM (Parrot assembly language);global variables>
+Global variables are stored in a C<Hash>, so every variable name
+must be unique.  PASM has two opcodes for globals, C<set_global> and
+C<get_global>:
+
+=begin PASM
+
+  new P10, "Int"
+  set P10, 42
+  set_global "$foo", P10
+  # ...
+  get_global P0, "$foo"
+  print P0                        # prints 42
+  end
+
+=end PASM
+
+The first two statements create a C<Int> in the PMC register
+C<P10> and give it the value 42. In the third statement,
+C<set_global> stores that PMC as the named global variable C<$foo>.
+At some later point in the program, C<get_global> retrieves the PMC
+from the global variable by name, and stores it in C<P0> so it can be
+printed.
+
+The C<set_global> opcode only stores a reference to the object. If
+we add an increment statement:
+
+=begin PASM
+
+  inc P10
+
+=end PASM
+
+after the C<set_global> it increments the stored global, printing 43.
+If that's not what you want, you can C<clone> the PMC before you store
+it. Leaving the global variable as an alias does have advantages,
+though. If you retrieve a stored global into a register and modify it
+as follows:
+
+=begin PASM
+
+  get_global P0, "varname"
+  inc P0
+
+=end PASM
+
+the value of the stored global is directly modified, so you don't need
+to call C<set_global> again.
+
+The two-argument forms of C<set_global> and C<get_global> store or
+retrieve globals from the outermost namespace (what Perl users will
+know as the "main" namespace). A simple flat global namespace isn't
+enough for most languages, so Parrot also needs to support
+hierarchical namespaces for separating packages (classes and modules
+in Perl 6). Use C<set_rootglobal> and
+C<get_root_global> add an argument to select a nested namespace:
+
+=begin PASM
+
+  set_root_global ["Foo"], "var", P0 # store P0 as var in the Foo namespace
+  get_root_global P1, ["Foo"], "var"  # get Foo::var
+
+=end PASM
+
+Eventually the global opcodes will have variants that take a PMC to
+specify the namespace, but the design and implementation of these
+aren't finished yet.
+
+=head3 Lexicals
+
+Z<CHP-5-SECT-6.2>
+
+X<PASM (Parrot assembly language);lexical variables>
+Lexical variables are stored in a lexical scratchpad. There's one pad
+for each lexical scope. Every pad has both a hash and an array, so
+elements can be stored either by name or by numeric index.
+
+=head4 Basic instructions
+
+Z<CHP-5-SECT-6.2.1>
+
+To store a lexical variable in the current scope pad, use C<store_lex>.
+Likewise, use C<find_lex> to retrieve a variable from the current pad.
+
+=begin PASM
+
+  new P0, "Int"            # create a variable
+  set P0, 10               # assign value to it
+  store_lex "foo", P0      # store the var with the variable name "foo"
+  # ...
+  find_lex P1, "foo"       # get the var "foo" into P1
+  print P1
+  print "\n"               # prints 10
+  end
+
+=end PASM
+
+=head2 Subroutines
+
+Z<CHP-5-SECT-7>
+
+X<subroutines>
+Subroutines and methods are the basic building blocks of larger
+programs. At the heart of every subroutine call are two fundamental
+actions: it has to store the current location so it can come back to
+it, and it has to transfer control to the subroutine. The
+C<bsr>X<bsr opcode (PASM)> opcode does both. It pushes the address of the
+next instruction onto the control stack, and then branches to a label
+that marks the subroutine:
+
+=begin PASM
+
+    print "in main\n"
+    bsr _sub
+    print "and back\n"
+    end
+  _sub:
+    print "in sub\n"
+    ret
+
+=end PASM
+
+At the end of the subroutine, the C<ret> instruction pops a location
+back off the control stack and goes there, returning control to the
+caller. The C<jsr>X<jsr opcode (PASM)> opcode pushes the current location
+onto the call stack and jumps to a subroutine. Just like the C<jump>
+opcode, it takes an absolute address in an integer register, so the
+address has to be calculated first with the C<set_addr>X<set_addr
+opcode (PASM)> opcode:
+
+=begin PASM
+
+    print "in main\n"
+    set_addr I0, _sub
+    jsr I0
+    print "and back\n"
+    end
+  _sub:
+    print "in sub\n"
+    ret
+
+=end PASM
+
+=head3 Calling Conventions
+
+Z<CHP-5-SECT-7.1>
+
+X<registers;usage for subroutine calls>
+X<subroutines;register usage>
+X<subroutines;calling conventions>
+A C<bsr> or C<jsr> is fine for a simple subroutine call, but few
+subroutines are quite that simple. Who is responsible for saving and
+restoring the registers, however, so that they don't get overwritten when
+we perform a c<bsr> or C<jsr>? How are arguments passed? Where are the
+subroutine's return values stored? A number of different answers are
+possible. You've seen how many ways Parrot has of storing values. The
+critical point is that the caller and the called subroutine have to
+agree on all the answers.
+
+=head4 Parrot calling conventions
+
+Z<CHP-5-SECT-7.1.2>
+
+Internal subroutines can use whatever calling convention serves them
+best. Externally visible subroutines and methods need stricter rules.
+Since these routines may be called as part of an included library or
+module and even from a different high level language, it's important
+to have a consistent interface.
+
+The C<.sub> directive defines globally accessible subroutine
+objects.
+
+Subroutine objects of all kinds can be called with the
+C<invoke>X<invoke opcode (PASM)> opcode. There is also an C<invoke>
+C<PR<x>> instruction for calling objects held in a different register.
+
+The C<invokecc>X<invokecc opcode (PASM)> opcode is like C<invoke>, but it
+also creates and stores a new return continuation. When the
+called subroutine invokes this return continuation, it returns control
+to the instruction after the function call. This kind of call is known
+as Continuation Passing Style (CPS).
+X<CPS (Continuation Passing Style)>
+X<Continuation Passing Style (CPS)>
+
+=head3 Native Call Interface
+
+Z<CHP-5-SECT-7.2>
+
+X<subroutines;calling conventions;NCI>
+A special version of the Parrot calling conventions are used by the
+X<NCI (Native Call Interface)> Native Call Interface (NCI) for calling
+subroutines with a known prototype in shared libraries. This is not
+really portable across all libraries, but it's worth a short example.
+This is a simplified version of the first test in F<t/pmc/nci.t>:
+
+=begin PASM
+
+    loadlib P1, "libnci"          # get library object for a shared lib
+    print "loaded\n"
+    dlfunc P0, P1, "nci_dd", "dd" # obtain the function object
+    print "dlfunced\n"
+    set I0, 1                     # prototype used - unchecked
+    set N5, 4.0                   # first argument
+    invoke                        # call nci_dd
+    ne N5, 8.0, nok_1             # the test functions returns 2*arg
+    print "ok 1\n"
+    end
+  nok_1:
+    #...
+
+=end PASM
+
+This example shows two new instructions: C<loadlib> and C<dlfunc>. The
+C<loadlib>X<loadlib opcode (PASM)> 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 C<.so> or C<.dll>. Which extensions it
+tries depends on the OS Parrot is running on.
+
+The C<dlfunc>X<dlfunc opcode (PASM)> 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. The
+characters used in X<NCI (Native Call Interface);function signatures>
+NCI function signatures are listed in Table 5-5.
+
+=begin table picture Function signature letters
+
+Z<CHP-5-TABLE-5>
+
+=headrow
+
+=row
+
+=cell Character
+
+=cell Register set
+
+=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
+
+For more information on callback functions, read the documentation in
+F<docs/pdds/pdd16_native_call.pod> and F<docs/pmc/struct.pod>.
+
+=head3 Coroutines
+
+Z<CHP-5-SECT-7.4>
+
+As we mentioned in the previous chapter, coroutines are
+X<subroutines;coroutines> subroutines that
+can suspend themselves and return control to the caller--and then pick
+up where they left off the next time they're called, as if they never
+left.
+
+X<coroutines>
+In PASM, coroutines are subroutine-like objects:
+
+=begin PASM
+
+  newsub P0, .Coroutine, _co_entry
+
+=end PASM
+
+The C<Coroutine> object has its own user stack, register frame stacks,
+control stack, and pad stack. The pad stack is inherited from the
+caller. The coroutine's control stack has the caller's control stack
+prepended, but is still distinct. When the coroutine invokes itself,
+it returns to the caller and restores the caller's context (basically
+swapping all stacks). The next time the coroutine is invoked, it
+continues to execute from the point at which it previously returned:
+
+=begin PASM
+
+    new_pad 0                # push a new lexical pad on stack
+    new P0, "Int"            # save one variable in it
+    set P0, 10
+    store_lex -1, "var", P0
+
+    newsub P0, .Coroutine, _cor
+                             # make a new coroutine object
+    saveall                  # preserve environment
+    invoke                   # invoke the coroutine
+    restoreall
+    print "back\n"
+    saveall
+    invoke                   # invoke coroutine again
+    restoreall
+    print "done\n"
+    pop_pad
+    end
+
+  _cor:
+    find_lex P1, "var"       # inherited pad from caller
+    print "in cor "
+    print P1
+    print "\n"
+    inc P1                   # var++
+    saveall
+    invoke                   # yield(  )
+    restoreall
+    print "again "
+    branch _cor              # next invocation of the coroutine
+
+=end PASM
+
+This prints out the result:
+
+  in cor 10
+  back
+  again in cor 11
+  done
+
+X<invoke opcode (PASM);coroutines and>
+The C<invoke> inside the coroutine is commonly referred to as
+I<yield>. The coroutine never ends. When it reaches the bottom, it
+branches back up to C<_cor> and executes until it hits C<invoke>
+again.
+
+The interesting part about this example is that the coroutine yields
+in the same way that a subroutine is called. This means that the
+coroutine has to preserve its own register values. This example uses
+C<saveall> but it could have only stored the registers the coroutine
+actually used. Saving off the registers like this works because
+coroutines have their own register frame stacks.
+
+=head3 Continuations
+
+Z<CHP-5-SECT-7.5>
+
+X<continuations>
+X<subroutines;continuations>
+A continuation is a subroutine that gets a complete copy of the
+caller's context, including its own copy of the call stack. Invoking a
+continuation starts or restarts it at the entry point:
+
+=begin PASM
+
+    new P1, "Int"
+    set P1, 5
+
+    newsub P0, .Continuation, _con
+  _con:
+    print "in cont "
+    print P1
+    print "\n"
+    dec P1
+    unless P1, done
+    invoke                        # P0
+  done:
+    print "done\n"
+    end
+
+=end PASM
+
+This prints:
+
+  in cont 5
+  in cont 4
+  in cont 3
+  in cont 2
+  in cont 1
+  done
+
+=head3 Evaluating a Code String
+
+Z<CHP-5-SECT-7.6>
+
+X<code strings, evaluating>
+This isn't really a subroutine operation, but it does produce a code
+object that can be invoked. In this case, it's a X<bytecode segment
+object> bytecode segment object.
+
+The first step is to get an assembler or compiler for the target
+language:
+
+=begin PASM
+
+  compreg P1, "PASM"
+
+=end PASM
+
+Within the Parrot interpreter there are currently three registered
+languages: C<PASM>, C<PIR>, and C<PASM1>. The first two are for parrot
+assembly language and parrot intermediate representation code. The third
+is for evaluating single statements in PASM. Parrot automatically adds
+an C<end> opcode at the end of C<PASM1> strings before they're
+compiled.
+
+This example places a bytecode segment object into the destination
+register C<P0> and then invokes it with C<invoke>:
+
+=begin PASM
+
+  compreg P1, "PASM1"                # get compiler
+  set S1, "in eval\n"
+  compile P0, P1, "print S1"
+  invoke                             # eval code P0
+  print "back again\n"
+  end
+
+=end PASM
+
+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.
+These compilers may be written in PASM or reside in shared libraries.
+
+=begin PASM
+
+  compreg "MyLanguage", P10
+
+=end PASM
+
+In this example the C<compreg> opcode registers the subroutine-like
+object C<P10> as a compiler for the language "MyLanguage". See
+F<examples/compilers> and F<examples/japh/japh16.pasm> for an external
+compiler in a shared library.
+
+=head2 Exceptions and Exception Handlers
+
+Z<CHP-5-SECT-8>
+
+X<exceptions>
+X<exception handlers>
+Exceptions provide a way of calling a piece of code outside the normal
+flow of control. They are mainly used for error reporting or cleanup
+tasks, but sometimes exceptions are just a funny way to branch from
+one code location to another one. The design and implementation of
+exceptions in Parrot isn't complete yet, but this section will give
+you an idea where we're headed.
+
+Exceptions are objects that hold all the information needed to handle
+the exception: the error message, the severity and type of the error,
+etc. The class of an exception object indicates the kind of exception
+it is.
+
+Exception handlers are derived from continuations. They are ordinary
+subroutines that follow the Parrot calling conventions, but are never
+explicitly called from within user code. User code pushes an exception
+handler onto the control stack with the C<set_eh>X<set_eh opcode (PASM)>
+opcode. The system calls the installed exception handler only when an
+exception is thrown (perhaps because of code that does division by
+zero or attempts to retrieve a global that wasn't stored.)
+
+=begin PASM
+
+    newsub P20, .ExceptionHandler, _handler
+    set_eh P20                  # push handler on control stack
+    null P10                    # set register to null
+    get_global P10, "none"     # may throw exception
+    clear_eh                    # pop the handler off the stack
+    #...
+
+  _handler:                     # if not, execution continues here
+    is_null P10, not_found      # test P10
+    #...
+
+=end PASM
+
+This example creates a new exception handler subroutine with the
+C<newsub> opcode and installs it on the control stack with the
+C<set_eh> opcode. It sets the C<P10> register to a null value (so it
+can be checked later) and attempts to retrieve the global variable
+named C<none>. If the global variable is found, the next statement
+(C<clear_eh>) pops the exception handler off the control stack and
+normal execution continues. If the C<get_global> call doesn't find
+C<none> it throws an exception by pushing an exception object onto the
+control stack. When Parrot sees that it has an exception, it pops it
+off the control stack and calls the exception handler C<_handler>.
+
+The first exception handler in the control stack sees every exception
+thrown. The handler has to examine the exception object and decide
+whether it can handle it (or discard it) or whether it should
+C<rethrow> the exception to pass it along to an exception handler
+deeper in the stack. The C<rethrow>X<rethrow opcode (PASM)> opcode is only
+valid in exception handlers. It pushes the exception object back onto
+the control stack so Parrot knows to search for the next exception
+handler in the stack. The process continues until some exception
+handler deals with the exception and returns normally, or until there
+are no more exception handlers on the control stack. When the system
+finds no installed exception handlers it defaults to a final action,
+which normally means it prints an appropriate message and terminates
+the program.
+
+When the system installs an exception handler, it creates a return
+continuation with a snapshot of the current interpreter context. If
+the exception handler just returns (that is, if the exception is
+cleanly caught) the return continuation restores the control stack
+back to its state when the exception handler was called, cleaning up
+the exception handler and any other changes that were made in the
+process of handling the exception.
+
+Exceptions thrown by standard Parrot opcodes (like the one thrown by
+C<get_global> above or by the C<throw> opcode) are always resumable,
+so when the exception handler function returns normally it continues
+execution at the opcode immediately after the one that threw the
+exception. Other exceptions at the run-loop level are also generally
+resumable.
+
+=begin PASM
+
+  new P10, 'Exception'    # create new Exception object
+  set P10, 'I die'        # set message attribute
+  throw P10               # throw it
+
+=end PASM
+
+Exceptions are designed to work with the Parrot calling conventions.
+Since the return addresses of C<bsr> subroutine calls and exception
+handlers are both pushed onto the control stack, it's generally a bad
+idea to combine the two.
+
+=head2 Events
+
+Z<CHP-5-SECT-9>
+
+An event is a notification that something has happened: a timer
+expired, an IO operation finished, a thread sent a message to
+another thread, or the user pressed C<Ctrl-C> to interrupt program
+execution.
+
+What all of these events have in common is that they arrive
+asynchronously. It's generally not safe to interrupt program flow at an
+arbitrary point and continue at a different position, so the event is
+placed in the
+interpreter's task queue. The run loops code regularly checks whether
+an event needs to be handled. Event handlers may be an internal piece
+of code or a user-defined event handler subroutine.
+
+Events are still experimental in Parrot, so the implementation and
+design is subject to change.
+
+=head3 Timers
+
+Z<CHP-5-SECT-9.1>
+
+C<Timer> objects are the replacement for Perl 5's C<alarm> handlers.
+They are also a significant improvement. Timers can fire once or
+repeatedly, and multiple timers can run independently. The precision
+of a timer is limited by the OS Parrot runs on, but it is always more
+fine-grained then a whole second. The final syntax isn't yet fixed, so
+please consult the documentation for examples.
+
+=head3 Signals
+
+Z<CHP-5-SECT-9.2>
+
+Signal handling is related to events. When Parrot gets a signal it
+needs to handle from the OS, it converts that signal into an event and
+broadcasts it to all running threads. Each thread independently
+decides if it's interested in this signal and, if so, how to respond to it.
+
+=begin PASM
+
+    newsub P20, .ExceptionHandler, _handler
+    set_eh P20                  # establish signal handler
+    print "send SIGINT:\n"
+    sleep 2                     # press ^C after you saw start
+    print "no SIGINT\n"
+    end
+  _handler:
+    .include "signal.pasm"      # get signal definitions
+    print "caught "
+    set I0, P5["type"]         # if _type is negative, the ...
+    neg I0, I0                  # ... negated type is the signal
+    ne I0, .SIGINT, nok
+    print "SIGINT\n"
+  nok:
+    end
+
+=end PASM
+
+This example creates a signal handler and pushes it on to the control
+stack. It then prompts the user to send a C<SIGINT> from the shell
+(this is usually C<Ctrl-C>, but it varies in different shells), and
+waits for 2 seconds. If the user doesn't send a SIGINT in 2 seconds
+the example just prints "no SIGINT" and ends. If the user does send a
+SIGINT, the signal handler catches it, prints out "caught SIGINT" and
+ends.N<Currently, only Linux installs a C<SIGINT> C<sigaction>
+handler, so this example won't work on other platforms.>
+
+=head2 Threads
+
+Z<CHP-5-SECT-10>
+
+Threads allow multiple pieces of code to run in parallel. This is
+useful when you have multiple physical CPUs to share the load of
+running individual threads. With a single processor, threads still
+provide the feeling of parallelism, but without any improvement in
+execution time. Even worse, sometimes using threads on a single
+processor will actually slow down your program.
+
+Still, many algorithms can be expressed more easily in terms of
+parallel running pieces of code and many applications profit from
+taking advantage of multiple CPUs. Threads can vastly simplify
+asynchronous programs like internet servers: a thread splits off,
+waits for some IO to happen, handles it, and relinquishes the
+processor again when it's done.
+
+Parrot compiles in thread support by default (at least, if the
+platform provides some kind of support for it). Unlike Perl 5,
+compiling with threading support doesn't impose any execution time
+penalty for a non-threaded program. Like exceptions and events,
+threads are still under development, so you can expect significant
+changes in the near future.
+
+As outlined in the previous chapter, Parrot implements three different
+threading models. (B<Note>:  As of version 1.0, the C<TQueue> PMC will be
+deprecated, rendering the following discussion obsolete.) The following
+example uses the third model, which takes advantage of shared data. It uses a
+C<TQueue> (thread-safe queue) object to synchronize the two parallel running
+threads. This is only a simple example to illustrate threads, not a typical
+usage of threads (no-one really wants to spawn two threads just to print out a
+simple string).
+
+=begin PASM
+
+    get_global P5, "_th1"              # locate thread function
+    new P2, "ParrotThread"              # create a new thread
+    find_method P0, P2, "thread3"       # a shared thread's entry
+    new P7, "TQueue"                    # create a Queue object
+    new P8, "Int"                       # and a Int
+    push P7, P8                         # push the Int onto queue
+    new P6, "String"                    # create new string
+    set P6, "Js nte artHce\n"
+    set I3, 3                           # thread function gets 3 args
+    invoke                              # _th1.run(P5,P6,P7)
+    new P2, "ParrotThread"              # same for a second thread
+    get_global P5, "_th2"
+    set P6, "utaohrPro akr"             # set string to 2nd thread's
+    invoke                              # ... data, run 2nd thread too
+    end                                 # Parrot joins both
+
+  .pcc_sub _th1:                        # 1st thread function
+  w1: sleep 0.001                       # wait a bit and schedule
+    defined I1, P7                      # check if queue entry is ...
+    unless I1, w1                       # ... defined, yes: it's ours
+    set S5, P6                          # get string param
+    substr S0, S5, I0, 1                # extract next char
+    print S0                            # and print it
+    inc I0                              # increment char pointer
+    shift P8, P7                        # pull item off from queue
+    if S0, w1                           # then wait again, if todo
+    invoke P1                           # done with string
+
+  .pcc_sub _th2:                        # 2nd thread function
+  w2: sleep 0.001
+    defined I1, P7                      # if queue entry is defined
+    if I1, w2                           # then wait
+    set S5, P6
+    substr S0, S5, I0, 1                # if not print next char
+    print S0
+    inc I0
+    new P8, "Int"                       # and put a defined entry
+    push P7, P8                         # onto the queue so that
+    if S0, w2                           # the other thread will run
+    invoke P1                           # done with string
+
+=end PASM
+
+This example creates a C<ParrotThread> object and calls its C<thread3>
+method, passing three arguments: a PMC for the C<_th1> subroutine in
+C<P5>, a string argument in C<P6>, and a C<TQueue> object in C<P7>
+containing a single integer. Remember from the earlier section
+"Parrot calling conventions" that registers 5-15
+hold the arguments for a subroutine or method call and C<I3> stores
+the number of arguments. The thread object is passed in C<P2>.
+
+This call to the C<thread3> method spawns a new thread to run the
+C<_th1> subroutine. The main body of the code then creates a second
+C<ParrotThread> object in C<P2>, stores a different subroutine in
+C<P5>, sets C<P6> to a new string value, and then calls the C<thread3>
+method again, passing it the same C<TQueue> object as the first
+thread. This method call spawns a second thread. The main body of code
+then ends, leaving the two threads to do the work.
+
+At this point the two threads have already started running. The first
+thread (C<_th1>) starts off by sleeping for a 1000th of a second. It
+then checks if the C<TQueue> object contains a value. Since it
+contains a value when the thread is first called, it goes ahead and
+runs the body of the subroutine. The first thing this does is shift
+the element off the C<TQueue>. It then pulls one character off a copy
+of the string parameter using C<substr>, prints the character,
+increments the current position (C<I0>) in the string, and loops back
+to the C<w1> label and sleeps. Since the queue doesn't have any
+elements now, the subroutine keeps sleeping.
+
+Meanwhile, the second thread (C<_th2>) also starts off by sleeping for
+a 1000th of a second. It checks if the shared C<TQueue> object
+contains a defined value but unlike the first thread it only continues
+sleeping if the queue does contain a value. Since the queue contains a
+value when the second thread is first called, the subroutine loops
+back to the C<w2> label and continues sleeping. It keeps sleeping
+until the first thread shifts the integer off the queue, then runs the
+body of the subroutine. The body pulls one character off a copy of the
+string parameter using C<substr>, prints the character, and increments
+the current position in the string. It then creates a new
+C<Int>, pushes it onto the shared queue, and loops back to the
+C<w2> label again to sleep. The queue has an element now, so the
+second thread keeps sleeping, but the first thread runs through its
+loop again.
+
+The two threads alternate like this, printing a character and marking
+the queue so the next thread can run, until there are no more
+characters in either string. At the end, each subroutine invokes the
+return continuation in C<P1> which terminates the thread. The
+interpreter waits for all threads to terminate in the cleanup phase
+after the C<end> in the main body of code.
+
+The final printed result (as you might have guessed) is:
+
+  Just another Parrot Hacker
+
+The syntax for threads isn't carved in stone and the implementation
+still isn't finished but as this example shows, threads are working
+now and already useful.
+
+Several methods are useful when working with threads. The C<join>
+method belongs to the C<ParrotThread> class. When it's called on a
+C<ParrotThread> object, the calling code waits until the thread
+terminates.
+
+=begin PASM
+
+    new P2, "ParrotThread"      # create a new thread
+    set I5, P2                  # get thread ID
+
+    find_method P0, P2, "join"  # get the join method...
+    invoke                      # ...and join (wait for) the thread
+    set P16, P5                 # the return result of the thread
+
+=end PASM
+
+C<kill> and C<detach> are interpreter methods, so you have to grab the
+current interpreter object before you can look up the method object.
+
+=begin PASM
+
+    set I5, P2                  # get thread ID of thread P2
+    getinterp P3                # get this interpreter object
+    find_method P0, P3, "kill"  # get kill method
+    invoke                      # kill thread with ID I5
+
+    find_method P0, P3, "detach"
+    invoke                      # detach thread with ID I5
+
+=end PASM
+
+By the time you read this, some of these combinations of statements
+and much of the threading syntax above may be reduced to a simpler set
+of opcodes.
+
+=head2 Loading Bytecode
+
+Z<CHP-5-SECT-11>
+
+In addition to running Parrot bytecode on the command-line, you can
+also load pre-compiled bytecode directly into your PASM source file.
+The C<load_bytecode>X<load_bytecode opcode (PASM)> opcode takes a single
+argument: the name of the bytecode file to load. So, if you create a
+file named F<file.pasm> containing a single subroutine:
+
+=begin PASM
+
+  # file.pasm
+  .sub _sub2:               # .sub stores a global sub
+     print "in sub2\n"
+     invoke P1
+
+=end PASM
+
+and compile it to bytecode using the C<-o> command-line switch:
+
+  $ parrot -o file.pbc file.pasm
+
+You can then load the compiled bytecode into F<main.pasm> and directly
+call the subroutine defined in F<file.pasm>:
+
+=begin PASM
+
+  # main.pasm
+  main:
+    load_bytecode "file.pbc"    # compiled file.pasm
+    get_global P0, "_sub2"
+    invokecc
+    end
+
+=end PASM
+
+The C<load_bytecode> opcode also works with source files, as long as
+Parrot has a compiler registered for that type of file:
+
+=begin PASM
+
+  # main2.pasm
+  main:
+    load_bytecode "file.pasm"  # PASM source code
+    set_global P0, "_sub2"
+    invokecc
+    end
+
+=end PASM
+
+Subroutines marked with C<:load> run as soon as they're loaded (before
+C<load_bytecode> returns), rather than waiting to be called. A
+subroutine marked with C<:main> will always run first, no matter what
+name you give it or where you define it in the file.
+
+=begin PASM
+
+  # file3.pasm
+  .sub :load                    # mark the sub as to be run
+    print "file3\n"
+    invoke P1                   # return
+
+  # main3.pasm
+  first:                        # first is never invoked
+    print "never\n"
+    invoke P1
+
+  .sub :main                    # because _main is marked as the
+    print "main\n"              # MAIN entry of program execution
+    load_bytecode "file3.pasm"
+    print "back\n"
+    end
+
+=end PASM
+
+This example uses both C<:load> and C<:main>. Because the C<main>
+subroutine is defined with C<:main> it will execute first even though
+another subroutine comes before it in the file. C<main> prints a
+line, loads the PASM source file, and then prints another line.
+Because C<_entry> in F<file3.pasm> is marked with C<:load> it runs
+before C<load_bytecode> returns, so the final output is:
+
+  main
+  file3
+  back
+
+=head2 Classes and Objects
+
+Z<CHP-5-SECT-12>
+
+This section revolves around one complete example that defines a
+class, instantiates objects, and uses them. The whole example is
+included at the end of the section.
+
+=head3 Class declaration
+
+Z<CHP-5-SECT-12.1>
+
+X<classes;in PASM>
+The C<newclass>X<newclass opcode (PASM)> opcode defines a new class.
+It takes two arguments, the name of the class and the destination
+register for the class PMC. All classes (and objects) inherit from the
+C<ParrotClass> PMCX<ParrotClass PMC>, which is the core of the Parrot
+object system.
+
+=begin PASM
+
+    newclass P1, "Foo"
+
+=end PASM
+
+To instantiate a new object of a particular class, you first look up
+the integer value for the class type with the C<find_type> opcode,
+then create an object of that type with the C<new> opcode:
+
+=begin PASM
+
+    find_type I1, "Foo"
+    new P3I I1
+
+=end PASM
+
+The C<new> opcode also checks to see if the class defines a
+method named "__init" and calls it if it exists.
+
+=head3 Attributes
+
+Z<CHP-5-SECT-12.2>
+
+X<attributes;in PASM>
+X<classes;attributes>
+The C<addattribute> opcode creates a slot in the class for an
+attribute (sometimes known as an I<instance variable>) and associates
+it with a name:
+
+=begin PASM
+
+    addattribute P1, ".i"                # Foo.i
+
+=end PASM
+
+This chunk of code
+from the C<__init> method looks up the position of the first
+attribute, creates a C<Int> PMC, and stores it as the first
+attribute:
+
+=begin PASM
+
+    classoffset I0, P2, "Foo"     # first "Foo" attribute of object P2
+    new P6, "Int"                 # create storage for the attribute
+    setattribute P2, I0, P6       # store the first attribute
+
+=end PASM
+
+The C<classoffset> opcodeX<classoffset opcode (PASM)> takes a PMC
+containing an object and the name of its class, and returns an integer
+index for the position of the first attribute. The C<setattribute>
+opcode uses the integer index to store a PMC value in one of the
+object's attribute slots. This example initializes the first
+attribute. The second attribute would be at C<I0 + 1>, the third
+attribute at C<I0 + 2>, etc:
+
+=begin PASM
+
+    inc I0
+    setattribute P2, I0, P7       # store next attribute
+    #...
+
+=end PASM
+
+There is also support for named parameters with fully qualified
+parameter names (although this is a little bit slower than getting
+the class offset once and accessing several attributes by index):
+
+=begin PASM
+
+    new P6, "Int"
+    setattribute P2, "Foo\x0.i", P6   # store the attribute
+
+=end PASM
+
+You use the same integer index to retrieve the value of an attribute.
+The C<getattribute>X<getattribute opcode (PASM)> opcode takes an object and
+an index as arguments and returns the attribute PMC at that position:
+
+=begin PASM
+
+    classoffset I0, P2, "Foo"         # first "Foo" attribute of object P2
+    getattribute P10, P2, I0          # indexed get of attribute
+
+=end PASM
+
+or
+
+=begin PASM
+
+    getattribute P10, P2, "Foo\x0.i"  # named get
+
+=end PASM
+
+To set the value of an attribute PMC, first retrieve it with
+C<getattribute> and then assign to the returned PMC. Because PMC
+registers are only pointers to values, you don't need to store the PMC
+again after you modify its value:
+
+=begin PASM
+
+    getattribute P10, P2, I0
+    set P10, I5
+
+=end PASM
+
+=head3 Methods
+
+Z<CHP-5-SECT-12.3>
+
+X<methods;in PASM>
+X<classes;methods>
+X<classes;namespaces>
+Methods in PASM are just subroutines installed in the namespace of the
+class. You define a method with the C<.pcc_sub> directive before the
+label:
+
+=begin PASM
+
+  .pcc_sub _half:                 # I5 = self."_half"()
+    classoffset I0, P2, "Foo"
+    getattribute P10, P2, I0
+    set I5, P10                   # get value
+    div I5, 2
+    invoke P1
+
+=end PASM
+
+This routine returns half of the value of the first attribute of the
+object. Method calls use the Parrot calling conventions so they always
+pass the I<invocant> object (often called I<self>) in C<P2>. Invoking
+the return continuation in C<P1> returns control to the caller.
+
+The C<.pcc_sub> directive automatically stores the subroutine as a
+global in the current namespace. The C<.namespace> directive sets the
+current namespace:
+
+=begin PASM
+
+  .namespace [ "Foo" ]
+
+=end PASM
+
+If the namespace is explicitly set to an empty string or key, then the
+subroutine is stored in the outermost namespace.
+
+The C<callmethodcc>X<callmethodcc opcode (PASM)> opcode makes a method
+call. It follows the Parrot calling conventions, so it expects to
+find the invocant object in C<P2>, the method object in C<P0>, etc. It
+adds one bit of magic, though. If you pass the name of the method in
+C<S0>, C<callmethodcc> looks up that method name in the invocant
+object and stores the method object in C<P0> for you:
+
+=begin PASM
+
+    set S0, "_half"             # set method name
+    set P2, P3                  # the object
+    callmethodcc                # create return continuation, call
+    print I5                    # result of method call
+    print "\n"
+
+=end PASM
+
+The C<callmethodcc> opcode also generates a return continuation and
+stores it in C<P1>. The C<callmethod> opcode doesn't generate a return
+continuation, but is otherwise identical to C<callmethodcc>. Just like
+ordinary subroutine calls, you have to preserve and restore any
+registers you want to keep after a method call. Whether you store
+individual registers, register frames, or half register frames is up
+to you.
+
+=head4 Overriding vtable functions
+
+Z<CHP-5-SECT-12.3.1>
+
+Every object inherits a default set of I<vtable> functions from the
+C<ParrotObject> PMC, but you can also override them with your own
+methods. The vtable functions have predefined names that start with a
+double underscore "__". The following code defines a method named
+C<__init> in the C<Foo> class that initializes the first attribute of
+the object with an integer:
+
+=begin PASM
+
+  .sub __init:
+    classoffset I0, P2, "Foo"     # lookup first attribute position
+    new P6, "Int"                 # create storage for the attribute
+    setattribute P2, I0, P6       # store the first attribute
+    invoke P1                     # return
+
+=end PASM
+
+Ordinary methods have to be called explicitly, but the vtable
+functions are called implicitly in many different contexts. Parrot
+saves and restores registers for you in these calls. The C<__init>
+method is called whenever a new object is constructed:
+
+=begin PASM
+
+    find_type I1, "Foo"
+    new P3, I1          # call __init if it exists
+
+=end PASM
+
+A few other vtable functions in the complete code example for this
+section are C<__set_integer_native>, C<__add>, C<__get_integer>,
+C<__get_string>, and C<__increment>. The C<set> opcode calls Foo's
+C<__set_integer_native> vtable function when its destination register
+is a C<Foo> object and the source register is a native integer:
+
+=begin PASM
+
+    set P3, 30          # call __set_integer_native method
+
+=end PASM
+
+The C<add> opcode calls Foo's C<__add> vtable function when it adds
+two C<Foo> objects:
+
+=begin PASM
+
+    new P4, I1          # same with P4
+    set P4, 12
+    new P5, I1          # create a new store for add
+
+    add P5, P3, P4      # __add method
+
+=end PASM
+
+The C<inc> opcode calls Foo's C<__increment> vtable function when it
+increments a C<Foo> object:
+
+=begin PASM
+
+    inc P3              # __increment
+
+=end PASM
+
+Foo's C<__get_integer> and C<__get_string> vtable functions are called
+whenever an integer or string value is retrieved from a C<Foo> object:
+
+=begin PASM
+
+    set I10, P5         # __get_integer
+    #...
+    print P5            # calls __get_string, prints 'fortytwo'
+
+=end PASM
+
+
+=head3 Inheritance
+
+Z<CHP-5-SECT-12.4>
+
+X<inheritance;in PASM>
+X<classes;inheritance>
+The C<subclass>X<subclass opcode (PASM)> opcode creates a new class that
+inherits methods and attributes from another class. It takes 3
+arguments: the destination register for the new class, a register
+containing the parent class, and the name of the new class:
+
+=begin PASM
+
+    subclass P3, P1, "Bar"
+
+=end PASM
+
+X<multiple inheritance; in PASM>
+For multiple inheritance, the C<addparent>X<addparent opcode (PASM)>
+opcode adds additional parents to a subclass.
+
+=begin PASM
+
+  newclass P4, "Baz"
+  addparent P3, P4
+
+=end PASM
+
+To override an inherited method, define a method with the same name in
+the namespace of the subclass. The following code overrides Bar's
+C<__increment> method so it decrements the value instead of
+incrementing it:
+
+=begin PASM
+
+  .namespace [ "Bar" ]
+
+  .sub __increment:
+    classoffset I0, P2, "Foo"     # get Foo's attribute slot offset
+    getattribute P10, P2, I0      # get the first Foo attribute
+    dec P10                       # the evil line
+    invoke P1
+
+=end PASM
+
+Notice that the attribute inherited from C<Foo> can only be looked up
+with the C<Foo> class name, not the C<Bar> class name. This preserves
+the distinction between attributes that belong to the class and
+inherited attributes.
+
+Object creation for subclasses is the same as for ordinary classes:
+
+=begin PASM
+
+    find_type I1, "Bar"
+    new P5, I1
+
+=end PASM
+
+Calls to inherited methods are just like calls to methods defined in
+the class:
+
+=begin PASM
+
+    set P5, 42                  # inherited __set_integer_native
+    inc P5                      # overridden __increment
+    print P5                    # prints 41 as Bar's __increment decrements
+    print "\n"
+
+    set S0, "_half"             # set method name
+    set P2, P5                  # the object
+    callmethodcc                # create return continuation, call
+    print I5
+    print "\n"
+
+=end PASM
+
+=head3 Additional Object Opcodes
+
+Z<CHP-5-SECT-12.5>
+
+The C<isa> and C<can> opcodes are also useful when working with
+objects. C<isa>X<isa opcode (PASM)> checks whether an object belongs to or
+inherits from a particular class. C<can>X<can opcode (PASM)> checks whether
+an object has a particular method. Both return a true or false value.
+
+=begin PASM
+
+    isa I0, P3, "Foo"           # 1
+    isa I0, P3, "Bar"           # 1
+    can I0, P3, "__add"         # 1
+
+=end PASM
+
+=head3 Complete Example
+
+Z<CHP-5-SECT-12.6>
+
+=begin PASM
+
+    newclass P1, "Foo"
+    addattribute P1, "$.i"                # Foo.i
+
+    find_type I1, "Foo"
+    new P3, I1          # call __init if it exists
+    set P3, 30          # call __set_integer_native method
+
+    new P4, I1          # same with P4
+    set P4, 12
+    new P5, I1          # create a new LHS for add
+
+    add P5, P3, P4      # __add method
+    set I10, P5         # __get_integer
+    print I10
+    print "\n"
+    print P5            # calls __get_string prints 'fortytwo'
+    print "\n"
+
+    inc P3              # __increment
+    add P5, P3, P4
+    print P5            # calls __get_string prints '43'
+    print "\n"
+
+    subclass P3, P1, "Bar"
+
+    find_type I1, "Bar"
+    new P3, I1
+
+    set P3, 100
+    new P4, I1
+    set P4, 200
+    new P5, I1
+
+    add P5, P3, P4
+    print P5                    # prints 300
+    print "\n"
+
+    set P5, 42
+    print P5                    # prints 'fortytwo'
+    print "\n"
+
+    inc P5
+    print P5                    # prints 41 as Bar's
+    print "\n"                  # __increment decrements
+
+    set S0, "_half"             # set method name
+    set P2, P3                  # the object
+    callmethodcc                # create return continuation, call
+    print I5                    # prints 50
+    print "\n"
+
+    end
+
+  .namespace [ "Foo" ]
+
+  .sub __init:
+    classoffset I0, P2, "Foo"     # lookup first attribute position
+    new P6, "Int"                 # create a store for the attribute
+    setattribute P2, I0, P6       # store the first attribute
+    invoke P1                     # return
+
+  .sub __set_integer_native:
+    classoffset I0, P2, "Foo"
+    getattribute P10, P2, I0
+    set P10, I5                   # assign passed in value
+    invoke P1
+
+  .sub __get_integer:
+    classoffset I0, P2, "Foo"
+    getattribute P10, P2, I0
+    set I5, P10                   # return value
+    invoke P1
+
+  .sub __get_string:
+    classoffset I0, P2, "Foo"
+    getattribute P10, P2, I0
+    set I5, P10
+    set S5, P10                   # get stringified value
+    ne I5, 42, ok
+    set S5, "fortytwo"            # or return modified one
+  ok:
+    invoke P1
+
+  .sub __increment:
+    classoffset I0, P2, "Foo"
+    getattribute P10, P2, I0      # as with all aggregates, this
+    inc P10                       # has reference semantics - no
+    invoke P1                     # setattribute needed
+
+  .sub __add:
+    classoffset I0, P2, "Foo"
+    getattribute P10, P2, I0      # object
+    getattribute P11, P5, I0      # argument
+    getattribute P12, P6, I0      # destination
+    add P12, P10, P11
+    invoke P1
+
+  .sub _half:                 # I5 = _half(self)
+    classoffset I0, P2, "Foo"
+    getattribute P10, P2, I0
+    set I5, P10                   # get value
+    div I5, 2
+    invoke P1
+
+
+  .namespace [ "Bar" ]
+
+  .sub __increment:
+    classoffset I0, P2, "Foo"     # get Foo's attribute slot offset
+    getattribute P10, P2, I0      # get the first Foo attribute
+    dec P10                       # the evil line
+    invoke P1
+
+=end PASM
+
+This example prints out:
+
+  42
+  fortytwo
+  43
+  300
+  fortytwo
+  41
+  50
+
+=cut
+
+# Local variables:
+#   c-file-style: "parrot"
+# End:
+# vim: expandtab shiftwidth=4:

Deleted: branches/headercleanup/docs/book/ch09_pct.pod
==============================================================================
--- branches/headercleanup/docs/book/ch09_pct.pod	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,712 +0,0 @@
-=pod
-
-=head1 PCT: Parrot Compiler Tools
-
-Z<CHP-9>
-
-So far we've talked a lot about low-level Parrot programming with
-PIR and PASM. However, the true power of Parrot is its ability to
-host programs written in high level languages such as Perl 6,
-Python, Ruby, Tcl, and PHP. In order to write code in these languages
-developers need there to be compilers that convert from the language
-into PIR or PASM (or even directly convert to Parrot Bytecode).
-People who have worked on compilers before may be anticipating us
-to use terms like "Lex and Yacc" here, but we promise that we won't.
-
-Instead of traditional lexical analyzers and parser-generators that
-have been the mainstay of compiler designers for decades, Parrot
-uses an advanced set of parsing tools called the Parrot Compiler
-Tools (PCT)X<Parrot Compiler Tools>. PCT 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. Instead of using
-traditional low-level languages to write compilers, we can use a
-modern dynamic language like Perl 6 to write it instead. On a more
-interesting note, this means that the Perl 6 compiler is itself
-being written in Perl 6, a mind-boggling process known as
-C<bootstrapping>.
-
-=head2 PCT Overview
-
-PCT is a collection of classes which handle the creation of a
-compiler and driver program for a high-level language. The
-C<PCT::HLLCompiler> class handles building the compiler front end
-while the C<PCT::Grammar>  and C<PCT::Grammar::Actions> classes handle
-building the parser and lexical analyzer. Creating a new HLL compiler
-is as easy as subclassing these three entities with methods specific
-to that high-level language.
-
-=head3 Grammars and Action Files
-
-Creating a compiler using PCT requires three basic files, plus any
-additional files needed to implement the languages logic and library:
-
-=over 4
-
-=item * A main file
-
-The main file should contain the C<:main> function that is the driver
-program for the compiler. Here, a new C<PCT::HLLCompiler> object is
-instantiated, libraries are loaded, and necessary special global
-variables are created. The driver program is typically written in PIR,
-although thankfully they tend to be very short. Most of the action
-happens elsewhere.
-
-=item * A parser file
-
-The grammar for the high level language is specified using the Perl 6
-grammar engine (PGE) and is stored in a C<.pg> file. This file should
-subclass the C<PCT::Grammar> class and implement all the necessary
-rules to successfully parse the language.
-
-=item * An actions file
-
-Actions files are written in NQP. They take match objects generated by
-the grammar file and convert them into an Abstract Syntax Tree (AST)
-X<Abstract Syntax Tree;Parrot Abstract Syntax Tree;AST;PAST>
-which is converted by PCT into PIR for compiling and execution.
-The PIR implementation of these AST trees and nodes is called the
-Parrot Abstract Syntax Tree (PAST).
-
-=back
-
-=head3 C<make_language_shell.pl>
-
-The Parrot repository contains a number of helpful utilities for doing
-some common development and building tasks with Parrot. Many of these
-utilities are currently written in Perl 5, though some run on Parrot
-directly, and in future releases more will be migrated to Parrot.
-
-One of the tools of use to new compiler designers and language implementers
-is C<make_language_shell.pl>. C<make_language_shell.pl> is a tool for
-automatically creating all the necessary stub files for creating a new
-compiler for Parrot. It generates the driver file, parser grammar and
-actions files, builtin functions stub file, makefile, and test harness.
-All of these are demonstrative stubs and will obviously need to be
-edited furiously or even completely overwritten, but they give a good idea
-of what is needed to start on development of the compiler.
-
-C<make_language_shell.pl> is designed to be run from within the Parrot
-repository file structure. It creates a subfolder in C</languages/>
-with the name of your new language implementation. Typically a new
-implementation of an existing language is not simply named after the
-language, but is given some other descriptive name to let users know it
-is only one implementation available. Consider the way Perl 5 distributions
-are named things like "Active Perl" or "Strawberry Perl", or how Python
-distributions might be "IronPython" or "VPython". If, on the other hand,
-you are implementing an entirely new language, you don't need to give it
-a fancy distribution name.
-
-=head3 Parsing Fundamentals
-
-Compilers typically consist of three components: The lexical analyzer,
-the parser, and the code generator C<This is an oversimplification, 
-compilers also may have semantic analyzers, symbol tables, optimizers,
-preprocessors, data flow analyzers, dependency analyzers, and resource
-allocators, among other components. All these things are internal to
-Parrot and aren't the concern of the compiler implementer. Plus, these
-are all well beyond the scope of this book>. The lexical analyzer converts
-the HLL input file into individual tokens. A token may consist of an
-individual punctuation mark("+"), an identifier ("myVar"), or a keyword
-("while"), or any other artifact that cannot be sensibly broken down. The
-parser takes a stream of these input tokens, and attempts to match them
-against a given pattern, or grammar. The matching process orders the input
-tokens into an abstract syntax tree (AST), which is a form that
-the computer can easily work with. This AST is passed to the code
-generator which converts it into code of the target language. For
-something like the GCC C compiler, the target language is machine code.
-For PCT and Parrot, the target language is PIR and PBC.
-
-Parsers come in two general varieties: Top-down and bottom-up. Top-down
-parsers start with a top-level rule, a rule which is supposed to
-represent the entire input. It attempts to match various combination of
-subrules until the entire input is matched. Bottom-down parsers, on the
-other hand, 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 itself is a top-down parser, although it also contains a bottom-up
-I<operator precedence> parser, for things like mathematical expressions
-where bottom-up methods are more efficient. We'll discuss both, and the
-methods for switching between the two, throughout this chapter.
-
-=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. Most commandline options are handled by PCT, but
-there are some behaviors that the driver program will want to
-override.
-
-PCT programs can, by default, be run in two ways: Interactive mode,
-which is run one statement at a time in the console, and file mode which
-loads and runs an entire file. For interactive mode, it is necessary
-to specify information about the prompt that's used and the environment
-that's expected. Help and error messages need to be written for the user
-too. 
-
-=head3 C<HLLCompiler> class
-
-
-=head2 Parrot Grammar Engine
-
-The Parrot Grammar Engine X<Parrot Grammar Engine;PGE> is an
-implementation of the Perl 6 grammar syntax in Parrot. The grammar
-engine in Perl 6 is much more advanced and flexible then the regular
-expression syntax of Perl 5. Since most other languages who implement
-regular expressions use a copy (or a subset) of Perl 5's regular
-expressions, PGE is much more powerful then those too.
-
-PGE uses a recursive descent algorithm N<it also uses an operator
-precedence parser, when you ask it nicely>which should be very familiar
-to users of the Perl 5 module C<Parse::RecDescent>. In fact, both were
-originally designed by the same developer, Damian Conway. Recursive
-Descent, for those who get into the algorithmic details, is a top-down
-parsing algorithm, unlike the bottom-up LALR algorithm used in parser-
-generators like Yacc and Bison. Most programmers won't notice the
-difference between the two for most applications, although there are
-some specific places where the behavior will be different.
-
-=head3 Rules and Actions
-
-A recursive descent parser, like the one used in PGE, is a top-down
-parser. This means it attempts to start at the highest-level rule and
-work its way down to the individual input tokens in order to match
-the given input. 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 is considered successful and the generated AST is
-delivered to the code generator for conversion into PIR.
-
-The parser is formed by creating a I<grammar>. Grammars consist of
-three primary components: rules, tokens, and protoregexes.
-
-=over 4
-
-=item * Rules
-
-Rules are the most basic grammar element. Rules may call subrules and
-may also contain arbitrary whitespace, which is ignored.
-
-=item * Tokens
-
-Tokens represent basic regular expressions. They may not call subrules
-and whitespace is treated literally. {{I don't think this is right, but
-I'm adding it here anyway as a placeholder -- Whiteknight}}
-
-=item * Protoregex
-
-A protoregex is like a rule or a token, except it can be overloaded
-dynamically.
-
-=back
-
-When a rule matches a sequence of input tokens, an associated method
-in NQP is called to convert that match into an AST node. This node
-is then inserted into the I<parse tree>.
-
-=head3 Basic Rules
-
-Let's start off with a simple rule:
-
- rule persons_name {
-    <first_name> <last_name>
- }
-
-We also define the two name tokens as:
-
- 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 "+" after the
-C<< <alpha> >> tag is a short way of saying "one or more". Our rule
-C<persons_name> would match something like C<Darth Vader> N<Actually,
-it matches a lot of things that aren't people's names>but wouldn't
-match something like C<C 3P0>. Notice that the rule above would match
-C<Jar Jar Binks>, but not the way you would expect: It would match the
-first "Jar" as C<< <first_name> >> and the second "Jar" as
-C<< <last_name> >> and wouldn't match "Binks" at all.
-
-In PGE, the top-level rule which starts the match process and must
-successfully match in order for the compiler to continue is always
-called C<TOP>. Without a TOP rule, your compiler won't do anything
-N<Actually, it will print out an error saying that you have no
-TOP rule, and then it will exit, but that isn't anything that we
-would want it to do>.
-
-Here's an example TOP rule that uses our definition for
-C<< <persons_name> >> above and matches a file that contains a comma-
-separated list of names:
-
- rule TOP {
-    [ <persons_name> ',' ]*
- }
-
-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.
-
-=head3 Calling Actions
-
-We haven't covered actions yet, but it's still important now to talk
-about how we will call them when we are ready. We call an action
-by inserting the C<{*}> token into the rule. When the C<{*}> rule is
-encountered, PGE calls the associated action method with the current
-match object as an argument. Let's take our C<persons_name> rule
-from above, and sprinkle 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 had a chance to match 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. Notice that
-if the match fails halfway through, we still call the actions where
-we succeeded, but do not call the actions after the failure. So, if
-we try to match the string "Leia", the action is called before the
-name and after the first name. When the rule tries to match the last
-name, it fails because no last name is provided, and the third action
-method call is never made.
-
-=head3 Alternations and Keys
-
-In addition to sub-rules, groups, and quantifiers, we also are able to
-take alternations between options that are either-or. The vertical bar
-token "|" can be used to distinguish between options where only one
-may match, Here's an example:
-
- rule hero {
-    ['Luke' | 'Leia'] 'Skywalker'
- }
-
-This rule will match either "Luke Skywalker" or "Leia Skywalker" but
-won't match "Luke Leia Skywalker" N<or anything else, for that matter>.
-With things like alternations, if we want to call an action method it's
-helpful to distinguish which combination we 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
-got matched.
-
-=head3 Warning: Left Recursion
-
-Getting into all the nitty-gritty theory behind parsers is well beyond
-the scope of this book. However, there is one potential pitfall that
-developers should be made aware of that is not immediately obvious.
-Like functions in ordinary procedural or functional languages, the
-methods in the PGE parser grammar can call themselves recursively.
-Consider the following 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>* '}'
- }
-
-Notice that 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 called
-I<recursion> X<Recursion>, and is part of where the "Recursive Descent"
-algorithm gets its name from.
-
-Now, let's look at a more direct example of a comma-separated list of
-integer digits to form an array. We can define this recursively as
-follows:
-
- rule list {
-     <list> ',' <digit> | <digit>
- }
-
-The intention is that if there is only one digit, we match the second
-option in the alternation, and if there are more digits we can match
-them recursively in the first alternation. However, take a close look
-at the insidious result. The recursive descent parser enters the C<list>
-rule. It's first option is to enter the list rule again, so it does.
-Recursive descent is a depth-first algorithm, and it will continue to
-descent down a particular path until it finds a successful match or a
-match failure. In this case, it matches C<list> and then it matches
-C<list> again, then it matches C<list> again, and so on and so forth.
-What we have created is an infinite loop pattern called I<left recursion>.
-
-Left recursion is caused when the left-most item of the left-most
-alternation is a recursion. The rule above can be easily resolved
-by writing:
-
- rule list {
-    <digit> | <list> ',' <digit>
- }
-
-Or even
-
- rule list {
-    <digit> ',' <list> | <digit>
- }
-
-Both of these two options make sure the left-most item in our rule is not
-a recursion, therefore preventing left recursion.
-
-Here is a more tricky example where the left recursion is hidden from
-view:
-
- rule term {
-    <expression> '*' <term> | <digit>
- }
-
- rule expression {
-    <term> '+' <expression> | <term>
- }
-
-This is a very limited subset of mathematical equations that we might like
-to write, and even in this small subset we have this 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> ...
-
-Left recursion is not the only problem you can run into with a recursive
-descent grammar, but it's one that's likely going to come up relatively
-often for new language designers, and one that is not always likely to
-generate useful error messages.
-
-=head3 Operator Precedence Parser
-
-Places where there are lots of little tokens in a statement, and where
-there are lots of possible options that a top-down parser will have to
-attempt can become relatively inefficient using PCT's recursive descent
-parser. Specifically, mathematical expressions are very open-ended and
-have forms that are difficult to anticipate. Consider the expression:
-
- a + b * c + d
-
-The recursive descent parser is going to have to recognize through
-significant trial and error how this statement should be parsed. For tasks
-like this, recursive descent parsers are not ideal, although a type of
-bottom-up parser called an I<operator precedence>
-X<Parser, Operator precedence> parser is. 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. The "things" in an
-equation are split into two subtypes: I<terms> and I<operators>. Operators
-themselves are split into a number of types including prefix (C<-a>),
-postfix (C<i++>), infix (C<x + y>), circumfix (C<[z]>), postcircumix
-(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. In the example above,
-the expression is parsed
-
- a + (b * c) + d
-
-This is because the C<*> operator has a higher precedence and therefore binds
-more tightly then the C<+> operator.
-
-To switch from the top-down recursive descent parser to the bottom-up
-operator precedence parser, a rule must be defined that is an C<optable>
-X<Parser, optable>:
-
- rule expression is optable { ... }
-
-The C<...> ellipses aren't an editorial shortcut, it's the Perl 6 operator
-that is used to define a function signature. The C<...> indicates that
-this is just a signature and that the actual guts of it will be filled in
-somewhere else. In this case, that "somewhere else" is in the definition of
-the optable role.
-
-=head3 Protofunction Definitions
-
-Protofunctions are used to define operators in the optable in the same way that
-rules and tokens are used throughout the rest of the grammar. A proto is a way
-of saying that the rule is overridable dynamically, and that it might be defined
-somewhere else. In this case, PCT takes information from the proto declaration
-and fills in the details for us. On another note, this also means that the HLL
-itself can modify its own grammar at run time, by overriding the proto
-definitions for its operator table. Some languages call this process "operator
-overloading".
-
-A proto is defined like this, taking some of our grammar rules above:
-
- 'proto' <proto_name> [ 'is' <property> ] '{' '...' '}'
-
-The name of the operator, listed as C<< <proto_name> >> above, contains both a
-location part and an identifier part. The location is one of the places where
-the operator can be located, 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. Some examples of
-this are:
-
- 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
-
-Protofunction definitions are function signatures which can be overridden via
-multimethod dispatch. This means functions can be written I<with the same name>
-as the rule to implement the behavior of the operator:
-
- rule infix:"+" { ... }
-
-And in a PIR file for built-in functions:
-
- .sub 'infix:+'
-    .param pmc a
-    .param pmc b
-    .local pmc c
-    c = a + b
-    .return(c)
- .end
-
-The question to ask then is "Why have an C<is subname()> property, if all
-operators can be defined as subroutines?" The answer is that 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 duplicating functionality, is there?
-
-The great thing about protos being overloadable is that you can specify
-different functions to call with different signatures:
-
- .sub 'infix:+' :multi('Integer', 'Integer')
-    ...
- .end
-
- .sub 'infix:+' :multi('CLispRatio', 'Number')
-    ...
- .end
-
- .sub 'infix:+' :multi('Perl6Double', 'PythonInteger')
-    ...
- .end
-
-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 for us all, this isn't the
-case because all these data types have those VTABLE interfaces that we can
-use. 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. This example was only a demonstration of the flexibility
-of the method.
-
-=head2 Actions and NQP
-
-Protofunction signatures aren't the only way to apply functions to rules
-matched by the parser. In fact, they might be the most primative because
-they use PIR code to implement the operator logic. Another way has been made
-available, by programming function actions in a language that's almost, but
-Not Quite Perl (NQP).
-
-NQP is a small language that's implemented as a subset of Perl 6 syntax and
-semantics. It's represents almost the smallest subset of the Perl 6 language
-necessary to implement the logic of a parser, although some developers have
-complained enough to get a few extra syntactic features added in above the
-bare minimum. NQP also happens to be a Perl 6 subset that's not entirely
-dissimilar from Perl 5, so Perl 5 programmers should not be too lost when
-writing NQP.
-
-=head3 NQP Basics
-
-Like Perl, NQP uses sigils to differentiate different types of variables.
-The C<$> sigil is used for scalars, C<@> is used for arrays, and C<%> is
-used for hashes N<Perl 6 aficionados will know that this isn't entirely
-true, but an in-depth look at Perl 6's context awareness is another topic
-for another book>. A "scalar" is really any single value, and can
-interchangably be given a string value, or an integer value, or an object.
-In NQP we can write things like this:
-
- $scalar := "This is a string"
- $x      := 123
- $pi     := 3.1415      # rounding
-
-Wait a minute, what's that weird C<:=> symbol? Why don't we just use the
-plain old vanilla C<=> sign? The problem is that I<NQP doesn't have it>.
-Remember how we mentioned that NQP was a minimal subset or Perl 6? The
-C<:=> operator is the I<bind> operator, that makes one value an alias
-C<C programmers and the like may call it a "reference"> for another. In
-most cases you can ignore the distinction between the two, but be warned
-that it's not a regular variable assignment.
-
-With hashes and arrays, it might be tempting to do a list assignment like
-we've all grown familiar with in Perl 5 and other dynamic languages:
-
- @small_integers := (1, 2, 3, 4);                        # WRONG!
- %leading_ladies := ("Leia" => "Starwars",
-                    "Trillian" => "Hitchhikers Guide"); # WRONG!
-
-Here's another little gotcha, NQP doesn't have list or hash context! If
-it's necessary to initialize a whole list at once, you can write:
-
- @small_integers[0] := 1;
- @small_integers[1] := 2;
- # ... And so on, and so forth ...
-
-It's also possible to assign a list in I<scalar context> as follows:
-
- $array_but_a_scalar := (1, 2, 3, 4)
-
-Remember how we said NQP was a bare-bones subset of Perl 6? If NQP had too
-many features, people would use it instead of Perl 6!
-
-=head3 Calling Actions From Rules
-
-When talking about grammar rules, we discussed the funny little C<{*}>
-symbol that calls an action. The action in question is an NQP method
-with the same name as the rule that calls it. NQP rules can be called
-with two different function signatures:
-
- method name ($/) { ... }
-
-And with a key:
-
- method name($/, $key) { ... }
-
-Here's an example that shows how the keys are used:
-
- rule cavepeople {
-      'Fred'  {*}    #= Caveman
-    | 'Wilma' {*}    #= Cavewoman
-    | 'Dino'  {*}    #= Dinosaur
- }
-
-And here is the rule that tells us 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 just a string that contains whatever text is on the line after
-the C<#=> symbol. If we don't have a C<#=> we don't use a C<$key> in our
-method.
-
-=head3 The Match Object C<$/>
-
-The match object C<$/> may have a funny-looking name, but it's a data
-structure that's all business. It's both a hash and an array. Plus,
-since it's a special variable it also gets a special shortcut syntax
-that can be used to save a few keystrokes:
-
- $/('Match_item')   is the same as  $<Match_item>
- $/[0]              is the same as  $[0]
-
-In the match object, each item in the hash is named after one of the items
-that we matched in the rule. So, if we have a file with input "C<X + 5>"
-and a rule:
-
- rule introductions {
-    <variable> <operator> <number>
- }
-
-Our match object is going to look like this: C<$/ = ("variable" => "x",
-"operator" => "+", "number" => "5")>
-
-If we have multiple values with the same name, or items with quantifiers
-C<*> or C<+> on it, those members of the match object may be arrays. So,
-if we have the input "A A A B B", and the following rule:
-
- rule letters {
-    <vowel>* <consonant>*
- }
-
-The match object will look like this (in Perl 5 syntax):
-
- $/ = ("vowel" => ["A", "A", "A"], "consonant" => ["B", "B"])
-
-We can get the number of matches in each group by casting it to a scalar
-using the C<$( )> operator:
-
- $($<vowel>) == 3
-
-=head3 Inline PIR
-
-Now that we know what the match object is, we can talk about the inline
-PIR functionality. In a PGE rule, we can use the C<{{ }}> double curly
-brackets to go into inline-PIR mode. Inside these brackets arbitrary
-PIR code can be executed to affect the operation of the parser. We can
-access the variable C<$/> directly in the grammar without having to
-jump into NQP, and actually examine and affect the values in it.
-
-=head3 PAST Nodes
-
-The job of NQP is to make abstract syntax trees, and the PCT implementation
-of syntax trees is implemented in the PAST class. There are many different
-types of objects in the PAST class, each of which represents a
-particular program construct. These constructs are relatively common and
-simple, but there are powerful levels of configuration that allow complicated
-programming structures to be represented.
-
-=head3 Making Trees
-
-Every action has the ability to create a PAST node that represents that
-action N<and additional PAST nodes, that are children of that node>. Calling
-the C<make> command on that node adds it into the growing PAST tree that
-PCT maintains. Once the C<TOP> rule matches successfully and returns,
-PCT takes that tree and starts the process of optimizing it and converting
-it into PIR and PBC code for execution.
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/headercleanup/docs/book/ch10_hlls.pod
==============================================================================
--- branches/headercleanup/docs/book/ch10_hlls.pod	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,266 +0,0 @@
-=pod
-
-=head1 HLLs and Interoperation
-
-Z<CHP-10>
-
-=head2 Parrot HLL Environment
-
-In the earliest days Parrot was designed to be the single-purpose backend
-for the Perl 6 language. It quickly blossomed beyond that, and now has a
-much grander purpose: to host all dynamic languages, and to host them
-together on a single platform. If we look back through the history of
-dynamic programming languages, they've had a more difficult time
-interoperating with each other then compiled languages have because
-compiled languages operate at the same machine-code level and typically
-can make use of the same application binary interface (ABI). With the
-right compiler settings, programs written in Visual Basic can interoperate
-with programs written in C N<On some systems anyway>, which can call
-functions written in C++, in Ada, Fortran, Pascal and so on. To try to mix
-two common dynamic languages, like Perl and Python, or Ruby and PHP, you
-would need to write some kind of custom "glue" function to try to include
-an interpreter object from one language as a library for another language,
-and then write code to try and get the parser for one to interact nicely
-with the parser for the other. It's a nightmare, frankly, and you don't
-see it happen too often.
-
-In Parrot, the situation is different because high level languages (HLL)
-are almost all written with the PCT tools, and are compiled to the same
-PIR and PBC code. Once compiled into PBC, a library written in any HLL
-language can be loaded and called by any other HLL N<Well, any HLL which
-supports loading libraries>. A language can have a syntax to include
-code snippets from other languages inline in the same file. We can write
-a binding for a popular library such as opengl or xlib once, and include
-that library into any language that needs it. Compare this to the current
-situation where a library like Gtk2 needs to have bindings for every
-language that wants to use it. In short, Parrot should make interoperation
-easier for everybody.
-
-This chapter is going to talk about HLLs, the way they operate, and the
-way they interoperate on Parrot.
-
-=head2 HLLs on Parrot
-
-=head2 Working with HLLs
-
-=head3 Fakecutables
-
-It's possible to turn compilers created with PCT into stand-alone
-executables that run without the Parrot executable. To do this, the
-compiler bytecode is linked together with a small driver program in
-C and the Parrot library, C<libparrot> X<libparrot>. These programs
-have been given a special name by the Parrot development community:
-I<fakecutables> X<fakecutables>. They're called fake because the PBC
-is not converted to native machine code like in a normal binary
-executable file, but instead is left in original PBC format.
-
-=head3 Compiler Objects
-
-The C<compreg> opcode has two forms that are used with HLL compilers. The
-first form stores an object as a compiler object to be retrieved later, and
-the second form retrieves a stored compiler object for a given language.
-The exact type of compiler object stored with C<compreg> can vary for each
-different language implementation, although most of the languages using PCT
-will have a common form. If a compiler object is in register C<$P0>, it can
-be stored using the following C<compreg> syntax:
-
-  compreg 'MyCompiler', $P0
-
-There are two built-in compiler objects: One for PIR and one for PASM. These
-two don't need to be stored first, they can simply be retrieved and used.
-The PIR and PASM compiler objects are Sub PMCs that take a single string
-argument and return an array PMC containing a list of all the compiled
-subroutines from the string. Other compiler objects might be different
-entirely, and may need to be used in different ways. A common convention is
-for a compiler to be an object with a C<compile> method. This is done with
-PCT-based compilers and for languages who use a stateful compiler.
-
-Compiler objects allow programs in Parrot to compile arbitrary code strings
-at runtime and execute them. This ability, to dynamically compile
-code that is represented in a string variable at runtime, is of fundamental
-importance to many modern dynamic languages.  Here's an example using
-the PIR compiler:
-
-  $P0 = compreg 'PIR'      # Get the compiler object
-  $P1 = $P0(code)          # Compile the string variable "code"
-
-The returned value from invoking the compiler object is an array of PMCs
-that contains the various executable subroutines from the compiled source.
-Here's a more verbose example of this:
-
-  $P0 = compreg 'PIR'
-  $S0 = << "END_OF_CODE"
-
-    .sub 'hello'
-       say 'hello world!'
-    .end
-  
-    .sub 'goodbye'
-       say 'goodbye world!'
-    .end
-
-  END_OF_CODE
-
-  $P1 = $P0($S0)
-  $P2 = $P1[0]      # The sub "hello"
-  $P3 = $P1[0]      # The sub "goodbye"
-
-  $P2()             # "hello world!"
-  $P3()             # "goodbye world!"
-
-Here's an example of a Read-Eval-Print-Loop (REPL) in PIR:
-
-  .sub main
-    $P0 = getstdin
-    $P1 = compreg 'PIR'
-    
-    loop_top:
-      $S0 = readline $P0
-      $S0 = ".sub '' :anon\n" . $S0
-      $S0 = $S0 . "\n.end\n"
-      $P2 = $P1($S0)
-      $P2()
-      
-      goto loop_top
-  .end
-
-The exact list of HLL packages installed on your system may vary. Some
-language compiler packages will exist as part of the Parrot source code
-repository, but many will be developed and maintained separately. In any
-case, these compilers will typically need to be loaded into your program
-first, before a compiler object for them can be retrieved and used.
-
-=head2 HLL Namespaces
-
-Let's take a closer look at namespaces then we have in previous chapters.
-Namespaces, as we mentioned before can be nested to an arbitrary depth
-starting with the root namespace. In practice, the root namespace is
-not used often, and is typically left for use by the Parrot internals.
-Directly beneath the root namespace are the X<HLL Namespaces> HLL
-Namespaces, named after the HLLs that the application software is written
-in. HLL namespaces are all lower-case, such as "perl6", or "cardinal",
-or "pynie". By sticking to this convention, multiple HLL compilers can
-operate on Parrot simultaneously while staying completely oblivious to
-each other.
-
-=head2 HLL Mapping
-
-HLL mapping enables Parrot to use a custom data type for internal operations
-instead of using the normal built-in types. Mappings can be created with the
-C<"hll_map"> method of the interpreter PMC.
-
-  $P0 = newclass "MyNewClass"         # New type
-  $P1 = getclass "ResizablePMCArray"  # Built-in type
-  $P2 = getinterp
-  $P2.'hll_map'($P1, $P0)
-
-With the mapping in place, anywhere that Parrot would have used a
-ResizablePMCArray it now uses a MyNewClass object instead. Here's one example
-of this:
-
-  .sub 'MyTestSub'
-      .param pmc arglist :slurpy   # A MyNewClass array of args
-      .return(arglist)
-  .end
-
-=head2 Interoperability Guidelines
-
-=head3 Libraries and APIs
-
-As a thought experiment, imagine a library written in Common Lisp that
-uses Common Lisp data types. We like this library, so we want to include
-it in our Ruby project and call the functions from Ruby. Immediately
-we might think about writing a wrapper to convert parameters from Ruby
-types into Common Lisp types, and then to convert the Common Lisp return
-values back into Ruby types. This seems sane, and it would probably even
-work well. Now, expand this to all the languages on Parrot. We would need
-wrappers or converters to allow every pair of languages to communicate,
-which requires C<N^2> libraries to make it work! As the number of languages
-hosted on the platform increases, this clearly becomes an untenable
-solution.
-
-So, what do we do? How do we make very different languages like Common
-Lisp, Ruby, Scheme, PHP, Perl and Python to interoperate with each other
-at the data level? There are two ways:
-
-=over 4
-
-=item * VTable methods
-
-VTable methods are the standard interface for PMC data types, and all PMCs
-have them. If the PMCs were written properly to satisfy this interface
-all the necessary information from those PMCs. Operate on the PMCs at the
-VTable level, and we can safely ignore the implementation details of them.
-
-=item * Class Methods
-
-If a library returns data in a particular format, the library reuser should
-know, understand, and make use of that format. Classes written in other
-languages will have a whole set of documented methods to be interfaced with
-and the reuser of those classes should use those methods. This only works,
-of course, in HLLs that allow object orientation and classes and methods,
-so for languages that don't have this the vtable interface should be used
-instead.
-
-=back
-
-=head3 Mixing and Matching Datatypes
-
-=head2 Linking and Embedding
-
-Not strictly a topic about HLLs and their interoperation, but it's important
-for us to also mention another interesting aspect of Parrot: Linking and
-embedding. We've touched on one related topic above, that of creating
-the compiler fakecutables. The fakecutables contain a link to C<libparrot>,
-which contains all the necessary guts of Parrot. When the fakecutable is
-executed, a small driver program loads the PBC data into libparrot through
-its API functions. The Parrot executable is just one small example of how
-Parrot's functionality can be implemented, and we will talk about a few other
-ways here too.
-
-=head3 Embedding Parrot
-
-C<libparrot> is a library that can be statically or dynamically linked
-to any other executable program that wants to use it. This linking process
-is known as I<embedding parrot>, and is a great way to interoperate
-
-=head3 Creating and Interoperating Interpreters
-
-Parrot's executable, which is the interface which most users are going
-to be familiar with, uses a single interpreter structure to perform a
-single execution task. However, this isn't the only supported structural
-model that Parrot supports. In fact, the interpreter structure is not a
-singleton, and multiple interpreters can be created by a single program.
-This allows separate tasks to be run in separate environments, which can
-be very helpful if we are writing programs and libraries in multiple
-languages. Interpreters can communicate and share data between each other,
-and can run independently from others in the same process.
-
-=head3 Small, Toy, and Domain-Specific Languages
-
-How many programs are out there with some sort of scripting capability?
-You can probably name a few off the top of your head with at least some
-amount of scripting or text-based commands. In developing programs like
-this, typically it's necessary to write a custom parser for the input
-commands, and a custom execution engine to make the instructions do what
-they are intended to do. Instead of doing all this, why not embed an
-instance of Parrot in the program, and let Parrot handle the parsing
-and executing details?
-
-Small scripting components which are not useful in a general sense like
-most programming languages, and are typically limited to use in very
-specific environments (such as within a single program) are called
-I<Domain-Specific Languages> (DSL). DSLs are a very popular topic because
-a DSL allows developers to create a custom language that makes dealing
-with a given problem space or data set very easy. Parrot and its suite
-of compiler tools in turn make creating the DSLs very easy. It's all
-about ease of use.
-
-=head3 Parrot API
-
-=cut
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Copied: branches/headercleanup/docs/book/ch10_opcode_reference.pod (from r38131, trunk/docs/book/ch10_opcode_reference.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/ch10_opcode_reference.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/ch10_opcode_reference.pod)
@@ -0,0 +1,2940 @@
+=pod
+
+=head1 Instruction Reference
+
+Z<CHP-13>
+
+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 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 ParrotIO 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 ParrotIO 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 13-1.
+
+=begin table picture Interpinfo flags
+
+Z<CHP-13-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 ParrotIO 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<setstdout opcode (PASM)>
+
+  setstderr R<DEST>
+  setstdout R<DEST>
+
+Set a ParrotIO 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 13-2.
+
+I<Arguments: IR, S, I or IR, I, I>
+
+=begin table picture Stat arguments
+
+Z<CHP-13-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 13-3.
+
+=begin table picture Stringinfo arguments
+
+Z<CHP-13-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 ParrotIO 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:

Copied: branches/headercleanup/docs/book/ch11_directive_reference.pod (from r38131, trunk/docs/book/ch11_directive_reference.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/ch11_directive_reference.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/ch11_directive_reference.pod)
@@ -0,0 +1,227 @@
+=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/headercleanup/docs/book/ch11_pmcs.pod
==============================================================================
--- branches/headercleanup/docs/book/ch11_pmcs.pod	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,237 +0,0 @@
-=pod
-
-=head1 PMCs
-
-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 litte 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/headercleanup/docs/book/ch12_opcodes.pod
==============================================================================
--- branches/headercleanup/docs/book/ch12_opcodes.pod	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,233 +0,0 @@
-=pod
-
-=head1 Opcodes
-
-Z<CHP-12>
-
-The smallest executable component is not the compilation unit or even the
-subroutine, but is actually the 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". Of course the list of things
-that qualify as "low-level" in Parrot can be pretty advanced compared to the
-functionality supplied by regular assembly language 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. The difference is that Parrot's opcodes can perform some
-very complex and high-level tasks that each may take many execution cycles
-for the average hardware processor. Also, Parrot's opcodes can be
-dynamically loaded in from a special library file called a I<dynop
-library>. We'll talk about dynops a little bit later.
-
-=head3 Opcode naming
-
-To the PIR and PASM programmers, opcodes appear to be polymorphic. That
-is, some opcodes appear to have multiple argument formats. This is just an
-illusion, however. Parrot opcodes are not polymorphic, although certain
-features enable it to appear that way. Different argument list formats
-are detected during parsing and translated into separate, and unique,
-opcode names. 
-
-=head3 Opcode Multiple Dispatch
-
-=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. This script is very similar to that used to
-define PMCs. The C<INTERP> constant, for instance, is always available
-in the opcodes like they are in VTABLE and METHOD declarations. Unlike
-VTABLEs and METHODs, opcodes are 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 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
-
-=item * NUM
-
-=item * STR
-
-=item * PMC
-
-=item * KEY
-
-=item * INTKEY
-
-=item * LABEL
-
-=back
-
-In addition to these types, you need to specify the direction that data is
-moving through that parameter:
-
-=over 4
-
-=item * in
-
-=item * out
-
-=item * inout
-
-=item * invar
-
-=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()
-
-If C<NEXT> contains the address of the next opcode in memory. You don't
-need to call C<goto NEXT()>, however, because the default behavior for
-all opcodes is to automatically jump to the next opcode in the program
-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 writte 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:

Copied: branches/headercleanup/docs/book/ch12_operator_reference.pod (from r38131, trunk/docs/book/ch12_operator_reference.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/ch12_operator_reference.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/ch12_operator_reference.pod)
@@ -0,0 +1,299 @@
+=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:

Deleted: branches/headercleanup/docs/book/ch13_reference.pod
==============================================================================
--- branches/headercleanup/docs/book/ch13_reference.pod	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,3639 +0,0 @@
-=pod
-
-=head1 Parrot Reference
-
-Z<CHP-13>
-
-This chapter contains a condensed list of PASM opcodes, PIR directives
-and instructions, and Parrot command-line options, sorted alphabetically
-for easy reference. Any PASM opcode is valid in PIR code, so if you're
-looking up PIR syntax you should check A<CHP-10-SECT-1>"PASM Opcodes",
-A<CHP-10-SECT-2>"PIR Directives", and A<CHP-10-SECT-3>"PIR
-Instructions".
-
-=head2 PASM Opcodes
-
-Z<CHP-13-SECT-1>
-
-X<PASM (Parrot assembly language);opcodes, quick reference>
-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)>
-
-  bor 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 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 conv_*
-
-  conv_i1     R<DEST>, R<VAL>
-  conv_i1_ovf R<DEST>, R<VAL>
-
-Convert value to integer or number of given type C<i1>, C<i2>, C<i4>, C<i8>,
-C<u1>, C<u2>, C<u4>, C<r4>, C<r8>. C<i> corresponds to a signed integer,
-C<u> to an unsigned integer and C<r> to a float; the number indicates the
-size (in bytes) of the type. The variants with C<_ovf> throw an exception
-if the conversion would overflow.
-
-=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 ParrotIO 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 ParrotIO 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
-A<CHP-10-TABLE-1>Table 11-1.
-
-=begin table picture Interpinfo flags
-
-Z<CHP-13-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 ParrotIO 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 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 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 spanw
-
-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 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 A<CHP-10-TABLE-2>Table 11-2.
-
-=begin table picture Stringinfo arguments
-
-Z<CHP-13-TABLE-2>
-
-=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 sublass 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 ParrotIO 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>
-
-=head2 PIR Directives
-
-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>.
-
-=head2 PIR Instructions
-
-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.
-
-
-=head2 Parrot 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>.
-
-=head3 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.
-
-=head3 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
-A<CHP-10-TABLE-3>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
-A<CHP-10-TABLE-4>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
-
-=head3 Bytecode Interpreter 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 --bounds-checks
-
-Activate bounds checking. This also runs with the I<slow core> as a
-side effect.
-
-=item --fast-core
-
-Run with the I<fast core>.
-
-=item --computed-goto-core
-
-Run the I<computed goto core> (CGoto).
-
-=item --jit-core
-
-Run with the I<JIT core> if available.
-
-=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 --CGP-core
-
-Run with the I<CGoto-Prederefed> core.
-
-=item --switched-core
-
-Run with the I<Switched 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:

Copied: branches/headercleanup/docs/book/draft/chXX_hlls.pod (from r38131, trunk/docs/book/draft/chXX_hlls.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/draft/chXX_hlls.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/draft/chXX_hlls.pod)
@@ -0,0 +1,266 @@
+=pod
+
+=head1 HLLs and Interoperation
+
+Z<CHP-10>
+
+=head2 Parrot HLL Environment
+
+In the earliest days Parrot was designed to be the single-purpose backend
+for the Perl 6 language. It quickly blossomed beyond that, and now has a
+much grander purpose: to host all dynamic languages, and to host them
+together on a single platform. If we look back through the history of
+dynamic programming languages, they've had a more difficult time
+interoperating with each other then compiled languages have because
+compiled languages operate at the same machine-code level and typically
+can make use of the same application binary interface (ABI). With the
+right compiler settings, programs written in Visual Basic can interoperate
+with programs written in C N<On some systems anyway>, which can call
+functions written in C++, in Ada, Fortran, Pascal and so on. To try to mix
+two common dynamic languages, like Perl and Python, or Ruby and PHP, you
+would need to write some kind of custom "glue" function to try to include
+an interpreter object from one language as a library for another language,
+and then write code to try and get the parser for one to interact nicely
+with the parser for the other. It's a nightmare, frankly, and you don't
+see it happen too often.
+
+In Parrot, the situation is different because high level languages (HLL)
+are almost all written with the PCT tools, and are compiled to the same
+PIR and PBC code. Once compiled into PBC, a library written in any HLL
+language can be loaded and called by any other HLL N<Well, any HLL which
+supports loading libraries>. A language can have a syntax to include
+code snippets from other languages inline in the same file. We can write
+a binding for a popular library such as opengl or xlib once, and include
+that library into any language that needs it. Compare this to the current
+situation where a library like Gtk2 needs to have bindings for every
+language that wants to use it. In short, Parrot should make interoperation
+easier for everybody.
+
+This chapter is going to talk about HLLs, the way they operate, and the
+way they interoperate on Parrot.
+
+=head2 HLLs on Parrot
+
+=head2 Working with HLLs
+
+=head3 Fakecutables
+
+It's possible to turn compilers created with PCT into stand-alone
+executables that run without the Parrot executable. To do this, the
+compiler bytecode is linked together with a small driver program in
+C and the Parrot library, C<libparrot> X<libparrot>. These programs
+have been given a special name by the Parrot development community:
+I<fakecutables> X<fakecutables>. They're called fake because the PBC
+is not converted to native machine code like in a normal binary
+executable file, but instead is left in original PBC format.
+
+=head3 Compiler Objects
+
+The C<compreg> opcode has two forms that are used with HLL compilers. The
+first form stores an object as a compiler object to be retrieved later, and
+the second form retrieves a stored compiler object for a given language.
+The exact type of compiler object stored with C<compreg> can vary for each
+different language implementation, although most of the languages using PCT
+will have a common form. If a compiler object is in register C<$P0>, it can
+be stored using the following C<compreg> syntax:
+
+  compreg 'MyCompiler', $P0
+
+There are two built-in compiler objects: One for PIR and one for PASM. These
+two don't need to be stored first, they can simply be retrieved and used.
+The PIR and PASM compiler objects are Sub PMCs that take a single string
+argument and return an array PMC containing a list of all the compiled
+subroutines from the string. Other compiler objects might be different
+entirely, and may need to be used in different ways. A common convention is
+for a compiler to be an object with a C<compile> method. This is done with
+PCT-based compilers and for languages who use a stateful compiler.
+
+Compiler objects allow programs in Parrot to compile arbitrary code strings
+at runtime and execute them. This ability, to dynamically compile
+code that is represented in a string variable at runtime, is of fundamental
+importance to many modern dynamic languages.  Here's an example using
+the PIR compiler:
+
+  $P0 = compreg 'PIR'      # Get the compiler object
+  $P1 = $P0(code)          # Compile the string variable "code"
+
+The returned value from invoking the compiler object is an array of PMCs
+that contains the various executable subroutines from the compiled source.
+Here's a more verbose example of this:
+
+  $P0 = compreg 'PIR'
+  $S0 = << "END_OF_CODE"
+
+    .sub 'hello'
+       say 'hello world!'
+    .end
+  
+    .sub 'goodbye'
+       say 'goodbye world!'
+    .end
+
+  END_OF_CODE
+
+  $P1 = $P0($S0)
+  $P2 = $P1[0]      # The sub "hello"
+  $P3 = $P1[0]      # The sub "goodbye"
+
+  $P2()             # "hello world!"
+  $P3()             # "goodbye world!"
+
+Here's an example of a Read-Eval-Print-Loop (REPL) in PIR:
+
+  .sub main
+    $P0 = getstdin
+    $P1 = compreg 'PIR'
+    
+    loop_top:
+      $S0 = readline $P0
+      $S0 = ".sub '' :anon\n" . $S0
+      $S0 = $S0 . "\n.end\n"
+      $P2 = $P1($S0)
+      $P2()
+      
+      goto loop_top
+  .end
+
+The exact list of HLL packages installed on your system may vary. Some
+language compiler packages will exist as part of the Parrot source code
+repository, but many will be developed and maintained separately. In any
+case, these compilers will typically need to be loaded into your program
+first, before a compiler object for them can be retrieved and used.
+
+=head2 HLL Namespaces
+
+Let's take a closer look at namespaces then we have in previous chapters.
+Namespaces, as we mentioned before can be nested to an arbitrary depth
+starting with the root namespace. In practice, the root namespace is
+not used often, and is typically left for use by the Parrot internals.
+Directly beneath the root namespace are the X<HLL Namespaces> HLL
+Namespaces, named after the HLLs that the application software is written
+in. HLL namespaces are all lower-case, such as "perl6", or "cardinal",
+or "pynie". By sticking to this convention, multiple HLL compilers can
+operate on Parrot simultaneously while staying completely oblivious to
+each other.
+
+=head2 HLL Mapping
+
+HLL mapping enables Parrot to use a custom data type for internal operations
+instead of using the normal built-in types. Mappings can be created with the
+C<"hll_map"> method of the interpreter PMC.
+
+  $P0 = newclass "MyNewClass"         # New type
+  $P1 = getclass "ResizablePMCArray"  # Built-in type
+  $P2 = getinterp
+  $P2.'hll_map'($P1, $P0)
+
+With the mapping in place, anywhere that Parrot would have used a
+ResizablePMCArray it now uses a MyNewClass object instead. Here's one example
+of this:
+
+  .sub 'MyTestSub'
+      .param pmc arglist :slurpy   # A MyNewClass array of args
+      .return(arglist)
+  .end
+
+=head2 Interoperability Guidelines
+
+=head3 Libraries and APIs
+
+As a thought experiment, imagine a library written in Common Lisp that
+uses Common Lisp data types. We like this library, so we want to include
+it in our Ruby project and call the functions from Ruby. Immediately
+we might think about writing a wrapper to convert parameters from Ruby
+types into Common Lisp types, and then to convert the Common Lisp return
+values back into Ruby types. This seems sane, and it would probably even
+work well. Now, expand this to all the languages on Parrot. We would need
+wrappers or converters to allow every pair of languages to communicate,
+which requires C<N^2> libraries to make it work! As the number of languages
+hosted on the platform increases, this clearly becomes an untenable
+solution.
+
+So, what do we do? How do we make very different languages like Common
+Lisp, Ruby, Scheme, PHP, Perl and Python to interoperate with each other
+at the data level? There are two ways:
+
+=over 4
+
+=item * VTable methods
+
+VTable methods are the standard interface for PMC data types, and all PMCs
+have them. If the PMCs were written properly to satisfy this interface
+all the necessary information from those PMCs. Operate on the PMCs at the
+VTable level, and we can safely ignore the implementation details of them.
+
+=item * Class Methods
+
+If a library returns data in a particular format, the library reuser should
+know, understand, and make use of that format. Classes written in other
+languages will have a whole set of documented methods to be interfaced with
+and the reuser of those classes should use those methods. This only works,
+of course, in HLLs that allow object orientation and classes and methods,
+so for languages that don't have this the vtable interface should be used
+instead.
+
+=back
+
+=head3 Mixing and Matching Datatypes
+
+=head2 Linking and Embedding
+
+Not strictly a topic about HLLs and their interoperation, but it's important
+for us to also mention another interesting aspect of Parrot: Linking and
+embedding. We've touched on one related topic above, that of creating
+the compiler fakecutables. The fakecutables contain a link to C<libparrot>,
+which contains all the necessary guts of Parrot. When the fakecutable is
+executed, a small driver program loads the PBC data into libparrot through
+its API functions. The Parrot executable is just one small example of how
+Parrot's functionality can be implemented, and we will talk about a few other
+ways here too.
+
+=head3 Embedding Parrot
+
+C<libparrot> is a library that can be statically or dynamically linked
+to any other executable program that wants to use it. This linking process
+is known as I<embedding parrot>, and is a great way to interoperate
+
+=head3 Creating and Interoperating Interpreters
+
+Parrot's executable, which is the interface which most users are going
+to be familiar with, uses a single interpreter structure to perform a
+single execution task. However, this isn't the only supported structural
+model that Parrot supports. In fact, the interpreter structure is not a
+singleton, and multiple interpreters can be created by a single program.
+This allows separate tasks to be run in separate environments, which can
+be very helpful if we are writing programs and libraries in multiple
+languages. Interpreters can communicate and share data between each other,
+and can run independently from others in the same process.
+
+=head3 Small, Toy, and Domain-Specific Languages
+
+How many programs are out there with some sort of scripting capability?
+You can probably name a few off the top of your head with at least some
+amount of scripting or text-based commands. In developing programs like
+this, typically it's necessary to write a custom parser for the input
+commands, and a custom execution engine to make the instructions do what
+they are intended to do. Instead of doing all this, why not embed an
+instance of Parrot in the program, and let Parrot handle the parsing
+and executing details?
+
+Small scripting components which are not useful in a general sense like
+most programming languages, and are typically limited to use in very
+specific environments (such as within a single program) are called
+I<Domain-Specific Languages> (DSL). DSLs are a very popular topic because
+a DSL allows developers to create a custom language that makes dealing
+with a given problem space or data set very easy. Parrot and its suite
+of compiler tools in turn make creating the DSLs very easy. It's all
+about ease of use.
+
+=head3 Parrot API
+
+=cut
+
+# Local variables:
+#   c-file-style: "parrot"
+# End:
+# vim: expandtab shiftwidth=4:

Copied: branches/headercleanup/docs/book/draft/chXX_library.pod (from r38131, trunk/docs/book/draft/chXX_library.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/draft/chXX_library.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/draft/chXX_library.pod)
@@ -0,0 +1,107 @@
+=pod
+
+Z<CHP-6>
+
+=head1 PIR Standard Library
+
+PIR and PASM are both very low-level languages by any programming
+standards, even though they support some important features of
+high-level dynamic languages,and PIR has some symbolic syntax features.
+Important re-occurring programming tasks in these languages have been
+extracted out into a series of runtime libraries to help make these
+tasks easier. Libraries written in PIR or PASM can be easily included
+and used from any of the high-level language compilers that target
+Parrot, in addition to being used in the Parrot test suite and
+PIR/PASM code generators like PCT.
+
+Some modules, such as F<pcre.pir> and F<postgres.pir> are NCI wrappers
+for common compiled shared libraries.
+
+From the Parrot repository, there are a number of premade libraries in
+F<runtime/library/>, and several generated libraries in F<runtime/include>
+that can be used by Parrot hackers and HLL-implementers alike, if needed.
+This chapter is going to give a brief overview of some of these libraries
+and how they are used.
+
+=head1 Loading and Using Libraries
+
+Libraries are precompiled code files that can be loaded into Parrot. There
+are ways to load a library into Parrot, each with a slightly different
+mechanism. The C<.loadlib> PIR directive causes the library file to be loaded
+at compile-time. The C<load_lib> opcode causes the library to be loaded
+dynamically at runtime.
+
+=head1 General Parrot Libraries
+
+=head2 F<Config.fpmc>
+
+C<Config.fpmc> is generated during the build process. The file defines a
+hash PMC that contains information about the system where Parrot was
+built. By accessing the data in this PMC, you can determine how Parrot
+was compiled and what features and libraries it has available.
+
+=head1 Perl-Inspired Libraries
+
+Since the Parrot project started as the internals of the Perl 6 development
+project, and since a number of Perl hackers are very active in Parrot,
+several libraries in the Parrot runtime are based on common Perl 5 libraries.
+
+=head2 F<Dumper.pir> and F<Data/Dumper.pir>
+
+Perl 5 had C<Data::Dumper>, that would print out the complete contents and
+structure of any arbitrary complex data type. This is useful in a number of
+cases, with debugging not the least of them. It's good to verify that
+complicated nested data structures are being composed and accessed in the
+manner that the programmer intends.
+
+=head1 NCI Wrapper Libraries
+
+Parrot does not intend to reinvent any wheels, and there is lots of important
+functionality encapsulated in various libraries that Parrot does not copy.
+Instead of having to reimplement all sorts of libraries for Parrot, Parrot
+provides the NCI interface to work with these libraries directly. PIR or
+PASM wrapper libraries are provided to create an interface that programs
+running on Parrot can use to access functionality in these libraries.
+
+Notice that these libraries are depending on having the compiled libraries
+they reference already installed on your system. Many of these are detected
+during the configuration process. If you do not have these libraries
+installed, you cannot call the modules discussed here. We will give some
+information about how to find and install the libraries, however.
+
+Notice that this is only a partial list of wrapper libraries that come
+bundled with the Parrot repository. Additional library wrappers may be
+added to the repository at a later date, or may be available from other
+sources.
+
+=head2 PCRE
+
+PCRE is a library that implements regular expressions using Perl 5 syntax.
+
+
+=head2 NCurses
+
+NCurses is a library for manipulating the console and the cursor.
+
+=head2 OpenGL
+
+OpenGL is a 3D graphics library.
+
+=head2 Postgres SQL
+
+=head2 SDL
+
+=head1 Mod_Parrot and CGI libraries
+
+Parrot is also available, through a related but separate development effort
+as a module for the Apache web server, Mod_Parrot. Mod_Parrot allows
+Parrot and the high-level languages which target it to be used in Apache
+to generate web content. Several libraries are available in the Parrot
+repository that can help manage these requests.
+
+=cut
+
+# Local variables:
+#   c-file-style: "parrot"
+# End:
+# vim: expandtab shiftwidth=4:

Copied: branches/headercleanup/docs/book/draft/chXX_testing_and_debugging.pod (from r38131, trunk/docs/book/draft/chXX_testing_and_debugging.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/headercleanup/docs/book/draft/chXX_testing_and_debugging.pod	Wed Apr 15 19:17:06 2009	(r38132, copy of r38131, trunk/docs/book/draft/chXX_testing_and_debugging.pod)
@@ -0,0 +1,128 @@
+=pod
+
+=head0 Testing and Debugging
+
+Z<CHP-7>
+
+Programming languages and the virtual machines on which they run are just
+one small part of the total programming ecosystem. Programmers require not
+just development tools, but also maintenance and management tools. Critical
+to development and maintenance of code are comprehensive testing tools and
+code debugging tools. Luckily, Parrot supports both. This chapter is going
+to discuss the testing frameworks available for HLLs written on Parrot,
+and the Parrot debugger which can be used for live debugging of software
+written in any of the HLLs that Parrot supports.
+
+=head1 Writing Tests
+
+Z<CHP-7-SECT-1>
+
+X<testing Parrot>
+Parrot is volunteer-driven, and contributions from new users are always
+welcome. Contributing tests is a good place for a new developer to start.
+You don't have to understand the code behind a PASM opcodeN<Or PIR
+instruction, or whatever.> to test it, you only have to understand
+the desired behavior. If you're working on some code and it doesn't do
+what the documentation claims, you can isolate the problem in a test or
+series of tests and send them to the bug tracking system. There's a
+good chance the problem will be fixed before the next release. Writing
+tests makes it a lot easier for the developer to know when they've solved
+your problem--it's solved when your tests pass. It also prevents that
+problem from appearing again, because it's checked every time anyone
+runs C<make> C<test>. As you move along, you'll want to write tests
+for every bug you fix or new feature you add.
+
+X<Test::Builder>
+X<Parrot::Test module>
+The Perl 5 testing framework is at the core of Parrot tests,
+particularly F<Test::Builder>. Parrot's F<Parrot::Test> module is an
+interface to F<Test::Builder> and implements the extra features needed
+for testing Parrot, like the fact that PASM and PIR code has to be
+compiled to bytecode before it runs. F<Parrot::Test> handles the
+compilation and running of the test code, and collects the output for
+verification.
+
+The main Parrot tests are in the top-level F<t/> directory of the
+Parrot source tree. F<t/op> contains tests for basic opcodes and
+F<t/pmc> has tests for PMCs. The names of the test files indicate the
+functionality tested, like F<integer.t>, F<number.t>, and F<string.t>.
+Part of the F<make test> target is the command F<perl t/harness>,
+which runs all the F<.t> files in the subdirectories under F</t>. You
+can run individual test files by passing their names to the F<harness>
+script:
+
+  $ perl t/harness t/op/string.t t/op/integer.t
+
+X<set opcode (PASM);test example>
+Here's a simple example that tests the C<set> opcode with integer
+registers, taken from F<t/op/integer.t>:
+
+  output_is(E<lt>E<lt>CODE, E<lt>E<lt>OUTPUT, "set_i");
+      set     I0, 42
+      set     I1, I0
+      print   I1
+      print   "\\n"
+      end
+  CODE
+  42
+  OUTPUT
+
+The code here sets integer register C<I0> to the value 42, sets C<I1>
+to the value of C<I0>, and then prints the value in C<I1>. The test
+passes if the value printed was 42, and fails otherwise.
+
+The C<output_is> subroutine takes three strings: the code to run, the
+expected output, and a description of the test. The first two strings
+can be quite long, so the convention is to use Perl 5 here-documents.
+If you look into the code section, you'll see that the literal C<\n>
+has to be escaped as C<\\n>. Many tests use the non-interpolating
+(C<E<lt>E<lt>'CODE>') form of here-document to avoid that problem. The
+description can be any text.  In this case, it's the fully qualified
+name of the C<set> opcode for integer registers, but it could have
+been "set a native integer register."
+
+If you look up at the top of F<integer.t>, you'll see the line:
+
+  use Parrot::Test tests => 38;
+
+(although the actual number may be larger if more tests have been added
+since this book went to press).
+
+The C<use> line for the F<Parrot::Test> module imports a set of
+subroutines into the test file, including C<output_is>. The end of the
+line gives the number of tests contained in the file.
+
+The C<output_is> subroutine looks for an exact match between the
+expected result and the actual output of the code. When the test
+result can't be compared exactly, you want C<output_like> instead. It
+takes a Perl 5 regular expression for the expected output:
+
+  output_like(<<'CODE', <<'OUTPUT', "testing for text match");
+  ...
+  CODE
+  /^Output is some \d+ number\n$/
+  OUTPUT
+
+F<Parrot::Test> also exports C<output_isnt>, which tests that the
+actual output of the code I<doesn't> match a particular value.
+
+There are a few guidelines to follow when you're writing a test for a
+new opcode or checking that an existing opcode has full test coverage.
+Tests should cover the opcode's standard operation, corner cases, and
+illegal input. The first tests should always cover the basic
+functionality of an opcode. Further tests can cover more complex
+operations and the interactions between opcodes. If the test program
+is complex or obscure, it helps to add comments. Tests should be
+self-contained to make it easy to identify where and why a test is
+failing.
+
+=head1 The Parrot Debugger
+
+Z<CHP-7-SECT-2>
+
+=cut
+
+# Local variables:
+#   c-file-style: "parrot"
+# End:
+# vim: expandtab shiftwidth=4:

Modified: branches/headercleanup/docs/pdds/draft/pdd08_keys.pod
==============================================================================
--- branches/headercleanup/docs/pdds/draft/pdd08_keys.pod	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/docs/pdds/draft/pdd08_keys.pod	Wed Apr 15 19:17:06 2009	(r38132)
@@ -47,8 +47,8 @@
 For this reason the following structure was produced.  Individual keys (e.g. a
 single C<Integer> or C<String>) are stored in a C<Key> PMC.  The type of the
 key is encoded in the private flags of the PMC as specified below.   The value
-of the C<Key> PMC is stored in the PMC's cache (i.e. C<PMC_pmc_val(key)>,
-C<PMC_int_val(key)>).
+of the C<Key> PMC is stored in the PMC's data structure internally and can be
+accessed using the appropriate get_* VTABLE functions.
 
 For example, indexing the multidimensional array C<@foo[$a,12;"hi"]>
 produces three PMCs; one with a PMC type, one with an integer type
@@ -79,8 +79,8 @@
 
 
 The C<KEY_register_FLAG> is used to indicate that value if the key is in a
-register.  In this case, C<PMC_int_val(key)> contains the number of a register
-of the appropriate type that contains the value.
+register.  In this case, the Key PMC's data contains the integer number of the
+appropriate register in the current context.
 
 Parrot must also have a way to combine multiple keys into a key that can be
 treated as a single unit.  This is done by forming a singly linked list such

Modified: branches/headercleanup/docs/pdds/draft/pdd16_native_call.pod
==============================================================================
--- branches/headercleanup/docs/pdds/draft/pdd16_native_call.pod	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/docs/pdds/draft/pdd16_native_call.pod	Wed Apr 15 19:17:06 2009	(r38132)
@@ -99,18 +99,15 @@
 
 =item 2
 
-A pointer to a short, taken from an P register of an int-like PMC. On return
-from NCI, the PMC_int_val will hold the new value.
+A pointer to a short, taken from an P register of an int-like PMC.
 
 =item 3
 
-A pointer to an int, taken from an P register of an int-like PMC. On return
-from NCI, the PMC_int_val will hold the new value.
+A pointer to an int, taken from an P register of an int-like PMC.
 
 =item 4
 
-A pointer to a long, taken from an P register of an int-like PMC. On return
-from NCI, the PMC_int_val will hold the new value.
+A pointer to a long, taken from an P register of an int-like PMC.
 
 =item t
 

Modified: branches/headercleanup/docs/pdds/pdd07_codingstd.pod
==============================================================================
--- branches/headercleanup/docs/pdds/pdd07_codingstd.pod	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/docs/pdds/pdd07_codingstd.pod	Wed Apr 15 19:17:06 2009	(r38132)
@@ -133,7 +133,7 @@
 C macro parameters must be parenthesized in macro bodies, to allow expressions
 passed as arguments; e.g.:
 
-  #define PMC_pmc_val(pmc)      (pmc)->obj.u._ptrs._pmc_val
+    #define POBJ_FLAG(n) ((UINTVAL)1 << (n))
 
 =back
 

Modified: branches/headercleanup/docs/pmc.pod
==============================================================================
--- branches/headercleanup/docs/pmc.pod	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/docs/pmc.pod	Wed Apr 15 19:17:06 2009	(r38132)
@@ -18,15 +18,6 @@
 B<PMC_data> or B<pmc_ext> is set to NULL. The flags are set to their default
 value, especially the private flags are 0.
 
-=head2 UnionVal usage
-
-There are no special rules, where to store what: use whatever fits best. If
-your PMC points to a B<STRING *>, hang it off the B<PMC_str_val()>, if it's an
-B<INTVAL>, place it in B<PMC_int_val()>. If you need to store two items, try to
-use union members that have distinct storage like B<PObj_bustart()> /
-B<PObj_buf_len()> or B<PMC_struct_val()> / B<PMC_pmc_val()> in parallel with
-B<PMC_num_val()>.
-
 =head2 PMC_data()
 
 If your PMC contains other PMCs that possibly would allow the creation of

Modified: branches/headercleanup/editor/pir-mode.el
==============================================================================
--- branches/headercleanup/editor/pir-mode.el	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/editor/pir-mode.el	Wed Apr 15 19:17:06 2009	(r38132)
@@ -153,10 +153,10 @@
     "ManagedStruct" "MultiSub" "NCI" "NameSpace" "Null"
     "OS" "Object" "OrderedHash" "PMCProxy" "ParrotClass"
     "ParrotIO" "ParrotInterpreter" "ParrotLibrary" "ParrotObject"
-    "ParrotRunningThread" "ParrotThread" "Pointer" "Random" "Ref"
+    "ParrotRunningThread" "ParrotThread" "Pointer" "Random"
     "ResizableBooleanArray" "ResizableFloatArray" "ResizableIntegerArray"
     "ResizablePMCArray" "ResizableStringArray" "RetContinuation"
-    "Role" "Scalar" "SharedRef" "String" "Sub" "Super"
+    "Role" "Scalar" "String" "Sub" "Super"
     "Timer" "UnManagedStruct" "Undef" "VtableCache"))
 
 (defvar pir-ops

Modified: branches/headercleanup/editor/skeleton.pir
==============================================================================
--- branches/headercleanup/editor/skeleton.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/editor/skeleton.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 .sub main :main
 .end
 

Modified: branches/headercleanup/examples/benchmarks/addit.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/addit.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/addit.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -54,3 +54,9 @@
 F<examples/benchmarks/addit2.pir>.
 
 =cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/bench_newp.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/bench_newp.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/bench_newp.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -103,3 +103,9 @@
 F<examples/benchmarks/gc_waves_sizeable_headers.pasm>.
 
 =cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/float4.pir
==============================================================================
--- branches/headercleanup/examples/benchmarks/float4.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/float4.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 float4.pir - Benchmark different ways of filling a float4 struct

Modified: branches/headercleanup/examples/benchmarks/freeze.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/freeze.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/freeze.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -71,3 +71,9 @@
 F<examples/benchmarks/freeze.pl>.
 
 =cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/gc_alloc_new.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/gc_alloc_new.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/gc_alloc_new.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -96,3 +96,9 @@
 F<examples/benchmarks/gc_waves_sizeable_headers.pasm>.
 
 =cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/gc_alloc_reuse.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/gc_alloc_reuse.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/gc_alloc_reuse.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -93,3 +93,9 @@
 F<examples/benchmarks/gc_waves_sizeable_headers.pasm>.
 
 =cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/gc_generations.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/gc_generations.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/gc_generations.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -132,3 +132,9 @@
 F<examples/benchmarks/gc_waves_sizeable_headers.pasm>.
 
 =cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/gc_header_new.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/gc_header_new.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/gc_header_new.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -123,3 +123,9 @@
 	print " total Buffer structs\n"
 
 	end
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/gc_header_reuse.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/gc_header_reuse.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/gc_header_reuse.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -101,3 +101,9 @@
 F<examples/benchmarks/gc_waves_sizeable_headers.pasm>.
 
 =cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/gc_waves_headers.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/gc_waves_headers.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/gc_waves_headers.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -113,3 +113,9 @@
 F<examples/benchmarks/gc_waves_sizeable_headers.pasm>.
 
 =cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/gc_waves_sizeable_data.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/gc_waves_sizeable_data.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/gc_waves_sizeable_data.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -133,3 +133,9 @@
 F<examples/benchmarks/gc_waves_sizeable_headers.pasm>.
 
 =cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/gc_waves_sizeable_headers.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/gc_waves_sizeable_headers.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/gc_waves_sizeable_headers.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -124,3 +124,9 @@
 F<examples/benchmarks/gc_waves_sizeable_data.pasm>.
 
 =cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/mops.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/mops.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/mops.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -76,3 +76,9 @@
 F<examples/mops/mops.scheme>.
 
 =cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/mops_intval.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/mops_intval.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/mops_intval.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -75,3 +75,9 @@
 
 =cut
 
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/oo1.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/oo1.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/oo1.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -65,3 +65,9 @@
     set P10, 20
     setattribute P2, ".j", P10
     returncc
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/oo2.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/oo2.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/oo2.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -52,3 +52,9 @@
     set P10, 20
     setattribute P2, ".j", P10
     returncc
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/oo3.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/oo3.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/oo3.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -35,3 +35,9 @@
     set P10, 20
     setattribute P2, ".j", P10
     returncc
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/oo4.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/oo4.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/oo4.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -34,3 +34,9 @@
     set P10, 20
     setattribute P2, ".j", P10
     returncc
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/primes.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/primes.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/primes.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -76,3 +76,8 @@
 
 =cut
 
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/primes_i.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/primes_i.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/primes_i.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -68,3 +68,8 @@
 
 =cut
 
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Deleted: branches/headercleanup/examples/benchmarks/shared_ref.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/shared_ref.pasm	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,32 +0,0 @@
-# Copyright (C) 2001-2006, Parrot Foundation.
-# $Id$
-
-=head1 NAME
-
-examples/benchmarks/shared_ref.pasm - Shared reference between threads
-
-=head1 SYNOPSIS
-
-    % time ./parrot examples/benchmarks/shared_ref.pasm
-
-=head1 DESCRIPTION
-
-Shares references between threads.
-
-=cut
-
-      set I0, 100000
-      set I1, 0
-lp:
-      new P0, 'Integer'
-      new P1, 'SharedRef', P0  # or 'Ref'
-      set P1, I1
-      inc I1
-      lt I1, I0, lp
-      end
-
-=head1 SEE ALSO
-
-F<examples/benchmarks/shared_ref.pl>.
-
-=cut

Deleted: branches/headercleanup/examples/benchmarks/shared_ref.pl
==============================================================================
--- branches/headercleanup/examples/benchmarks/shared_ref.pl	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,42 +0,0 @@
-#! perl
-# Copyright (C) 2001-2003, Parrot Foundation.
-# $Id$
-
-=head1 NAME
-
-examples/benchmarks/shared_ref.pl - Shared reference between threads
-
-=head1 SYNOPSIS
-
-    % time perl examples/benchmarks/shared_ref.pl
-
-=head1 DESCRIPTION
-
-Shares references between threads.
-
-=cut
-
-use strict;
-use warnings;
-use threads;
-use threads::shared;
-
-for my $i ( 0 .. 99_999 ) {
-    my $r : shared;
-    my $j : shared;
-    $r  = \$j;
-    $$r = $i;
-}
-
-=head1 SEE ALSO
-
-F<examples/benchmarks/shared_ref.pasm>.
-
-=cut
-
-# Local Variables:
-#   mode: cperl
-#   cperl-indent-level: 4
-#   fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4:

Modified: branches/headercleanup/examples/benchmarks/stress.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/stress.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/stress.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -67,11 +67,17 @@
 
 =head1 SEE ALSO
 
-F<examples/benchmarks/stress.pl>, 
-F<examples/benchmarks/stress1.pasm>, 
-F<examples/benchmarks/stress1.pl>, 
-F<examples/benchmarks/stress2.pasm>, 
-F<examples/benchmarks/stress2.pl>, 
+F<examples/benchmarks/stress.pl>,
+F<examples/benchmarks/stress1.pasm>,
+F<examples/benchmarks/stress1.pl>,
+F<examples/benchmarks/stress2.pasm>,
+F<examples/benchmarks/stress2.pl>,
 F<examples/benchmarks/stress3.pasm>.
 
 =cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/stress1.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/stress1.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/stress1.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -75,10 +75,16 @@
 
 =head1 SEE ALSO
 
-F<examples/benchmarks/stress.pasm>, 
-F<examples/benchmarks/stress.pl>, 
-F<examples/benchmarks/stress1.pl>, 
-F<examples/benchmarks/stress2.pl>, 
+F<examples/benchmarks/stress.pasm>,
+F<examples/benchmarks/stress.pl>,
+F<examples/benchmarks/stress1.pl>,
+F<examples/benchmarks/stress2.pl>,
 F<examples/benchmarks/stress3.pasm>.
 
 =cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/stress2.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/stress2.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/stress2.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -41,11 +41,17 @@
 
 =head1 SEE ALSO
 
-F<examples/benchmarks/stress.pasm>, 
-F<examples/benchmarks/stress.pl>, 
-F<examples/benchmarks/stress1.pasm>, 
-F<examples/benchmarks/stress1.pl>, 
-F<examples/benchmarks/stress2.pl>, 
+F<examples/benchmarks/stress.pasm>,
+F<examples/benchmarks/stress.pl>,
+F<examples/benchmarks/stress1.pasm>,
+F<examples/benchmarks/stress1.pl>,
+F<examples/benchmarks/stress2.pl>,
 F<examples/benchmarks/stress3.pasm>.
 
 =cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/stress3.pasm
==============================================================================
--- branches/headercleanup/examples/benchmarks/stress3.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/stress3.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -85,12 +85,18 @@
 
 =head1 SEE ALSO
 
-F<examples/benchmarks/stress.pasm>, 
-F<examples/benchmarks/stress.pl>, 
-F<examples/benchmarks/stress1.pasm>, 
-F<examples/benchmarks/stress1.pl>, 
-F<examples/benchmarks/stress2.pasm>, 
-F<examples/benchmarks/stress2.pl>, 
+F<examples/benchmarks/stress.pasm>,
+F<examples/benchmarks/stress.pl>,
+F<examples/benchmarks/stress1.pasm>,
+F<examples/benchmarks/stress1.pl>,
+F<examples/benchmarks/stress2.pasm>,
+F<examples/benchmarks/stress2.pl>,
 F<examples/benchmarks/stress3.pasm>.
 
 =cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/benchmarks/vpm.pir
==============================================================================
--- branches/headercleanup/examples/benchmarks/vpm.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/benchmarks/vpm.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 # beginn
 #use strict;
 #

Modified: branches/headercleanup/examples/japh/japh1.pasm
==============================================================================
--- branches/headercleanup/examples/japh/japh1.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/japh/japh1.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 	newclass P0, "Japh"
 	new P0, "Japh"
 	set I0, 0
@@ -18,3 +20,9 @@
 	set S1, "Just another "
 	set_returns "0", S1
 	returncc
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/japh/japh3.pasm
==============================================================================
--- branches/headercleanup/examples/japh/japh3.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/japh/japh3.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 # the substr JaPH
     set S0, "Hacker\n"
     set S1, "Parrot "
@@ -10,5 +12,11 @@
     set I3, 3
     bsr I3
     end
-	print S3
+    print S3
     ret
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/japh/japh4.pasm
==============================================================================
--- branches/headercleanup/examples/japh/japh4.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/japh/japh4.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 newclass P1, "Japh"
 new P2, "Japh"
 print P2
@@ -8,3 +10,9 @@
 	set S3, "Just another Parrot Hacker\n"
 	set_returns "0", S3
 	returncc
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/japh/japh5.pasm
==============================================================================
--- branches/headercleanup/examples/japh/japh5.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/japh/japh5.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 # JaPH utilizing an object
     newclass P0, "Japh"
     new P0, "Japh"
@@ -8,7 +10,7 @@
     end
 .namespace ["Japh"]
 .pcc_sub :vtable set_string_keyed:
-	get_params "0,0,0", P5, I5, S5
+    get_params "0,0,0", P5, I5, S5
     print S5
     if I5, sp
     print "\n"
@@ -17,3 +19,8 @@
     print " "
     returncc
 
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/languages/abc/abc.pir
==============================================================================
--- branches/headercleanup/examples/languages/abc/abc.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/languages/abc/abc.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 abc.pir - A basic calculator.

Modified: branches/headercleanup/examples/namespace/namespace_dump.pir
==============================================================================
--- branches/headercleanup/examples/namespace/namespace_dump.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/namespace/namespace_dump.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 #
 # dump all namespaces and the contents recursively
 #

Modified: branches/headercleanup/examples/nci/QtHelloWorld.pasm
==============================================================================
--- branches/headercleanup/examples/nci/QtHelloWorld.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/nci/QtHelloWorld.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -61,3 +61,9 @@
 F<examples/nci/PQt.C>, F<docs/pdds/pdd03_calling_conventions.pod>.
 
 =cut
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/opengl/shapes.pir
==============================================================================
--- branches/headercleanup/examples/opengl/shapes.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/opengl/shapes.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 shapes.pir - Exercise basic OpenGL 1.1/GLUT 3 APIs by drawing animated shapes

Modified: branches/headercleanup/examples/opengl/static-triangle.pir
==============================================================================
--- branches/headercleanup/examples/opengl/static-triangle.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/opengl/static-triangle.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 static-triangle.pir - Minimal OpenGL/GLUT setup and render for NCI tests

Modified: branches/headercleanup/examples/opengl/triangle.pir
==============================================================================
--- branches/headercleanup/examples/opengl/triangle.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/opengl/triangle.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 triangle.pir - Initialize GLUT and render a simple OpenGL animation

Modified: branches/headercleanup/examples/pasm/cat.pasm
==============================================================================
--- branches/headercleanup/examples/pasm/cat.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/pasm/cat.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -13,7 +13,7 @@
 
 Simple C<cat>-like utility to test PIO read/write. Does not use STDIO.
 
-Echoes what you type once you hit return. 
+Echoes what you type once you hit return.
 
 You'll have to Ctl-C to exit.
 
@@ -26,3 +26,9 @@
 	print S0
 	if S0, REDO
 	end
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/pasm/fact.pasm
==============================================================================
--- branches/headercleanup/examples/pasm/fact.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/pasm/fact.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -29,12 +29,12 @@
 main:
 	set 	I1,0
 	## P9 is used as a stack for temporaries.
-	new     P9, 'ResizableIntegerArray'
+	new	P9, 'ResizableIntegerArray'
 loop:
 	print	"fact of "
 	print	I1
 	print	" is: "
-    new P0, 'Integer'
+	new P0, 'Integer'
 	set	P0,I1
 	bsr	fact
 	print	P0
@@ -54,8 +54,14 @@
 	dec	P0
 	bsr	fact
 	mul	P0,P0,I2
-	pop     I2,P9
+	pop	I2,P9
 	ret
 is_one:
 	set	P0,1
 	ret
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/pasm/hello.pasm
==============================================================================
--- branches/headercleanup/examples/pasm/hello.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/pasm/hello.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -28,3 +28,9 @@
     print S1
     print "\n"
     end
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/pasm/trace.pasm
==============================================================================
--- branches/headercleanup/examples/pasm/trace.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/pasm/trace.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -22,3 +22,9 @@
 trace 0
 print "Partner!\n"
 end
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/sdl/anim_image.pir
==============================================================================
--- branches/headercleanup/examples/sdl/anim_image.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/anim_image.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 anim_image.pir - animate an image in a Parrot SDL window

Modified: branches/headercleanup/examples/sdl/anim_image_dblbuf.pir
==============================================================================
--- branches/headercleanup/examples/sdl/anim_image_dblbuf.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/anim_image_dblbuf.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 anim_image_dblbuf.pir - animate an image in a doublebuffered Parrot SDL window

Modified: branches/headercleanup/examples/sdl/blue_font.pir
==============================================================================
--- branches/headercleanup/examples/sdl/blue_font.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/blue_font.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 blue_font.pir - draw a friendly message to the screen

Modified: branches/headercleanup/examples/sdl/blue_rect.pir
==============================================================================
--- branches/headercleanup/examples/sdl/blue_rect.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/blue_rect.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 blue_rect.pir - draw a blue rectangle with the SDL Parrot bindings

Modified: branches/headercleanup/examples/sdl/bounce_parrot_logo.pir
==============================================================================
--- branches/headercleanup/examples/sdl/bounce_parrot_logo.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/bounce_parrot_logo.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 bounce_parrot_logo.pir - bounce a Parrot logo with the SDL Parrot bindings

Modified: branches/headercleanup/examples/sdl/lcd/clock.pir
==============================================================================
--- branches/headercleanup/examples/sdl/lcd/clock.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/lcd/clock.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 clock.pir - LCD clock

Modified: branches/headercleanup/examples/sdl/minesweeper/eventhandler.pir
==============================================================================
--- branches/headercleanup/examples/sdl/minesweeper/eventhandler.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/minesweeper/eventhandler.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 eventhandler.pir - a minesweeper event handler

Modified: branches/headercleanup/examples/sdl/minesweeper/mines.pir
==============================================================================
--- branches/headercleanup/examples/sdl/minesweeper/mines.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/minesweeper/mines.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 mines.pir - a minesweeper clone for parrot (with parrot's SDL bindings)

Modified: branches/headercleanup/examples/sdl/move_parrot_logo.pir
==============================================================================
--- branches/headercleanup/examples/sdl/move_parrot_logo.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/move_parrot_logo.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 move_parrot_logo.pir - move a Parrot logo with the SDL Parrot bindings

Modified: branches/headercleanup/examples/sdl/raw_pixels.pir
==============================================================================
--- branches/headercleanup/examples/sdl/raw_pixels.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/raw_pixels.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 raw_pixels.pir - paint the screen blue, pixel by pixel

Modified: branches/headercleanup/examples/sdl/tetris/app.pir
==============================================================================
--- branches/headercleanup/examples/sdl/tetris/app.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/tetris/app.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 app.pir - a tetris application object

Modified: branches/headercleanup/examples/sdl/tetris/block.pir
==============================================================================
--- branches/headercleanup/examples/sdl/tetris/block.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/tetris/block.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 block.pir - a tetris block class

Modified: branches/headercleanup/examples/sdl/tetris/blockdata.pir
==============================================================================
--- branches/headercleanup/examples/sdl/tetris/blockdata.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/tetris/blockdata.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 blockdata.pir - a tetris block data class

Modified: branches/headercleanup/examples/sdl/tetris/blocks.pir
==============================================================================
--- branches/headercleanup/examples/sdl/tetris/blocks.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/tetris/blocks.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 blocks.pir - tetris block classes

Modified: branches/headercleanup/examples/sdl/tetris/board.pir
==============================================================================
--- branches/headercleanup/examples/sdl/tetris/board.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/tetris/board.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 board.pir - a tetris board class.

Modified: branches/headercleanup/examples/sdl/tetris/boarddata.pir
==============================================================================
--- branches/headercleanup/examples/sdl/tetris/boarddata.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/tetris/boarddata.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 boarddata.pir - a tetris board data class

Modified: branches/headercleanup/examples/sdl/tetris/eventhandler.pir
==============================================================================
--- branches/headercleanup/examples/sdl/tetris/eventhandler.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/tetris/eventhandler.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 eventhandler.pir - a tetris event handler class

Modified: branches/headercleanup/examples/sdl/tetris/tetris.pir
==============================================================================
--- branches/headercleanup/examples/sdl/tetris/tetris.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/sdl/tetris/tetris.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 tetris.pir - a second tetris for parrot (with parrot's SDL bindings)

Modified: branches/headercleanup/examples/shootout/ack.pir
==============================================================================
--- branches/headercleanup/examples/shootout/ack.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/ack.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot
+# $Id$
 # OUTPUT="Ack(3, 9) = 4093\n"
 #
 # ./parrot -Oc -R cgp-jit

Modified: branches/headercleanup/examples/shootout/binarytrees.pir
==============================================================================
--- branches/headercleanup/examples/shootout/binarytrees.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/binarytrees.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot -R cgp
+# $Id$
 #
 # binarytrees.pir N         (N = 16 for shootout)
 # by Joshua Isom, modified by Leopold Toetsch

Modified: branches/headercleanup/examples/shootout/fannkuch.pir
==============================================================================
--- branches/headercleanup/examples/shootout/fannkuch.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/fannkuch.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot
+# $Id$
 #
 # ./parrot -R jit fannkuch.pir N         (N = 9 for shootout)
 # by Joshua Isom

Modified: branches/headercleanup/examples/shootout/fasta.pir
==============================================================================
--- branches/headercleanup/examples/shootout/fasta.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/fasta.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot -R cgp
+# $Id$
 #
 # fasta.pir N         (N = 2500000 for shootout)
 # by Joshua Isom

Modified: branches/headercleanup/examples/shootout/harmonic.pir
==============================================================================
--- branches/headercleanup/examples/shootout/harmonic.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/harmonic.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 examples/shootout/harmonic.pir - Partial sum of Harmonic series

Modified: branches/headercleanup/examples/shootout/knucleotide.pir
==============================================================================
--- branches/headercleanup/examples/shootout/knucleotide.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/knucleotide.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,4 @@
+# $Id$
 
 .sub main :main
 	.local pmc stdin

Modified: branches/headercleanup/examples/shootout/mandelbrot.pir
==============================================================================
--- branches/headercleanup/examples/shootout/mandelbrot.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/mandelbrot.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,6 @@
 #!./parrot
+# $Id$
+
 =head1 NAME
 
 examples/shootout/mandelbrot.pir - Print the Mandelbrot set

Modified: branches/headercleanup/examples/shootout/nbody.pir
==============================================================================
--- branches/headercleanup/examples/shootout/nbody.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/nbody.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot
+# $Id$
 # The Computer Language Shootout
 # http://shootout.alioth.debian.org/
 #

Modified: branches/headercleanup/examples/shootout/nsieve-bits-2.pir
==============================================================================
--- branches/headercleanup/examples/shootout/nsieve-bits-2.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/nsieve-bits-2.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot
+# $Id$
 #
 # ./parrot -R jit nsieve-bits-2.pir N  (N = 9 for shootout)
 # by Leopold Toetsch

Modified: branches/headercleanup/examples/shootout/nsieve-bits.pir
==============================================================================
--- branches/headercleanup/examples/shootout/nsieve-bits.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/nsieve-bits.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot
+# $Id$
 #
 # ./parrot -R jit nsieve-bits.pir N  (N = 9 for shootout)
 # by Leopold Toetsch

Modified: branches/headercleanup/examples/shootout/nsieve.pir
==============================================================================
--- branches/headercleanup/examples/shootout/nsieve.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/nsieve.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot
+# $Id$
 #
 # ./parrot -R jit nsieve.pir N  (N = 9 for shootout)
 # by Leopold Toetsch

Modified: branches/headercleanup/examples/shootout/partialsums-2.pir
==============================================================================
--- branches/headercleanup/examples/shootout/partialsums-2.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/partialsums-2.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot
+# $Id$
 #
 # ./parrot -R jit partialsums-2.pir N  (N = 2500000 for shootout)
 #

Modified: branches/headercleanup/examples/shootout/partialsums.pir
==============================================================================
--- branches/headercleanup/examples/shootout/partialsums.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/partialsums.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot -R cgp
+# $Id$
 #
 # partialsums N  (N = 2500000 for shootout)
 #

Modified: branches/headercleanup/examples/shootout/pidigits.pir
==============================================================================
--- branches/headercleanup/examples/shootout/pidigits.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/pidigits.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot -R cgp
+# $Id$
 #
 # pidigits N  (N = 1000 for shootout)
 #

Modified: branches/headercleanup/examples/shootout/random.pasm
==============================================================================
--- branches/headercleanup/examples/shootout/random.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/random.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot -R jit
+# $Id$
 #
 # random.pasm N         (N = 900000 for shootout)
 # by Joshua Isom
@@ -45,3 +46,8 @@
     div N3, .IM
     ret
 
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/shootout/random.pir
==============================================================================
--- branches/headercleanup/examples/shootout/random.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/random.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot -R cgp
+# $Id$
 #
 # random.pir N         (N = 900000 for shootout)
 # by Joshua Isom

Modified: branches/headercleanup/examples/shootout/recursive-2.pir
==============================================================================
--- branches/headercleanup/examples/shootout/recursive-2.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/recursive-2.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot
+# $Id$
 #
 # Ack by Leopold Toetsch
 # Fib and Tak by Joshua Isom

Modified: branches/headercleanup/examples/shootout/recursive.pir
==============================================================================
--- branches/headercleanup/examples/shootout/recursive.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/recursive.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot
+# $Id$
 #
 # Ack by Leopold Toetsch
 # Fib and Tak by Joshua Isom

Modified: branches/headercleanup/examples/shootout/regexdna.pir
==============================================================================
--- branches/headercleanup/examples/shootout/regexdna.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/regexdna.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 .sub main :main
 	load_bytecode "PGE.pbc"
 	.local pmc p6rule_compile, rulesub, match, variants, variants_p5, iub, iter, matches, capt

Modified: branches/headercleanup/examples/shootout/revcomp.pir
==============================================================================
--- branches/headercleanup/examples/shootout/revcomp.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/revcomp.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!parrot
+# $Id$
 # Reads from stdin a file in the format made by fasta.pir
 # ./parrot -R jit
 # N = 2500000 for fasta

Modified: branches/headercleanup/examples/shootout/spectralnorm.pir
==============================================================================
--- branches/headercleanup/examples/shootout/spectralnorm.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/spectralnorm.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot
+# $Id$
 #
 # ./parrot -R jit spectralnorm.pir N         (N = 100 for shootout)
 # by Michal Jurosz

Modified: branches/headercleanup/examples/shootout/sumcol.pir
==============================================================================
--- branches/headercleanup/examples/shootout/sumcol.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/sumcol.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot
+# $Id$
 #
 # ./parrot -R jit sumcol.pir < sum8M
 # by Joshua Isom

Modified: branches/headercleanup/examples/shootout/takfp.pir
==============================================================================
--- branches/headercleanup/examples/shootout/takfp.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/shootout/takfp.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #!./parrot -R cgp
+# $Id$
 #
 # ./parrot -R cgp takfp.pir N         (N = 10 for shootout)
 # by Joshua Isom

Modified: branches/headercleanup/examples/streams/Bytes.pir
==============================================================================
--- branches/headercleanup/examples/streams/Bytes.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/streams/Bytes.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Bytes Example
 
 This example shows the usage of C<Stream::read_bytes>.

Modified: branches/headercleanup/examples/streams/Combiner.pir
==============================================================================
--- branches/headercleanup/examples/streams/Combiner.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/streams/Combiner.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Combiner Example
 
 This example shows the usage of C<Stream::Combiner>.

Modified: branches/headercleanup/examples/streams/Coroutine.pir
==============================================================================
--- branches/headercleanup/examples/streams/Coroutine.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/streams/Coroutine.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Coroutine Example
 
 This example shows the usage of C<Stream::Coroutine>.

Modified: branches/headercleanup/examples/streams/FileLines.pir
==============================================================================
--- branches/headercleanup/examples/streams/FileLines.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/streams/FileLines.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Advanced Lines Example
 
 This is an advanced example.

Modified: branches/headercleanup/examples/streams/Filter.pir
==============================================================================
--- branches/headercleanup/examples/streams/Filter.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/streams/Filter.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Filter Example
 
 This example shows the usage of C<Stream::Filter>.

Modified: branches/headercleanup/examples/streams/Include.pir
==============================================================================
--- branches/headercleanup/examples/streams/Include.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/streams/Include.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Include Example
 
 This example demonstrates how to include another stream inside a stream.

Modified: branches/headercleanup/examples/streams/Lines.pir
==============================================================================
--- branches/headercleanup/examples/streams/Lines.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/streams/Lines.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Lines Example
 
 This example demonstrates what C<Stream::Lines> does.

Modified: branches/headercleanup/examples/streams/ParrotIO.pir
==============================================================================
--- branches/headercleanup/examples/streams/ParrotIO.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/streams/ParrotIO.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Filehandle Object Example
 
 This small example shows the usage of C<Stream::ParrotIO>.

Modified: branches/headercleanup/examples/streams/Replay.pir
==============================================================================
--- branches/headercleanup/examples/streams/Replay.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/streams/Replay.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 .sub _main :main
     .local pmc stream
 

Modified: branches/headercleanup/examples/streams/SubCounter.pir
==============================================================================
--- branches/headercleanup/examples/streams/SubCounter.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/streams/SubCounter.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Counter Example
 
 This example shows the usage of C<Stream::Sub>.

Modified: branches/headercleanup/examples/streams/SubHello.pir
==============================================================================
--- branches/headercleanup/examples/streams/SubHello.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/streams/SubHello.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Hello Example
 
 This example shows the usage of C<Stream::Sub>.

Modified: branches/headercleanup/examples/streams/Writer.pir
==============================================================================
--- branches/headercleanup/examples/streams/Writer.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/streams/Writer.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Write Example
 
 This example shows the usage of C<Stream::Write>.

Modified: branches/headercleanup/examples/subs/bsr_ret.pasm
==============================================================================
--- branches/headercleanup/examples/subs/bsr_ret.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/subs/bsr_ret.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -21,14 +21,14 @@
 =cut
 
 MAIN:	print "Main\n"
-	bsr TESTSUB 
+	bsr TESTSUB
 	print "Main: Return from TestSub\n"
 END:	end
 
 
 TESTSUB:
 	print "TestSub\n"
-	bsr NESTSUB	
+	bsr NESTSUB
 	print "TestSub: Ret from NestSub\n"
 	ret
 
@@ -36,3 +36,8 @@
 	print "NestSub\n"
 	ret
 
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/subs/coroutine.pasm
==============================================================================
--- branches/headercleanup/examples/subs/coroutine.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/subs/coroutine.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -50,3 +50,8 @@
     print "Done\n"
     yield
 
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/subs/jsr_ret.pasm
==============================================================================
--- branches/headercleanup/examples/subs/jsr_ret.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/subs/jsr_ret.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -45,3 +45,8 @@
             print "Returning from subroutine SUB_2.\n"
             ret
 
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/subs/pasm_sub1.pasm
==============================================================================
--- branches/headercleanup/examples/subs/pasm_sub1.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/subs/pasm_sub1.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -43,3 +43,8 @@
     # Call the return continuation
     returncc
 
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/examples/tcl/tcltkdemo.pir
==============================================================================
--- branches/headercleanup/examples/tcl/tcltkdemo.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tcl/tcltkdemo.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,4 @@
+# $Id$
 # demonstrate Tcl/Tk GUI using NCI
 
 .include 'runtime/parrot/library/TclLibrary.pir'

Modified: branches/headercleanup/examples/tge/branch/lib/Branch.pir
==============================================================================
--- branches/headercleanup/examples/tge/branch/lib/Branch.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tge/branch/lib/Branch.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 Branch - a sample branch node for Language::AttributeGrammar

Modified: branches/headercleanup/examples/tge/branch/lib/Leaf.pir
==============================================================================
--- branches/headercleanup/examples/tge/branch/lib/Leaf.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tge/branch/lib/Leaf.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 Leaf - a sample leaf node for Language::AttributeGrammar

Modified: branches/headercleanup/examples/tge/branch/transform.pir
==============================================================================
--- branches/headercleanup/examples/tge/branch/transform.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tge/branch/transform.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 transform - transform a sample tree of Branch and Leaf nodes

Modified: branches/headercleanup/examples/tutorial/01_temp_var.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/01_temp_var.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/01_temp_var.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Simple Variables
 
 PIR has two kinds of variables. The most simple kind are Parrot

Modified: branches/headercleanup/examples/tutorial/02_local_var.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/02_local_var.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/02_local_var.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Named Variables
 
 The other kind of variables in PIR are named variables.

Modified: branches/headercleanup/examples/tutorial/03_temp_var_basic_pmcs.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/03_temp_var_basic_pmcs.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/03_temp_var_basic_pmcs.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Basic PMC Types
 
 PMCs are objects, so to use a PMC, you first have to instantiate an object for

Modified: branches/headercleanup/examples/tutorial/04_pod_comments.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/04_pod_comments.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/04_pod_comments.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Pod Documentation
 
 As you may have noticed, PIR files can contain POD documentation.

Modified: branches/headercleanup/examples/tutorial/10_math_ops.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/10_math_ops.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/10_math_ops.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Math Operations
 
 Many common math operations have simple operator syntax in PIR. Operators

Modified: branches/headercleanup/examples/tutorial/11_math_ops_self_mod.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/11_math_ops_self_mod.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/11_math_ops_self_mod.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Math Operations (continued)
 
 There is a second common form of math operations. This form takes

Modified: branches/headercleanup/examples/tutorial/12_math_ops_pasm.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/12_math_ops_pasm.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/12_math_ops_pasm.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Math Operations (continued)
 
 Some math operations have an opcode name, but no simple operator syntax in

Modified: branches/headercleanup/examples/tutorial/13_logical_ops.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/13_logical_ops.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/13_logical_ops.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Logical Operations
 
 The logical operations are short-circuiting, so if the first argument to an

Modified: branches/headercleanup/examples/tutorial/20_string_ops.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/20_string_ops.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/20_string_ops.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 String Operations
 
 Some operations aren't mathematical at all. Concatenation is an example

Modified: branches/headercleanup/examples/tutorial/21_string_ops_repeat.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/21_string_ops_repeat.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/21_string_ops_repeat.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 String Operations (continued)
 
 PIR has a string repeat opcode, that concatenates a string with

Modified: branches/headercleanup/examples/tutorial/22_string_ops_length.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/22_string_ops_length.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/22_string_ops_length.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 String Operations (continued)
 
 To find the length of a string in PIR, use the length opcode. It works on

Modified: branches/headercleanup/examples/tutorial/23_string_ops_substr.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/23_string_ops_substr.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/23_string_ops_substr.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 String Operations (continued)
 
 We can pick apart a string and pull substrings out of it using the

Modified: branches/headercleanup/examples/tutorial/24_string_ops_clone.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/24_string_ops_clone.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/24_string_ops_clone.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1
 
 This code example illustrates cloning with PMC strings. Simple copying

Modified: branches/headercleanup/examples/tutorial/30_arrays_basic.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/30_arrays_basic.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/30_arrays_basic.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1
 
 PMC registers can contain instances of array or hash data types, or

Modified: branches/headercleanup/examples/tutorial/31_array_ops_split.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/31_array_ops_split.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/31_array_ops_split.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1
 
 C<split> is an operation that breaks up a string at certain marker

Modified: branches/headercleanup/examples/tutorial/32_array_ops_sprintf.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/32_array_ops_sprintf.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/32_array_ops_sprintf.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1
 
 C<sprintf> is a function common to most programmers as part of the C

Modified: branches/headercleanup/examples/tutorial/33_hashes.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/33_hashes.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/33_hashes.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Hashes
 
 Hashes, also known in some places as "dictionaries" or "associative arrays"

Modified: branches/headercleanup/examples/tutorial/34_multikey.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/34_multikey.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/34_multikey.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Multi-Level Keys
 
 Hashes and arrays can be combined in a number of ways to make interesting

Modified: branches/headercleanup/examples/tutorial/40_file_ops.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/40_file_ops.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/40_file_ops.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 File Operations
 
 This example demonstrates basic file operations. Note the readmode.

Modified: branches/headercleanup/examples/tutorial/50_goto.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/50_goto.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/50_goto.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1
 
 The unconditional jump is the simplest of all flow control devices in any

Modified: branches/headercleanup/examples/tutorial/51_if_unless.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/51_if_unless.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/51_if_unless.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 if and unless
 
 Both the if and unless conditionals are supported in PIR.  When the

Modified: branches/headercleanup/examples/tutorial/52_if_compare.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/52_if_compare.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/52_if_compare.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Comparison Branching
 
 A simple C<goto> is the most simple version of flow control, but its

Modified: branches/headercleanup/examples/tutorial/53_loop.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/53_loop.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/53_loop.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Loops
 
 PIR has no built-in looping structures such as C<for>, C<while>,

Modified: branches/headercleanup/examples/tutorial/55_iterator.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/55_iterator.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/55_iterator.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 iterators
 
 An iterator is a type of PMC that helps with looping operations

Modified: branches/headercleanup/examples/tutorial/56_defined.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/56_defined.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/56_defined.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 defined
 
 The C<defined> opcode tells you if the contents of a PMC is defined or not.

Modified: branches/headercleanup/examples/tutorial/57_exists.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/57_exists.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/57_exists.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 exists
 
 The C<exists> opcode tells you whether an element of a container PMC

Modified: branches/headercleanup/examples/tutorial/60_subroutines.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/60_subroutines.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/60_subroutines.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Subroutines
 
 PIR is a subroutine-based or "procedural" programming language.

Modified: branches/headercleanup/examples/tutorial/61_namespaces.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/61_namespaces.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/61_namespaces.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Namespaces
 
 Subroutines all have a unique name, which is how the software recognizes

Modified: branches/headercleanup/examples/tutorial/62_namespaces.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/62_namespaces.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/62_namespaces.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Subroutines in a Namespace
 
 Subroutines created in one namespace can be accessed from another

Modified: branches/headercleanup/examples/tutorial/70_class_object.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/70_class_object.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/70_class_object.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Classes
 
 If we combine the ideas of namespaces, subroutines, and global variables,

Modified: branches/headercleanup/examples/tutorial/81_continuation.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/81_continuation.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/81_continuation.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Continuations
 
 Continuations are tricky and amazing things. Parrot uses continuations for

Modified: branches/headercleanup/examples/tutorial/82_coroutine.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/82_coroutine.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/82_coroutine.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Coroutines
 
 Coroutines are like special subroutines that use C<.yield> instead of

Modified: branches/headercleanup/examples/tutorial/83_external_libraries.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/83_external_libraries.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/83_external_libraries.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 External C Function Call
 
 There is a vast wealth of libraries written for a variety of tasks, and

Modified: branches/headercleanup/examples/tutorial/90_writing_tests.pir
==============================================================================
--- branches/headercleanup/examples/tutorial/90_writing_tests.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/examples/tutorial/90_writing_tests.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Writing Tests
 
 This example demonstrates writing tests using the PIR version of Test::More.

Modified: branches/headercleanup/ext/Parrot-Embed/t/greet.pir
==============================================================================
--- branches/headercleanup/ext/Parrot-Embed/t/greet.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/ext/Parrot-Embed/t/greet.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 .sub greet
 	.param pmc    name
 

Modified: branches/headercleanup/ext/SQLite3/SQLite3.pir
==============================================================================
--- branches/headercleanup/ext/SQLite3/SQLite3.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/ext/SQLite3/SQLite3.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,4 @@
+# $Id$
 
 .namespace ['SQLite']
 

Modified: branches/headercleanup/ext/SQLite3/test.pir
==============================================================================
--- branches/headercleanup/ext/SQLite3/test.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/ext/SQLite3/test.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,6 @@
 #../../parrot -t5 test.pir
+# $Id$
+
 .sub 'main'
 load_bytecode 'SQLite3'
 

Modified: branches/headercleanup/include/parrot/oo.h
==============================================================================
--- branches/headercleanup/include/parrot/oo.h	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/include/parrot/oo.h	Wed Apr 15 19:17:06 2009	(r38132)
@@ -25,10 +25,7 @@
 } PARROT_CLASS_DATA_ENUM;
 
 
-/* Objects, classes and PMCarrays all use the same data scheme:
- * PMC_data() holds a malloced array, PMC_int_val() is the size of it
- * this simplifies the GC mark phase a lot
- *
+/*
  * The active destroy flag is necessary to free the malloced array.
  */
 #define SLOTTYPE PMC*
@@ -38,13 +35,6 @@
         GC_WRITE_BARRIER(interp, (o), ((PMC **)(x))[y], (z)); \
         ((PMC **)(x))[(y)] = (z); \
     } while (0)
-#define set_attrib_flags(x) do { \
-        PObj_active_destroy_SET(x); \
-    } while (0)
-#define set_attrib_array_size(o, y) do { \
-    PMC_data(o) = mem_sys_allocate_zeroed((sizeof (PMC *)*(y))); \
-    PMC_int_val(o) = (y); \
-} while (0)
 
 /*
  * class macros

Modified: branches/headercleanup/include/parrot/pobj.h
==============================================================================
--- branches/headercleanup/include/parrot/pobj.h	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/include/parrot/pobj.h	Wed Apr 15 19:17:06 2009	(r38132)
@@ -55,10 +55,6 @@
 
 #define PObj_bufstart(pmc)    (pmc)->cache._b._bufstart
 #define PObj_buflen(pmc)      (pmc)->cache._b._buflen
-#define PMC_struct_val(pmc)   (pmc)->cache._ptrs._struct_val
-#define PMC_pmc_val(pmc)      (pmc)->cache._ptrs._pmc_val
-#define PMC_int_val(pmc)      (pmc)->cache._i._int_val
-#define PMC_str_val(pmc)      (pmc)->cache._string_val
 
 /* See src/gc/resources.c. the basic idea is that buffer memory is
    set up as follows:
@@ -179,7 +175,6 @@
 #define PMC_metadata(pmc)     PMC_ext_checked(pmc)->_metadata
 #define PMC_next_for_GC(pmc)  PMC_ext_checked(pmc)->_next_for_GC
 #define PMC_sync(pmc)         PMC_ext_checked(pmc)->_synchronize
-#define PMC_union(pmc)        (pmc)->cache
 
 #define POBJ_FLAG(n) ((UINTVAL)1 << (n))
 /* PObj flags */

Modified: branches/headercleanup/lib/Parrot/Distribution.pm
==============================================================================
--- branches/headercleanup/lib/Parrot/Distribution.pm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/lib/Parrot/Distribution.pm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -202,7 +202,7 @@
         source => {
             c   => { file_exts => ['c'] },
             pmc => { file_exts => ['pmc'] },
-            pir => { file_exts => ['pir', 't'] },
+            pir => { file_exts => ['pir', 'pasm', 't'] },
             ops => { file_exts => ['ops'] },
             lex => {
                 file_exts   => ['l'],
@@ -589,7 +589,8 @@
     return 0 unless -f $filename;
 
     # .pir files should always be tested
-    return 1 if $filename =~ /\.pir$/;
+    return 1 if $filename =~ /\.(?:pir|pasm)$/;
+    return 1 if $filename =~ /_(?:pir|pasm)\.in$/;
 
     # test files (.t) files might need testing.
     # ignore everything else.

Modified: branches/headercleanup/lib/Parrot/Ops2pm.pm
==============================================================================
--- branches/headercleanup/lib/Parrot/Ops2pm.pm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/lib/Parrot/Ops2pm.pm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -285,6 +285,9 @@
         if ( $n != $el->{CODE} ) {
             die "op $opname: number mismatch: ops.num $n vs. core.ops $el->{CODE}";
         }
+        if ( $seq != $el->{CODE} ) {
+            die "op $opname: sequence mismatch: ops.num $seq vs. core.ops $el->{CODE}";
+        }
         push @{ $real_ops->{OPS} }, $el;
         ++$seq;
     }

Modified: branches/headercleanup/lib/Parrot/Pmc2c/PMC/Null.pm
==============================================================================
--- branches/headercleanup/lib/Parrot/Pmc2c/PMC/Null.pm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/lib/Parrot/Pmc2c/PMC/Null.pm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -36,12 +36,24 @@
             }
         );
 
-        # don't return anything, ever
-        my $output = <<"EOC";
+        # take care to mark the parameters as unused
+        # to avoid compiler warnings
+        my $body = <<"EOC";
+    UNUSED(interp)
+    UNUSED(pmc)
+EOC
+
+        foreach my $param (split /,\s*/, $method->parameters) {
+            $param =~ s/.*\b(\w+)/$1/;
+            $body .= "    UNUSED($param)\n";
+        }
+        $body .= <<"EOC";
+
     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_NULL_REG_ACCESS,
         "Null PMC access in $vt_method_name()");
 EOC
-        $new_default_method->body( Parrot::Pmc2c::Emitter->text($output) );
+
+        $new_default_method->body( Parrot::Pmc2c::Emitter->text($body) );
         $self->add_method($new_default_method);
     }
     return 1;

Deleted: branches/headercleanup/lib/Parrot/Pmc2c/PMC/Ref.pm
==============================================================================
--- branches/headercleanup/lib/Parrot/Pmc2c/PMC/Ref.pm	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,111 +0,0 @@
-# Copyright (C) 2007-2008, Parrot Foundation.
-# $Id$
-
-=head1 Parrot::Pmc2c::Ref Instance Methods
-
-=over 4
-
-=cut
-
-package Parrot::Pmc2c::PMC::Ref;
-use base 'Parrot::Pmc2c::PMC';
-use strict;
-use warnings;
-use Parrot::Pmc2c::UtilFunctions qw( return_statement passable_args_from_parameter_list );
-
-=item C<prederef($method)>
-
-Returns C code to be executed before executing a delegated method.
-Default versions always returns an empty string.
-
-=cut
-
-sub prederef {
-    return '';
-}
-
-=item C<postderef($method)>
-
-Returns C code to be executed after executing a delegated method
-through this reference. Default version returns an empty string.
-
-=cut
-
-sub postderef {
-    return '';
-}
-
-=item C<raw_deref($method)>
-
-Returns C code that can be used to access the underlying PMC in the
-delegated methods. Default is PMC_pmc_val(pmc)
-
-=cut
-
-sub raw_deref {
-    my ( $self, $method ) = @_;
-    return 'PMC_pmc_val(pmc)';
-}
-
-=item C<body($method, $line, $out_name)>
-
-Returns the C code for the method body.
-
-Overrides the default implementation to direct all unknown methods to
-the thing referred to.
-
-=cut
-
-sub pre_method_gen {
-    my ($self) = @_;
-
-    # vtable methods
-    foreach my $method ( @{ $self->vtable->methods } ) {
-        my $vt_method_name = $method->name;
-        next unless $self->normal_unimplemented_vtable($vt_method_name);
-        my $new_default_method = $method->clone(
-            {
-                parent_name => $self->name,
-                type        => Parrot::Pmc2c::Method::VTABLE,
-            }
-        );
-
-        my $arg        = passable_args_from_parameter_list( $method->parameters );
-        my $pre        = $self->prederef($method);
-        my $post       = $self->postderef($method);
-        my $deref      = $self->raw_deref($method);
-        my $ret_def    = '';
-        my $ret_assign = '';
-        my $ret        = '';
-
-        if ( $method->return_type ne 'void' ) {
-            $ret_def    = $method->return_type . ' ret_val;';
-            $ret_assign = 'ret_val = ';
-            $ret        = return_statement( $method, 'ret_val' );
-        }
-        my $body = <<EOC;
-    $ret_def
-    $pre
-    $ret_assign VTABLE_$vt_method_name(interp, $deref$arg);
-    $post
-    $ret
-EOC
-
-        $new_default_method->body( Parrot::Pmc2c::Emitter->text($body) );
-        $self->add_method($new_default_method);
-    }
-    return 1;
-}
-
-1;
-
-=back
-
-=cut
-
-# Local Variables:
-#   mode: cperl
-#   cperl-indent-level: 4
-#   fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: branches/headercleanup/lib/Parrot/Pmc2c/PMC/SharedRef.pm
==============================================================================
--- branches/headercleanup/lib/Parrot/Pmc2c/PMC/SharedRef.pm	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,49 +0,0 @@
-# Copyright (C) 2007, Parrot Foundation.
-# $Id$
-
-=head1 Parrot::Pmc2c::SharedRef Instance Methods
-
-=over 4
-
-=cut
-
-package Parrot::Pmc2c::PMC::SharedRef;
-use base 'Parrot::Pmc2c::PMC::Ref';
-use strict;
-use warnings;
-
-=item C<prederef($method)>
-
-Returns code that will lock the PMC for calling the underlying
-implementation of $method.
-
-=cut
-
-sub prederef {
-    my ( $self, $method ) = @_;
-    return 'LOCK_PMC(interp, pmc);';
-}
-
-=item C<postderef($method)>
-
-Returns the unlocking code.
-
-=cut
-
-sub postderef {
-    my ( $self, $method ) = @_;
-    return 'UNLOCK_PMC(interp, pmc);';
-}
-
-=back
-
-=cut
-
-1;
-
-# Local Variables:
-#   mode: cperl
-#   cperl-indent-level: 4
-#   fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4:

Modified: branches/headercleanup/lib/Parrot/Pmc2c/PMC/default.pm
==============================================================================
--- branches/headercleanup/lib/Parrot/Pmc2c/PMC/default.pm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/lib/Parrot/Pmc2c/PMC/default.pm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -32,12 +32,18 @@
                 type        => Parrot::Pmc2c::Method::VTABLE,
             }
         );
-
         my $ret = return_statement($method);
-        $new_default_method->body( Parrot::Pmc2c::Emitter->text(<<"EOC") );
-    cant_do_method(interp, pmc, "$vt_method_name");
-    $ret
-EOC
+
+        # take care to mark the parameters as unused
+        # to avoid compiler warnings
+        my $body;
+        foreach my $param (split /,\s*/, $method->parameters) {
+            $param =~ s/.*\b(\w+)/$1/;
+            $body .= "    UNUSED($param)\n";
+        }
+        $body .= qq{    cant_do_method(interp, pmc, "$vt_method_name");\n};
+
+        $new_default_method->body( Parrot::Pmc2c::Emitter->text($body));
         $self->add_method($new_default_method);
     }
     return 1;

Modified: branches/headercleanup/lib/Parrot/Pmc2c/Pmc2cMain.pm
==============================================================================
--- branches/headercleanup/lib/Parrot/Pmc2c/Pmc2cMain.pm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/lib/Parrot/Pmc2c/Pmc2cMain.pm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -18,8 +18,6 @@
 use Parrot::Pmc2c::PCCMETHOD ();
 use Parrot::Pmc2c::PMC::default ();
 use Parrot::Pmc2c::PMC::Null ();
-use Parrot::Pmc2c::PMC::Ref ();
-use Parrot::Pmc2c::PMC::SharedRef ();
 use Parrot::Pmc2c::PMC::Object ();
 
 $SIG{'__WARN__'} = sub { use Carp; warn $_[0]; Carp::confess; };

Modified: branches/headercleanup/runtime/parrot/include/fp_equality.pasm
==============================================================================
--- branches/headercleanup/runtime/parrot/include/fp_equality.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/include/fp_equality.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -8,7 +8,7 @@
 =head1 DESCRIPTION
 
 This file provides two PIR macros to determine if a pair of floating point numbers are equivalent.
-The same macros are also provided for PASM. 
+The same macros are also provided for PASM.
 
 =cut
 

Modified: branches/headercleanup/runtime/parrot/include/hllmacros.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/include/hllmacros.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/include/hllmacros.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 High Level Language Macros
 
 These macros are to make it easier to write readable and maintainable PIR by

Modified: branches/headercleanup/runtime/parrot/include/sockets.pasm
==============================================================================
--- branches/headercleanup/runtime/parrot/include/sockets.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/include/sockets.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,4 @@
+# $Id$
 
 # families
 .macro_const AF_UNSPEC  0 # unspecified
@@ -21,3 +22,9 @@
 .macro_const IPPROTO_IPV6   41 # IP6 header
 .macro_const IPPROTO_RAW   255 # raw IP packet
 .macro_const IPPROTO_MAX   256
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/runtime/parrot/library/Config/JSON.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/Config/JSON.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/Config/JSON.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Config::JSON
 
 Provides a simple wrapper to read and write JSON config files.

Modified: branches/headercleanup/runtime/parrot/library/Crow.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/Crow.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/Crow.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 .namespace ['Crow']
 
 .sub 'get_args'

Modified: branches/headercleanup/runtime/parrot/library/Data/Dumper.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/Data/Dumper.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/Data/Dumper.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 .sub __library_data_dumper_onload :load
     .local pmc dd_class
     dd_class = get_class "Data::Dumper"

Modified: branches/headercleanup/runtime/parrot/library/Data/Dumper/Base.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/Data/Dumper/Base.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/Data/Dumper/Base.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 Data::Dumper::Base - style baseclass

Modified: branches/headercleanup/runtime/parrot/library/Data/Dumper/Default.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/Data/Dumper/Default.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/Data/Dumper/Default.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 Data::Dumper::Default - The default output module of Data::Dumper.

Modified: branches/headercleanup/runtime/parrot/library/Getopt/Obj.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/Getopt/Obj.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/Getopt/Obj.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 library/Getopt/Obj.pir - parse long and short command line options

Modified: branches/headercleanup/runtime/parrot/library/JSON.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/JSON.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/JSON.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 JSON.pir - PIR implementation of JSON data interchange format.

Modified: branches/headercleanup/runtime/parrot/library/NCI/call_toolkit_init.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/NCI/call_toolkit_init.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/NCI/call_toolkit_init.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 call_toolkit_init.pir - PIR code to call toolkits that alter argv

Modified: branches/headercleanup/runtime/parrot/library/OpenGL.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/OpenGL.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/OpenGL.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 OpenGL - Parrot extension for OpenGL bindings

Modified: branches/headercleanup/runtime/parrot/library/PGE/Dumper.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/PGE/Dumper.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/PGE/Dumper.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 PGE::Dumper - various methods for displaying PGE structures

Modified: branches/headercleanup/runtime/parrot/library/PGE/Glob.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/PGE/Glob.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/PGE/Glob.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 Glob - Parse and compile glob notation expressions.

Modified: branches/headercleanup/runtime/parrot/library/PGE/Hs.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/PGE/Hs.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/PGE/Hs.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Title
 
 PGE::Hs - Match and display PGE rules as Haskell expressions

Modified: branches/headercleanup/runtime/parrot/library/PGE/Perl6Grammar.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/PGE/Perl6Grammar.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/PGE/Perl6Grammar.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 Perl6Grammar - compiler for Perl 6 grammars

Modified: branches/headercleanup/runtime/parrot/library/PGE/Text.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/PGE/Text.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/PGE/Text.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 PGE::Text - rules for extracting delimited text sequences from strings

Modified: branches/headercleanup/runtime/parrot/library/PGE/Util.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/PGE/Util.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/PGE/Util.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 PGE/Util.pir - useful rules for working with PGE grammars

Modified: branches/headercleanup/runtime/parrot/library/Protoobject.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/Protoobject.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/Protoobject.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 Protoobject.pir - PIR implementation for creating protoobjects

Modified: branches/headercleanup/runtime/parrot/library/Range.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/Range.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/Range.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 Range
 
 Based on the Range object described in S03:

Modified: branches/headercleanup/runtime/parrot/library/SDL.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/SDL.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/SDL.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 SDL - Parrot extension for SDL bindings

Modified: branches/headercleanup/runtime/parrot/library/Stream/Coroutine.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/Stream/Coroutine.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/Stream/Coroutine.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 Stream::Base - Stream library base class

Modified: branches/headercleanup/runtime/parrot/library/Tcl/Glob.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/Tcl/Glob.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/Tcl/Glob.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 Tcl::Glob - Parse and compile glob notation expressions.

Modified: branches/headercleanup/runtime/parrot/library/Test/Builder.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/Test/Builder.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/Test/Builder.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 Test::Builder - Parrot extension for building test modules

Modified: branches/headercleanup/runtime/parrot/library/Test/Builder/Output.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/Test/Builder/Output.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/Test/Builder/Output.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 Test::Builder::Output - manages output for Test::Builder

Modified: branches/headercleanup/runtime/parrot/library/Test/Builder/Test.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/Test/Builder/Test.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/Test/Builder/Test.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 Test::Builder::Test - base class for all Test::Builder test objects

Modified: branches/headercleanup/runtime/parrot/library/Test/Builder/TestPlan.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/Test/Builder/TestPlan.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/Test/Builder/TestPlan.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 Test::Builder::TestPlan - class representing the current Test::Builder test plan

Modified: branches/headercleanup/runtime/parrot/library/Test/Class.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/Test/Class.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/Test/Class.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 Test::Class - Parrot extension for objecty testing of modules

Modified: branches/headercleanup/runtime/parrot/library/Test/More.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/Test/More.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/Test/More.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 NAME
 
 Test::More - Parrot extension for testing modules

Modified: branches/headercleanup/runtime/parrot/library/YAML/Dumper.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/YAML/Dumper.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/YAML/Dumper.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 .sub __library_data_dumper_onload :load
     .local pmc yd_class
     yd_class = get_class "YAML::Dumper"

Modified: branches/headercleanup/runtime/parrot/library/YAML/Dumper/Base.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/YAML/Dumper/Base.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/YAML/Dumper/Base.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 YAML::Dumper::Base - style baseclass

Modified: branches/headercleanup/runtime/parrot/library/YAML/Dumper/Default.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/YAML/Dumper/Default.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/YAML/Dumper/Default.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 =head1 TITLE
 
 YAML::Dumper::Default - The default output module of YAML::Dumper.

Modified: branches/headercleanup/runtime/parrot/library/ncurses.pasm
==============================================================================
--- branches/headercleanup/runtime/parrot/library/ncurses.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/ncurses.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 .pcc_sub :load __ncurses_init:
 loadlib P1, 'libform'
 dlfunc P2, P1, 'new_field', 'piiiiii'
@@ -649,3 +651,9 @@
 dlfunc P2, P1, 'has_key', 'ii'
 store_global 'ncurses::has_key', P2
 returncc
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/runtime/parrot/library/ncurses.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/ncurses.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/ncurses.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 .sub __ncurses_init :load
 
 loadlib $P1, 'libform'

Modified: branches/headercleanup/runtime/parrot/library/pcore.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/pcore.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/pcore.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,4 @@
+# $Id$
 # create/export some useful but rarely used methods
 
 # TODO podify & beautify & doc

Modified: branches/headercleanup/runtime/parrot/library/postgres.pasm
==============================================================================
--- branches/headercleanup/runtime/parrot/library/postgres.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/postgres.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 .pcc_sub __postgres_init :load
 
 loadlib $P1, 'libpq'
@@ -188,3 +190,8 @@
 .end_return
 .end
 
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/runtime/parrot/library/postgres.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/postgres.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/postgres.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 .namespace ['Pg']
 .sub __postgres_init :load
 

Modified: branches/headercleanup/runtime/parrot/library/random_lib.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/random_lib.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/random_lib.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,4 @@
+# $Id$
 # used by examples/shootout/random.pir and others
 # by Joshua Isom
 

Modified: branches/headercleanup/runtime/parrot/library/tcpstream.pir
==============================================================================
--- branches/headercleanup/runtime/parrot/library/tcpstream.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/runtime/parrot/library/tcpstream.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,4 @@
+# $Id$
 
 =head1 NAME
 

Modified: branches/headercleanup/src/debug.c
==============================================================================
--- branches/headercleanup/src/debug.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/debug.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -308,7 +308,7 @@
     PDB_list(pdb->debugee, cmd);
 }
 
-static void dbg_listbreakpoints(PDB_t * pdb, const char * cmd) /* HEADERIZER SKIP */
+static void dbg_listbreakpoints(PDB_t * pdb, SHIM(const char * cmd)) /* HEADERIZER SKIP */
 {
     TRACEDEB_MSG("dbg_list");
 

Modified: branches/headercleanup/src/dynpmc/dynlexpad.pmc
==============================================================================
--- branches/headercleanup/src/dynpmc/dynlexpad.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/dynpmc/dynlexpad.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -20,6 +20,8 @@
 */
 
 pmclass DynLexPad dynpmc provides lexpad need_ext {
+    ATTR Hash *hash;
+    ATTR PMC  *init; /* the PMC used to initialize this DynLexPad */
 
     VTABLE void init() {
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
@@ -38,16 +40,20 @@
 */
     void init_pmc(PMC* lexinfo) {
         Hash *hash;
+
+        Parrot_DynLexPad_attributes *attrs =
+            mem_allocate_zeroed_typed(Parrot_DynLexPad_attributes);
+        PMC_data(SELF) = attrs;
+
         if (VTABLE_elements(interp, lexinfo)) {
-            PMC_pmc_val(SELF) =
-                pmc_new_init(interp, enum_class_LexPad, lexinfo);
+            attrs->init = pmc_new_init(interp, enum_class_LexPad, lexinfo);
         }
         else
-            PMC_pmc_val(SELF) = NULL;
+            attrs->init = NULL;
 
-        hash                 = parrot_new_hash(INTERP);
-        PMC_struct_val(SELF) = hash;
-        hash->container      = SELF;
+        hash             = parrot_new_hash(INTERP);
+        attrs->hash      = hash;
+        hash->container  = SELF;
         PObj_custom_mark_destroy_SETALL(SELF);
     }
 
@@ -61,7 +67,7 @@
 
 */
     void set_pointer(void* ctx) {
-        PMC *std_pad = PMC_pmc_val(SELF);
+        PMC *std_pad = PARROT_DYNLEXPAD(SELF)->init;
         if (std_pad)
             VTABLE_set_pointer(interp, std_pad, ctx);
     }
@@ -76,7 +82,7 @@
 
 */
     INTVAL elements() {
-        return parrot_hash_size(interp, (Hash*) PMC_struct_val(SELF));
+        return parrot_hash_size(interp, PARROT_DYNLEXPAD(SELF)->hash);
     }
 
 /*
@@ -98,9 +104,9 @@
 
     INTVAL exists_keyed_str(STRING* name) {
         PMC *std_pad;
-        if (parrot_hash_exists(interp, (Hash*) PMC_struct_val(SELF), name))
+        if (parrot_hash_exists(interp, PARROT_DYNLEXPAD(SELF)->hash, name))
             return 1;
-        std_pad = PMC_pmc_val(SELF);
+        std_pad = PARROT_DYNLEXPAD(SELF)->init;
         if (std_pad)
             return VTABLE_exists_keyed_str(interp, std_pad, name);
         return 0;
@@ -120,10 +126,10 @@
 */
     PMC* get_pmc_keyed_str(STRING* name) {
         HashBucket *b = parrot_hash_get_bucket(interp,
-            (Hash *)PMC_struct_val(SELF), name);
+            PARROT_DYNLEXPAD(SELF)->hash, name);
 
         if (!b) {
-            PMC *std_pad = PMC_pmc_val(SELF);
+            PMC *std_pad = PARROT_DYNLEXPAD(SELF)->init;
 
             if (std_pad)
                 return VTABLE_get_pmc_keyed_str(interp, std_pad, name);
@@ -159,12 +165,12 @@
     }
 
     void set_pmc_keyed_str(STRING* name, PMC* value) {
-        PMC *std_pad = PMC_pmc_val(SELF);
+        PMC *std_pad = PARROT_DYNLEXPAD(SELF)->init;
 
         if (std_pad && VTABLE_exists_keyed_str(interp, std_pad, name))
             VTABLE_set_pmc_keyed_str(interp, std_pad, name, value);
 
-        parrot_hash_put(interp, (Hash *)PMC_struct_val(SELF), name, value);
+        parrot_hash_put(interp, PARROT_DYNLEXPAD(SELF)->hash, name, value);
     }
 
 /*
@@ -178,10 +184,11 @@
 */
 
     VTABLE void destroy() {
-        if (PMC_struct_val(SELF)) {
-            parrot_hash_destroy(interp, (Hash*) PMC_struct_val(SELF));
-            PMC_struct_val(SELF) = NULL;
+        if (PARROT_DYNLEXPAD(SELF)->hash) {
+            parrot_hash_destroy(interp, PARROT_DYNLEXPAD(SELF)->hash);
+            PARROT_DYNLEXPAD(SELF)->hash = NULL;
         }
+        mem_sys_free(PMC_data(SELF));
     }
 /*
 
@@ -194,15 +201,14 @@
 */
 
     VTABLE void mark() {
-        PMC *std_pad = PMC_pmc_val(SELF);
+        PMC *std_pad = PARROT_DYNLEXPAD(SELF)->init;
         if (std_pad)
             pobject_lives(interp, (PObj *)std_pad);
-        if (PMC_struct_val(SELF))
-            parrot_mark_hash(interp, (Hash *)PMC_struct_val(SELF));
+        if (PARROT_DYNLEXPAD(SELF)->hash)
+            parrot_mark_hash(interp, PARROT_DYNLEXPAD(SELF)->hash);
     }
 
 
-
 }
 
 

Modified: branches/headercleanup/src/dynpmc/ext.pir
==============================================================================
--- branches/headercleanup/src/dynpmc/ext.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/dynpmc/ext.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,3 +1,5 @@
+# $Id$
+
 .sub _ext_main
     print "in ext.pir\n"
     new P2, 'Undef'

Modified: branches/headercleanup/src/dynpmc/main.pasm
==============================================================================
--- branches/headercleanup/src/dynpmc/main.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/dynpmc/main.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -12,7 +12,7 @@
 _main:
 	loadlib P1, "subproxy"
 
-        # set up which Sub should eventually be called 
+        # set up which Sub should eventually be called
 	new P3, 'Key'
 	set P3, "src/dynpmc/ext.pir"	# file - FIXME path handling
 	new P4, 'Key'
@@ -27,3 +27,9 @@
 	invokecc P0
 	print "back\n"
 end
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/src/embed.c
==============================================================================
--- branches/headercleanup/src/embed.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/embed.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1158,7 +1158,7 @@
 
 PARROT_EXPORT
 void
-Parrot_disassemble(PARROT_INTERP, const char *outfile, Parrot_disassemble_options options)
+Parrot_disassemble(PARROT_INTERP, SHIM(const char *outfile), Parrot_disassemble_options options)
 {
     PDB_line_t *line;
     PDB_t      *pdb             = mem_allocate_zeroed_typed(PDB_t);

Modified: branches/headercleanup/src/exceptions.c
==============================================================================
--- branches/headercleanup/src/exceptions.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/exceptions.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -19,6 +19,7 @@
 */
 
 #include "parrot/parrot.h"
+#include "parrot/call.h"
 #include "parrot/exceptions.h"
 #include "exceptions.str"
 #include "pmc/pmc_continuation.h"
@@ -183,7 +184,11 @@
 =item C<opcode_t * Parrot_ex_throw_from_op(PARROT_INTERP, PMC *exception, void
 *dest)>
 
-Runs the exception handler.
+Throw an exception from inside an op. Looks for an exception handler in the
+current concurrency scheduler. If a suitable handler is found, invoke it and
+return the address where execution should continue. If no handler is found,
+the exception message is printed along with the current line number
+annotation and a backtrace before exiting Parrot.
 
 =cut
 
@@ -242,6 +247,9 @@
 =item C<static opcode_t * pass_exception_args(PARROT_INTERP, const char *sig,
 opcode_t *dest, Parrot_Context * old_ctx, ...)>
 
+Passes arguments to the exception handler routine. These are retrieved with
+the .get_results() directive in PIR code.
+
 =cut
 
 */
@@ -267,6 +275,10 @@
 =item C<static PMC * build_exception_from_args(PARROT_INTERP, int ex_type, const
 char *format, va_list arglist)>
 
+Builds an exception PMC with the given integer type C<ex_type>, and the string
+message given as a format/arglist combo, like is used by the Parrot_vsprintf*
+family of functions.
+
 =cut
 
 */
@@ -290,10 +302,14 @@
 
 =item C<void Parrot_ex_throw_from_c(PARROT_INTERP, PMC *exception)>
 
-Throws an exception object.
+Throws an exception object from any location in C code. A suitable handler
+is retrieved from the concurrency scheduler. If the handler is found, control
+flow is passed to it. Handlers can be either C-level or PIR-level routines. If
+no suitable handler is found, Parrot exits with the stored exception error
+message.
 
 See also C<exit_fatal()>, which signals fatal errors, and
-C<Parrot_ex_throw_from_op>.
+C<Parrot_ex_throw_from_op> which throws an exception from within an op.
 
 The 'invoke' vtable function doesn't actually execute a
 sub/continuation/handler, it only sets up the environment for invocation and
@@ -365,10 +381,10 @@
 ex_type, const char *format, ...)>
 
 Throws an exception from an opcode, with an error message constructed
-from a format string and arguments.
+from a format string and arguments. Constructs an Exception PMC, and passes it
+to C<Parrot_ex_throw_from_op>.
 
-See also C<Parrot_ex_throw_from_c>, C<Parrot_ex_throw_from_op>, and
-C<exit_fatal()>.
+See also C<Parrot_ex_throw_from_c> and C<exit_fatal()>.
 
 =cut
 
@@ -399,10 +415,10 @@
 Throws an exception, with an error message constructed from a format string and
 arguments. C<ret_addr> is the address from which to resume, if some handler
 decides that is appropriate, or zero to make the error non-resumable.
-C<exitcode> is a C<exception_type_enum> value.
+C<exitcode> is a C<exception_type_enum> value. Constructs an Exception PMC
+and passes it to C<Parrot_ex_throw_from_c>.
 
-See also C<Parrot_ex_throw_from_c>, C<Parrot_ex_throw_from_op>, and
-C<exit_fatal()>.
+See also C<Parrot_ex_throw_from_op> and C<exit_fatal()>.
 
 =cut
 
@@ -429,7 +445,9 @@
 
 =item C<opcode_t * Parrot_ex_rethrow_from_op(PARROT_INTERP, PMC *exception)>
 
-Rethrow the exception.
+Rethrow the given exception from an op, if it has previously been thrown and
+not handled by the provided handler. Marks the exception object as being
+unhandled and throws it again.
 
 =cut
 
@@ -454,8 +472,8 @@
 
 =item C<void Parrot_ex_rethrow_from_c(PARROT_INTERP, PMC *exception)>
 
-Return back to runloop, assumes exception is still in todo (see RT #45915) and
-that this is called from within a handler setup with C<new_c_exception>.
+Rethrow the exception from C code. Marks the Exception PMC as being unhandled
+and throws it again.
 
 =cut
 
@@ -498,6 +516,8 @@
 handler, and return the offset to the handler so it can become the next op in
 the runloop.
 
+TT #546: This function appears to be unused.
+
 =cut
 
 */
@@ -683,7 +703,9 @@
 =item C<void do_panic(NULLOK_INTERP, const char *message, const char *file,
 unsigned int line)>
 
-Panic handler.
+Panic handler. Things have gone very wrong in an unexpected way. Print out an
+error message and instructions for the user to report the error to the
+developers
 
 =cut
 

Modified: branches/headercleanup/src/gc/api.c
==============================================================================
--- branches/headercleanup/src/gc/api.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/gc/api.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -293,7 +293,6 @@
 
     pmc->pmc_ext     = (PMC_EXT *)0xdeadbeef;
     pmc->vtable      = (VTABLE  *)0xdeadbeef;
-    PMC_pmc_val(pmc) = (PMC     *)0xdeadbeef;
 
 #endif
 

Modified: branches/headercleanup/src/gc/register.c
==============================================================================
--- branches/headercleanup/src/gc/register.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/gc/register.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -272,8 +272,7 @@
     }
 
     if (Interp_debug_TEST(interp, PARROT_REG_DEBUG_FLAG)) {
-        /* depending on -D40 we set int, num to garbage different garbage
-         * RT #46179 remove this code for parrot 1.0 */
+        /* depending on -D40 we set int and num to be identifiable garbage values */
         for (i = 0; i < ctx->n_regs_used[REGNO_INT]; i++) {
             CTX_REG_INT(ctx, i) = -999;
         }
@@ -281,14 +280,6 @@
             CTX_REG_NUM(ctx, i) = -99.9;
         }
     }
-    else {
-        for (i = 0; i < ctx->n_regs_used[REGNO_INT]; i++) {
-            CTX_REG_INT(ctx, i) = -888;
-        }
-        for (i = 0; i < ctx->n_regs_used[REGNO_NUM]; i++) {
-            CTX_REG_NUM(ctx, i) = -88.8;
-        }
-    }
 }
 
 

Modified: branches/headercleanup/src/io/socket_api.c
==============================================================================
--- branches/headercleanup/src/io/socket_api.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/io/socket_api.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -21,6 +21,7 @@
 #include "parrot/parrot.h"
 #include "io_private.h"
 #include "api.str"
+#include "../pmc/pmc_socket.h"
 
 #include <stdarg.h>
 
@@ -110,7 +111,15 @@
 Parrot_io_socket_is_closed(ARGMOD(PMC *socket))
 {
     ASSERT_ARGS(Parrot_io_socket_is_closed)
-    return 0;
+#ifdef PIO_OS_WIN32
+    return (PARROT_SOCKET(socket)->os_handle == (PIOHANDLE)INVALID_HANDLE_VALUE);
+#endif
+#ifdef PIO_OS_UNIX
+    return (PARROT_SOCKET(socket)->os_handle == (PIOHANDLE)-1);
+#endif
+#ifdef PIO_OS_STDIO
+    return (PARROT_SOCKET(socket)->os_handle == (PIOHANDLE)NULL);
+#endif
 }
 
 /*

Modified: branches/headercleanup/src/io/win32.c
==============================================================================
--- branches/headercleanup/src/io/win32.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/io/win32.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -142,19 +142,19 @@
         _PIO_STDIN(interp) = Parrot_io_fdopen_win32(interp, PMCNULL, h, PIO_F_READ);
     }
     else {
-        return -1;
+        _PIO_STDIN(interp) = PMCNULL;
     }
     if ((h = GetStdHandle(STD_OUTPUT_HANDLE)) != INVALID_HANDLE_VALUE) {
         _PIO_STDOUT(interp) = Parrot_io_fdopen_win32(interp, PMCNULL, h, PIO_F_WRITE);
     }
     else {
-        return -2;
+        _PIO_STDOUT(interp) = PMCNULL;
     }
     if ((h = GetStdHandle(STD_ERROR_HANDLE)) != INVALID_HANDLE_VALUE) {
         _PIO_STDERR(interp) = Parrot_io_fdopen_win32(interp, PMCNULL, h, PIO_F_WRITE);
     }
     else {
-        return -3;
+        _PIO_STDERR(interp) = PMCNULL;
     }
 #  if PARROT_NET_DEVEL
     /* Start Winsock

Modified: branches/headercleanup/src/jit.c
==============================================================================
--- branches/headercleanup/src/jit.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/jit.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -35,6 +35,7 @@
 #include "parrot/packfile.h"
 #include "parrot/oplib/ops.h"
 #include "pmc/pmc_sub.h"
+#include "pmc/pmc_managedstruct.h"
 
 #define JIT_SEGS 0
 
@@ -1257,7 +1258,7 @@
     }
     /* arena stuff */
     mem_sys_free(jit_info->arena.op_map);
-    mem_free_executable(jit_info->arena.start);
+    mem_free_executable(jit_info->arena.start, jit_info->arena.size);
     fixup = jit_info->arena.fixups;
     while (fixup) {
         next_f = fixup->next;
@@ -1525,7 +1526,7 @@
                 Parrot_jit_extend_arena(jit_info);
 #else
                 new_arena = (char *)mem_realloc_executable(jit_info->arena.start,
-                        (size_t)jit_info->arena.size * 2);
+                        jit_info->arena.size, (size_t)jit_info->arena.size * 2);
                 jit_info->arena.size *= 2;
                 jit_info->native_ptr  = new_arena +
                     (jit_info->native_ptr - jit_info->arena.start);
@@ -1753,6 +1754,79 @@
 
 /*
 
+=item C<void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv)>
+
+This is a callback to implement the proper freeing semantics.  It is called by
+the ManagedStruct PMC as it is garbage collected.
+
+=cut
+
+*/
+
+void
+Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv)
+{
+    struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv;
+    mem_free_executable(ptr, jit->size);
+    free(priv);
+}
+
+/*
+
+=item C<PMC *Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv)>
+
+This is a callback to implement the proper cloning semantics for jit buffers.
+It is called by the ManagedStruct PMC's clone() function.
+
+=cut
+
+*/
+
+PMC *
+Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv)
+{
+    struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv;
+    PMC *rv = pmc_new(interp, pmc->vtable->base_type);
+    void *tmp, *freepriv, *clonepriv;
+
+    VTABLE_init(interp, rv);
+    /* copy the attributes */
+    GETATTR_ManagedStruct_custom_free_func(interp, pmc, tmp);
+    SETATTR_ManagedStruct_custom_free_func(interp, rv , tmp);
+    GETATTR_ManagedStruct_custom_clone_func(interp, pmc, tmp);
+    SETATTR_ManagedStruct_custom_clone_func(interp, rv , tmp);
+    GETATTR_ManagedStruct_custom_free_priv(interp , pmc, freepriv);
+    GETATTR_ManagedStruct_custom_clone_priv(interp, pmc, clonepriv);
+    if (freepriv) {
+        tmp = mem_sys_allocate(sizeof (struct jit_buffer_private_data));
+        memcpy(tmp, freepriv, sizeof (struct jit_buffer_private_data));
+        SETATTR_ManagedStruct_custom_free_priv(interp, rv , tmp);
+        if (clonepriv == freepriv) {
+            /* clonepriv is a copy of freepriv, make it a copy in the clone too. */
+            SETATTR_ManagedStruct_custom_clone_priv(interp, rv , tmp);
+            clonepriv = NULL; /* disable the clonepriv copying below */
+        }
+    }
+    if (clonepriv) {
+        tmp = mem_sys_allocate(sizeof (struct jit_buffer_private_data));
+        memcpy(tmp, clonepriv, sizeof (struct jit_buffer_private_data));
+        SETATTR_ManagedStruct_custom_clone_priv(interp, rv , tmp);
+    }
+
+    /* copy the execmem buffer */
+    if (PARROT_MANAGEDSTRUCT(pmc)->ptr) {
+        void *newptr, *ptr = PARROT_MANAGEDSTRUCT(pmc)->ptr;
+        newptr = mem_alloc_executable(jit->size);
+        memcpy(newptr, ptr, jit->size);
+        PARROT_MANAGEDSTRUCT(rv)->ptr = newptr;
+    }
+
+    return rv;
+}
+
+
+/*
+
 =back
 
 =head1 SEE ALSO

Modified: branches/headercleanup/src/jit.h
==============================================================================
--- branches/headercleanup/src/jit.h	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/jit.h	Wed Apr 15 19:17:06 2009	(r38132)
@@ -321,7 +321,13 @@
 /*
  * NCI interface
  */
-void *Parrot_jit_build_call_func(Interp *, PMC *, STRING *);
+void *Parrot_jit_build_call_func(Interp *, PMC *, STRING *, int *);
+/* custom pmc callback functions */
+void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv);
+PMC* Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv);
+struct jit_buffer_private_data {
+    int size;
+};
 
 #endif /* PARROT_JIT_H_GUARD */
 

Modified: branches/headercleanup/src/jit/i386/jit_defs.c
==============================================================================
--- branches/headercleanup/src/jit/i386/jit_defs.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/jit/i386/jit_defs.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -12,6 +12,7 @@
 #include "parrot/oplib/ops.h"
 #include "pmc/pmc_fixedintegerarray.h"
 #include "pmc/pmc_unmanagedstruct.h"
+#include "pmc/pmc_pointer.h"
 #include "jit.h"
 #include "jit_emit.h"
 
@@ -2116,10 +2117,13 @@
  * The generate function for a specific signature looks quite similar to
  * an optimized compile of src/nci.c:pcf_x_yy(). In case of any troubles
  * just compare the disassembly.
+ *
+ * If a non-NULL sizeptr is passed, the integer it points to will be written
+ * with the size of the allocated execmem buffer.
  */
 
 void *
-Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature)
+Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature, int *sizeptr)
 {
     Parrot_jit_info_t jit_info;
     char     *pc;
@@ -2263,8 +2267,11 @@
                 break;
             case 'V':
                 emitm_call_cfunc(pc, get_nci_P);
-                emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(struct PMC, data));
-                /* emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, 0); */
+                emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
+                /* Call the get_pointer VTABLE on the Pointer PMC to get the returned pointer */
+                emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(PMC, vtable));
+                emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(VTABLE, get_pointer));
+                emitm_callr(pc, emit_EAX);
                 emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
                 break;
             case 'b':   /* buffer (void*) pass PObj_bufstart(SReg) */
@@ -2289,16 +2296,9 @@
             case '2':
             case '3':
             case '4':
-                mem_free_executable(jit_info.native_ptr);
+                mem_free_executable(jit_info.native_ptr, JIT_ALLOC_SIZE);
                 return NULL;
                 break;
-                /* This might be right. Or not... */
-                /* we need the offset of PMC_int_val */
-                emitm_call_cfunc(pc, get_nci_P);
-                emitm_lea_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1,
-                              (size_t) &PMC_int_val((PMC *) 0));
-                emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, args_offset);
-                break;
             default:
                 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR,
                     "Unknown arg Signature %c\n", *sig);
@@ -2306,7 +2306,7 @@
                  * oops unknown signature:
                  * cleanup and try nci.c
                  */
-                mem_free_executable(jit_info.native_ptr);
+                mem_free_executable(jit_info.native_ptr, JIT_ALLOC_SIZE);
                 return NULL;
         }
         args_offset +=4;
@@ -2314,10 +2314,25 @@
         sig++;
     }
 
-    emitm_addl_i_r(pc, 16, emit_ESP);
-    /* get the pmc from stack - movl 12(%ebp), %eax */
+    /* prepare to call VTABLE_get_pointer, set up args */
+    /* interpreter - movl 8(%ebp), %eax */
+    emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 8);
+    emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 0);
+
+    /* pmc - movl 12(%ebp), %eax */
     emitm_movl_m_r(interp, pc, emit_EAX, emit_EBP, 0, 1, 12);
-    emitm_callm(pc, emit_EAX, emit_None, emit_None, 0);
+    emitm_movl_r_m(interp, pc, emit_EAX, emit_EBP, 0, 1, temp_calls_offset + 4);
+
+    /* get the get_pointer() pointer from the pmc's vtable */
+    emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(PMC, vtable));
+    emitm_movl_m_r(interp, pc, emit_EAX, emit_EAX, 0, 1, offsetof(VTABLE, get_pointer));
+
+    /* call get_pointer(), result goes into eax */
+    emitm_callr(pc, emit_EAX);
+    emitm_addl_i_r(pc, 16, emit_ESP);
+
+    /* call the resulting function pointer */
+    emitm_callr(pc, emit_EAX);
     emitm_subl_i_r(pc, 16, emit_ESP);
 
     /* SAVE OFF EAX */
@@ -2435,7 +2450,7 @@
              * oops unknown signature:
              * cleanup and try nci.c
              */
-            mem_free_executable(jit_info.native_ptr);
+            mem_free_executable(jit_info.native_ptr, JIT_ALLOC_SIZE);
             return NULL;
     }
 
@@ -2453,6 +2468,8 @@
     PARROT_ASSERT(pc - jit_info.arena.start <= JIT_ALLOC_SIZE);
     /* could shrink arena.start here to used size */
     PObj_active_destroy_SET(pmc_nci);
+    if (sizeptr)
+        *sizeptr = JIT_ALLOC_SIZE;
     return (void *)D2FPTR(jit_info.arena.start);
 }
 

Modified: branches/headercleanup/src/jit/i386/jit_emit.h
==============================================================================
--- branches/headercleanup/src/jit/i386/jit_emit.h	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/jit/i386/jit_emit.h	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1879,7 +1879,7 @@
 size_t calc_signature_needs(const char *sig, int *strings);
 
 void * Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci,
-    STRING *signature);
+    STRING *signature, int *sizeptr);
 
 /*
  * register usage

Modified: branches/headercleanup/src/jit/ppc/jit_emit.h
==============================================================================
--- branches/headercleanup/src/jit/ppc/jit_emit.h	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/jit/ppc/jit_emit.h	Wed Apr 15 19:17:06 2009	(r38132)
@@ -880,7 +880,7 @@
 {
     PMC    *sig_pmc  = CONTEXT(interp)->constants[CUR_OPCODE[1]]->u.key;
     INTVAL *sig_bits = PMC_data_typed(sig_pmc, INTVAL *);
-    INTVAL  n        = PMC_int_val(sig_pmc);
+    INTVAL  n        = VTABLE_get_integer(interp, sig_pmc);
     INTVAL  i;
 
     jit_info->n_args = n;

Modified: branches/headercleanup/src/key.c
==============================================================================
--- branches/headercleanup/src/key.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/key.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -416,7 +416,6 @@
         return REG_NUM(interp, int_key);
     case KEY_pmc_FLAG:
         return VTABLE_get_number(interp, key);
-                                                 /*  PMC_pmc_val(key)); */
     case KEY_pmc_FLAG | KEY_register_FLAG:
         {
         PMC *reg;
@@ -470,7 +469,6 @@
                 s = Parrot_str_new_COW(interp, s);
             return s;
         }
-                                               /*   PMC_pmc_val(key)); */
         case KEY_pmc_FLAG | KEY_register_FLAG:
         {
             PMC *reg;
@@ -524,7 +522,7 @@
         GETATTR_Key_int_key(interp, key, int_key);
         return REG_PMC(interp, int_key);
     default:
-        return key; /* PMC_pmc_val(key); */
+        return key;
     }
 }
 

Modified: branches/headercleanup/src/misc.c
==============================================================================
--- branches/headercleanup/src/misc.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/misc.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -252,7 +252,8 @@
 
 PARROT_EXPORT
 int
-Parrot_secret_snprintf(ARGOUT(char *buffer), const size_t len, ARGIN(const char *format), ...)
+Parrot_secret_snprintf(ARGOUT(char *buffer), SHIM(const size_t len),
+        ARGIN(const char *format), ...)
 {
     ASSERT_ARGS(Parrot_secret_snprintf)
     int retval;

Modified: branches/headercleanup/src/nci_test.c
==============================================================================
--- branches/headercleanup/src/nci_test.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/nci_test.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -108,6 +108,7 @@
 PARROT_EXPORT char * nci_ttt(char *, char *);
 PARROT_EXPORT void   nci_vfff(float, float, float);
 PARROT_EXPORT void   nci_vV(const char **);
+PARROT_EXPORT void   nci_vVVV(const char **, const char **, const char **);
 
 /* Declarations for callback tests */
 
@@ -1170,6 +1171,25 @@
   *ptr = "Hello bright new world\n";
 }
 
+/*
+
+=item C<PARROT_EXPORT float
+nci_fff(float l1, float l2)>
+
+Returns the result of C<l1> / C<l2>.
+
+=cut
+
+*/
+
+PARROT_EXPORT void
+nci_vVVV(const char **ptr1, const char **ptr2, const char **ptr3)
+{
+  *ptr1 = "Hello bright new world!\n";
+  *ptr2 = "It is a beautiful day!\n";
+  *ptr3 = "Go suck a lemon.\n";
+}
+
 #ifdef TEST
 
 char l2 = 4;

Modified: branches/headercleanup/src/oo.c
==============================================================================
--- branches/headercleanup/src/oo.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/oo.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -538,7 +538,6 @@
                     "Unrecognized class name PMC type");
             break;
     }
-    return 0;
 }
 
 

Modified: branches/headercleanup/src/pbc_info.c
==============================================================================
--- branches/headercleanup/src/pbc_info.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pbc_info.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -62,7 +62,7 @@
 */
 
 int
-main(int argc, char *argv[])
+main(SHIM(int argc), char *argv[])
 {
     PackFile *pf;
     Interp *interp;

Modified: branches/headercleanup/src/pmc.c
==============================================================================
--- branches/headercleanup/src/pmc.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -690,9 +690,6 @@
 
         gc_flag_CLEAR(is_special_PMC, _class);
 
-        PMC_pmc_val(_class)    = (PMC  *)0xdeadbeef;
-        PMC_struct_val(_class) = (void *)0xdeadbeef;
-
         PObj_is_PMC_shared_CLEAR(_class);
 
         interp->vtables[type]->pmc_class = _class;

Modified: branches/headercleanup/src/pmc/array.pmc
==============================================================================
--- branches/headercleanup/src/pmc/array.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/array.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1156,9 +1156,7 @@
             PMC * const item2 = VTABLE_get_pmc_keyed_int(INTERP, value, j);
 
             if (item1 != item2) {
-                INTVAL result;
-                Parrot_mmd_multi_dispatch_from_c_args(INTERP, "is_equal",
-                    "PP->I", item1, item2, &result);
+                INTVAL result = VTABLE_is_equal(INTERP, item1, item2);
                 if (!result)
                     return 0;
             }

Modified: branches/headercleanup/src/pmc/bigint.pmc
==============================================================================
--- branches/headercleanup/src/pmc/bigint.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/bigint.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -606,6 +606,7 @@
 
 */
     VTABLE PMC *instantiate(PMC *sig) {
+        UNUSED(sig)
         return PMCNULL;
 
         /* TODO -- actually build this thing */
@@ -852,6 +853,7 @@
     }
 
     MULTI PMC *add(DEFAULT value, PMC *dest) {
+        UNUSED(dest)
         Parrot_ex_throw_from_c_args(INTERP, NULL,
             EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
             "BigInt: no multiple dispatch variant 'add' for %Ss",
@@ -885,6 +887,7 @@
     }
 
     VTABLE void i_add_float(FLOATVAL value) {
+        UNUSED(value)
         Parrot_ex_throw_from_c_args(INTERP, NULL,
             EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
             "BigInt: no multiple dispatch variant 'i_add_float' for FLOATVAL");
@@ -912,6 +915,7 @@
     }
 
     MULTI PMC *subtract(DEFAULT value, PMC *dest) {
+        UNUSED(dest)
         Parrot_ex_throw_from_c_args(INTERP, NULL,
             EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
             "BigInt: no multiple dispatch variant 'subtract' for %Ss",
@@ -948,6 +952,7 @@
     }
 
     VTABLE void i_subtract_float(FLOATVAL value) {
+        UNUSED(value)
         Parrot_ex_throw_from_c_args(INTERP, NULL,
             EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
             "BigInt: no multiple dispatch variant 'i_subtract_float' for FLOATVAL");
@@ -969,6 +974,7 @@
     }
 
     MULTI PMC *multiply(DEFAULT value, PMC *dest) {
+        UNUSED(dest)
          Parrot_ex_throw_from_c_args(INTERP, NULL,
             EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
             "BigInt: no multiple dispatch variant 'multiply' for %Ss",
@@ -1000,6 +1006,7 @@
     }
 
     VTABLE void i_multiply_float(FLOATVAL value) {
+        UNUSED(value)
         Parrot_ex_throw_from_c_args(INTERP, NULL,
             EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
             "BigInt: no multiple dispatch variant 'i_multiply_float' for FLOATVAL");
@@ -1055,6 +1062,7 @@
     }
 
     MULTI PMC *divide(DEFAULT value, PMC *dest) {
+        UNUSED(dest)
         Parrot_ex_throw_from_c_args(INTERP, NULL,
             EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
             "BigInt: no multiple dispatch variant 'divide' for %Ss",
@@ -1103,6 +1111,7 @@
     }
 
     MULTI PMC *floor_divide(DEFAULT value, PMC *dest) {
+        UNUSED(dest)
         Parrot_ex_throw_from_c_args(INTERP, NULL,
             EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
             "BigInt: no multiple dispatch variant 'floor_divide' for %Ss",
@@ -1159,6 +1168,7 @@
     }
 
     MULTI PMC *modulus(DEFAULT value, PMC *dest) {
+        UNUSED(dest)
         Parrot_ex_throw_from_c_args(INTERP, NULL,
             EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
             "BigInt: no multiple dispatch variant 'modulus' for %Ss",
@@ -1296,6 +1306,7 @@
         return dest;
     }
     MULTI PMC *bitwise_shl(DEFAULT value, PMC *dest) {
+        UNUSED(dest)
         Parrot_ex_throw_from_c_args(INTERP, NULL,
             EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
             "BigInt: no multiple dispatch variant 'bitwise_shl' for %Ss",
@@ -1377,6 +1388,7 @@
     }
 
     MULTI PMC *bitwise_shr(DEFAULT value, PMC *dest) {
+        UNUSED(dest)
         Parrot_ex_throw_from_c_args(INTERP, NULL,
             EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
             "BigInt: no multiple dispatch variant 'bitwise_shr' for %Ss",

Modified: branches/headercleanup/src/pmc/class.pmc
==============================================================================
--- branches/headercleanup/src/pmc/class.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/class.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1605,8 +1605,9 @@
 
 */
 
-    void thawfinish(visit_info *info) {
+    VTABLE void thawfinish(visit_info *info) {
         Parrot_Class_attributes * const _class = PARROT_CLASS(SELF);
+        UNUSED(info)
 
         /* Recalculate full MRO from thawed parents */
         _class->all_parents         = Parrot_ComputeMRO_C3(interp, SELF);

Modified: branches/headercleanup/src/pmc/codestring.pmc
==============================================================================
--- branches/headercleanup/src/pmc/codestring.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/codestring.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -153,7 +153,7 @@
     }
     RETURN(INTVAL line);
 }
-        
+
 
 /*
 

Modified: branches/headercleanup/src/pmc/continuation.pmc
==============================================================================
--- branches/headercleanup/src/pmc/continuation.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/continuation.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -234,6 +234,7 @@
         Parrot_Context   *from_ctx     = CONTEXT(interp);
         Parrot_Context   *to_ctx       = cc->to_ctx;
         opcode_t         *pc           = cc->address;
+        UNUSED(next)
 
         Parrot_continuation_check(interp, SELF, cc);
         Parrot_continuation_rewind_environment(interp, SELF, cc);

Modified: branches/headercleanup/src/pmc/coroutine.pmc
==============================================================================
--- branches/headercleanup/src/pmc/coroutine.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/coroutine.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -144,7 +144,6 @@
             Parrot_Context *ctx;
             PMC *ccont;
 
-            /* RT#46699 factor out common code with Sub.invoke and inherit it */
             ccont = INTERP->current_cont;
 
             if (ccont == NEED_CONTINUATION)

Modified: branches/headercleanup/src/pmc/cpointer.pmc
==============================================================================
--- branches/headercleanup/src/pmc/cpointer.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/cpointer.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -182,6 +182,8 @@
 
     VTABLE STRING *get_string_keyed_str(STRING *key) {
         Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
+        UNUSED(key)
+
         return data->sig;
     }
 
@@ -197,6 +199,8 @@
 
     VTABLE void set_string_keyed_str(STRING *key, STRING *value) {
         Parrot_CPointer_attributes * const data = PARROT_CPOINTER(SELF);
+        UNUSED(key)
+
         data->sig = value;
     }
 

Modified: branches/headercleanup/src/pmc/default.pmc
==============================================================================
--- branches/headercleanup/src/pmc/default.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/default.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -59,6 +59,7 @@
 
 */
 
+PARROT_DOES_NOT_RETURN
 static void
 cant_do_method(PARROT_INTERP, PMC *pmc /*NULLOK*/, const char *methname)
 {
@@ -890,6 +891,7 @@
 */
 
     INTVAL does_pmc(PMC *role) {
+        UNUSED(role)
         /* No C-level roles yet. */
         return 0;
     }
@@ -1021,10 +1023,12 @@
 
 */
     VTABLE PMC *get_attr_keyed(PMC *key, STRING *name) {
+        UNUSED(key)
         return VTABLE_get_attr_str(INTERP, SELF, name);
     }
 
     VTABLE void set_attr_keyed(PMC *key, STRING *name, PMC *value) {
+        UNUSED(key)
         VTABLE_set_attr_str(INTERP, SELF, name, value);
     }
 
@@ -1039,6 +1043,7 @@
 */
 
     VTABLE void add_parent(PMC *parent) {
+        UNUSED(parent)
         if (!PObj_is_class_TEST(SELF))
             Parrot_ex_throw_from_c_args(interp, NULL, 1,
                 "Only classes can be subclassed");
@@ -1097,6 +1102,7 @@
 */
 
     VTABLE void freeze(visit_info *info) {
+        UNUSED(info)
         /* default - no action */
     }
 
@@ -1135,7 +1141,8 @@
 
 */
 
-    void thawfinish(visit_info *info) {
+    VTABLE void thawfinish(visit_info *info) {
+        UNUSED(info)
         /* default - no action */
     }
 

Modified: branches/headercleanup/src/pmc/hash.pmc
==============================================================================
--- branches/headercleanup/src/pmc/hash.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/hash.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -35,6 +35,7 @@
 */
 
 static PMC *get_integer_pmc(PARROT_INTERP, INTVAL base_type) {
+    UNUSED(base_type)
     return pmc_new(interp, Parrot_get_ctx_HLL_type(interp, enum_class_Integer));
 }
 
@@ -52,6 +53,7 @@
 */
 
 static PMC *get_number_pmc(PARROT_INTERP, INTVAL base_type) {
+    UNUSED(base_type)
     return pmc_new(interp, Parrot_get_ctx_HLL_type(interp, enum_class_Float));
 }
 
@@ -68,6 +70,7 @@
 */
 
 static PMC *get_string_pmc(PARROT_INTERP, INTVAL base_type) {
+    UNUSED(base_type)
     return pmc_new(interp, Parrot_get_ctx_HLL_type(interp, enum_class_String));
 }
 
@@ -1040,7 +1043,7 @@
     VTABLE PMC *slice(PMC *key, INTVAL f) {
         if (f == 0) {
             PMC * const iter = pmc_new_init(INTERP, enum_class_Iterator, SELF);
-            PMC_struct_val(iter) = key;
+            PARROT_ITERATOR(iter)->key = key;
             return iter;
         }
 

Modified: branches/headercleanup/src/pmc/integer.pmc
==============================================================================
--- branches/headercleanup/src/pmc/integer.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/integer.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -135,7 +135,8 @@
             ? constant_pmc_new(INTERP, type)
             : pmc_new(INTERP, type);
 
-        /* RT #46623 bigint overflow */
+        /* Parrot_str_to_int catches overflow automatically, so we don't need to
+           worry about it here. */
         VTABLE_set_integer_native(INTERP, res, Parrot_str_to_int(INTERP, rep));
         return res;
     }
@@ -425,26 +426,32 @@
 
 */
 
-    MULTI void i_add(Integer value) {
-        STATICSELF.i_add_int(VTABLE_get_integer(INTERP, value));
-    }
-
-
-    MULTI void i_add(Complex value) {
-        const INTVAL a = SELF.get_integer();
+    VTABLE void i_add(PMC *value) {
+        const INTVAL type = value->vtable->base_type;
 
-        pmc_reuse(INTERP, SELF, enum_class_Complex, 0);
-        VTABLE_set_number_native(INTERP, SELF,
-                SELF.get_integer() + VTABLE_get_number(INTERP, value));
+        switch (type) {
+            case enum_class_Integer:
+                STATICSELF.i_add_int(VTABLE_get_integer(INTERP, value));
+                break;
+
+            case enum_class_Complex:
+                pmc_reuse(INTERP, SELF, enum_class_Complex, 0);
+                VTABLE_set_number_native(INTERP, SELF,
+                        SELF.get_integer() + VTABLE_get_number(INTERP, value));
+                break;
+
+            default:
+                VTABLE_set_number_native(INTERP, SELF,
+                        SELF.get_integer() + VTABLE_get_number(INTERP, value));
+                break;
+        }
     }
 
-
     MULTI void i_add(DEFAULT value) {
         VTABLE_set_number_native(INTERP, SELF,
                 SELF.get_integer() + VTABLE_get_number(INTERP, value));
     }
 
-
     VTABLE void i_add_int(INTVAL b) {
         const INTVAL a = SELF.get_integer();
         const INTVAL c = a + b;
@@ -1149,16 +1156,20 @@
 
 */
 
-    MULTI INTVAL is_equal(BigInt value) {
-        PMC * const temp = pmc_new(INTERP, enum_class_BigInt);
-        VTABLE_set_integer_native(INTERP, temp, SELF.get_integer());
-        return Parrot_BigInt_multi_is_equal_BigInt(INTERP, temp, value);
-    }
-
+    VTABLE INTVAL is_equal(PMC *value) {
+        PMC *temp;
 
-    MULTI INTVAL is_equal(DEFAULT value) {
-        return (VTABLE_get_integer(INTERP, SELF)
-            ==  VTABLE_get_integer(INTERP, value));
+        switch (value->vtable->base_type) {
+            case enum_class_BigInt:
+                temp = pmc_new(INTERP, enum_class_BigInt);
+                VTABLE_set_integer_native(INTERP, temp, SELF.get_integer());
+                return Parrot_BigInt_multi_is_equal_BigInt(INTERP, temp, value);
+                break;
+            default:
+                return (VTABLE_get_integer(INTERP, SELF)
+                    ==  VTABLE_get_integer(INTERP, value));
+                break;
+        }
     }
 
 

Modified: branches/headercleanup/src/pmc/key.pmc
==============================================================================
--- branches/headercleanup/src/pmc/key.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/key.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -487,6 +487,7 @@
 
     VTABLE void thawfinish(visit_info *info) {
         PMC *key = SELF;
+        UNUSED(info)
 
         while (1) {
             PMC *next;

Modified: branches/headercleanup/src/pmc/lexinfo.pmc
==============================================================================
--- branches/headercleanup/src/pmc/lexinfo.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/lexinfo.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -66,7 +66,6 @@
         Parrot_LexInfo_attributes *attrs =
             mem_allocate_zeroed_typed(Parrot_LexInfo_attributes);
         PARROT_ASSERT(PObj_constant_TEST(SELF));
-        PMC_pmc_val(SELF) = sub;
 
         hash = parrot_create_hash(INTERP,
             (PARROT_DATA_TYPE)enum_hash_int,

Modified: branches/headercleanup/src/pmc/managedstruct.pmc
==============================================================================
--- branches/headercleanup/src/pmc/managedstruct.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/managedstruct.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -21,8 +21,21 @@
 
 #include "parrot/parrot.h"
 
+typedef void (*custom_free_func_t)(PARROT_INTERP, void *ptr, void *priv);
+typedef PMC * (*custom_clone_func_t)(PARROT_INTERP, PMC *ptr, void *priv);
 
 pmclass ManagedStruct extends UnManagedStruct need_ext {
+    /* if custom_free_func and ptr (inherited from UnManagedStruct) are both set,
+     * custom_free_func is called before the normal destroy() function does any
+     * work.
+     */
+    ATTR void *custom_free_func;
+    ATTR void *custom_free_priv;
+    /* if custom_clone_func is set, it will be called *instead* of the normal
+     * clone() function logic.
+     */
+    ATTR void *custom_clone_func;
+    ATTR void *custom_clone_priv;
 
 /*
 
@@ -63,13 +76,24 @@
 
 Destroys the struct, freeing the allocated memory.
 
+If the "custom_free_func" attribute is set, it is called to free the pointer.
+Otherwise, mem_sys_free() is used.
+
 =cut
 
 */
 
     VTABLE void destroy() {
-        if (PARROT_MANAGEDSTRUCT(SELF)->ptr)
-            mem_sys_free(PARROT_MANAGEDSTRUCT(SELF)->ptr);
+        void *ptr = PARROT_MANAGEDSTRUCT(SELF)->ptr;
+        if (ptr) {
+            custom_free_func_t free_func =
+                (custom_free_func_t)PARROT_MANAGEDSTRUCT(SELF)->custom_free_func;
+            if (free_func) {
+                void *free_data = PARROT_MANAGEDSTRUCT(SELF)->custom_free_priv;
+                free_func(interp, ptr, free_data);
+            } else
+                mem_sys_free(ptr);
+        }
         mem_sys_free(PMC_data(SELF));
     }
 
@@ -109,16 +133,25 @@
 
 =item C<PMC * clone()>
 
-Creates a clone of this PMC; clones any unmanaged memory it holds too.  Note
-that the latter is only a shallow copy, as there's no general way of knowing
-how to clone I<that> data.
+Creates a clone of this PMC; clones any unmanaged memory it holds too.
+
+If the "custom_clone_func" attribute is set, it is called to clone the PMC.
+Otherwise, a basic (shallow copy) clone is performed, as there's no general way
+of knowing how to make a deep copy of the pointer contents.
 
 =cut
 
 */
 
     VTABLE PMC *clone() {
-        PMC *dest = pmc_new_init(interp, SELF->vtable->base_type,
+        custom_clone_func_t clone_func =
+            (custom_clone_func_t)PARROT_MANAGEDSTRUCT(SELF)->custom_clone_func;
+        PMC *dest;
+        if (clone_func) {
+            void *clone_data = PARROT_MANAGEDSTRUCT(SELF)->custom_clone_priv;
+            return clone_func(interp, SELF, clone_data);
+        }
+        dest = pmc_new_init(interp, SELF->vtable->base_type,
             PARROT_MANAGEDSTRUCT(SELF)->init);
 
         if (PARROT_MANAGEDSTRUCT(SELF)->ptr)

Modified: branches/headercleanup/src/pmc/namespace.pmc
==============================================================================
--- branches/headercleanup/src/pmc/namespace.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/namespace.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -10,14 +10,6 @@
 
 These are the vtable functions for the namespace PMC.
 
-=head2 Data
-
-  PMC_struct_val       ... the hash, bucket->value is a
-                           var/sub, a namespace, or a FixedPMCarray
-                           of 2 PMCs (namespace, sub/var) slots
-  PMC_pmc_val          ... parent namespace
-  PMC_data             ... Namespace information struct (name, class/role)
-
 =head2 Functions
 
 =over 4
@@ -140,6 +132,7 @@
                             * goes away when the methods are sucked in by a
                             * class. */
     ATTR PMC    *vtable;   /* A Hash of vtable subs, keyed on the vtable index */
+    ATTR PMC    *parent;   /* This NameSpace's parent NameSpace */
 
 /*
 
@@ -153,7 +146,6 @@
 
     VTABLE void init() {
         SUPER();
-        PMC_pmc_val(SELF) = NULL;  /* parent */
         PMC_data(SELF)    =
                 mem_allocate_zeroed_typed(Parrot_NameSpace_attributes);
         PARROT_NAMESPACE(SELF)->vtable = PMCNULL;
@@ -175,8 +167,8 @@
     VTABLE void mark() {
         Parrot_NameSpace_attributes * const nsinfo = PARROT_NAMESPACE(SELF);
         SUPER();
-        if (PMC_pmc_val(SELF))
-            pobject_lives(INTERP, (PObj *)PMC_pmc_val(SELF));
+        if (nsinfo->parent)
+            pobject_lives(INTERP, (PObj *)nsinfo->parent);
         if (nsinfo->name)
             pobject_lives(INTERP, (PObj *)nsinfo->name);
         if (nsinfo->_class)
@@ -331,8 +323,8 @@
         if (val_is_NS) {
             /* TODO - this hack needs to go */
             Parrot_NameSpace_attributes *nsinfo = PARROT_NAMESPACE(value);
-            PMC_pmc_val(value)       = SELF;  /* set parent */
-            nsinfo->name             = key;   /* and name */
+            nsinfo->parent = SELF;  /* set parent */
+            nsinfo->name   = key;   /* and name */
 
             if (new_tuple) {
                 VTABLE_set_pmc_keyed_int(INTERP, new_tuple, NS_slot_ns, value);
@@ -651,7 +643,7 @@
         while (ns) {
             Parrot_NameSpace_attributes *nsinfo = PARROT_NAMESPACE(ns);
             VTABLE_unshift_string(INTERP, ar, nsinfo->name);
-            ns = PMC_pmc_val(ns);
+            ns = nsinfo->parent;
             elements++;
         }
 
@@ -932,7 +924,7 @@
 */
 
     METHOD get_parent() {
-        PMC *parent = PMC_pmc_val(SELF) ? PMC_pmc_val(SELF) : PMCNULL;
+        PMC *parent = PARROT_NAMESPACE(SELF)->parent ? PARROT_NAMESPACE(SELF)->parent : PMCNULL;
         RETURN(PMC *parent);
     }
 

Modified: branches/headercleanup/src/pmc/nci.pmc
==============================================================================
--- branches/headercleanup/src/pmc/nci.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/nci.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -171,6 +171,10 @@
         PObj_flag_SET(private2, SELF);
     }
 
+    VTABLE void *get_pointer() {
+        return PARROT_NCI(SELF)->orig_func;
+    }
+
     VTABLE void set_pointer_keyed_str(STRING *key, void *func) {
         Parrot_NCI_attributes * const nci_info = PARROT_NCI(SELF);
         int                             jitted = 0;
@@ -260,7 +264,7 @@
         nci_info_ret->pcc_params_signature  = nci_info_self->pcc_params_signature;
         nci_info_ret->arity                 = nci_info_self->arity;
         nci_info_ret->jitted                = nci_info_self->jitted;
-        PObj_get_FLAGS(ret)    |= (PObj_get_FLAGS(SELF) & 0x7);
+        PObj_get_FLAGS(ret)                |= (PObj_get_FLAGS(SELF) & 0x7);
 
         return ret;
     }
@@ -312,13 +316,8 @@
 
             nci_jit_sub_t jit_func = (nci_jit_sub_t) D2FPTR(nci_info->func);
 
-            /* TT #365 - Some i386 jit code depends on this.  If t/pmc/nci.t
-             * passes without it, the next line is safe to remove. */
-            PMC_struct_val(SELF) = nci_info->orig_func;
-
             /* Parrot_eprintf(interp, "JITTED %S\n", nci_info->signature); */
-            jit_func(INTERP, SELF,
-                (char *) nci_info->pcc_params_signature->strstart);
+            jit_func(INTERP, SELF, (char *) nci_info->pcc_params_signature->strstart);
         }
         else {
             if (PObj_flag_TEST(private2, SELF)) {

Modified: branches/headercleanup/src/pmc/null.pmc
==============================================================================
--- branches/headercleanup/src/pmc/null.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/null.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -46,6 +46,7 @@
     }
 
     VTABLE INTVAL does(STRING *what) {
+        UNUSED(what)
         /* XXX maybe a hack to get TGE running again */
         return 0;
     }

Modified: branches/headercleanup/src/pmc/object.pmc
==============================================================================
--- branches/headercleanup/src/pmc/object.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/object.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -764,7 +764,7 @@
 
 */
 
-    void thawfinish(visit_info *info) {
+    VTABLE void thawfinish(visit_info *info) {
         /* Set custom GC mark and destroy on the object. */
         PObj_custom_mark_SET(SELF);
         PObj_active_destroy_SET(SELF);

Modified: branches/headercleanup/src/pmc/parrotinterpreter.pmc
==============================================================================
--- branches/headercleanup/src/pmc/parrotinterpreter.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/parrotinterpreter.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -179,6 +179,8 @@
 recursion_limit(PARROT_INTERP, PMC *self, int l)
 {
     const int ret           = interp->recursion_limit;
+    UNUSED(self)
+
     interp->recursion_limit = l;
     return ret;
 }
@@ -698,10 +700,11 @@
         }
     }
 
-    void thawfinish(visit_info *info) {
+    VTABLE void thawfinish(visit_info *info) {
         PMC * const new_info = PMC_args(SELF);
         const INTVAL  m      = VTABLE_elements(INTERP, new_info);
         INTVAL  i;
+        UNUSED(info)
 
         PMC_args(SELF) = NULL;
 

Modified: branches/headercleanup/src/pmc/pointer.pmc
==============================================================================
--- branches/headercleanup/src/pmc/pointer.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/pointer.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -23,6 +23,8 @@
 #include "parrot/parrot.h"
 
 pmclass Pointer need_ext {
+    ATTR void * mark_function;
+    ATTR void * pointer;
 
 /*
 
@@ -35,11 +37,27 @@
 */
 
     VTABLE void init() {
-        PObj_custom_mark_SET(SELF);
+        PObj_custom_mark_destroy_SETALL(SELF);
+        PMC_data(SELF) = mem_allocate_zeroed_typed(Parrot_Pointer_attributes);
     }
 
 /*
 
+=item C<void destroy()>
+
+Destroy the Pointer and free associated memory
+
+=cut
+
+*/
+
+    VTABLE void destroy() {
+        mem_sys_free(PARROT_POINTER(SELF));
+    }
+
+
+/*
+
 =item C<void mark()>
 
 Marks the pointer as live.
@@ -50,10 +68,10 @@
 
     VTABLE void mark() {
         void (*mark_function)(Interp *, void *) =
-            (void (*)(Interp *, void *))D2FPTR(PMC_struct_val(SELF));
-
-        if (PMC_data(SELF) && PMC_struct_val(SELF))
-            (*mark_function)(INTERP, PMC_data(SELF));
+            (void (*)(Interp *, void *))D2FPTR(PARROT_POINTER(SELF)->mark_function);
+        void * data = PARROT_POINTER(SELF)->pointer;
+        if (data && mark_function)
+            (*mark_function)(INTERP, data);
     }
 
 /*
@@ -75,6 +93,20 @@
 
 /*
 
+=item C<void set_pointer(void *)>
+
+Sets the pointer value.
+
+=cut
+
+*/
+
+    VTABLE void set_pointer(void *ptr) {
+        PARROT_POINTER(SELF)->pointer = ptr;
+    }
+
+/*
+
 =item C<void *get_pointer()>
 
 Returns the pointer value.
@@ -84,7 +116,7 @@
 */
 
     VTABLE void *get_pointer() {
-        return PMC_data(SELF);
+        return PARROT_POINTER(SELF)->pointer;
     }
 
 /*
@@ -98,7 +130,7 @@
 */
 
     VTABLE INTVAL get_integer() {
-        return (INTVAL)PMC_data(SELF);
+        return (INTVAL)(PARROT_POINTER(SELF)->pointer);
     }
 
 /*
@@ -112,7 +144,7 @@
 */
 
     VTABLE FLOATVAL get_number() {
-        return (FLOATVAL)(INTVAL)PMC_data(SELF);
+        return (FLOATVAL)(INTVAL)(PARROT_POINTER(SELF)->pointer);
     }
 
 /*
@@ -126,7 +158,7 @@
 */
 
     VTABLE STRING *get_repr() {
-        return Parrot_sprintf_c(INTERP, "Pointer = 0x%p", PMC_data(SELF));
+        return Parrot_sprintf_c(INTERP, "Pointer = 0x%p", PARROT_POINTER(SELF)->pointer);
     }
 
 
@@ -141,7 +173,7 @@
 */
 
     VTABLE STRING *get_string() {
-        return Parrot_sprintf_c(INTERP, "%s", PMC_data(SELF));
+        return Parrot_sprintf_c(INTERP, "%s", PARROT_POINTER(SELF)->pointer);
     }
 
 /*
@@ -170,7 +202,7 @@
 
     VTABLE INTVAL is_same(PMC *pmc2) {
         return (INTVAL)(SELF->vtable   == pmc2->vtable &&
-                        PMC_data(SELF) == PMC_data(pmc2));
+                        PARROT_POINTER(SELF)->pointer == PARROT_POINTER(pmc2)->pointer);
     }
 }
 

Deleted: branches/headercleanup/src/pmc/ref.pmc
==============================================================================
--- branches/headercleanup/src/pmc/ref.pmc	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,164 +0,0 @@
-/*
-Copyright (C) 2001-2008, Parrot Foundation.
-$Id$
-
-=head1 NAME
-
-src/pmc/ref.pmc - Reference to a PMC
-
-=head1 DESCRIPTION
-
-The vtable functions for the Ref base class.
-
-All methods not present below get a default body autogenerated inside
-C<Parrot::Pmc2c>.
-
-=head2 Methods
-
-=over 4
-
-=cut
-
-*/
-
-#include "parrot/parrot.h"
-
-pmclass Ref provides ref {
-
-/*
-
-=item C<void init()>
-
-Sets the referenced PMC to C<PMCNULL>.
-
-=cut
-
-*/
-
-    VTABLE void init() {
-        SELF.init_pmc(PMCNULL);
-    }
-
-    VTABLE void destroy() {
-        SELF.init_pmc(NULL);
-        /* don't pass it on */
-    }
-
-/*
-
-=item C<void init_pmc(PMC *initializer)>
-
-Sets the referenced PMC to C<initializer>.
-
-=cut
-
-*/
-
-    VTABLE void init_pmc(PMC *initializer) {
-        /* the referred PMC itself */
-        PMC_pmc_val(SELF) = initializer;
-        PObj_custom_mark_SET(SELF);
-
-        /* if referred PMC needs active destruction we have to pass it on */
-        if (initializer && PObj_active_destroy_TEST(initializer))
-            PObj_active_destroy_SET(SELF);
-    }
-
-/*
-
-=item C<void set_pmc(PMC *other)>
-
-Sets the referenced PMC to C<*other>.
-
-=item C<PMC *get_pmc()>
-
-Get the referenced PMC.
-
-=cut
-
-*/
-
-    VTABLE void set_pmc(PMC *other) {
-        PObj_active_destroy_CLEAR(SELF);
-        GC_WRITE_BARRIER(INTERP, SELF, PMC_pmc_val(SELF), other);
-        SELF.init_pmc(other);
-    }
-
-    VTABLE void assign_pmc(PMC *other) {
-        SELF.set_pmc(other);
-    }
-
-    VTABLE PMC *get_pmc() {
-        return PMC_pmc_val(SELF);
-    }
-
-/*
-
-=item C<INTVAL type()>
-
-Returns the PMC's type.
-
-=cut
-
-*/
-
-    VTABLE INTVAL type() {
-        return VTABLE_type(interp, PMC_pmc_val(SELF));
-    }
-
-/*
-
-=item C<void mark()>
-
-Marks the referenced PMC as live.
-
-=cut
-
-*/
-
-    VTABLE void mark() {
-        pobject_lives(INTERP, (PObj *)PMC_pmc_val(SELF));
-    }
-
-/*
-
-=back
-
-These two methods must be implemented because they are not delegated.
-
-=over 4
-
-=item C<STRING *name()>
-
-Returns the name of the PMC, not the name of the referenced PMC.
-
-=cut
-
-*/
-
-    VTABLE STRING *name() {
-        return SUPER();
-    }
-
-}
-
-/*
-
-=back
-
-=head1 HISTORY
-
-Initial revision by leo 2003.09.01.
-
-Allowed null value by TOGoS 2004.07.28 (evil+bad?)
-
-=cut
-
-*/
-
-/*
- * Local variables:
- *   c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */

Modified: branches/headercleanup/src/pmc/retcontinuation.pmc
==============================================================================
--- branches/headercleanup/src/pmc/retcontinuation.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/retcontinuation.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -92,6 +92,7 @@
         Parrot_Context    *from_ctx   = cc->from_ctx;
         PackFile_ByteCode * const seg = cc->seg;
         opcode_t          *next       = cc->address;
+        UNUSED(in_next)
 
         Parrot_continuation_check(interp, SELF, cc);
         Parrot_continuation_rewind_environment(interp, SELF, cc);

Modified: branches/headercleanup/src/pmc/scalar.pmc
==============================================================================
--- branches/headercleanup/src/pmc/scalar.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/scalar.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -132,29 +132,12 @@
             SELF.set_string_native(v);
             return;
         }
-        pmc_reuse(INTERP, SELF, enum_class_Ref, 0);
+        pmc_reuse(INTERP, SELF, value->vtable->base_type, 0);
         SELF.set_pmc(value);
     }
 
 /*
 
-=item C<PMC *clone()>
-
-Creates and returns a clone of the scalar.
-
-=cut
-
-*/
-
-    VTABLE PMC *clone() {
-        PMC * const dest = pmc_new(INTERP, VTABLE_type(INTERP, SELF));
-        memcpy(&PMC_union(dest), &PMC_union(SELF), sizeof (UnionVal));
-        return dest;
-    }
-
-
-/*
-
 =back
 
 =head1 Mathematical Methods
@@ -1218,11 +1201,12 @@
 
 */
 
+/*
     MULTI INTVAL is_equal(PMC *value) {
         return (SELF->vtable         == value->vtable
-            &&  PMC_struct_val(SELF) == PMC_struct_val(value)
             &&  PMC_data(SELF)       == PMC_data(value));
     }
+*/
 
 /*
 

Modified: branches/headercleanup/src/pmc/scheduler.pmc
==============================================================================
--- branches/headercleanup/src/pmc/scheduler.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/scheduler.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -370,7 +370,7 @@
 
 */
 
-    void thawfinish(visit_info *info) {
+    VTABLE void thawfinish(visit_info *info) {
         Parrot_cx_refresh_task_list(INTERP, SELF);
     }
 

Deleted: branches/headercleanup/src/pmc/sharedref.pmc
==============================================================================
--- branches/headercleanup/src/pmc/sharedref.pmc	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,170 +0,0 @@
-/*
-Copyright (C) 2001-2008, Parrot Foundation.
-$Id$
-
-=head1 NAME
-
-src/pmc/sharedref.pmc - Shared PMC Reference
-
-=head1 DESCRIPTION
-
-The vtable functions for the SharedRef base class.
-
-This class wraps locking around PMC access.
-
-All methods not present below get a default body autogenerated inside
-C<Parrot::Pmc2c>.
-
-Currently all access is locked. When we have a non-copying GC allocator
-we can relax that a bit.
-
-=head2 Methods
-
-=over 4
-
-=cut
-
-*/
-
-#include "parrot/parrot.h"
-
-/*
- * TODO we should catch exceptions around these locks
- *      if the vtable meth throws the lock is never unlocked
- */
-#define LOCK_PMC(interp, pmc) LOCK(PMC_sync(pmc)->pmc_lock);
-#define UNLOCK_PMC(interp, pmc) UNLOCK(PMC_sync(pmc)->pmc_lock);
-
-pmclass SharedRef provides ref need_ext is_shared extends Ref {
-
-    VTABLE void init() {
-        SUPER();
-    }
-
-/*
-
-=item C<void init_pmc(PMC *init)>
-
-Initialize the shared reference.
-
-TODO - If the PMC we refer to is an aggregate (or has properties) then:
-
-=over 4
-
-=item *
-
-call C<share()> on the aggregate, which calls C<share()> on its contents
-- so getting aggregate members only yields shared PMCs
-
-=item *
-
-and unshare the aggregate itself, because we lock on behalf of the
-referee
-
-=back
-
-A direct dereference of the C<SharedRef> is currently not enabled so we
-shouldn't leak unshared PMCs into different threads.
-
-=cut
-
-*/
-
-    VTABLE void init_pmc(PMC *initializer) {
-        SUPER(initializer);
-        PObj_active_destroy_SET(SELF);
-    }
-
-/*
-
-=item C<void share()>
-
-We already share, so just ignore.
-
-=cut
-
-*/
-
-    VTABLE void share() {
-    }
-
-/*
-
-=item C<void mark()>
-
-Marks the reference as live.
-
-=cut
-
-*/
-
-    VTABLE void mark() {
-        SUPER();
-    }
-
-/*
-
-=item C<void set_pmc(PMC *other)>
-
-Sets the referenced PMC to C<*other>.
-
-=item C<PMC *get_pmc()>
-
-Catch dereferencing. This would unshare the referred PMC.
-
-=cut
-
-*/
-
-    VTABLE void set_pmc(PMC *other) {
-        SUPER(other);
-        PObj_active_destroy_SET(SELF);
-    }
-
-    VTABLE PMC *get_pmc() {
-        Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
-            "deref not allowed");
-    }
-
-/*
-
-=item C<void destroy()>
-
-Destroys the referred object and itself. This probably needs destroy ordering
-or at least a detection if the referred PMC is already destroyed.
-
-=cut
-
-*/
-
-    VTABLE void destroy() {
-        PMC * const ref = PMC_pmc_val(SELF);
-
-        if (ref && PObj_active_destroy_TEST(ref))
-            VTABLE_destroy(INTERP, ref);
-
-        if (PMC_sync(SELF)->owner != INTERP)
-            PANIC(INTERP, "SharedRef destroyed by wrong interpreter");
-
-        SUPER();
-    }
-}
-
-/*
-
-=back
-
-=head1 HISTORY
-
-Initial revision by leo 2004.01.14.
-
-=cut
-
-*/
-
-/*
- * Local variables:
- *   c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */

Modified: branches/headercleanup/src/pmc/socket.pmc
==============================================================================
--- branches/headercleanup/src/pmc/socket.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/socket.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -109,23 +109,14 @@
 
 =item C<INTVAL get_bool()>
 
-Returns whether the Socket was successfully created.
+Returns whether the Socket is currently open.
 
 =cut
 
 */
 
     VTABLE INTVAL get_bool() {
-        /* Initialize the os_handle to the platform-specific value for closed. */
-#ifdef PIO_OS_WIN32
-        return (PARROT_SOCKET(SELF)->os_handle != (PIOHANDLE)INVALID_HANDLE_VALUE);
-#endif
-#ifdef PIO_OS_UNIX
-        return (PARROT_SOCKET(SELF)->os_handle != (PIOHANDLE)-1);
-#endif
-#ifdef PIO_OS_STDIO
-        return (PARROT_SOCKET(SELF)->os_handle != (PIOHANDLE)NULL);
-#endif
+        return !Parrot_io_socket_is_closed(SELF);
     }
 
 /*

Modified: branches/headercleanup/src/pmc/sub.pmc
==============================================================================
--- branches/headercleanup/src/pmc/sub.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/sub.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -146,6 +146,7 @@
 */
 
     VTABLE void set_pointer(void *value) {
+        UNUSED(value)
         Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
             "Don't set the address of a sub\nuse .const 'Sub' instead");
     }
@@ -180,6 +181,8 @@
 
     VTABLE INTVAL get_integer_keyed(PMC *key) {
         Parrot_sub *sub;
+        UNUSED(key)
+
         PMC_get_sub(INTERP, SELF, sub);
         return (INTVAL) (sub->seg->base.data);
     }
@@ -406,6 +409,9 @@
         if (sub->name != NULL)
             sub->name = Parrot_str_copy(INTERP, sub->name);
 
+        /* Be sure not to share arg_info. */
+        dest_sub->arg_info = NULL;
+
         if (sub->ctx)
             Parrot_context_ref(INTERP, sub->ctx);
         if (sub->outer_ctx)

Modified: branches/headercleanup/src/pmc/task.pmc
==============================================================================
--- branches/headercleanup/src/pmc/task.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/task.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -520,7 +520,7 @@
 
 */
 
-    void thawfinish(visit_info *info) {
+    VTABLE void thawfinish(visit_info *info) {
         Parrot_Task_attributes * core_struct = PARROT_TASK(SELF);
 
         UNUSED(core_struct); /* TODO: Rebuild the task index. */

Modified: branches/headercleanup/src/pmc/undef.pmc
==============================================================================
--- branches/headercleanup/src/pmc/undef.pmc	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/pmc/undef.pmc	Wed Apr 15 19:17:06 2009	(r38132)
@@ -40,7 +40,7 @@
 */
 
     VTABLE void set_pmc(PMC *other) {
-        pmc_reuse(INTERP, SELF, enum_class_Ref, 0);
+        pmc_reuse(INTERP, SELF, other->vtable->base_type, 0);
         VTABLE_set_pmc(INTERP, SELF, other);
     }
 

Modified: branches/headercleanup/src/scheduler.c
==============================================================================
--- branches/headercleanup/src/scheduler.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/scheduler.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -725,7 +725,7 @@
 
 PARROT_EXPORT
 void
-Parrot_cx_send_message(PARROT_INTERP, ARGIN(STRING *messagetype), ARGIN_NULLOK(PMC *payload))
+Parrot_cx_send_message(PARROT_INTERP, ARGIN(STRING *messagetype), SHIM(PMC *payload))
 {
     ASSERT_ARGS(Parrot_cx_send_message)
     if (interp->scheduler) {

Modified: branches/headercleanup/src/string/api.c
==============================================================================
--- branches/headercleanup/src/string/api.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/string/api.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -2025,7 +2025,7 @@
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 INTVAL
-Parrot_str_to_int(SHIM_INTERP, ARGIN_NULLOK(const STRING *s))
+Parrot_str_to_int(PARROT_INTERP, ARGIN_NULLOK(const STRING *s))
 {
     ASSERT_ARGS(Parrot_str_to_int)
     if (s == NULL)
@@ -2033,6 +2033,8 @@
     {
         const char         *start     = s->strstart;
         const char * const  end       = start + s->bufused;
+        const INTVAL        max_safe  = PARROT_INTVAL_MAX / 10;
+        const INTVAL        last_dig  = PARROT_INTVAL_MAX % 10;
         int                 sign      = 1;
         INTVAL              in_number = 0;
         INTVAL              i         = 0;
@@ -2043,8 +2045,13 @@
             const unsigned char c = *start;
 
             if (isdigit((unsigned char)c)) {
+                const INTVAL nextval = c - '0';
                 in_number = 1;
-                i         = i * 10 + (c - '0');
+                if (i < max_safe || (i == max_safe && nextval <= last_dig))
+                    i = i * 10 + nextval;
+                else
+                    Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ERR_OVERFLOW,
+                        "Integer value of String '%S' too big", s);
             }
             else if (!in_number) {
                 /* we've not yet seen any digits */

Modified: branches/headercleanup/src/string/charset/unicode.c
==============================================================================
--- branches/headercleanup/src/string/charset/unicode.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/string/charset/unicode.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -746,7 +746,7 @@
 
 static INTVAL
 cs_rindex(PARROT_INTERP, SHIM(STRING *source_string),
-        SHIM(STRING *search_string), UINTVAL offset)
+        SHIM(STRING *search_string), SHIM(UINTVAL offset))
 {
     ASSERT_ARGS(cs_rindex)
     /* TODO: RT #59696 Implement this. */

Modified: branches/headercleanup/src/string/encoding/ucs2.c
==============================================================================
--- branches/headercleanup/src/string/encoding/ucs2.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/string/encoding/ucs2.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -256,6 +256,7 @@
     UChar * const s = (UChar*) src->strstart;
     return s[offset];
 #else
+    UNUSED(offset)
     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
         "no ICU lib loaded");
 #endif
@@ -280,7 +281,9 @@
     UChar * const s = (UChar*) src->strstart;
     s[offset] = codepoint;
 #else
-    UNUSED(src);
+    UNUSED(src)
+    UNUSED(offset)
+    UNUSED(codepoint)
     Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
         "no ICU lib loaded");
 #endif
@@ -298,7 +301,7 @@
 */
 
 static UINTVAL
-get_byte(PARROT_INTERP, SHIM(const STRING *src), UINTVAL offset)
+get_byte(PARROT_INTERP, SHIM(const STRING *src), SHIM(UINTVAL offset))
 {
     ASSERT_ARGS(get_byte)
     UNIMPL;
@@ -316,7 +319,8 @@
 */
 
 static void
-set_byte(PARROT_INTERP, SHIM(const STRING *src), UINTVAL offset, UINTVAL byte)
+set_byte(PARROT_INTERP, SHIM(const STRING *src), SHIM(UINTVAL offset),
+        SHIM(UINTVAL byte))
 {
     ASSERT_ARGS(set_byte)
     UNIMPL;
@@ -376,7 +380,8 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static STRING *
-get_bytes(PARROT_INTERP, SHIM(STRING *src), UINTVAL offset, UINTVAL count)
+get_bytes(PARROT_INTERP, SHIM(STRING *src), SHIM(UINTVAL offset),
+        SHIM(UINTVAL count))
 {
     ASSERT_ARGS(get_bytes)
     UNIMPL;
@@ -399,7 +404,7 @@
 PARROT_CANNOT_RETURN_NULL
 static STRING *
 get_codepoints_inplace(PARROT_INTERP, SHIM(STRING *src),
-        UINTVAL offset, UINTVAL count, SHIM(STRING *dest_string))
+        SHIM(UINTVAL offset), SHIM(UINTVAL count), SHIM(STRING *dest_string))
 {
     ASSERT_ARGS(get_codepoints_inplace)
     UNIMPL;
@@ -421,7 +426,7 @@
 PARROT_CANNOT_RETURN_NULL
 static STRING *
 get_bytes_inplace(PARROT_INTERP, SHIM(STRING *src),
-        UINTVAL offset, UINTVAL count, SHIM(STRING *return_string))
+        SHIM(UINTVAL offset), SHIM(UINTVAL count), SHIM(STRING *return_string))
 {
     ASSERT_ARGS(get_bytes_inplace)
     UNIMPL;
@@ -441,7 +446,7 @@
 
 static void
 set_codepoints(PARROT_INTERP, SHIM(STRING *src),
-        UINTVAL offset, UINTVAL count, SHIM(STRING *new_codepoints))
+        SHIM(UINTVAL offset), SHIM(UINTVAL count), SHIM(STRING *new_codepoints))
 {
     ASSERT_ARGS(set_codepoints)
     UNIMPL;
@@ -461,7 +466,7 @@
 
 static void
 set_bytes(PARROT_INTERP, SHIM(STRING *src),
-        UINTVAL offset, UINTVAL count, SHIM(STRING *new_bytes))
+        SHIM(UINTVAL offset), SHIM(UINTVAL count), SHIM(STRING *new_bytes))
 {
     ASSERT_ARGS(set_bytes)
     UNIMPL;

Modified: branches/headercleanup/src/string/encoding/utf8.c
==============================================================================
--- branches/headercleanup/src/string/encoding/utf8.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/string/encoding/utf8.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -854,7 +854,7 @@
 PARROT_CANNOT_RETURN_NULL
 static STRING *
 get_bytes_inplace(PARROT_INTERP, SHIM(STRING *src),
-        UINTVAL offset, UINTVAL count, SHIM(STRING *return_string))
+        SHIM(UINTVAL offset), SHIM(UINTVAL count), SHIM(STRING *return_string))
 {
     ASSERT_ARGS(get_bytes_inplace)
     UNIMPL;
@@ -874,7 +874,7 @@
 
 static void
 set_codepoints(PARROT_INTERP, SHIM(STRING *src),
-        UINTVAL offset, UINTVAL count, SHIM(STRING *new_codepoints))
+        SHIM(UINTVAL offset), SHIM(UINTVAL count), SHIM(STRING *new_codepoints))
 {
     ASSERT_ARGS(set_codepoints)
     UNIMPL;
@@ -894,7 +894,7 @@
 
 static void
 set_bytes(PARROT_INTERP, SHIM(STRING *src),
-        UINTVAL offset, UINTVAL count, SHIM(STRING *new_bytes))
+        SHIM(UINTVAL offset), SHIM(UINTVAL count), SHIM(STRING *new_bytes))
 {
     ASSERT_ARGS(set_bytes)
     UNIMPL;

Modified: branches/headercleanup/src/thread.c
==============================================================================
--- branches/headercleanup/src/thread.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/thread.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -678,7 +678,7 @@
 */
 
 void
-pt_thread_prepare_for_run(Parrot_Interp d, Parrot_Interp s)
+pt_thread_prepare_for_run(Parrot_Interp d, SHIM(Parrot_Interp s))
 {
     ASSERT_ARGS(pt_thread_prepare_for_run)
     Parrot_setup_event_func_ptrs(d);

Modified: branches/headercleanup/src/utils.c
==============================================================================
--- branches/headercleanup/src/utils.c	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/src/utils.c	Wed Apr 15 19:17:06 2009	(r38132)
@@ -21,6 +21,7 @@
 */
 
 #include "parrot/parrot.h"
+#include "pmc/pmc_nci.h"
 
 typedef unsigned short _rand_buf[3];
 
@@ -906,7 +907,7 @@
         return VTABLE_cmp(interp, (PMC *)a, (PMC *)b);
 
     if (cmp->vtable->base_type == enum_class_NCI) {
-        const sort_func_t f = (sort_func_t)D2FPTR(PMC_struct_val(cmp));
+        const sort_func_t f = (sort_func_t)D2FPTR(PARROT_NCI(cmp)->func);
         return f(interp, a, b);
     }
 

Modified: branches/headercleanup/t/codingstd/c_function_docs.t
==============================================================================
--- branches/headercleanup/t/codingstd/c_function_docs.t	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/t/codingstd/c_function_docs.t	Wed Apr 15 19:17:06 2009	(r38132)
@@ -128,7 +128,6 @@
 examples/embed/lorito.c
 src/atomic/gcc_x86.c
 src/debug.c
-src/exceptions.c
 src/gc/res_lea.c
 src/io/io_string.c
 src/io/socket_api.c

Modified: branches/headercleanup/t/codingstd/svn_id.t
==============================================================================
--- branches/headercleanup/t/codingstd/svn_id.t	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/t/codingstd/svn_id.t	Wed Apr 15 19:17:06 2009	(r38132)
@@ -35,12 +35,12 @@
 
 my $DIST = Parrot::Distribution->new;
 
-my @c_files    = $DIST->get_c_language_files();
-my @perl_files = $DIST->get_perl_language_files();
-my @make_files = $DIST->get_make_language_files();
-my @all_files  = ( @c_files, @perl_files, @make_files );
-
-my @files = @ARGV ? <@ARGV> : @all_files;
+my @files = @ARGV ? <@ARGV> : (
+    $DIST->get_c_language_files(),
+    $DIST->get_make_language_files(),
+    $DIST->get_perl_language_files(),
+    $DIST->get_pir_language_files(),
+);
 my @no_id_files;
 
 foreach my $file (@files) {

Modified: branches/headercleanup/t/op/gc.t
==============================================================================
--- branches/headercleanup/t/op/gc.t	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/t/op/gc.t	Wed Apr 15 19:17:06 2009	(r38132)
@@ -6,7 +6,7 @@
 use warnings;
 use lib qw( . lib ../lib ../../lib );
 use Test::More;
-use Parrot::Test tests => 19;
+use Parrot::Test tests => 18;
 
 =head1 NAME
 
@@ -406,74 +406,6 @@
 ok
 OUTPUT
 
-pasm_output_is( <<'CODE', <<OUTPUT, "write barrier 3 - ref" );
-    null I2
-    set I3, 10
-lp3:
-    null I0
-    set I1, 100
-    new P5, 'Ref'
-    new P0, 'Integer'
-    needs_destroy P0
-    # force partial sweep
-    # ref should now be black
-    sweep 0
-    # store white hash in ref - needs a barrier
-    new P1, 'Hash'
-    setref P5, P1
-    null P1
-    new P0, 'Integer'
-    needs_destroy P0
-    null P0
-    # force full sweep
-    sweep 0
-    deref P1, P5
-lp1:
-    new P0, 'Integer'
-    new P2, 'Ref', P0
-    set P0, I0
-    set S0, I0
-    set P1[S0], P2
-    if I0, not_0
-    new P0, 'Integer'
-not_0:
-    new P3, 'Undef'
-    new P4, 'Undef'
-    inc I0
-    lt I0, I1, lp1
-
-    null I0
-    deref P1, P5
-    # trace 1
-lp2:
-    set S0, I0
-    set P2, P1[S0]
-    deref P2, P2
-    eq P2, I0, ok
-    print "nok\n"
-    print "I0: "
-    print I0
-    print " P2: "
-    print P2
-    print " type: "
-    typeof S0, P2
-    print S0
-    print " I2: "
-    print I2
-    print "\n"
-    exit 1
-ok:
-    inc I0
-    lt I0, I1, lp2
-    inc I2
-    lt I2, I3, lp3
-    print "ok\n"
-    end
-
-CODE
-ok
-OUTPUT
-
 pir_output_is( <<'CODE', <<'OUTPUT', "verify pmc proxy object marking" );
 .sub main :main
     .local pmc cl, s, t

Modified: branches/headercleanup/t/perl/testlib/hello.pasm
==============================================================================
--- branches/headercleanup/t/perl/testlib/hello.pasm	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/t/perl/testlib/hello.pasm	Wed Apr 15 19:17:06 2009	(r38132)
@@ -18,3 +18,9 @@
     print S1
     print "\n"
     end
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/t/pmc/codestring.t
==============================================================================
--- branches/headercleanup/t/pmc/codestring.t	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/t/pmc/codestring.t	Wed Apr 15 19:17:06 2009	(r38132)
@@ -186,8 +186,8 @@
     is($I0, 0x266d, "MUSIC FLAT SIGN")
     $I0 = code.'charname_to_ord'('RECYCLING SYMBOL FOR TYPE-1 PLASTICS')
     is($I0, 0x2673, "RECYCLING SYMBOL FOR TYPE-1 PLASTICS")
-    $I0 = code.'charname_to_ord'('<no such symbol>')
-    is($I0, -1, '<no such symbol>')
+    $I0 = code.'charname_to_ord'('no such symbol')
+    is($I0, -1, 'no such symbol')
 .end
 
 .sub 'lineof_tests'

Modified: branches/headercleanup/t/pmc/managedstruct.t
==============================================================================
--- branches/headercleanup/t/pmc/managedstruct.t	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/t/pmc/managedstruct.t	Wed Apr 15 19:17:06 2009	(r38132)
@@ -81,7 +81,7 @@
     push $P2, 0
     new $P0, ['ManagedStruct'], $P2
     set $I0, $P0
-    $I1 = ge $I0, 2
+    $I1 = isge $I0, 2
     ok($I1, "ManagedStruct size is at least 2")
 
     set $P0[0;0], 1

Modified: branches/headercleanup/t/pmc/nci.t
==============================================================================
--- branches/headercleanup/t/pmc/nci.t	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/t/pmc/nci.t	Wed Apr 15 19:17:06 2009	(r38132)
@@ -6,7 +6,7 @@
 use warnings;
 use lib qw( . lib ../lib ../../lib );
 use Test::More;
-use Parrot::Test tests => 69;
+use Parrot::Test tests => 70;
 use Parrot::Config qw(%PConfig);
 
 =head1 NAME
@@ -2726,6 +2726,34 @@
 Hello bright new world
 OUTPUT
 
+pir_output_is( << 'CODE', << 'OUTPUT', "nci_vVV - multiple char** out parameters" );
+.sub test :main
+    .local string library_name
+    library_name = 'libnci_test'
+    .local pmc libnci_test
+    libnci_test = loadlib  library_name
+
+    .local pmc nci_vVVV
+    nci_vVVV = dlfunc libnci_test, "nci_vVVV", "vVVV"
+
+    .local pmc char_s_s1, char_s_s2, char_s_s3
+    char_s_s1 = new ['Pointer']
+    char_s_s2 = new ['Pointer']
+    char_s_s3 = new ['Pointer']
+    nci_vVVV(char_s_s1, char_s_s2, char_s_s3)
+    $S1 = char_s_s1
+    print $S1
+    $S1 = char_s_s2
+    print $S1
+    $S1 = char_s_s3
+    print $S1
+.end
+CODE
+Hello bright new world!
+It is a beautiful day!
+Go suck a lemon.
+OUTPUT
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4

Modified: branches/headercleanup/t/pmc/pmc.t
==============================================================================
--- branches/headercleanup/t/pmc/pmc.t	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/t/pmc/pmc.t	Wed Apr 15 19:17:06 2009	(r38132)
@@ -49,9 +49,7 @@
 my $checkTypes;
 my %types_we_cant_test
     = map { $_ => 1; } (    # These require initializers.
-    qw(Null Iterator Enumerate Ref SharedRef
-        ParrotObject ParrotThread
-        BigInt LexInfo LexPad Object),
+    qw(Null Iterator Enumerate ParrotObject ParrotThread BigInt LexInfo LexPad Object),
 
     # Instances of these appear to have other types.
     qw(PMCProxy Class) );

Deleted: branches/headercleanup/t/pmc/ref.t
==============================================================================
--- branches/headercleanup/t/pmc/ref.t	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,210 +0,0 @@
-#! parrot
-# Copyright (C) 2001-2009, Parrot Foundation.
-# $Id$
-
-=head1 NAME
-
-t/pmc/ref.t - Reference PMC
-
-=head1 SYNOPSIS
-
-    % prove t/pmc/ref.t
-
-=head1 DESCRIPTION
-
-Tests that vtable method delegation works on a C<Ref> PMC.
-
-=cut
-
-.sub main :main
-    .include 'test_more.pir'
-    plan(42)
-
-    basic_ref_tests()
-    setref_tests()
-    assign_ref_tests()
-    sharedref_tests()
-    interface_tests()
-    set_get_tests()
-    push_pop_tests()
-    add_tests()
-.end
-
-
-.sub basic_ref_tests
-    new $P2, ['Integer']
-    new $P1, ['Ref'], $P2
-    ok(1, "Ref creation didn't explode")
-
-    inc $P1
-    is($P2, 1, "inc ref incremented the referand")
-    is($P1, 1, "inc ref incremented the ref")
-
-    dec $P1
-    is($P2, 0, "dec ref decremented the referand")
-    is($P1, 0, "dec ref decremented the ref")
-
-    deref $P3, $P1
-    typeof $S0, $P1
-    is($S0, 'Ref', "Ref has correct type")
-    typeof $S0, $P3
-    is($S0, 'Integer', "referand has correct type")
-.end
-
-.sub setref_tests
-    new $P2, ['Integer']
-    new $P3, ['Float']
-    set $P3, 0.5
-    new $P1, ['Ref'], $P2
-    inc $P1
-    is($P1, 1, "Integer Ref is incremented correctly")
-    setref $P1, $P3
-    inc $P1
-    is($P1, 1.5, "Float Ref (formerly Int Ref) is incremented correctly")
-    is($P2, 1, "Int formerly referred to by Ref stays the same")
-    is($P3, 1.5, "new Float Ref has right value")
-.end
-
-.sub assign_ref_tests
-    new $P2, ['Integer']
-    new $P3, ['Float']
-    set $P2, 0
-    set $P3, 0.5
-    new $P1, ['Ref'], $P2
-    assign $P1, 1
-    $I0 = $P1
-    is($I0, 1, "Ref has correct value")
-    $I0 = $P2
-    is($I0, 1, "assigned Ref has correct value")
-    assign $P1, $P3
-    $N0 = $P1
-    is($N0, 0.5, "assigned Ref has correct value")
-    $I0 = $P2
-    is($I0, 1, "previously assigned Ref maintained previous value")
-    $N0 = $P3
-    is($N0, 0.5, "assigned Ref has correct value")
-.end
-
-.sub sharedref_tests
-    new $P2, ['Integer']
-    new $P1, ['SharedRef'], $P2
-    ok(1, "SharedRef created without explosion")
-    set $P1, 4711
-    is($P1, 4711, "SharedRef assignment looks good")
-    typeof $S0, $P1
-    is($S0, "Integer", "SharedRef type looks good")
-    set $P1, "hello"
-    typeof $S0, $P1
-    is($S0, "String", "SharedRef type looks good after type change")
-    is($P1, "hello", "SharedRef value looks good after type change")
-
-    new $P2, ['Integer']
-    new $P1, ['SharedRef'], $P2
-    ok(1, "SharedRef creation didn't explode")
-    push_eh eh
-    deref $P3, $P1
-    pop_eh
-    ok(0, "deref of SharedRef didn't cause an exception")
-    goto end
-eh:
-    ok(1, "deref of SharedRef caused an exception")
-end:
-.end
-
-.sub interface_tests
-    .local pmc pmc1
-    pmc1 = new ['Array']
-    .local pmc pmc2
-    pmc2 = new ['Ref'], pmc1
-    .local pmc pmc3
-    pmc3 = new ['SharedRef'], pmc1
-    .local int bool1
-    does bool1, pmc2, "scalar"
-    is(bool1, 0, "Ref doesn't do scalar")
-    does bool1, pmc2, "array"
-    is(bool1, 1, "Ref does do array")
-    does bool1, pmc2, "no_interface"
-    is(bool1, 0, "Ref doesn't do no_interface")
-
-    does bool1, pmc3, "scalar"
-    is(bool1, 0, "SharedRef doesn't do scalar")
-    does bool1, pmc3, "array"
-    is(bool1, 1, "SharedRef does do array")
-    does bool1, pmc3, "no_interface"
-    is(bool1, 0, "SharedRef doesn't do no_interface")
-.end
-
-
-.sub set_get_tests
-    new $P2, ['Integer']
-    new $P1, ['Ref'], $P2
-    set $P1, 10
-    is($P1, 10, "set works on Integer Ref")
-    set $I0, $P1
-    is($I0, 10, "get works on Integer Ref")
-
-    new $P2, ['Float']
-    new $P1, ['Ref'], $P2
-    set $P1, 12.5
-    set $N0, $P2
-    set $N1, 12.5
-    is($N0, $N1, "set works on Float Ref")
-    set $N2, $P1
-    is($N2, $N1, "get works on Float Ref")
-.end
-
-.sub push_pop_tests
-    new $P2, ['ResizableIntegerArray']
-    new $P1, ['Ref'], $P2
-    push $P1, 200
-    push $P1, -3
-    set $I0, $P1
-    is($I0, 2, "element count of array via Ref is correct")
-    set $I0, $P2
-    is($I0, 2, "direct element count of array is correct")
-    pop $I1, $P1
-    pop $I2, $P1
-    is($I1, -3, "first element popped via Ref is correct")
-    is($I2, 200, "second element popped via Ref is correct")
-    set $I0, $P1
-    is($I0, 0, "element count of array via Ref is correct")
-.end
-
-.sub add_tests
-    new $P2, ['Integer']
-    new $P1, ['Ref'], $P2
-    set $P1, 10
-    add $P1, $P1
-    is($P2, 20, "add ref,ref is ok")
-
-    new $P3, ['Integer']
-    new $P2, ['Integer']
-    new $P1, ['Ref'], $P2
-    set $P3, 12
-    set $P1, 10
-    add $P1, $P3
-    is($P2, 22, "add ref,int is ok")
-
-    new $P3, ['Integer']
-    new $P2, ['Integer']
-    new $P1, ['Ref'], $P2
-    set $P3, 12
-    set $P1, 10
-    add $P4, $P3, $P1
-    is($P4, 22, "add dest,int,ref is ok")
-
-    new $P3, ['Integer']
-    new $P2, ['Integer']
-    new $P1, ['Ref'], $P2
-    set $P3, 12
-    set $P1, 10
-    add $P4, $P1, $P3
-    is($P4, 22, "add dest,ref,int is ok")
-.end
-
-# Local Variables:
-#   mode: pir
-#   cperl-indent-level: 4
-#   fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4 ft=pir:

Deleted: branches/headercleanup/t/pmc/sharedref.t
==============================================================================
--- branches/headercleanup/t/pmc/sharedref.t	Wed Apr 15 19:17:06 2009	(r38131)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,32 +0,0 @@
-#! parrot
-# Copyright (C) 2006-2008, Parrot Foundation.
-# $Id$
-
-=head1 NAME
-
-t/pmc/sharedref.t - test the SharedRef PMC
-
-=head1 SYNOPSIS
-
-    % prove t/pmc/sharedref.t
-
-=head1 DESCRIPTION
-
-Tests the SharedRef PMC.
-
-=cut
-
-.sub main :main
-    .include 'test_more.pir'
-
-    plan(1)
-
-    new $P0, ['SharedRef']
-    ok(1, 'Instantiated a SharedRef PMC')
-.end
-
-# Local Variables:
-#   mode: pir
-#   fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4 ft=pir:

Modified: branches/headercleanup/t/pmc/sockaddr.t
==============================================================================
--- branches/headercleanup/t/pmc/sockaddr.t	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/t/pmc/sockaddr.t	Wed Apr 15 19:17:06 2009	(r38132)
@@ -12,7 +12,7 @@
 
 =head1 DESCRIPTION
 
-Tests the SharedRef PMC.
+Test the Sockaddr PMC.
 
 =cut
 

Modified: branches/headercleanup/t/pmc/threads.t
==============================================================================
--- branches/headercleanup/t/pmc/threads.t	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/t/pmc/threads.t	Wed Apr 15 19:17:06 2009	(r38132)
@@ -46,7 +46,7 @@
     }
 }
 if ( $platforms{$^O} ) {
-    plan tests => 15;
+    plan tests => 14;
 }
 else {
     plan skip_all => "No threading yet or test not enabled for '$^O'";
@@ -288,42 +288,6 @@
 500500
 OUTPUT
 
-pir_output_is( <<'CODE', <<'OUTPUT', "share a PMC" );
-.sub main :main
-    .local pmc foo
-    foo = get_global "_foo"
-    .local pmc to_share
-    to_share = new ['Integer']
-    .local pmc shared_ref
-    shared_ref = new ['SharedRef'], to_share
-    shared_ref = 20
-    .local pmc thread
-    thread = new ['ParrotThread']
-    thread.'run_clone'(foo, shared_ref)
-
-    sleep 0.1 # to let the thread run
-
-    .local pmc result
-    thread.'join'()
-    print "done\n"
-    print shared_ref
-    print "\n"
-.end
-
-.sub _foo
-    .param pmc shared_ref
-    print "thread\n"
-    print shared_ref
-    print "\n"
-    inc shared_ref
-.end
-CODE
-thread
-20
-done
-21
-OUTPUT
-
 pir_output_is( <<'CODE', <<'OUT', "sub name lookup in new thread" );
 .sub check
     $P0 = get_global ['Foo'], 'foo'

Modified: branches/headercleanup/t/tools/ops2pm/samples/pic_ops.original
==============================================================================
--- branches/headercleanup/t/tools/ops2pm/samples/pic_ops.original	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/t/tools/ops2pm/samples/pic_ops.original	Wed Apr 15 19:17:06 2009	(r38132)
@@ -90,14 +90,14 @@
     rt = VTABLE_type(interp, right);
     lr_types = (lt << 16) | rt;
     if (lru->u.type == lr_types) {
-        INTVAL a = lt == enum_class_Integer ? PMC_int_val(left) :
+        INTVAL a = lt == enum_class_Integer ? VTABLE_get_integer(interp, left) :
             VTABLE_get_integer(interp, left);
-        INTVAL b = rt == enum_class_Integer ? PMC_int_val(right) :
+        INTVAL b = rt == enum_class_Integer ? VTABLE_get_integer(interp, right) :
             VTABLE_get_integer(interp, right);
         INTVAL c = a - b;
         if ((c^a) >= 0 || (c^~b) >= 0) {
             if (lt == enum_class_Integer)
-                PMC_int_val(left) = c;
+                VTABLE_get_integer(interp, left) = c;
             else
                 VTABLE_set_integer_native(interp, left, c);
         }
@@ -196,7 +196,7 @@
     cc = PMC_cont(ccont);
     if (!cc->address) {
         interp->current_returns = CUR_OPCODE;
-        n = PMC_int_val(mic->m.sig);
+        n = VTABLE_get_integer(interp, mic->m.sig);
         goto OFFSET(n + 2);
     }
     caller_ctx = cc->to_ctx;

Modified: branches/headercleanup/tools/build/nativecall.pl
==============================================================================
--- branches/headercleanup/tools/build/nativecall.pl	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/tools/build/nativecall.pl	Wed Apr 15 19:17:06 2009	(r38132)
@@ -195,8 +195,11 @@
 #include "parrot/parrot.h"
 #include "parrot/hash.h"
 #include "parrot/oplib/ops.h"
+#include "pmc/pmc_managedstruct.h"
 #include "pmc/pmc_nci.h"
+#include "pmc/pmc_pointer.h"
 #include "nci.str"
+#include "jit.h"
 
 /* HEADERIZER HFILE: none */
 /* HEADERIZER STOP */
@@ -346,12 +349,15 @@
     /p/ && do {
         push @{$temps_ref},          "PMC *t_$temp_num;";
         push @{$extra_preamble_ref}, "t_$temp_num = GET_NCI_P($reg_num);";
-        return "PMC_data(t_$temp_num)";
+        return "VTABLE_get_pointer(interp, t_$temp_num)";
     };
     /V/ && do {
         push @{$temps_ref},          "PMC *t_$temp_num;";
+        push @{$temps_ref},          "void *v_$temp_num;";
         push @{$extra_preamble_ref}, "t_$temp_num = GET_NCI_P($reg_num);";
-        return "(void**)&PMC_data(t_$temp_num)";
+        push @{$extra_preamble_ref}, "v_$temp_num = VTABLE_get_pointer(interp, t_$temp_num);";
+        push @{$extra_postamble_ref}, "VTABLE_set_pointer(interp, t_$temp_num, v_$temp_num);";
+        return "&v_$temp_num";
     };
     /[ilIscfdNS]/ && do {
         my $ret_type = $sig_table{$_}{return_type};
@@ -498,11 +504,10 @@
 void *
 build_call_func(PARROT_INTERP,
 #if defined(CAN_BUILD_CALL_FRAMES)
-PMC *pmc_nci,
+PMC *pmc_nci, NOTNULL(STRING *signature), NOTNULL(int *jitted))
 #else
-SHIM(PMC *pmc_nci),
+SHIM(PMC *pmc_nci), NOTNULL(STRING *signature), SHIM(int *jitted))
 #endif
-NOTNULL(STRING *signature), NOTNULL(int *jitted))
 {
     char       *c;
     STRING     *ns, *message;
@@ -554,11 +559,22 @@
         return F2DPTR(VTABLE_get_pointer(interp, b));
     }
     else {
-        void * const result = Parrot_jit_build_call_func(interp, pmc_nci, signature);
+        int jit_size;
+        void * const result = Parrot_jit_build_call_func(interp, pmc_nci, signature, &jit_size);
         if (result) {
+            struct jit_buffer_private_data *priv;
             *jitted = 1;
             temp_pmc = pmc_new(interp, enum_class_ManagedStruct);
             VTABLE_set_pointer(interp, temp_pmc, (void *)result);
+#ifdef PARROT_HAS_EXEC_PROTECT
+            priv = (struct jit_buffer_private_data *)
+                mem_sys_allocate(sizeof(struct jit_buffer_private_data));
+            priv->size = jit_size;
+            SETATTR_ManagedStruct_custom_free_func(interp, temp_pmc, Parrot_jit_free_buffer);
+            SETATTR_ManagedStruct_custom_free_priv(interp, temp_pmc, priv);
+            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);
             return result;
         }
@@ -606,7 +622,6 @@
     $ret_type (*pointer)();
     $ret_type return_data;
 
-    pointer = PMC_struct_val(self);
     return_data = ($ret_type)(*pointer)($params);
     $ret_reg  = return_data;
     REG_INT(interp, 0) = $stack_returns;

Modified: branches/headercleanup/tools/dev/pbc_to_exe.pir
==============================================================================
--- branches/headercleanup/tools/dev/pbc_to_exe.pir	Wed Apr 15 18:41:36 2009	(r38131)
+++ branches/headercleanup/tools/dev/pbc_to_exe.pir	Wed Apr 15 19:17:06 2009	(r38132)
@@ -1,4 +1,5 @@
 #! parrot
+# $Id$
 
 =head1 NAME
 


More information about the parrot-commits mailing list