[svn:parrot] r38120 - in trunk: . docs/book docs/book/draft docs/book/figs

allison at svn.parrot.org allison at svn.parrot.org
Wed Apr 15 17:41:05 UTC 2009


Author: allison
Date: Wed Apr 15 17:40:59 2009
New Revision: 38120
URL: https://trac.parrot.org/parrot/changeset/38120

Log:
[book] Reordering chapters as they will appear in the book.

Added:
   trunk/docs/book/appb_patch_submission.pod   (props changed)
      - copied unchanged from r38119, trunk/docs/book/appX_patch_submission.pod
   trunk/docs/book/ch01_introduction.pod   (props changed)
      - copied unchanged from r38119, trunk/docs/book/ch01_overview.pod
   trunk/docs/book/ch03_pir.pod   (props changed)
      - copied unchanged from r38119, trunk/docs/book/ch03_pir_basics.pod
   trunk/docs/book/ch04_compiler_tools.pod
      - copied unchanged from r38119, trunk/docs/book/ch09_pct.pod
   trunk/docs/book/ch07_dynpmcs.pod
      - copied unchanged from r38119, trunk/docs/book/ch11_pmcs.pod
   trunk/docs/book/ch08_dynops.pod
      - copied unchanged from r38119, trunk/docs/book/ch12_opcodes.pod
   trunk/docs/book/ch09_pasm.pod   (props changed)
      - copied unchanged from r38119, trunk/docs/book/ch05_pasm.pod
   trunk/docs/book/ch10_opcode_reference.pod
      - copied unchanged from r38119, trunk/docs/book/ch13_reference.pod
   trunk/docs/book/draft/
   trunk/docs/book/draft/chXX_hlls.pod
      - copied unchanged from r38119, trunk/docs/book/ch10_hlls.pod
   trunk/docs/book/draft/chXX_library.pod   (props changed)
      - copied unchanged from r38119, trunk/docs/book/ch06_library.pod
   trunk/docs/book/draft/chXX_testing_and_debugging.pod
      - copied unchanged from r38119, trunk/docs/book/ch07_testing_and_debugging.pod
Deleted:
   trunk/docs/book/appX_patch_submission.pod
   trunk/docs/book/ch01_overview.pod
   trunk/docs/book/ch03_pir_basics.pod
   trunk/docs/book/ch05_pasm.pod
   trunk/docs/book/ch06_library.pod
   trunk/docs/book/ch07_testing_and_debugging.pod
   trunk/docs/book/ch08_architecture.pod
   trunk/docs/book/ch09_pct.pod
   trunk/docs/book/ch10_hlls.pod
   trunk/docs/book/ch11_pmcs.pod
   trunk/docs/book/ch12_opcodes.pod
   trunk/docs/book/ch13_reference.pod
   trunk/docs/book/figs/
Modified:
   trunk/MANIFEST
   trunk/MANIFEST.SKIP

Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST	Wed Apr 15 16:30:07 2009	(r38119)
+++ trunk/MANIFEST	Wed Apr 15 17:40:59 2009	(r38120)
@@ -1,7 +1,7 @@
 # ex: set ro:
 # $Id$
 #
-# generated by tools/dev/mk_manifest_and_skip.pl Fri Apr 10 20:55:13 2009 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Wed Apr 15 17:34:44 2009 UT
 #
 # See tools/dev/install_files.pl for documentation on the
 # format of this file.
@@ -411,21 +411,19 @@
 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/appb_patch_submission.pod                         []
+docs/book/ch01_introduction.pod                             []
 docs/book/ch02_getting_started.pod                          []
-docs/book/ch03_pir_basics.pod                               []
+docs/book/ch03_pir.pod                                      []
+docs/book/ch04_compiler_tools.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/ch07_dynpmcs.pod                                  []
+docs/book/ch08_dynops.pod                                   []
+docs/book/ch09_pasm.pod                                     []
+docs/book/ch10_opcode_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

