[svn:parrot] r37625 - trunk/docs/book

coke at svn.parrot.org coke at svn.parrot.org
Sat Mar 21 20:34:29 UTC 2009


Author: coke
Date: Sat Mar 21 20:34:26 2009
New Revision: 37625
URL: https://trac.parrot.org/parrot/changeset/37625

Log:
[t/docs] test more PASM code.
Update some old tests and docs. Mark some as "PASM TODO" - those snippets fail and need review.

Modified:
   trunk/docs/book/ch05_pasm.pod

Modified: trunk/docs/book/ch05_pasm.pod
==============================================================================
--- trunk/docs/book/ch05_pasm.pod	Sat Mar 21 19:34:03 2009	(r37624)
+++ trunk/docs/book/ch05_pasm.pod	Sat Mar 21 20:34:26 2009	(r37625)
@@ -72,30 +72,46 @@
 followed by a colon. It can be on its own line N<In fact, we recommend
 that it be on its own line, for readability.>:
 
+=begin PASM
+
   LABEL:
       print "Norwegian Blue\n"
 
+=end PASM
+
 or before a statement on the same line:
 
+=begin PASM
+
   LABEL: print "Norwegian Blue\n"
 
+=end PASM
+
 X<PASM (Parrot assembly language);comments>
 POD (plain old documentation) is also allowed in PASM like it is in PIR.
 An equals sign in the first column marks the start of a POD block, and
 a C<=cut> marker signals the end of a POD block.
 
-  =head1
+=begin PASM
+
+=head1
 
   This is POD documentation, and is treated like a
   comment. The PASM interpreter ignores this.
 
-  =cut
+=cut
+
+=end PASM
 
 Besides POD, there are also ordinary 1-line comments using the # sign,
 which is the same in PIR:
 
+=begin PASM
+
   LABEL:                        # This is a comment for a label
-    print 'Norwegian Blue\n"    # Print a color
+    print "Norwegian Blue\n"    # Print a color
+
+=end PASM
 
 =head2 Constants
 
@@ -105,23 +121,31 @@
 Integer constants are signed integers.N<The size of integers is
 defined when Parrot is configured. It's typically 32 bits on 32-bit
 machines (a range of -2G<31> to +2G<31>-1) and twice that size on
-64-bit processors.> Integer constants can have a positive (C<+>) or
+64-bit processors.> Decimal integer constants can have a positive (C<+>) or
 negative (C<->) sign in front. Binary integers are preceded by C<0b>
 or C<0B>, and hexadecimal integers are preceded by C<0x> or C<0X>:
 
-  print 42         # integer constant
+=begin PASM
+
+  print 42         # Decimalinteger constant
+  print +144       # integer constant
   print 0x2A       # hexadecimal integer
   print 0b1101     # binary integer
-  print -0b101     # binary integer with sign
+
+=end PASM
 
 Floating-point constants can also be positive or negative. Scientific
 notation provides an exponent, marked with C<e> or C<E> (the sign of
 the exponent is optional):
 
+=begin PASM
+
   print 3.14159    # floating point constant
   print 1.e6       # scientific notation
   print -1.23e+45
 
+=end PASM
+
 String constants are wrapped in single or double quotation marks.
 Quotation marks inside the string must be escaped by a backslash.
 Other special characters also have escape sequences. These are the
@@ -129,11 +153,14 @@
 C<\r> (return), C<\f> (form feed), C<\\> (literal slash), C<\">
 (literal double quote), etc.
 
+=begin PASM
+
   print "string\n"    # string constant with escaped newline
   print "\\"          # a literal backslash
-  print 'that\'s it'  # escaped single quote
   print 'a\n'         # three chars: 'a', a backslash, and a 'n'
 
+=end PASM
+
 =head2 Working with Registers
 
 Z<CHP-5-SECT-2.2>
@@ -183,28 +210,39 @@
 The most basic operation on registers is assignment using the C<set>
 opcode:
 
+=begin PASM
+
   set I0, 42        # set integer register #0 to the integer value 42
   set N3, 3.14159   # set number register #3 to an approximation of E<#x3C0>
   set I1, I0        # set register I1 to what I0 contains
   set I2, N3        # truncate the floating point number to an integer
 
+=end PASM
+
 PASM uses registers where a high-level language would use variables.
 The C<exchange> opcode swaps the contents of two registers of the same
 type:
 
+=begin PASM
+
   exchange I1, I0   # set register I1 to what I0 contains
                     # and set register I0 to what I1 contains
+=end PASM
 
 As we mentioned before, string and PMC registers are slightly
 different because they hold a pointer instead of directly holding a
 value. Assigning one string register to another:
 
+=begin PASM
+
   set S0, "Ford"
   set S1, S0
   set S0, "Zaphod"
   print S1                # prints "Ford"
   end
 
+=end PASM
+
 doesn't make a copy of the string; it makes a copy of the pointer.
 N<Strings in Parrot use Copy-On-Write (COW) optimizations. When we
 call C<set S1, S0> we copy the pointer only, so both registers point
@@ -223,6 +261,8 @@
 do what they say they do.>. So, rewriting the same example using a PMC
 has a completely different result:
 
+=begin PASM
+
   new P0, "String"
   set P0, "Ford"
   set P1, P0
@@ -230,14 +270,20 @@
   print P1                # prints "Zaphod"
   end
 
+=end PASM
+
 The C<new> opcode creates an instance of the C<.String> class. The
 class's vtable methods define how the PMC in C<P0> operates.  The
 first C<set> statement calls C<P0>'s vtable method
 C<set_string_native>, which assigns the string "Ford" to the PMC. When
 C<P0> is assigned to C<P1>:
 
+=begin PASM
+
   set P1, P0
 
+=end PASM
+
 it copies the pointer, so C<P1> and C<P0> are both aliases to the same
 PMC. Then, assigning the string "Zaphod" to C<P0> changes the
 underlying PMC, so printing C<P1> or C<P0> prints "Zaphod".N<Contrast
@@ -258,12 +304,16 @@
 When the source argument is a PMC and the destination is a string
 register, C<typeof> returns the name of the type:
 
+=begin PASM
+
   new P0, "String"
   typeof S0, P0               # S0 is "String"
   print S0
   print "\n"
   end
 
+=end PASM
+
 In this example, C<typeof> returns the type name "String".
 
 X<PMCs (Polymorphic Containers);inheritance>
@@ -291,6 +341,8 @@
 converts it into a String PMC. Assigning an integer value converts it to a
 C<Integer>, and assigning C<undef> morphs it to C<Undef>:
 
+=begin PASM
+
   new P0, "String"
   set P0, "Ford\n"
   print P0           # prints "Ford\n"
@@ -302,6 +354,8 @@
   print "\n"
   end
 
