<commit_before>=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 unweildy 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:

  .sub main
    $S0 = "hello "
    print $S0
    $S1 = "world!"
    print $S1
  .end

We'll talk about subroutines in more detail in the next chapter. For now,
we can dissect this little bit of code to see what is happening. The C<.sub>
and C<.end> directives demarcate the beginning and end of a subroutine
called C<main>. This convention should be familiar to C and C++ programmers,
although it's not required that the first subroutine N<or any subroutine
for that matter> be named "main". In this code sequence, we assign the
string C<"hello "> to the register C<$S0> and use the C<print> opcode to
display it to the terminal. Then, we assign a second string C<"world!"> to
a second register C<$S1>, and then C<print> that to the terminal as well.
The resulting output of this small program is, of course, the well-worn
salutation C<hello world!>.

Parrot's compiler and register allocator are smart enough to realize that
the two registers in the example above, C<$S0> and C<$S1> are used exclusively
of one another. C<$S0> is assigned a value in line 2, and is read in line 3,
but is never accessed after that. So, Parrot determines that its lifespan
ends at line 3. The register C<$S1> is used first on line 4, and is accessed
again on line 5. Sinec these two do not overlap, Parrot's compiler can
determine that it can use only one register for both operations. This saves
the second allocation. Notice that this code with only one register performs
identically to the previous example:

  .sub main
    $S0 = "hello "
    print $S0
    $S0 = "world!"
    print $S0
  .end

In some situations it can be helpful to turn the allocator off and avoid
expensive optimizations. Such situations are subroutines where there are a
small fixed number of registers used, when variables are used throughout the
subroutine and should never be reused, or when some kind of pointer reference
needs to be made to the register N<this happens in some NCI calls that take
pointers and return values>. To turn off the register allocator for certain
variables, you can use the C<:unique_reg> modifier:

  .local pmc MyUniquePMC :unique_reg

Notice that C<:unique_reg> shouldn't affect the behavior of Parrot, but
instead only changes the way registers are allocated. It's a trade off between
using more memory in exchange for less time spent optimizing the subroutine.

=head2 PMC variables

Z<CHP-3-SECT-2.4>

PMC registers and variables act much like any integer, floating-point
number, or string register or variable, but you have to instantiate a
new PMC object into a type before you use it. The C<new> instruction creates
a new PMC of the specified type:

  $P0 = new 'PerlString'     # This is how the Perl people do it
  $P0 = "Hello, Polly.\n"
  print $P0

This example creates a C<PerlString> object, stores it in the PMC
register C<$P0>, assigns the value "Hello, Polly.\n" to it, and prints
it.  With named variables the type passed to the C<.local> directive is
either the generic C<pmc> or a type compatible with the type passed to
C<new>:

  .local PerlString hello    # or .local pmc hello
  hello = new 'PerlString'
  hello = "Hello, Polly.\n"
  print hello

PIR is a dynamic language, and that dynamicism is readily displayed in
the way PMC values are handled. Primitive registers like strings,
numbers, and integers perform a special action called I<autoboxing>
when they are assigned to a PMC. Autoboxing is when a primative scalar
type is automatically converted to a PMC object type. There are PMC
classes for String, Number, and Integer which can be quickly converted
to and from primitive int, number, and string types. Notice that the
primative types are in lower-case, while the PMC classes are
capitalized. If you want to box a value explicitly, you can use the C<box>
opcode:

  $P0 = new 'Integer'       # The boxed form of int
  $P0 = box 42
  $P1 = new 'Number'        # The boxed form of num
  $P1 = box 3.14
  $P2 = new 'String'        # The boxed form of string
  $P2 = "This is a string!" 

The PMC classes C<Integer>, C<Number>, and C<String> are thin overlays on
the primative types they represent. However, these PMC types have the benefit
of the X<PMC;VTABLE Interface> VTABLE interface. VTABLEs are a standard
API that all PMCs conform to for performing standard operations. These PMC
types also have special custom methods available for performing various
operations, they may be passed as PMCs to subroutines that only expect
PMC arguments, and they can be subclassed by a user-defined type. We'll
discuss all these complicated topics later in this chapter and in the next
chapter. We will discuss PMC and all the details of their implementation and
interactions in A<CHP-11> Chapter 11.