Modified: trunk/MANIFEST.SKIP
==============================================================================
--- trunk/MANIFEST.SKIP	Wed Apr 15 16:30:07 2009	(r38119)
+++ trunk/MANIFEST.SKIP	Wed Apr 15 17:40:59 2009	(r38120)
@@ -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$

Deleted: trunk/docs/book/appX_patch_submission.pod
==============================================================================
--- trunk/docs/book/appX_patch_submission.pod	Wed Apr 15 17:40:59 2009	(r38119)
+++ /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: trunk/docs/book/appb_patch_submission.pod (from r38119, trunk/docs/book/appX_patch_submission.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/docs/book/appb_patch_submission.pod	Wed Apr 15 17:40:59 2009	(r38120, copy of r38119, trunk/docs/book/appX_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 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: trunk/docs/book/ch01_introduction.pod (from r38119, trunk/docs/book/ch01_overview.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/docs/book/ch01_introduction.pod	Wed Apr 15 17:40:59 2009	(r38120, copy of r38119, trunk/docs/book/ch01_overview.pod)
@@ -0,0 +1,210 @@
+=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:

Deleted: trunk/docs/book/ch01_overview.pod
==============================================================================
--- trunk/docs/book/ch01_overview.pod	Wed Apr 15 17:40:59 2009	(r38119)
+++ /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:

Copied: trunk/docs/book/ch03_pir.pod (from r38119, trunk/docs/book/ch03_pir_basics.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/docs/book/ch03_pir.pod	Wed Apr 15 17:40:59 2009	(r38120, copy of r38119, trunk/docs/book/ch03_pir_basics.pod)
@@ -0,0 +1,1294 @@
+=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. 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 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 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.
+
+=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:

Deleted: trunk/docs/book/ch03_pir_basics.pod
==============================================================================
--- trunk/docs/book/ch03_pir_basics.pod	Wed Apr 15 17:40:59 2009	(r38119)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,1294 +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. 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 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 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.
-
-=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: trunk/docs/book/ch04_compiler_tools.pod (from r38119, trunk/docs/book/ch09_pct.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/docs/book/ch04_compiler_tools.pod	Wed Apr 15 17:40:59 2009	(r38120, copy of r38119, trunk/docs/book/ch09_pct.pod)
@@ -0,0 +1,712 @@
+=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]>), 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.
+
+=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 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.
+
+=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
+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:

Deleted: trunk/docs/book/ch05_pasm.pod
==============================================================================
--- trunk/docs/book/ch05_pasm.pod	Wed Apr 15 17:40:59 2009	(r38119)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,3291 +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<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.
-
-=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:

Deleted: trunk/docs/book/ch06_library.pod
==============================================================================
--- trunk/docs/book/ch06_library.pod	Wed Apr 15 17:40:59 2009	(r38119)
+++ /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> 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: trunk/docs/book/ch07_dynpmcs.pod (from r38119, trunk/docs/book/ch11_pmcs.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/docs/book/ch07_dynpmcs.pod	Wed Apr 15 17:40:59 2009	(r38120, copy of r38119, trunk/docs/book/ch11_pmcs.pod)
@@ -0,0 +1,237 @@
+=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 little bit more involved than 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: trunk/docs/book/ch07_testing_and_debugging.pod
==============================================================================
--- trunk/docs/book/ch07_testing_and_debugging.pod	Wed Apr 15 17:40:59 2009	(r38119)
+++ /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: trunk/docs/book/ch08_architecture.pod
==============================================================================
--- trunk/docs/book/ch08_architecture.pod	Wed Apr 15 17:40:59 2009	(r38119)
+++ /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: trunk/docs/book/ch08_dynops.pod (from r38119, trunk/docs/book/ch12_opcodes.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/docs/book/ch08_dynops.pod	Wed Apr 15 17:40:59 2009	(r38120, copy of r38119, trunk/docs/book/ch12_opcodes.pod)
@@ -0,0 +1,233 @@
+=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 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: trunk/docs/book/ch09_pasm.pod (from r38119, trunk/docs/book/ch05_pasm.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/docs/book/ch09_pasm.pod	Wed Apr 15 17:40:59 2009	(r38120, copy of r38119, trunk/docs/book/ch05_pasm.pod)
@@ -0,0 +1,3291 @@
+=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<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.
+
+=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:

Deleted: trunk/docs/book/ch09_pct.pod
==============================================================================
--- trunk/docs/book/ch09_pct.pod	Wed Apr 15 17:40:59 2009	(r38119)
+++ /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]>), 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.
-
-=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 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.
-
-=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
-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:

Deleted: trunk/docs/book/ch10_hlls.pod
==============================================================================
--- trunk/docs/book/ch10_hlls.pod	Wed Apr 15 17:40:59 2009	(r38119)
+++ /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: trunk/docs/book/ch10_opcode_reference.pod (from r38119, trunk/docs/book/ch13_reference.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/docs/book/ch10_opcode_reference.pod	Wed Apr 15 17:40:59 2009	(r38120, copy of r38119, trunk/docs/book/ch13_reference.pod)
@@ -0,0 +1,3767 @@
+=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)>
+
+  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
+A<CHP-13-TABLE-1>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
+A<CHP-13-TABLE-2>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 A<CHP-13-TABLE-3>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>
+
+=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-13-TABLE-4>Table 13-4. 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-4>
+
+=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-13-TABLE-5>Table 13-5.
+
+X<Parrot;optimizations>
+X<optimizations (Parrot)>
+
+=begin table picture Optimizations
+
+Z<CHP-13-TABLE-5>
+
+=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:

Deleted: trunk/docs/book/ch11_pmcs.pod
==============================================================================
--- trunk/docs/book/ch11_pmcs.pod	Wed Apr 15 17:40:59 2009	(r38119)
+++ /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 little bit more involved than 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: trunk/docs/book/ch12_opcodes.pod
==============================================================================
--- trunk/docs/book/ch12_opcodes.pod	Wed Apr 15 17:40:59 2009	(r38119)
+++ /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 written in a C<.ops> file like the normal built-in ops are.
-The ops file should use C<#include "parrot/extend.h"> in addition to any
-other libraries the ops need. They can be compiled into C using the opcode
-compiler, then compiled into a shared library using a normal C compiler. Once
-compiled, the dynops can be loaded into Parrot using the .loadlib directive.
-
-=cut
-
-
-# Local variables:
-#   c-file-style: "parrot"
-# End:
-# vim: expandtab shiftwidth=4:

Deleted: trunk/docs/book/ch13_reference.pod
==============================================================================
--- trunk/docs/book/ch13_reference.pod	Wed Apr 15 17:40:59 2009	(r38119)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,3767 +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)>
-
-  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
-A<CHP-13-TABLE-1>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
-A<CHP-13-TABLE-2>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 A<CHP-13-TABLE-3>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>
-
-=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-13-TABLE-4>Table 13-4. 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-4>
-
-=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-13-TABLE-5>Table 13-5.
-
-X<Parrot;optimizations>
-X<optimizations (Parrot)>
-
-=begin table picture Optimizations
-
-Z<CHP-13-TABLE-5>
-
-=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: trunk/docs/book/draft/chXX_hlls.pod (from r38119, trunk/docs/book/ch10_hlls.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/docs/book/draft/chXX_hlls.pod	Wed Apr 15 17:40:59 2009	(r38120, copy of r38119, trunk/docs/book/ch10_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: trunk/docs/book/draft/chXX_library.pod (from r38119, trunk/docs/book/ch06_library.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/docs/book/draft/chXX_library.pod	Wed Apr 15 17:40:59 2009	(r38120, copy of r38119, trunk/docs/book/ch06_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: trunk/docs/book/draft/chXX_testing_and_debugging.pod (from r38119, trunk/docs/book/ch07_testing_and_debugging.pod)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/docs/book/draft/chXX_testing_and_debugging.pod	Wed Apr 15 17:40:59 2009	(r38120, copy of r38119, trunk/docs/book/ch07_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:


More information about the parrot-commits mailing list