+=end PASM
+
 C<P0> starts as a C<String>, but when C<set> assigns it an integer
 value 42 (replacing the old string value C<"Ford">), it changes type
 to C<Integer>. This behavior only works for the wrapper PMC types for the
@@ -318,9 +372,13 @@
 a numeric object. Most of the major math opcodes have two- and
 three-argument forms:
 
+=begin PASM
+
   add I0, I1              # I0 += I1
   add I10, I11, I2        # I10 = I11 + I2
 
+=end PASM
+
 The three-argument form of C<add>X<add opcode (PASM)> stores the sum
 of the last two registers in the first register. The two-argument form
 adds the first register to the second and stores the result back in
@@ -331,9 +389,13 @@
 Generally, "compatible" means that the source and destination have to
 be the same type, but there are a few exceptions:
 
+=begin PASM
+
   sub P0, P1, 2          # P0 = P1 - 2
   sub P0, P1, 1.5        # P0 = P1 - 1.5
 
+=end PASM
+
 If the destination register is an integer register, like C<I0>, the
 other arguments must be integer registers or integer constants. A
 floating-point destination, like C<N0>, usually requires
@@ -341,6 +403,8 @@
 argument to be an integer. Opcodes with a PMC destination register may
 take an integer, floating-point, or PMC final argument:
 
+=begin PASM
+
   mul P0, P1             # P0 *= P1
   mul P0, I1
   mul P0, N1
@@ -348,6 +412,8 @@
   mul P0, P1, I2
   mul P0, P1, N2
 
+=end PASM
+
 X<PMCs (Polymorphic Containers);operations on>
 Operations on a PMC are implemented by the vtable method of the
 destination (in the two-argument form) or the left source argument (in
@@ -369,10 +435,14 @@
 (decrement), C<abs> (absolute value), C<neg> (negate), and C<fact>
 (factorial):
 
+=begin PASM
+
   abs N0, -5.0  # the absolute value of -5.0 is 5.0
   fact I1, 5    # the factorial of 5 is 120
   inc I1        # 120 incremented by 1 is 121
 
+=end PASM
+
 =head3 Binary math opcodes
 
 Z<CHP-5-SECT-2.3.2>
@@ -391,9 +461,13 @@
 common divisor) and C<lcm>X<lcm opcode (PASM)> (least common
 multiple).
 
+=begin PASM
+
   div I0, 12, 5   # I0 = 12 / 5
   mod I0, 12, 5   # I0 = 12 % 5
 
+=end PASM
+
 =head3 Floating-point operations
 
 Z<CHP-5-SECT-2.3.3>
@@ -412,9 +486,13 @@
 X<trigonometric functions (PASM)> trigonometric functions are in
 radians:
 
+=begin PASM
+
   sin N1, N0
   exp N1, 2
 
+=end PASM
+
 The majority of the floating-point operations have a single source
 argument and a single destination argument. Even though the
 destination must be a floating-point register, the source can be
@@ -423,8 +501,12 @@
 The C<atan>X<atan opcode (PASM)> opcode also has a three-argument
 variant that implements C's C<atan2()>:
 
+=begin PASM
+
   atan N0, 1, 1
 
+=end PASM
+
 =head2 Working with Strings
 
 Z<CHP-5-SECT-2.4>
@@ -444,6 +526,8 @@
 has both a two-argument and a three-argument form. The first argument
 is a source and a destination in the two-argument form:
 
+=begin PASM
+
   set S0, "ab"
   concat S0, "cd"     # S0 has "cd" appended
   print S0            # prints "abcd"
@@ -454,6 +538,8 @@
   print "\n"
   end
 
+=end PASM
+
 The first C<concat> concatenates the string "cd" onto the string "ab"
 in C<S0>. It generates a new string "abcd" and changes C<S0> to point
 to the new string. The second C<concat> concatenates "xy" onto the
@@ -463,6 +549,8 @@
 For PMC registers, C<concat> has only a three-argument form with
 separate registers for source and destination:
 
+=begin PASM
+
   new P0, "String"
   new P1, "String"
   new P2, "String"
@@ -473,6 +561,8 @@
   print "\n"
   end
 
+=end PASM
+
 Here, C<concat> concatenates the strings in C<P0> and C<P1> and stores
 the result in C<P2>.
 
@@ -484,12 +574,16 @@
 The C<repeat>X<repeat opcode (PASM)> opcode repeats a string a certain
 number of times:
 
+=begin PASM
+
   set S0, "x"
   repeat S1, S0, 5  # S1 = S0 x 5
   print S1          # prints "xxxxx"
   print "\n"
   end
 
+=end PASM
+
 In this example, C<repeat> generates a new string with "x" repeated
 five times and stores a pointer to it in C<S1>.
 
@@ -502,12 +596,16 @@
 string in characters. This won't be the same as the length in bytes
 for multibyte encoded strings:
 
+=begin PASM
+
   set S0, "abcd"
   length I0, S0                # the length is 4
   print I0
   print "\n"
   end
 
+=end PASM
+
 C<length> doesn't have an equivalent for PMC strings.
 
 =head3 Substrings
@@ -521,8 +619,12 @@
 starting from the offset position (0 is the first character) and
 spanning the length:
 
+=begin PASM
+
   substr S0, "abcde", 1, 2        # S0 is "bc"
 
+=end PASM
+
 This example extracts a two-character string from "abcde" at a
 one-character offset from the beginning of the string (starting with
 the second character). It generates a new string, "bc", in the
@@ -536,6 +638,8 @@
 string to replace the substring. This modifies the second argument and
 returns the removed substring in the destination register.
 
+=begin PASM
+
   set S1, "abcde"
   substr S0, S1, 1, 2, "XYZ"
   print S0                        # prints "bc"
@@ -544,6 +648,8 @@
   print "\n"
   end
 
+=end PASM
+
 This replaces the substring "bc" in C<S1> with the string "XYZ", and
 returns "bc" in C<S0>.
 
@@ -557,12 +663,16 @@
 optimized version of C<substr> that just does a replace without
 returning the removed substring.
 
+=begin PASM
+
   set S1, "abcde"
   substr S1, 1, 2, "XYZ"
   print S1                        # prints "aXYZde"
   print "\n"
   end
 
+=end PASM
+
 The PMC versions of C<substr> are not yet implemented.
 
 =head3 Chopping strings
@@ -574,32 +684,44 @@
 end of a string. It takes two arguments: the string to modify and the
 count of characters to remove.
 
+=begin PASM
+
   set S0, "abcde"
   chopn S0, 2
   print S0         # prints "abc"
   print "\n"
   end
 
+=end PASM
+
 This example removes two characters from the end of C<S0>. If the
 count is negative, that many characters are kept in the string:
 