=head2 Named Constants

Z<CHP-3-SECT-2.5>

X<PIR (Parrot intermediate representation);named constants>
X<named constants (PIR)>
The C<.const> directive declares a named constant. It's very similar
to C<.local>, and requires a type and a name. The value of a constant
must be assigned in the declaration statement. As with named
variables, named constants are visible only within the compilation
unit where they're declared. This example declares a named string
constant C<hello> and prints the value:

  .const string hello = "Hello, Polly.\n"
  print hello

Named constants may be used in all the same places as literal constants,
but have to be declared beforehand:

  .const int the_answer = 42        # integer constant
  .const string mouse = "Mouse"     # string constant
  .const num pi = 3.14159           # floating point constant

In addition to normal local constants, you can also specify a global constant
which is accessible from everywhere in the current code file:

  .globalconst int days = 365

Currently there is no way to specify a PMC constant in PIR source code,
although a way to do so may be added in later versions of Parrot.

=head1 Symbol Operators

Z<CHP-3-SECT-3>

X<symbol operators in PIR>
PIR has many other symbol operators: arithmetic, concatenation,
comparison, bitwise, and logical. All PIR operators are translated
into one or more Parrot opcodes internally, but the details of this
translation stay safely hidden from the programmer. Consider this
example snippet:

  .local int sum
  sum = $I42 + 5
  print sum
  print "\n"

The statement C<sum = $I42 + 5> translates to the equivalent statement
C<add sum, $I42, 5>. This in turn will be translated to an equivalent
PASM instruction which will be similar to C<add I0, I1, 5>. Notice that
in the PASM instruction the register names do not have the C<$> symbol in
front of them, and they've already been optimized into smaller numbers by
the register allocator. The exact translation from PIR statement to PASM
instruction isn't too important N<Unless you're hacking on the Parrot
compiler!>, so we don't have to worry about it for now. We will talk more
about PASM, its syntax and its instruction set in X<CHP-5> Chapter 5.
Here are examples of some PIR symbolic operations:

  $I0 = $I1 + 5      # Addition
  $N0 = $N1 - 7      # Subtraction
  $I3 = 4 * 6        # Multiplication
  $N7 = 3.14 / $N2   # Division
  $S0 = $S1 . $S2    # String concatenation

PIR also provides automatic assignment operators such as C<+=>, C<-=>,
and C<<< >>= >>>. These operators help programmers to perform common
manipulations on a data value in place, and save a few keystrokes while
doing them.

A complete list of PIR operators is available in A<CHP-13> Chapter 13.

=head2 C<=> and Type Conversion

We've mostly glossed over the behavior of the C<=> operator, although it's
a very powerful and important operator in PIR. In it's most simple form,
C<=> stores a value into one of the Parrot registers. We've seen cases where
it can be used to assign a string value to a C<string> register, or an integer
value to an C<int> register, or a floating point value into a C<number>
register, etc. However, the C<=> operator can be used to assign any type
of value into any type of register, and Parrot will handle the conversion
for you automatically:

  $I0 = 5     # Integer. 5
  $S0 = $I0   # Stringify. "5"
  $N0 = $S0   # Numify. 5.0
  $I0 = $N0   # Intify. 5

Notice that conversions between the numeric formats and strings only makes
sense when the value to convert is a number.

  $S0 = "parrot"
  $I0 = $S0        # 0

We've also seen an example earlier where a string literal was set into a
PMC register that had a type C<String>. This works for all the primitive
types and their autoboxed PMC equivalents:

  $P0 = new 'Integer'
  $P0 = 5
  $S0 = $P0      # Stringify. "5"
  $N0 = $P0      # Numify. 5.0
  $I0 = $P0      # De-box. $I0 = 5

  $P1 = new 'String'
  $P1 = "5 birds"
  $S1 = $P1      # De-box. $S1 = "5 birds"
  $I1 = $P1      # Intify. 5
  $N1 = $P1      # Numify. 5.0

  $P2 = new 'Number'
  $P2 = 3.14
  $S2 = $P2      # Stringify. "3.14"
  $I2 = $P2      # Intify. 3
  $N2 = $P2      # De-box. $N2 = 3.14

=head1 Labels

Z<CHP-3-SECT-4>