+=begin PASM
+
   set S0, "abcde"
   chopn S0, -2
   print S0         # prints "ab"
   print "\n"
   end
 
+=end PASM
+
 This keeps the first two characters in C<S0> and removes the rest.
 C<chopn> also has a three-argument version that stores the chopped
 string in a separate destination register, leaving the original string
 untouched:
 
+=begin PASM
+
   set S0, "abcde"
   chopn S1, S0, 1
   print S1         # prints "abcd"
   print "\n"
   end
 
+=end PASM
+
 =head3 Copying strings
 
 Z<CHP-5-SECT-2.4.6>
@@ -610,6 +732,8 @@
 assignment would, it recursively copies the string or object
 underneath.
 
+=begin PASM
+
   new P0, "String"
   set P0, "Ford"
   clone P1, P0
@@ -617,6 +741,8 @@
   print P1        # prints "Ford"
   end
 
+=end PASM
+
 This example creates an identical, independent clone of the PMC in
 C<P0> and puts a pointer to it in C<P1>. Later changes to C<P0> have
 no effect on C<P1>.
@@ -639,20 +765,32 @@
 and returns the integer that represents that character in the string's
 encoding:
 
+=begin PASM
+
   chr S0, 65                # S0 is "A"
   ord I0, S0                # I0 is 65
 
+=end PASM
+
 C<ord> has a three-argument variant that takes a character offset to
 select a single character from a multicharacter string. The offset
 must be within the length of the string:
 
+=begin PASM
+
   ord I0, "ABC", 2        # I0 is 67
 
+=end PASM
+
 A negative offset counts backward from the end of the string, so -1 is
 the last character.
 
+=begin PASM
+
   ord I0, "ABC", -1        # I0 is 67
 
+=end PASM
+
 =head3 Formatting strings
 
 Z<CHP-5-SECT-2.4.8>
@@ -665,9 +803,13 @@
 be formatted. The format string and the destination register can be
 either strings or PMCs:
 
+=begin PASM
+
   sprintf S0, S1, P2
   sprintf P0, P1, P2
 
+=end PASM
+
 The format string is similar to the one for C's C<sprintf> function,
 but with some extensions for Parrot data types. Each format field in
 the string starts with a C<%>
@@ -911,6 +1053,8 @@
 
 Here's a short illustration of string formats:
 
+=begin PASM
+
   new P2, "Array"
   new P0, "Int"
   set P0, 42
@@ -923,6 +1067,8 @@
   print "\n"
   end
 
+=end PASM
+
 The first eight lines create a C<Array> with two elements: a
 C<Int> and a C<Num>. The format string of the C<sprintf> has
 two format fields. The first, C<%#Px>, takes a PMC argument from the
@@ -945,6 +1091,8 @@
 where the substring was found as a character offset from the beginning
 of the string. If it fails to find the substring, it returns -1:
 
+=begin PASM
+
   index I0, "Beeblebrox", "eb"
   print I0                       # prints 2
   print "\n"
@@ -953,14 +1101,20 @@
   print "\n"
   end
 
+=end PASM
+
 C<index> also has a four-argument version, where the fourth argument
 defines an offset position for starting the search:
 
+=begin PASM
+
   index I0, "Beeblebrox", "eb", 3
   print I0                         # prints 5
   print "\n"
   end
 
+=end PASM
+
 This finds the second "eb" in "Beeblebrox" instead of the first,
 because the search skips the first three characters in the
 string.
@@ -971,6 +1125,8 @@
 string. The second argument separates the individual elements of the
 PMC in the final string result.
 
+=begin PASM
+
   new P0, "Array"
   push P0, "hi"
   push P0, 0
@@ -980,6 +1136,7 @@
   join S0, "__", P0
   print S0              # prints "hi__0__1__0__parrot"
   end
+=end PASM
 
 This example builds a C<Array> in C<P0> with the values C<"hi">,
 C<0>, C<1>, C<0>, and C<"parrot">. It then joins those values (separated
@@ -990,6 +1147,8 @@
 Splitting a string yields a new array containing the resulting
 substrings of the original string.
 
+=begin PASM
+
   split P0, "", "abc"
   set P1, P0[0]
   print P1              # 'a'
@@ -997,6 +1156,8 @@
   print P1              # 'c'
   end
 
+=end PASM
+
 This example splits the string "abc" into individual characters and
 stores them in an array in C<P0>. It then prints out the first and
 third elements of the array. For now, the split pattern (the second
@@ -1021,17 +1182,25 @@
 The C<and>X<and opcode (PASM)> opcode returns the second argument if
 it's false and the third argument otherwise:
 
+=begin PASM
+
   and I0, 0, 1  # returns 0
   and I0, 1, 2  # returns 2
 
+=end PASM
+
 The C<or>X<or opcode (PASM)> opcode returns the second argument if
 it's true and the third argument otherwise:
 
+=begin PASM
+
   or I0, 1, 0  # returns 1
   or I0, 0, 2  # returns 2
 
   or P0, P1, P2
 
+=end PASM
+
 Both C<and> and C<or> are short-circuiting. If they can determine what
 value to return from the second argument, they'll never evaluate the
 third.  This is significant only for PMCs, as they might have side
@@ -1042,18 +1211,26 @@
 only true value, and returns false if both values are true or both are
 false:
 
+=begin PASM
+
   xor I0, 1, 0  # returns 1
   xor I0, 0, 1  # returns 1
   xor I0, 1, 1  # returns 0
   xor I0, 0, 0  # returns 0
 
+=end PASM
+
 The C<not>X<not opcode (PASM)> opcode returns a true value when the
 second argument is false, and a false value if the second argument is
 true:
 
+=begin PASM
+
   not I0, I1
   not P0, P1
 
+=end PASM
+
 The X<bitwise;opcodes (PASM)> bitwise opcodes operate on their values
 a single bit at a time. C<band>X<band opcode (PASM)>,
 C<bor>X<bor opcode (PASM)>, and C<bxor>X<bxor opcode (PASM)> return a
@@ -1063,11 +1240,15 @@
 also a source.  C<bnot>X<bnot opcode (PASM)> is the logical NOT of
 each bit in a single source argument.
 
+=begin PASM
+
   bnot I0, I1
   band P0, P1
   bor I0, I1, I2
   bxor P0, P1, I2
 
+=end PASM
+
 X<bitwise;string opcodes>
 The bitwise opcodes also have string variants for AND, OR, and XOR:
 C<bors>X<bors opcode (PASM)>, C<bands>X<bands opcode (PASM)>, and
@@ -1075,10 +1256,14 @@
 string source arguments and perform the logical operation on each byte
 of the strings to produce the final string.
 
+=begin PASM
+
   bors S0, S1
   bands P0, P1
   bors S0, S1, S2
-  bxors P0, P1, I2
+  bxors P0, P1, S2
+
+=end PASM
 
 The bitwise string opcodes only have meaningful results when they're
 used with simple ASCII strings because the bitwise operation is done
@@ -1087,10 +1272,14 @@
 The logical and arithmetic shift operations shift their values by a
 specified number of bits:
 
+=begin PASM
+
   shl  I0, I1, I2        # shift I1 left by count I2 giving I0
   shr  I0, I1, I2        # arithmetic shift right
   lsr  P0, P1, P2        # logical shift right
 
+=end PASM
+
 =head1 Working with PMCs
 
 Z<CHP-5-SECT-3>
@@ -1126,6 +1315,8 @@
 zero-based integer keys. The syntax for X<keyed access to PMCs> keyed access to a
 PMC puts the key in square brackets after the register name:
 
+=begin PASM
+
   new P0, "Array"     # obtain a new array object
   set P0, 2           # set its length
   set P0[0], 10       # set first element to 10
@@ -1133,6 +1324,8 @@
   set I0, P0[0]       # get the first element
   set I1, P0          # get array length
 
+=end PASM
+
 A key on the destination register of a C<set> operation sets a value
 for that key in the aggregate. A key on the source register of a
 C<set> returns the value for that key. If you set C<P0> without a key,
@@ -1147,14 +1340,17 @@
 allocation (how much storage the array provides) from the actual
 element count. The currently proposed syntax uses C<set> to set or
 retrieve the allocated size of an array, and an C<elements>
-X<elements opcode (PASM)> opcode to set or retrieve the count of
+X<elements opcode (PASM)> opcode to retrieve the count of
 elements stored in the array.
 
+=begin PASM
+
   set P0, 100         # allocate store for 100 elements
-  elements P0, 5      # set element count to 5
   set I0, P0          # obtain current allocation size
   elements I0, P0     # get element count
 
+=end PASM
+
 Some other useful instructions for working with arrays are C<push>,
 C<pop>, C<shift>, and C<unshift> (you'll find them in
 A<CHP-11-SECT-1>"PASM Opcodes" in Chapter 11).
@@ -1167,16 +1363,22 @@
 The C<Hash>X<Hash PMC> PMC is an unordered aggregate with
 string keys:
 
+=begin PASM
+
   new P1, "Hash"      # generate a new hash object
   set P1["key"], 10   # set key and value
   set I0, P1["key"]   # obtain value for key
   set I1, P1          # number of entries in hash
 
+=end PASM
+
 The C<exists>X<exists opcode (PASM)> opcode tests whether a keyed
 value exists in an aggregate. It returns 1 if it finds the key in the
 aggregate, and returns 0 if it doesn't. It doesn't care if the value
 itself is true or false, only that the key has been set:
 
+=begin PASM
+
   new P0, "Hash"
   set P0["key"], 0
   exists I0, P0["key"] # does a value exist at "key"
@@ -1184,6 +1386,8 @@
   print "\n"
   end
 
+=end PASM
+
 The C<delete>X<delete opcode (PASM)> opcode is also useful for working
 with hashes: it removes a key/value pair.
 
@@ -1195,8 +1399,12 @@
 by creating a new C<Iterator> PMC, and passing the array to C<new> as
 an additional parameter:
 
+=begin PASM
+
       new P1, "Iterator", P2
 
+=end PASM
+
 The include file F<iterator.pasm> defines some constants for working
 with iterators. The C<.ITERATE_FROM_START> and C<.ITERATE_FROM_END>
 constants are used to select whether an array iterator starts from the
@@ -1204,6 +1412,8 @@
 from the array. An iterator PMC is true as long as it still has values
 to be retrieved (tested by C<unless> below).
 
+=begin PASM
+
   .include "iterator.pasm"
       new P2, "Array"
       push P2, "a"
@@ -1220,10 +1430,14 @@
   iter_end:
       end
 
+=end PASM
+
 Hash iterators work similarly to array iterators, but they extract
 keys. With hashes it's only meaningful to iterate in one direction,
 since they don't define any order for their keys.
 
+=begin PASM
+
   .include "iterator.pasm"
       new P2, "Hash"
       set P2["a"], 10
@@ -1241,6 +1455,8 @@
   iter_end:
       end
 
+=end PASM
+
 =head3 Data structures
 
 Z<CHP-5-SECT-3.1.4>
@@ -1252,6 +1468,8 @@
 Complex keys specify a series of nested data structures, with each
 individual key separated by a semicolon:
 
+=begin PASM
+
   new P0, "Hash"
   new P1, "Array"
   set P1[2], 42
@@ -1262,12 +1480,18 @@
   print "\n"
   end
 
+=end PASM
+
 This example builds up a data structure of a hash containing an array.
 The complex key C<P0["answer";I1]> retrieves an element of the array
 within the hash. You can also set a value using a complex key:
 
+=begin PASM
+
   set P0["answer";0], 5   # %hash{"answer"}[0] = 5
 
+=end PASM
+
 The individual keys are integers or strings, or registers with integer
 or string values.
 
@@ -1281,6 +1505,8 @@
 want to assign the value of one PMC to another PMC, you need the
 C<assign>X<assign opcode (PASM)> opcode:
 
+=begin PASM
+
   new P0, "Int"
   new P1, "Int"
   set P0, 42
@@ -1295,6 +1521,8 @@
   print "\n"
   end
 
+=end PASM
+
 This example creates two C<Int> PMCs: C<P0> and C<P1>. It gives
 C<P0> a value of 42. It then uses C<set> to give the same value to
 C<P2>, but uses C<assign> to give the value to C<P1>. When C<P0> is
@@ -1322,6 +1550,8 @@
 PMC to store the property's value, the name of the property, and the
 PMC from which the property value is to be retrieved:
 
+=begin PASM
+
   new P0, "String"
   set P0, "Zaphod"
   new P1, "Int"
@@ -1332,6 +1562,8 @@
   print "\n"
   end
 
+=end PASM
+
 This example creates a C<String> object in C<P0>, and a C<Int>
 object with the value 1 in C<P1>. C<setprop> sets a property named
 "constant" on the object in C<P0> and gives the property the value in
@@ -1346,13 +1578,21 @@
 
 C<delprop>X<delprop opcode (PASM)> deletes a property from a PMC.
 
+=begin PASM
+
   delprop P1, "constant"  # delete property
 
+=end PASM
+
 You can also return a complete hash of all properties on a PMC with
 C<prophash>X<prophash opcode (PASM)>.
 
+=begin PASM
+
   prophash P0, P1         # set P0 to the property hash of P1
 
+=end PASM
+
 =head1 Flow Control
 
 Z<CHP-5-SECT-4>
@@ -1369,12 +1609,16 @@
 rarely any need to do so. The simplest branch instruction is
 C<branch>:
 
+=begin PASM
+
     branch L1                # branch 4
     print "skipped\n"
   L1:
     print "after branch\n"
     end
 
+=end PASM
+
 This example unconditionally branches to the location of the label
 C<L1>, skipping over the first C<print> statement.
 
@@ -1382,6 +1626,8 @@
 opcode doesn't calculate an address from a label, so it's used
 together with C<set_addr>:
 
+=begin PASM
+
     set_addr I0, L1
     jump I0
     print "skipped\n"
@@ -1390,6 +1636,8 @@
     print "after jump\n"
     end
 
+=end PASM
+
 The C<set_addr>X<set_addr opcode (PASM)> opcode takes a label or an
 integer offset and returns an absolute address.
 
@@ -1414,6 +1662,8 @@
 The following example has C<if>X<if (conditional);opcode (PASM)> and
 C<unless>X<unless (conditional);opcode (PASM)> conditional branches:
 
+=begin PASM
+
     set I0, 0
     if I0, TRUE
     unless I0, FALSE
@@ -1426,6 +1676,8 @@
     print "the value was false\n"
     end
 
+=end PASM
+
 C<if> branches if its first argument is a true value, and C<unless>
 branches if its first argument is a false value. In this case, the
 C<if> doesn't branch because C<I0> is false, but the C<unless> does
@@ -1441,6 +1693,8 @@
 greater than or equal). The two compared arguments must be the same
 register type:
 
+=begin PASM
+
     set I0, 4
     set I1, 4
     eq I0, I1, EQUAL
@@ -1450,6 +1704,8 @@
     print "the two values are equal\n"
     end
 
+=end PASM
+
 This compares two integers, C<I0> and C<I1>, and branches if they're
 equal. Strings of different character sets or encodings are converted
 to Unicode before they're compared. PMCs have a C<cmp> vtable method.
@@ -1464,14 +1720,22 @@
 on two PMCs, use the alternate comparison opcodes that end in the
 C<_num> and C<_str> suffixes.
 
+=begin PASM
+
   eq_str P0, P1, label     # always a string compare
   gt_num P0, P1, label     # always numerically
 
+=end PASM
+
 Finally, the C<eq_addr> opcode branches if two PMCs or strings are
 actually the same object (have the same address):
 
+=begin PASM
+
   eq_addr P0, P1, same_pmcs_found
 
+=end PASM
+
 =head2 Iteration
 
 Z<CHP-5-SECT-4.2>
@@ -1483,6 +1747,8 @@
 I<do-while>X<do-while style loop;(PASM)> style loop can be constructed
 with a single conditional branch:
 
+=begin PASM
+
     set I0, 0
     set I1, 10
   REDO:
@@ -1492,6 +1758,8 @@
     lt I0, I1, REDO
     end
 
+=end PASM
+
 This example prints out the numbers 1 to 10. The first time through,
 it executes all statements up to the C<lt> statement.  If the
 condition evaluates as true (C<I0> is less than C<I1>) it branches to
@@ -1501,6 +1769,8 @@
 Conditional and unconditional branches can build up quite complex
 looping constructs, as follows:
 
+=begin PASM
+
     # loop ($i=1; $i<=10; $i++) {
     #    print "$i\n";
     # }
@@ -1520,6 +1790,8 @@
   out:
     end
 
+=end PASM
+
 X<loops;PASM>
 X<PASM (Parrot assembly language);loops>
 This example emulates a X<counter-controlled loop> counter-controlled
@@ -1561,51 +1833,67 @@
 
 X<PASM (Parrot assembly language);global variables>
 Global variables are stored in a C<Hash>, so every variable name
-must be unique.  PASM has two opcodes for globals, C<store_global> and
-C<find_global>:
+must be unique.  PASM has two opcodes for globals, C<set_global> and
+C<get_global>:
+
+=begin PASM
 
   new P10, "Int"
   set P10, 42
-  store_global "$foo", P10
+  set_global "$foo", P10
   # ...
-  find_global P0, "$foo"
+  get_global P0, "$foo"
   print P0                        # prints 42
   end
 
+=end PASM
+
 The first two statements create a C<Int> in the PMC register
 C<P10> and give it the value 42. In the third statement,
-C<store_global> stores that PMC as the named global variable C<$foo>.
-At some later point in the program, C<find_global> retrieves the PMC
+C<set_global> stores that PMC as the named global variable C<$foo>.
+At some later point in the program, C<get_global> retrieves the PMC
 from the global variable by name, and stores it in C<P0> so it can be
 printed.
 
-The C<store_global> opcode only stores a reference to the object. If
+The C<set_global> opcode only stores a reference to the object. If
 we add an increment statement:
 
+=begin PASM
+
   inc P10
 
-after the C<store_global> it increments the stored global, printing 43.
+=end PASM
+
+after the C<set_global> it increments the stored global, printing 43.
 If that's not what you want, you can C<clone> the PMC before you store
 it. Leaving the global variable as an alias does have advantages,
 though. If you retrieve a stored global into a register and modify it
 as follows:
 
-  find_global P0, "varname"
+=begin PASM
+
+  get_global P0, "varname"
   inc P0
 
+=end PASM
+
 the value of the stored global is directly modified, so you don't need
-to call C<store_global> again.
+to call C<set_global> again.
 
-The two-argument forms of C<store_global> and C<find_global> store or
+The two-argument forms of C<set_global> and C<get_global> store or
 retrieve globals from the outermost namespace (what Perl users will
 know as the "main" namespace). A simple flat global namespace isn't
 enough for most languages, so Parrot also needs to support
 hierarchical namespaces for separating packages (classes and modules
-in Perl 6). The three-argument versions of C<store_global> and
-C<find_global> add an argument to select a nested namespace:
+in Perl 6). Use C<set_rootglobal> and
+C<get_root_global> add an argument to select a nested namespace:
+
+=begin PASM
 