X<PIR (Parrot intermediate representation);labels>
X<labels (PIR)>
Any line in PIR can start with a label definition like C<LABEL:>,
but label definitions can also stand alone on their own line. Labels are
like flags or markers that the program can jump to or return to at different
times. Labels and jump operations (which we will discuss a little bit
later) are one of the primary methods to change control flow in PIR, so
it is well worth understanding.

Labels are most often used in branching instructions, which are used
to implement high level control structures by our high-level language
compilers.

=head2 Compilation Units

Z<CHP-3-SECT-4.1>

X<PIR (Parrot intermediate representation);compilation units>
X<compilation units (PIR)>
Compilation units in PIR are roughly equivalent to the subroutines or
methods of a high-level language. Though they will be explained in
more detail later, we introduce them here because all code in a PIR
source file must be defined in a compilation unit. We've already seen an
example for the simplest syntax for a PIR compilation unit. It starts with
the C<.sub> directive and ends with the C<.end> directive:

  .sub main
      print "Hello, Polly.\n"
  .end

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.

  .sub first
      print "Polly want a cracker?\n"
  .end

  .sub second :main
      print "Hello, Polly.\n"
  .end

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:

  .sub first :main
      print "Polly want a cracker?\n"
  .end

  .sub second
      print "Hello, Polly.\n"
  .end

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>.

  .sub _main
      goto L1
      print "never printed"
  L1:
      print "after branch\n"
      end
  .end

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>.

  .sub _main
      $I0 = 42
      if $I0 goto L1
      print "never printed"
  L1: print "after branch\n"
      end
  .end

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:

  .sub _main
      $I0 = 42
      $I1 = 43
      if $I0 < $I1 goto L1
      print "never printed"
  L1:
      print "after branch\n"
      end
  .end

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:

  .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

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:

  .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

This example tests the counter C<$I1> at the start of the loop. At the
end of the loop, it unconditionally branches back to the start of the
loop and tests the condition again. The loop ends when the counter
C<$I1> reaches 0 and the C<if> branches to the C<LAST> label. If the
counter isn't a positive number before the loop, the loop never
executes.

Any high-level flow control construct can be built from conditional
and unconditional branches, because this is the way almost all computer
hardware operates at the lowest-level, so all modern programming
languages use branching constructs to implement their most complex
flow control devices.

Fortunately, libraries of macros have been developed that can implement
more familiar syntax for many of these control structures. We will discuss
these libraries in more detail in A<CHP-6> "PIR Standard Library".

=head1 Classes and Objects

It may seem more appropriate for a discussion of PIR's support for classes
and objects to reside in its own chapter, instead of appearing in a generic
chapter about PIR programming "basics". However, part of PIR's core
functionality is its support for object-oriented programming. PIR doesn't
use all the fancy syntax as other OO languages, and it doesn't even support
all the features that most modern OO languages have. What PIR does have is
support for some of the basic structures and abilities, the necessary subset
to construct richer and higher-level object systems.

=head2 PMCs as Classes

PMCs aren't exactly "classes" in the way that this term is normally used.
They are polymorphic data items that can be one of a large variety of
predefined types. As we have seen briefly, and as we will see in more depth
later, PMCs have a standard interface called the VTABLE interface. VTABLEs
are a standard list of functions that all PMCs implement N<or, PMCs can
choose not to implement each interface explicitly and instead let Parrot
call the default implementations>. 

VTABLEs are very strict: There are a fixed number with fixed names and
fixed argument lists. You can't just create any random VTABLE interface that
you want to create, you can only make use of the ones that Parrot supplies
and expects. To circumvent this limitation, PMCs may have METHODS in
addition to VTABLEs. METHODs are arbitrary code functions that can be
written in C, may have any name, and may implement any behavior.

=head2 VTABLE Interfaces

Internally, all operations on PMCs are performed by calling various VTABLE
interfaces.

=head2 Class and Object PMCs

The details about various PMC classes are managed by the Class PMC. Class PMCs
contain information about the class, available methods, the inheritance
hierarchy of the class, and various other details. Classes can be created
with the C<newclass> opcode:

  $P0 = newclass "MyClass"

Once we have created the class PMC, we can instantiate objects of that class
using the C<new> opcode. The C<new> opcode takes either the class name or the
Class PMC as an argument:

  $P1 = new $P0        # $P0 is the Class PMC
  $P2 = new "MyClass"  # Same

The C<new> opcode can create two different types of PMC. The first type are
the built-in core PMC classes. The built-in PMCs are written in C and cannot
be extended from PIR without subclassing. However, you can also create
user-defined PMC types in PIR. User-defined PMCs use the Object PMC type for
instantiation. Object PMCs are used for all user-defined type and keep track
of the methods and VTABLE override definitions. We're going to talk about
methods and VTABLE overrides in the next chapter.

=head2 Subclassing PMCs

Existing built-in PMC types can be subclassed to associate additional data
and methods with that PMC type. Subclassed PMC types act like their PMC
base types, by sharing the same VTABLE methods and underlying data types.
However, the subclass can define additional methods and attribute data
storage. If necessary new VTABLE interfaces can be defined in PIR and old
VTABLE methods can be overriden using PIR. We'll talk about defining
methods and VTABLE interface overrides in the next chapter.

Creating a new subclass of an existing PMC class is done using the
C<subclass> keyword:

  # create an anonymous subclass
  $P0 = subclass 'ResizablePMCArray'

  # create a subclass named "MyArray"
  $P0 = subclass 'ResizablePMCArray', 'MyArray'

This returns a C<Class> PMC which can be used to create and modify the
class by adding attributes or creating objects of that class. You can also
use the new class PMC to create additional subclasses:

  $P0 = subclass 'ResizablePMCArray', 'MyArray'
  $P1 = subclass $P0, 'MyOtherArray'

Once you have created these classes, you can create them like normal with
the C<new> keyword:

  $P0 = new 'MyArray'
  $P1 = new 'MyOtherArray'

=head2 Attributes

Classes and subclasses can be given attributes N<in addition to methods,
which we will talk about in the next chapter> which are named data fields.
Attributes are created with the C<addattribute> opcode, and can be set
and retrieved with the C<setattribute> and C<getattribute> opcodes
respectively:

  # Create the new class with two attributes
  $P0 = newclass 'MyClass'
  addattribute $P0, 'First'
  addattribute $P0, 'Second'

  # Create a new item of type MyClass
  $P1 = new 'MyClass'

  # Set values to the attributes
  setattribute $P1, 'First', 'First Value'
  setattribute $P1, 'Second', 'Second Value'

  # Get the attribute values
  $S0 = getattribute $P1, 'First'
  $S1 = getattribute $P1, 'Second'

Those values added as attributes don't need to be strings, even though
both of the ones in the example are. They can be integers, numbers
or PMCs too.

=head1 Input and Output

Like almost everything else in Parrot, input and output are handled by PMCs.
Using the C<print> opcode or the C<say> opcode like we've already seen in
some examples does this internally without your knowledge. However, we can
do it explicitly too. First we'll talk about basic I/O, and then we will talk
about using PMC-based filehandles for more advanced operations.

=head2 Basic I/O Opcodes

We've seen C<print> and C<say>. These are carry-over artifacts from Perl, when
Parrot was simply the VM backend to the Perl 6 language. C<print> prints
the given string argument, or the stringified form of the argument, if it's
not a string, to standard output. C<say> does the same thing but also appends
a trailing newline to it. Another opcode worth mentioning is the C<printerr>
opcode, which prints an argument to the standard error output instead.

We can read values from the standard input using the C<read> and C<readline>
ops. C<read> takes an integer value and returns a string with that many
characters. C<readline> reads an entire line of input from the standard
input, and returns the string without the trailing newline. Here is a simple
echo program that reads in characters from the user and echos them to
standard output:

  .sub main
    loop_top:
      $S0 = read 10
      print $S0
      goto loop_top
  .end

=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.

  .sub main
    $P0 = getstdout
    $P1 = open "myfile.txt", "r"
    loop_top:
      $S0 = readline $P1
      say $P0, $S0
      if $P1 goto loop_top
    close $P1
  .end

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.

=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.

=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.

=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

=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:
<commit_msg>[Book] Update section on Filehandle PMC, adding examples that show how the various methods relate to IO opcodes.<commit_after>=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 unweildy 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:

  .sub main
    $S0 = "hello "
    print $S0
    $S1 = "world!"
    print $S1
  .end