-  store_global "Foo", "var", P0 # store P0 as var in the Foo namespace
-  find_global P1, "Foo", "var"  # get Foo::var
+  set_root_global ["Foo"], "var", P0 # store P0 as var in the Foo namespace
+  get_root_global P1, ["Foo"], "var"  # get Foo::var
+
+=end PASM
 
 Eventually the global opcodes will have variants that take a PMC to
 specify the namespace, but the design and implementation of these
@@ -1627,6 +1915,8 @@
 To store a lexical variable in the current scope pad, use C<store_lex>.
 Likewise, use C<find_lex> to retrieve a variable from the current pad.
 
+=begin PASM
+
   new P0, "Int"            # create a variable
   set P0, 10               # assign value to it
   store_lex "foo", P0      # store the var with the variable name "foo"
@@ -1636,6 +1926,8 @@
   print "\n"               # prints 10
   end
 
+=end PASM
+
 =head1 Subroutines
 
 Z<CHP-5-SECT-7>
@@ -1649,6 +1941,8 @@
 next instruction onto the control stack, and then branches to a label
 that marks the subroutine:
 
+=begin PASM
+
     print "in main\n"
     bsr _sub
     print "and back\n"
@@ -1657,6 +1951,8 @@
     print "in sub\n"
     ret
 