We'll talk about subroutines in more detail in the next chapter. For now,
we can dissect this little bit of code to see what is happening. The C<.sub>
and C<.end> directives demarcate the beginning and end of a subroutine
called C<main>. This convention should be familiar to C and C++ programmers,
although it's not required that the first subroutine N<or any subroutine
for that matter> be named "main". In this code sequence, we assign the
string C<"hello "> to the register C<$S0> and use the C<print> opcode to
display it to the terminal. Then, we assign a second string C<"world!"> to
a second register C<$S1>, and then C<print> that to the terminal as well.
The resulting output of this small program is, of course, the well-worn
salutation C<hello world!>.

Parrot's compiler and register allocator are smart enough to realize that
the two registers in the example above, C<$S0> and C<$S1> are used exclusively
of one another. C<$S0> is assigned a value in line 2, and is read in line 3,
but is never accessed after that. So, Parrot determines that its lifespan
ends at line 3. The register C<$S1> is used first on line 4, and is accessed
again on line 5. Sinec these two do not overlap, Parrot's compiler can
determine that it can use only one register for both operations. This saves
the second allocation. Notice that this code with only one register performs
identically to the previous example:

  .sub main
    $S0 = "hello "
    print $S0
    $S0 = "world!"
    print $S0
  .end

In some situations it can be helpful to turn the allocator off and avoid
expensive optimizations. Such situations are subroutines where there are a
small fixed number of registers used, when variables are used throughout the
subroutine and should never be reused, or when some kind of pointer reference
needs to be made to the register N<this happens in some NCI calls that take
pointers and return values>. To turn off the register allocator for certain
variables, you can use the C<:unique_reg> modifier:

  .local pmc MyUniquePMC :unique_reg

Notice that C<:unique_reg> shouldn't affect the behavior of Parrot, but
instead only changes the way registers are allocated. It's a trade off between
using more memory in exchange for less time spent optimizing the subroutine.

=head2 PMC variables

Z<CHP-3-SECT-2.4>

PMC registers and variables act much like any integer, floating-point
number, or string register or variable, but you have to instantiate a
new PMC object into a type before you use it. The C<new> instruction creates
a new PMC of the specified type:

  $P0 = new 'PerlString'     # This is how the Perl people do it
  $P0 = "Hello, Polly.\n"
  print $P0

This example creates a C<PerlString> object, stores it in the PMC
register C<$P0>, assigns the value "Hello, Polly.\n" to it, and prints
it.  With named variables the type passed to the C<.local> directive is
either the generic C<pmc> or a type compatible with the type passed to
C<new>:

  .local PerlString hello    # or .local pmc hello
  hello = new 'PerlString'
  hello = "Hello, Polly.\n"
  print hello

PIR is a dynamic language, and that dynamicism is readily displayed in
the way PMC values are handled. Primitive registers like strings,
numbers, and integers perform a special action called I<autoboxing>
when they are assigned to a PMC. Autoboxing is when a primative scalar
type is automatically converted to a PMC object type. There are PMC
classes for String, Number, and Integer which can be quickly converted
to and from primitive int, number, and string types. Notice that the
primative types are in lower-case, while the PMC classes are
capitalized. If you want to box a value explicitly, you can use the C<box>
opcode:

  $P0 = new 'Integer'       # The boxed form of int
  $P0 = box 42
  $P1 = new 'Number'        # The boxed form of num
  $P1 = box 3.14
  $P2 = new 'String'        # The boxed form of string
  $P2 = "This is a string!" 

The PMC classes C<Integer>, C<Number>, and C<String> are thin overlays on
the primative types they represent. However, these PMC types have the benefit
of the X<PMC;VTABLE Interface> VTABLE interface. VTABLEs are a standard
API that all PMCs conform to for performing standard operations. These PMC
types also have special custom methods available for performing various
operations, they may be passed as PMCs to subroutines that only expect
PMC arguments, and they can be subclassed by a user-defined type. We'll
discuss all these complicated topics later in this chapter and in the next
chapter. We will discuss PMC and all the details of their implementation and
interactions in A<CHP-11> Chapter 11.

=head2 Named Constants

Z<CHP-3-SECT-2.5>