+=end PASM
+
 At the end of the subroutine, the C<ret> instruction pops a location
 back off the control stack and goes there, returning control to the
 caller. The C<jsr>X<jsr opcode (PASM)> opcode pushes the current location
@@ -1665,6 +1961,8 @@
 address has to be calculated first with the C<set_addr>X<set_addr
 opcode (PASM)> opcode:
 
+=begin PASM
+
     print "in main\n"
     set_addr I0, _sub
     jsr I0
@@ -1674,6 +1972,8 @@
     print "in sub\n"
     ret
 
+=end PASM
+
 =head2 Calling Conventions
 
 Z<CHP-5-SECT-7.1>
@@ -1726,6 +2026,8 @@
 really portable across all libraries, but it's worth a short example.
 This is a simplified version of the first test in F<t/pmc/nci.t>:
 
+=begin PASM TODO
+
     loadlib P1, "libnci"          # get library object for a shared lib
     print "loaded\n"
     dlfunc P0, P1, "nci_dd", "dd" # obtain the function object
@@ -1737,7 +2039,9 @@
     print "ok 1\n"
     end
   nok_1:
-    ...
+    #...
+
+=end PASM TODO
 
 This example shows two new instructions: C<loadlib> and C<dlfunc>. The
 C<loadlib>X<loadlib opcode (PASM)> opcode obtains a handle for a shared
@@ -1901,8 +2205,12 @@
 X<coroutines>
 In PASM, coroutines are subroutine-like objects:
 
+=begin PASM TODO
+
   newsub P0, .Coroutine, _co_entry
 
+=end PASM TODO
+
 The C<Coroutine> object has its own user stack, register frame stacks,
 control stack, and pad stack. The pad stack is inherited from the
 caller. The coroutine's control stack has the caller's control stack
@@ -1911,6 +2219,8 @@
 swapping all stacks). The next time the coroutine is invoked, it
 continues to execute from the point at which it previously returned:
 
+=begin PASM TODO
+
     new_pad 0                # push a new lexical pad on stack
     new P0, "Int"            # save one variable in it
     set P0, 10
@@ -1941,6 +2251,8 @@
     print "again "
     branch _cor              # next invocation of the coroutine
 
+=end PASM TODO
+
 This prints out the result:
 
   in cor 10
@@ -1971,6 +2283,8 @@
 caller's context, including its own copy of the call stack. Invoking a
 continuation starts or restarts it at the entry point:
 
+=begin PASM XXX
+
     new P1, "Int"
     set P1, 5
 
@@ -1986,6 +2300,8 @@
     print "done\n"
     end
 
+=end PASM XXX
+
 This prints:
 
   in cont 5
@@ -2007,8 +2323,12 @@
 The first step is to get an assembler or compiler for the target
 language:
 
+=begin PASM
+
   compreg P1, "PASM"
 
+=end PASM
+
 Within the Parrot interpreter there are currently three registered
 languages: C<PASM>, C<PIR>, and C<PASM1>. The first two are for parrot
 assembly language and parrot intermediate representation code. The third
@@ -2019,6 +2339,8 @@
 This example places a bytecode segment object into the destination
 register C<P0> and then invokes it with C<invoke>:
 
+=begin PASM TODO
+
   compreg P1, "PASM1"                # get compiler
   set S1, "in eval\n"
   compile P0, P1, "print S1"
@@ -2026,12 +2348,18 @@
   print "back again\n"
   end
 
+=end PASM TODO
+
 You can register a compiler or assembler for any language inside the
 Parrot core and use it to compile and invoke code from that language.
 These compilers may be written in PASM or reside in shared libraries.
 
+=begin PASM
+
   compreg "MyLanguage", P10
 
+=end PASM
+
 In this example the C<compreg> opcode registers the subroutine-like
 object C<P10> as a compiler for the language "MyLanguage". See
 F<examples/compilers> and F<examples/japh/japh16.pasm> for an external
@@ -2063,16 +2391,20 @@
 exception is thrown (perhaps because of code that does division by
 zero or attempts to retrieve a global that wasn't stored.)
 
+=begin PASM TODO
+
     newsub P20, .ExceptionHandler, _handler
     set_eh P20                  # push handler on control stack
     null P10                    # set register to null
-    find_global P10, "none"     # may throw exception
+    get_global P10, "none"     # may throw exception
     clear_eh                    # pop the handler off the stack
-    ...
+    #...
 
   _handler:                     # if not, execution continues here
     is_null P10, not_found      # test P10
-    ...
+    #...
+
+=end PASM TODO
 
 This example creates a new exception handler subroutine with the
 C<newsub> opcode and installs it on the control stack with the
@@ -2080,7 +2412,7 @@
 can be checked later) and attempts to retrieve the global variable
 named C<none>. If the global variable is found, the next statement
 (C<clear_eh>) pops the exception handler off the control stack and
-normal execution continues. If the C<find_global> call doesn't find
+normal execution continues. If the C<get_global> call doesn't find
 C<none> it throws an exception by pushing an exception object onto the
 control stack. When Parrot sees that it has an exception, it pops it
 off the control stack and calls the exception handler C<_handler>.
@@ -2108,16 +2440,20 @@
 process of handling the exception.
 
 Exceptions thrown by standard Parrot opcodes (like the one thrown by
-C<find_global> above or by the C<throw> opcode) are always resumable,
+C<get_global> above or by the C<throw> opcode) are always resumable,
 so when the exception handler function returns normally it continues
 execution at the opcode immediately after the one that threw the
 exception. Other exceptions at the run-loop level are also generally
 resumable.
 
+=begin PASM
+
   new P10, 'Exception'    # create new Exception object
   set P10, 'I die'        # set message attribute
   throw P10               # throw it
 
+=end PASM
+
 Exceptions are designed to work with the Parrot calling conventions.
 Since the return addresses of C<bsr> subroutine calls and exception
 handlers are both pushed onto the control stack, it's generally a bad
@@ -2163,6 +2499,8 @@
 broadcasts it to all running threads. Each thread independently
 decides if it's interested in this signal and, if so, how to respond to it.
 
+=begin PASM TODO
+
     newsub P20, .ExceptionHandler, _handler
     set_eh P20                  # establish signal handler
     print "send SIGINT:\n"
@@ -2179,6 +2517,8 @@
   nok:
     end
 
+=end PASM TODO
+
 This example creates a signal handler and pushes it on to the control
 stack. It then prompts the user to send a C<SIGINT> from the shell
 (this is usually C<Ctrl-C>, but it varies in different shells), and
@@ -2222,7 +2562,9 @@
 usage of threads (no-one really wants to spawn two threads just to print out a
 simple string).
 
-    find_global P5, "_th1"              # locate thread function
+=begin PASM TODO
+
+    get_global P5, "_th1"              # locate thread function
     new P2, "ParrotThread"              # create a new thread
     find_method P0, P2, "thread3"       # a shared thread's entry
     new P7, "TQueue"                    # create a Queue object
@@ -2233,7 +2575,7 @@
     set I3, 3                           # thread function gets 3 args
     invoke                              # _th1.run(P5,P6,P7)
     new P2, "ParrotThread"              # same for a second thread
-    find_global P5, "_th2"
+    get_global P5, "_th2"
     set P6, "utaohrPro akr"             # set string to 2nd thread's
     invoke                              # ... data, run 2nd thread too
     end                                 # Parrot joins both
@@ -2263,6 +2605,8 @@
     if S0, w2                           # the other thread will run
     invoke P1                           # done with string
 
+=end PASM TODO
+
 This example creates a C<ParrotThread> object and calls its C<thread3>
 method, passing three arguments: a PMC for the C<_th1> subroutine in
 C<P5>, a string argument in C<P6>, and a C<TQueue> object in C<P7>
@@ -2325,6 +2669,8 @@
 C<ParrotThread> object, the calling code waits until the thread
 terminates.
 
+=begin PASM TODO
+
     new P2, "ParrotThread"      # create a new thread
     set I5, P2                  # get thread ID
 
@@ -2332,9 +2678,13 @@
     invoke                      # ...and join (wait for) the thread
     set P16, P5                 # the return result of the thread
 
+=end PASM TODO
+
 C<kill> and C<detach> are interpreter methods, so you have to grab the
 current interpreter object before you can look up the method object.
 
+=begin PASM TODO
+
     set I5, P2                  # get thread ID of thread P2
     getinterp P3                # get this interpreter object
     find_method P0, P3, "kill"  # get kill method
@@ -2343,6 +2693,8 @@
     find_method P0, P3, "detach"
     invoke                      # detach thread with ID I5
 
+=end PASM TODO
+
 By the time you read this, some of these combinations of statements
 and much of the threading syntax above may be reduced to a simpler set
 of opcodes.
@@ -2357,11 +2709,15 @@
 argument: the name of the bytecode file to load. So, if you create a
 file named F<file.pasm> containing a single subroutine:
 
+=begin PASM TODO
+
   # file.pasm
   .sub _sub2:               # .sub stores a global sub
      print "in sub2\n"
      invoke P1
 
+=end PASM TODO
+
 and compile it to bytecode using the C<-o> command-line switch:
 
   $ parrot -o file.pbc file.pasm
@@ -2369,28 +2725,38 @@
 You can then load the compiled bytecode into F<main.pasm> and directly
 call the subroutine defined in F<file.pasm>:
 
+=begin PASM TODO
+
   # main.pasm
   main:
     load_bytecode "file.pbc"    # compiled file.pasm
-    find_global P0, "_sub2"
+    get_global P0, "_sub2"
     invokecc
     end
 
+=end PASM TODO
+
 The C<load_bytecode> opcode also works with source files, as long as
 Parrot has a compiler registered for that type of file:
 
+=begin PASM TODO
+
   # main2.pasm
   main:
     load_bytecode "file.pasm"  # PASM source code
-    find_global P0, "_sub2"
+    set_global P0, "_sub2"
     invokecc
     end
 
+=end PASM TODO
+
 Subroutines marked with C<:load> run as soon as they're loaded (before
 C<load_bytecode> returns), rather than waiting to be called. A
 subroutine marked with C<:main> will always run first, no matter what
 name you give it or where you define it in the file.
 
+=begin PASM TODO
+
   # file3.pasm
   .sub :load                    # mark the sub as to be run
     print "file3\n"
@@ -2407,6 +2773,8 @@
     print "back\n"
     end
 
+=end PASM TODO
+
 This example uses both C<:load> and C<:main>. Because the C<main>
 subroutine is defined with C<:main> it will execute first even though
 another subroutine comes before it in the file. C<main> prints a
@@ -2437,14 +2805,22 @@
 C<ParrotClass> PMCX<ParrotClass PMC>, which is the core of the Parrot
 object system.
 
+=begin PASM
+
     newclass P1, "Foo"
 
+=end PASM
+
 To instantiate a new object of a particular class, you first look up
 the integer value for the class type with the C<find_type> opcode,
 then create an object of that type with the C<new> opcode:
 
+=begin PASM TODO
+
     find_type I1, "Foo"
-    new P3, I1
+    new P3I I1
+
+=end PASM TODO
 
 The C<new> opcode also checks to see if the class defines a
 method named "__init" and calls it if it exists.
@@ -2459,17 +2835,25 @@
 attribute (sometimes known as an I<instance variable>) and associates
 it with a name:
 
+=begin PASM
+
     addattribute P1, ".i"                # Foo.i
 
+=end PASM
+
 This chunk of code
 from the C<__init> method looks up the position of the first
 attribute, creates a C<Int> PMC, and stores it as the first
 attribute:
 
+=begin PASM TODO
+
     classoffset I0, P2, "Foo"     # first "Foo" attribute of object P2
     new P6, "Int"                 # create storage for the attribute
     setattribute P2, I0, P6       # store the first attribute
 
+=end PASM TODO
+
 The C<classoffset> opcodeX<classoffset opcode (PASM)> takes a PMC
 containing an object and the name of its class, and returns an integer
 index for the position of the first attribute. The C<setattribute>
@@ -2478,36 +2862,56 @@
 attribute. The second attribute would be at C<I0 + 1>, the third
 attribute at C<I0 + 2>, etc:
 
+=begin PASM TODO
+
     inc I0
     setattribute P2, I0, P7       # store next attribute
-    ...
+    #...
+
+=end PASM TODO
 
 There is also support for named parameters with fully qualified
 parameter names (although this is a little bit slower than getting
 the class offset once and accessing several attributes by index):
 
+=begin PASM
+
     new P6, "Int"
     setattribute P2, "Foo\x0.i", P6   # store the attribute
 
+=end PASM
+
 You use the same integer index to retrieve the value of an attribute.
 The C<getattribute>X<getattribute opcode (PASM)> opcode takes an object and
 an index as arguments and returns the attribute PMC at that position:
 
+=begin PASM TODO
+
     classoffset I0, P2, "Foo"         # first "Foo" attribute of object P2
     getattribute P10, P2, I0          # indexed get of attribute
 