X<PIR (Parrot intermediate representation);named constants>
X<named constants (PIR)>
The C<.const> directive declares a named constant. It's very similar
to C<.local>, and requires a type and a name. The value of a constant
must be assigned in the declaration statement. As with named
variables, named constants are visible only within the compilation
unit where they're declared. This example declares a named string
constant C<hello> and prints the value:

  .const string hello = "Hello, Polly.\n"
  print hello

Named constants may be used in all the same places as literal constants,
but have to be declared beforehand:

  .const int the_answer = 42        # integer constant
  .const string mouse = "Mouse"     # string constant
  .const num pi = 3.14159           # floating point constant

In addition to normal local constants, you can also specify a global constant
which is accessible from everywhere in the current code file:

  .globalconst int days = 365

Currently there is no way to specify a PMC constant in PIR source code,
although a way to do so may be added in later versions of Parrot.

=head1 Symbol Operators

Z<CHP-3-SECT-3>

X<symbol operators in PIR>
PIR has many other symbol operators: arithmetic, concatenation,
comparison, bitwise, and logical. All PIR operators are translated
into one or more Parrot opcodes internally, but the details of this
translation stay safely hidden from the programmer. Consider this
example snippet:

  .local int sum
  sum = $I42 + 5
  print sum
  print "\n"

The statement C<sum = $I42 + 5> translates to the equivalent statement
C<add sum, $I42, 5>. This in turn will be translated to an equivalent
PASM instruction which will be similar to C<add I0, I1, 5>. Notice that
in the PASM instruction the register names do not have the C<$> symbol in
front of them, and they've already been optimized into smaller numbers by
the register allocator. The exact translation from PIR statement to PASM
instruction isn't too important N<Unless you're hacking on the Parrot
compiler!>, so we don't have to worry about it for now. We will talk more
about PASM, its syntax and its instruction set in X<CHP-5> Chapter 5.
Here are examples of some PIR symbolic operations:

  $I0 = $I1 + 5      # Addition
  $N0 = $N1 - 7      # Subtraction
  $I3 = 4 * 6        # Multiplication
  $N7 = 3.14 / $N2   # Division
  $S0 = $S1 . $S2    # String concatenation

PIR also provides automatic assignment operators such as C<+=>, C<-=>,
and C<<< >>= >>>. These operators help programmers to perform common
manipulations on a data value in place, and save a few keystrokes while
doing them.

A complete list of PIR operators is available in A<CHP-13> Chapter 13.

=head2 C<=> and Type Conversion

We've mostly glossed over the behavior of the C<=> operator, although it's
a very powerful and important operator in PIR. In it's most simple form,
C<=> stores a value into one of the Parrot registers. We've seen cases where
it can be used to assign a string value to a C<string> register, or an integer
value to an C<int> register, or a floating point value into a C<number>
register, etc. However, the C<=> operator can be used to assign any type
of value into any type of register, and Parrot will handle the conversion
for you automatically:

  $I0 = 5     # Integer. 5
  $S0 = $I0   # Stringify. "5"
  $N0 = $S0   # Numify. 5.0
  $I0 = $N0   # Intify. 5

Notice that conversions between the numeric formats and strings only makes
sense when the value to convert is a number.

  $S0 = "parrot"
  $I0 = $S0        # 0

We've also seen an example earlier where a string literal was set into a
PMC register that had a type C<String>. This works for all the primitive
types and their autoboxed PMC equivalents:

  $P0 = new 'Integer'
  $P0 = 5
  $S0 = $P0      # Stringify. "5"
  $N0 = $P0      # Numify. 5.0
  $I0 = $P0      # De-box. $I0 = 5

  $P1 = new 'String'
  $P1 = "5 birds"
  $S1 = $P1      # De-box. $S1 = "5 birds"
  $I1 = $P1      # Intify. 5
  $N1 = $P1      # Numify. 5.0

  $P2 = new 'Number'
  $P2 = 3.14
  $S2 = $P2      # Stringify. "3.14"
  $I2 = $P2      # Intify. 3
  $N2 = $P2      # De-box. $N2 = 3.14

=head1 Labels

Z<CHP-3-SECT-4>

X<PIR (Parrot intermediate representation);labels>
X<labels (PIR)>
Any line in PIR can start with a label definition like C<LABEL:>,
but label definitions can also stand alone on their own line. Labels are
like flags or markers that the program can jump to or return to at different
times. Labels and jump operations (which we will discuss a little bit
later) are one of the primary methods to change control flow in PIR, so
it is well worth understanding.

Labels are most often used in branching instructions, which are used
to implement high level control structures by our high-level language
compilers.

=head2 Compilation Units

Z<CHP-3-SECT-4.1>

X<PIR (Parrot intermediate representation);compilation units>
X<compilation units (PIR)>
Compilation units in PIR are roughly equivalent to the subroutines or
methods of a high-level language. Though they will be explained in
more detail later, we introduce them here because all code in a PIR
source file must be defined in a compilation unit. We've already seen an
example for the simplest syntax for a PIR compilation unit. It starts with
the C<.sub> directive and ends with the C<.end> directive:

  .sub main
      print "Hello, Polly.\n"
  .end

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.

  .sub first
      print "Polly want a cracker?\n"
  .end

  .sub second :main
      print "Hello, Polly.\n"
  .end

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:

  .sub first :main
      print "Polly want a cracker?\n"
  .end

  .sub second
      print "Hello, Polly.\n"
  .end

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>.

  .sub _main
      goto L1
      print "never printed"
  L1:
      print "after branch\n"
      end
  .end

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>.

  .sub _main
      $I0 = 42
      if $I0 goto L1
      print "never printed"
  L1: print "after branch\n"
      end
  .end

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:

  .sub _main
      $I0 = 42
      $I1 = 43
      if $I0 < $I1 goto L1
      print "never printed"
  L1:
      print "after branch\n"
      end
  .end

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:

  .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

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:

  .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

This example tests the counter C<$I1> at the start of the loop. At the
end of the loop, it unconditionally branches back to the start of the
loop and tests the condition again. The loop ends when the counter
C<$I1> reaches 0 and the C<if> branches to the C<LAST> label. If the
counter isn't a positive number before the loop, the loop never
executes.

Any high-level flow control construct can be built from conditional
and unconditional branches, because this is the way almost all computer
hardware operates at the lowest-level, so all modern programming
languages use branching constructs to implement their most complex
flow control devices.

Fortunately, libraries of macros have been developed that can implement
more familiar syntax for many of these control structures. We will discuss
these libraries in more detail in A<CHP-6> "PIR Standard Library".

=head1 Classes and Objects

It may seem more appropriate for a discussion of PIR's support for classes
and objects to reside in its own chapter, instead of appearing in a generic
chapter about PIR programming "basics". However, part of PIR's core
functionality is its support for object-oriented programming. PIR doesn't
use all the fancy syntax as other OO languages, and it doesn't even support
all the features that most modern OO languages have. What PIR does have is
support for some of the basic structures and abilities, the necessary subset
to construct richer and higher-level object systems.

=head2 PMCs as Classes

PMCs aren't exactly "classes" in the way that this term is normally used.
They are polymorphic data items that can be one of a large variety of
predefined types. As we have seen briefly, and as we will see in more depth
later, PMCs have a standard interface called the VTABLE interface. VTABLEs
are a standard list of functions that all PMCs implement N<or, PMCs can
choose not to implement each interface explicitly and instead let Parrot
call the default implementations>. 

VTABLEs are very strict: There are a fixed number with fixed names and
fixed argument lists. You can't just create any random VTABLE interface that
you want to create, you can only make use of the ones that Parrot supplies
and expects. To circumvent this limitation, PMCs may have METHODS in
addition to VTABLEs. METHODs are arbitrary code functions that can be
written in C, may have any name, and may implement any behavior.

=head2 VTABLE Interfaces

Internally, all operations on PMCs are performed by calling various VTABLE
interfaces.

=head2 Class and Object PMCs

The details about various PMC classes are managed by the Class PMC. Class PMCs
contain information about the class, available methods, the inheritance
hierarchy of the class, and various other details. Classes can be created
with the C<newclass> opcode:

  $P0 = newclass "MyClass"

Once we have created the class PMC, we can instantiate objects of that class
using the C<new> opcode. The C<new> opcode takes either the class name or the
Class PMC as an argument:

  $P1 = new $P0        # $P0 is the Class PMC
  $P2 = new "MyClass"  # Same