+=end PASM TODO
+
 or
 
+=begin PASM TODO
+
     getattribute P10, P2, "Foo\x0.i"  # named get
 
+=end PASM TODO
+
 To set the value of an attribute PMC, first retrieve it with
 C<getattribute> and then assign to the returned PMC. Because PMC
 registers are only pointers to values, you don't need to store the PMC
 again after you modify its value:
 
+=begin PASM TODO
+
     getattribute P10, P2, I0
     set P10, I5
 
+=end PASM TODO
+
 =head2 Methods
 
 Z<CHP-5-SECT-12.3>
@@ -2519,6 +2923,8 @@
 class. You define a method with the C<.pcc_sub> directive before the
 label:
 
+=begin PASM TODO
+
   .pcc_sub _half:                 # I5 = self."_half"()
     classoffset I0, P2, "Foo"
     getattribute P10, P2, I0
@@ -2526,6 +2932,8 @@
     div I5, 2
     invoke P1
 
+=end PASM TODO
+
 This routine returns half of the value of the first attribute of the
 object. Method calls use the Parrot calling conventions so they always
 pass the I<invocant> object (often called I<self>) in C<P2>. Invoking
@@ -2535,8 +2943,12 @@
 global in the current namespace. The C<.namespace> directive sets the
 current namespace:
 
+=begin PASM
+
   .namespace [ "Foo" ]
 
+=end PASM
+
 If the namespace is explicitly set to an empty string or key, then the
 subroutine is stored in the outermost namespace.
 
@@ -2547,12 +2959,16 @@
 C<S0>, C<callmethodcc> looks up that method name in the invocant
 object and stores the method object in C<P0> for you:
 
+=begin PASM TODO
+
     set S0, "_half"             # set method name
     set P2, P3                  # the object
     callmethodcc                # create return continuation, call
     print I5                    # result of method call
     print "\n"
 
+=end PASM TODO
+
 The C<callmethodcc> opcode also generates a return continuation and
 stores it in C<P1>. The C<callmethod> opcode doesn't generate a return
 continuation, but is otherwise identical to C<callmethodcc>. Just like
@@ -2572,49 +2988,73 @@
 C<__init> in the C<Foo> class that initializes the first attribute of
 the object with an integer:
 
+=begin PASM TODO
+
   .sub __init:
     classoffset I0, P2, "Foo"     # lookup first attribute position
     new P6, "Int"                 # create storage for the attribute
     setattribute P2, I0, P6       # store the first attribute
     invoke P1                     # return
 
+=end PASM TODO
+
 Ordinary methods have to be called explicitly, but the vtable
 functions are called implicitly in many different contexts. Parrot
 saves and restores registers for you in these calls. The C<__init>
 method is called whenever a new object is constructed:
 
+=begin PASM TODO
+
     find_type I1, "Foo"
     new P3, I1          # call __init if it exists
 
+=end PASM TODO
+
 A few other vtable functions in the complete code example for this
 section are C<__set_integer_native>, C<__add>, C<__get_integer>,
 C<__get_string>, and C<__increment>. The C<set> opcode calls Foo's
 C<__set_integer_native> vtable function when its destination register
 is a C<Foo> object and the source register is a native integer:
 
+=begin PASM
+
     set P3, 30          # call __set_integer_native method
 
+=end PASM
+
 The C<add> opcode calls Foo's C<__add> vtable function when it adds
 two C<Foo> objects:
 
+=begin PASM TODO
+
     new P4, I1          # same with P4
     set P4, 12
     new P5, I1          # create a new store for add
 
     add P5, P3, P4      # __add method
 
+=end PASM TODO
+
 The C<inc> opcode calls Foo's C<__increment> vtable function when it
 increments a C<Foo> object:
 
+=begin PASM
+
     inc P3              # __increment
 
+=end PASM
+
 Foo's C<__get_integer> and C<__get_string> vtable functions are called
 whenever an integer or string value is retrieved from a C<Foo> object:
 
+=begin PASM
+
     set I10, P5         # __get_integer
-    ...
+    #...
     print P5            # calls __get_string, prints 'fortytwo'
 
+=end PASM
+
 
 =head2 Inheritance
 
@@ -2627,20 +3067,30 @@
 arguments: the destination register for the new class, a register
 containing the parent class, and the name of the new class:
 
+=begin PASM
+
     subclass P3, P1, "Bar"
 
+=end PASM
+
 X<multiple inheritance; in PASM>
 For multiple inheritance, the C<addparent>X<addparent opcode (PASM)>
 opcode adds additional parents to a subclass.
 
+=begin PASM
+
   newclass P4, "Baz"
   addparent P3, P4
 
+=end PASM
+
 To override an inherited method, define a method with the same name in
 the namespace of the subclass. The following code overrides Bar's
 C<__increment> method so it decrements the value instead of
 incrementing it:
 
+=begin PASM TODO
+
   .namespace [ "Bar" ]
 
   .sub __increment:
@@ -2649,6 +3099,8 @@
     dec P10                       # the evil line
     invoke P1
 
+=end PASM TODO
+
 Notice that the attribute inherited from C<Foo> can only be looked up
 with the C<Foo> class name, not the C<Bar> class name. This preserves
 the distinction between attributes that belong to the class and
@@ -2656,12 +3108,18 @@
 
 Object creation for subclasses is the same as for ordinary classes:
 
+=begin PASM TODO
+
     find_type I1, "Bar"
     new P5, I1
 
+=end PASM TODO
+
 Calls to inherited methods are just like calls to methods defined in
 the class:
 
+=begin PASM TODO
+
     set P5, 42                  # inherited __set_integer_native
     inc P5                      # overridden __increment
     print P5                    # prints 41 as Bar's __increment decrements
@@ -2673,6 +3131,8 @@
     print I5
     print "\n"
 
+=end PASM TODO
+
 =head2 Additional Object Opcodes
 
 Z<CHP-5-SECT-12.5>
@@ -2682,13 +3142,19 @@
 inherits from a particular class. C<can>X<can opcode (PASM)> checks whether
 an object has a particular method. Both return a true or false value.
 
+=begin PASM
+
     isa I0, P3, "Foo"           # 1
     isa I0, P3, "Bar"           # 1
     can I0, P3, "__add"         # 1
 
+=end PASM
+
 =head2 Complete Example
 
 Z<CHP-5-SECT-12.6>
+ 
+=begin PASM TODO
 
     newclass P1, "Foo"
     addattribute P1, "$.i"                # Foo.i
@@ -2803,7 +3269,7 @@
     dec P10                       # the evil line
     invoke P1
 
-  # end of object example
+=end PASM TODO
 
 This example prints out:
 


More information about the parrot-commits mailing list