The C<new> opcode can create two different types of PMC. The first type are
the built-in core PMC classes. The built-in PMCs are written in C and cannot
be extended from PIR without subclassing. However, you can also create
user-defined PMC types in PIR. User-defined PMCs use the Object PMC type for
instantiation. Object PMCs are used for all user-defined type and keep track
of the methods and VTABLE override definitions. We're going to talk about
methods and VTABLE overrides in the next chapter.

=head2 Subclassing PMCs

Existing built-in PMC types can be subclassed to associate additional data
and methods with that PMC type. Subclassed PMC types act like their PMC
base types, by sharing the same VTABLE methods and underlying data types.
However, the subclass can define additional methods and attribute data
storage. If necessary new VTABLE interfaces can be defined in PIR and old
VTABLE methods can be overriden using PIR. We'll talk about defining
methods and VTABLE interface overrides in the next chapter.

Creating a new subclass of an existing PMC class is done using the
C<subclass> keyword:

  # create an anonymous subclass
  $P0 = subclass 'ResizablePMCArray'

  # create a subclass named "MyArray"
  $P0 = subclass 'ResizablePMCArray', 'MyArray'

This returns a C<Class> PMC which can be used to create and modify the
class by adding attributes or creating objects of that class. You can also
use the new class PMC to create additional subclasses:

  $P0 = subclass 'ResizablePMCArray', 'MyArray'
  $P1 = subclass $P0, 'MyOtherArray'

Once you have created these classes, you can create them like normal with
the C<new> keyword:

  $P0 = new 'MyArray'
  $P1 = new 'MyOtherArray'

=head2 Attributes

Classes and subclasses can be given attributes N<in addition to methods,
which we will talk about in the next chapter> which are named data fields.
Attributes are created with the C<addattribute> opcode, and can be set
and retrieved with the C<setattribute> and C<getattribute> opcodes
respectively:

  # Create the new class with two attributes
  $P0 = newclass 'MyClass'
  addattribute $P0, 'First'
  addattribute $P0, 'Second'

  # Create a new item of type MyClass
  $P1 = new 'MyClass'

  # Set values to the attributes
  setattribute $P1, 'First', 'First Value'
  setattribute $P1, 'Second', 'Second Value'

  # Get the attribute values
  $S0 = getattribute $P1, 'First'
  $S1 = getattribute $P1, 'Second'

Those values added as attributes don't need to be strings, even though
both of the ones in the example are. They can be integers, numbers
or PMCs too.

=head1 Input and Output

Like almost everything else in Parrot, input and output are handled by PMCs.
Using the C<print> opcode or the C<say> opcode like we've already seen in
some examples does this internally without your knowledge. However, we can
do it explicitly too. First we'll talk about basic I/O, and then we will talk
about using PMC-based filehandles for more advanced operations.

=head2 Basic I/O Opcodes

We've seen C<print> and C<say>. These are carry-over artifacts from Perl, when
Parrot was simply the VM backend to the Perl 6 language. C<print> prints
the given string argument, or the stringified form of the argument, if it's
not a string, to standard output. C<say> does the same thing but also appends
a trailing newline to it. Another opcode worth mentioning is the C<printerr>
opcode, which prints an argument to the standard error output instead.

We can read values from the standard input using the C<read> and C<readline>
ops. C<read> takes an integer value and returns a string with that many
characters. C<readline> reads an entire line of input from the standard
input, and returns the string without the trailing newline. Here is a simple
echo program that reads in characters from the user and echos them to
standard output:

  .sub main
    loop_top:
      $S0 = read 10
      print $S0
      goto loop_top
  .end

=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.

  .sub main
    $P0 = getstdout
    $P1 = open "myfile.txt", "r"
    loop_top:
      $S0 = readline $P1
      say $P0, $S0
      if $P1 goto loop_top
    close $P1
  .end

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:

{'fraction_non_alphanumeric': 0.05683536329273414, 'fraction_numerical': 0.010279294414111718, 'mean_word_length': 3.849091186803116, 'pattern_counts': {'":': 0, '<': 537, '<?xml version=': 0, '>': 531, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4201375', 'n_tokens_mistral': 27486, 'n_tokens_neox': 26072, 'n_words': 14810}