[svn:parrot] r38811 - trunk/docs

coke at svn.parrot.org coke at svn.parrot.org
Sat May 16 02:08:14 UTC 2009


Author: coke
Date: Sat May 16 02:08:14 2009
New Revision: 38811
URL: https://trac.parrot.org/parrot/changeset/38811

Log:
[docs] mark & test more PIR/PASM samples

rip out one sample that was marked as out of date anyway.

Modified:
   trunk/docs/compiler_faq.pod
   trunk/docs/intro.pod

Modified: trunk/docs/compiler_faq.pod
==============================================================================
--- trunk/docs/compiler_faq.pod	Sat May 16 01:44:32 2009	(r38810)
+++ trunk/docs/compiler_faq.pod	Sat May 16 02:08:14 2009	(r38811)
@@ -31,22 +31,39 @@
 
 This looks like a function call in many HLLs:
 
+=begin PIR_FRAGMENT
+
    $P0( $P1, $P2, $P3 )
 
+=end PIR_FRAGMENT
+
 where $P0 is the function object, and $P1, $P2, and $P3 are its
 parameters. You can also use a function's name in place of the
 object, as long as it's in the same namespace.
 
+=begin PIR_FRAGMENT
+
    somefunctionlabel( $P1, $P2, $P3 )
 
+=end PIR_FRAGMENT
+
 You can also get return value(s):
 
+=begin PIR_FRAGMENT
+
   ($P1,$P2) = $P0( $P1, $P2, $P3 )
 
+=end PIR_FRAGMENT
+
 If the function name might collide with a Parrot opcode, quote it:
 
+=begin PIR_FRAGMENT
+
+   .local int i
    i = 'new'(42)
 
+=end PIR_FRAGMENT
+
 You can also use the full PCC for these calls. See
 L<docs/pdd19_pir.pod/Parameter Passing and Getting Flags> and other
 questions below for more information.
@@ -56,14 +73,24 @@
 Similar to function calls, just append C<.> and the method name to the object.
 You should quote a literal method name to avoid confusion.
 
+=begin PIR_FRAGMENT
+
+  .local pmc ret_val, some_obj, arg
   ret_val = some_obj.'some_meth'(arg)
 
+=end PIR_FRAGMENT
+
 The method name may also be a string variable representing a method name:
 
+=begin PIR_FRAGMENT
+
   .local string m
+  .local pmc curses_obj
   m = 'bold'
   curses_obj.m()
 
+=end PIR_FRAGMENT
+
 =head2 How do I locate or create a subroutine object?
 
 There are several ways to achieve this, depending on the location of
@@ -71,15 +98,23 @@
 
 If the sub is in the same compilation unit use a Sub constant:
 
+=begin PIR_FRAGMENT
+
   .const 'Sub' foo = 'foo'
-  ...
+  # ...
   foo()
 
+=end PIR_FRAGMENT
+
 A more dynamic way is:
 
+=begin PIR_FRAGMENT
+
   .local pmc foo
   foo = find_name 'foo'
 
+=end PIR_FRAGMENT
+
 This searches for a subroutine 'foo' in the current lexical pad, in
 the current namespace, in the global, and in the builtin namespace in
 that order. This opcode is generated, if I<foo()> is used, but the
@@ -88,8 +123,13 @@
 If the subroutine is in a different namespace, use the
 C<get_hll_global> or C<get_root_global> opcodes:
 
+=begin PIR_FRAGMENT
+
+  .local pmc foo
   foo = get_root_global ['Foo'], 'foo'
 
+=end PIR_FRAGMENT
+
 This fetches the sub C<foo> in the C<Foo> namespace.
 
 =head2 How do I create a Closure or Coroutine?
@@ -99,10 +139,14 @@
 First use one of the above ways to locate the Sub object.
 Then use the op C<newclosure> to capture the environment.
 
+=begin PIR_FRAGMENT
+
   .local pmc coro
   coro = find_name 'my_coro'
   coro = newclosure coro
 
+=end PIR_FRAGMENT
+
 Any subroutine that contains a C<.yield> directive is automatically
 created as a Coroutine PMC:
 
@@ -143,39 +187,56 @@
 If you have a variable amounts of arguments in an array, you can
 pass all items of that array with the C<:flat> directive.
 
+=begin PIR_FRAGMENT
+
+  .local pmc ar, foo
   ar = new 'ResizablePMCArray'
   push ar, "arg 1\n"
   push ar, "arg 2\n"
-  ...
+  #...
   foo(ar :flat)
-  ...
+  #...
+
+=end PIR_FRAGMENT
 
 =head2 How to I retrieve the contents of a variable-length parameter
 list being passed to me?
 
 Use a slurpy array:
 
+=begin PIR
+
   .sub mysub
     .param pmc argv      :slurpy
     .local int argc
     argc = argv
-    ...
+    #...
+  .end
+
+=end PIR
 
 If you have a few fixed parameters too, you can use a slurpy array
 to get the rest of the arguments
 
+=begin PIR
+
   .sub mysub
     .param pmc arg0
     .param pmc arg1
     .param pmc varargs   :slurpy
     .local int num_varargs
     num_varargs = varargs
-    ...
+    # ...
+  .end
+
+=end PIR
 
 =head2 How do I pass optional arguments?
 
 Use the C<:optional> and C<:opt_flag> pragmas:
 
+=begin PIR
+
   .sub foo
      .param pmc arg1       :optional
      .param int has_arg1   :opt_flag
@@ -183,7 +244,10 @@
      .param int has_arg2   :opt_flag
 
      if has_arg1 goto got_arg1
-     ...
+     #...
+  .end
+
+=end PIR
 
 =head2 How do I create nested subroutines?
 
@@ -197,13 +261,19 @@
 
 Use the C<get_root_global> or C<get_hll_global> op:
 
+=begin PIR_FRAGMENT
+
     get_hll_global $P0, ['name'; 'space'], 'name_of_the_global'
     get_hll_global $P1, 'name_of_the_global'
 
+=end PIR_FRAGMENT
+
 =head2 How can I delete a global?
 
 You can retrieve the namespace hash and use the C<delete> opcode.
 
+=begin PIR
+
     .sub main :main
     $P0 = new 'Integer'
     $P0 = 42
@@ -228,6 +298,7 @@
     print "null.\n"
     .end
 
+=end PIR
 
 =head2 How do I use lexical pads to have both a function scope and a
 global scope?
@@ -244,16 +315,24 @@
 
 Use C<find_name>:
 
+=begin PIR_FRAGMENT
+
     $P0 = find_name '$x'
     find_name $P0, 'foo'    # same thing
 
+=end PIR_FRAGMENT
+
 This will find the name C<foo> in the lexical, global, or builtin namespace, in
 that order, and store it in C<$P0>.
 
 =head2 How do I fetch a variable from the current lexical pad?
 
+=begin PIR_FRAGMENT
+
     find_lex $P0, 'foo'
 
+=end PIR_FRAGMENT
+
 or much better, if possible just use the variable defined along with
 the C<.lex> definition of C<foo>.
 
@@ -261,8 +340,12 @@
 
 That is still the same:
 
+=begin PIR_FRAGMENT
+
     find_lex $P0, 'foo'
 
+=end PIR_FRAGMENT
+
 This finds a C<foo> variable at any B<outer> depth starting from the top.
 
 If your language looks up variables differently, you have to walk the
@@ -285,53 +368,72 @@
 
 With the C<newclass> op:
 
+=begin PIR_FRAGMENT
+
     newclass $P0, 'Animal'
 
+=end PIR_FRAGMENT
+
 =head2 How do I add instance variables/attributes?
 
 Each class knows which attributes its objects can have. You can add attributes
 to a class (not to individual objects) like so:
 
+=begin PIR_FRAGMENT
+
     addattribute $P0, 'legs'
 
+=end PIR_FRAGMENT
+
 =head2 How do I add instance methods to a class?
 
 Methods are declared as functions in the class namespace with the C<:method>
 keyword appended to the function declaration:
 
+=begin PIR
+
   .namespace [ 'Animal' ]
 
   .sub run :method
      print "slow and steady\n"
   .end
 
+=end PIR
+
 =head2 How do I override a vtable on a class?
 
 As with methods, but note the new keyword. The vtable name specified B<must>
 be an existing vtable slot.
 
+=begin PIR
+
   .namespace [ 'NearlyPi' ]
 
   .sub get_string :vtable
      .return ('three and a half')
   .end
 
+=end PIR
+
 Now, given an instance of NearlyPi in $P0
 
+=begin PIR_FRAGMENT
+
   $S0 = $P0
   say $S0  # prints 'three and a half'
 
+=end PIR_FRAGMENT
+
 =head2 How do I access attributes?
 
 You can access attributes by a short name:
 
+=begin PIR_FRAGMENT_INVALID
+
   $P0 = getattribute self, 'legs'
   assign $P0, 4                   # set attribute's value
 
-or by a fully qualified name: XXX This is long dead.
-
-  $P0 = getattribute self, "Animal\0legs"
-  assign $P0, 4                   # set attribute's value
+=end PIR_FRAGMENT_INVALID
 
 =head2 When should I use properties vs. attributes?
 
@@ -344,13 +446,21 @@
 Either you use the PMC returned by the C<newclass> op if you created
 the class, or use the C<get_class> op:
 
+=begin PIR_FRAGMENT
+
     get_class $P0, 'Animal'
 
+=end PIR_FRAGMENT
+
 Then you can use the C<subclass> op to create a new class that is a
 subclass of this class:
 
+=begin PIR_FRAGMENT
+
     subclass $P1, $P0, 'Dog'
 
+=end PIR_FRAGMENT
+
 This stores the newly created class PMC in $P1.
 
 =head2 How do I create a class that has more than one parent class?
@@ -365,39 +475,59 @@
 If you have a class PMC (created with C<newclass> or by C<subclass>),
 you can add more parent classes to it with the C<addparent> op:
 
+=begin PIR_FRAGMENT
+
     get_class $P1, 'Dog'
     subclass $P2, $P1, 'SmallDog'
     get_class $P3, 'Pet'
     addparent $P2, $P3  # make "SmallDog" also a "Pet"
 
+=end PIR_FRAGMENT
+
 =head2 How can I specify the constructor of a class?
 
 Just override the init vtable for that class.
 
-    newclass $P0, 'Dog'         # create a class named Dog
-    # ...
+=begin PIR
+
+    .sub _ :main
+      newclass $P0, 'Dog'         # create a class named Dog
+    .end
 
     .namespace ['Dog']
 
     .sub init :vtable
       # ...
+    .end
+
+=end PIR
 
 Or you can specify the constructor method by setting the BUILD
 property of the class PMC:
 
+=begin PIR_FRAGMENT
+
     newclass $P0, 'Dog'         # create a class named Dog
     new $P1, 'String'           # create a string
     set $P1, 'initialise'       # set it to the name of the constructor method
     setprop $P0, 'BUILD', $P1   # set the BUILD property
 
+=end PIR_FRAGMENT
+
 =head2 How do I instantiate a class?
 
 You can do so either with the class name:
 
+=begin PIR_FRAGMENT
+
     new $P0, 'Dog'
 
+=end PIR_FRAGMENT
+
 or with the class object:
 
+=begin PIR_FRAGMENT
+
     $P1 = get_class 'Dog'   # find the 'Dog' class
     unless null $P1 goto have_dog_class
     printerr "Oops; can't find the 'Dog' class.\n"
@@ -405,6 +535,8 @@
   have_dog_class:
     new $P0, $P1    # creates a Dog object and stores it in register $P0
 
+=end PIR_FRAGMENT
+
 The chief difference is that using a string constant will produce the
 specific error "Class 'Dog' not found" if that happens to be the case;
 the other code has to check explicitly.
@@ -417,14 +549,17 @@
 a hash PMC is passed to the constructor that contains the arguments as
 key/value pairs:
 
+=begin PIR_FRAGMENT
+
     new $P0, 'Hash'
     set $P0['greeting'], 'hello'
     set $P0['size'], 1.23
 
-    find_type $I0, 'Alien'
-    new $P1, $I0, $P0           # create an Alien object and pass
+    new $P1, 'Alien', $P0       # create an Alien object and pass
                                 # the hash to the constructor
 
+=end PIR_FRAGMENT
+
 =head2 How do I add module/class methods?
 
 XXX
@@ -439,53 +574,74 @@
 
 The easiest way is the perl-like
 
+=begin PIR_FRAGMENT
+
     die 'Eeeek!'
 
+=end PIR_FRAGMENT
+
 You can also explicitly create an exception object and throw it:
 
+=begin PIR_FRAGMENT
+
     $P0 = new 'Exception'
     $P0 = 'something happened'
     throw $P0
 
+=end PIR_FRAGMENT
+
 =head2 How do I catch an exception in PIR?
 
 Use C<push_eh> to push an exception handler onto the stack. End the set of
 instructions that might throw the exception you're interested in with
 C<pop_eh>.
 
+=begin PIR_FRAGMENT
+
     push_eh handler
       die 'whoops'  # or any other code that might throw an exception...
     pop_eh
-    ... # ok
+    # ok
+
+=end PIR_FRAGMENT
 
 An exception handler is called with one argument, which is the exception object.
 The message of the exception can be easily extracted, as follows:
 
+=begin PIR_FRAGMENT
+
   handler: # exception
     .get_results ($P0)
     print 'Exception caught:'
     $S0 = $P0['message']
     say $S0
-    ...
+
+=end PIR_FRAGMENT
 
 =head2 How do I let exceptions from C<exit> pass through my handler?
 
 Rethrow the exception if it has a severity of C<EXCEPT_EXIT>.
 
+=begin PIR_FRAGMENT
+
   .include 'except_severity.pasm'
-  ...
+  # ...
   handler:
     .get_results ($P0)
     $I0 = $P0['severity']
     if $I0 == .EXCEPT_EXIT goto handle_exit
     say 'Exception caught!'
-    ...
+    # ...
 
   handle_exit:
     rethrow $P0 # let the next handler deal with it.
 
+=end PIR_FRAGMENT
+
 Exception example:
 
+=begin PIR_FRAGMENT
+
     push_eh handler
     $P0 = new 'Exception'
     $P0 = 'something happened'
@@ -503,6 +659,8 @@
     print "\n"
     exit 1
 
+=end PIR_FRAGMENT
+
 =head1 C Extensions
 
 =head2 How do I create PMCs for my compiler?
@@ -578,6 +736,8 @@
 Then, after having compiled the file as a shared library, the PIR code looks
 like this:
 
+=begin PIR
+
   .sub main :main
      .local pmc lib, func
 
@@ -593,15 +753,21 @@
 
   .end
 
+=end PIR
+
 If you embedded a Parrot in your C file and you want to invoke another function
 in that same C file, you should pass a null string to loadlib. Do that as follows:
 
+=begin PIR_FRAGMENT
+
  .local pmc lib
  .local string libname
  null libname
 
  lib = loadlib libname
 
+=end PIR_FRAGMENT
+
 Under Linux, the .c file must then be linked with the -export-dynamic option.
 
 =head1 Misc
@@ -610,18 +776,26 @@
 
 Create a new C<Env> PMC and access it like a hash.
 
+=begin PIR_FRAGMENT
+
     .local pmc e
     e = new 'Env'
     $P0 = e['USER']      # lt
 
+=end PIR_FRAGMENT
+
 =head2 How can I access Parrot's configuration?
 
+=begin PIR_FRAGMENT
+
     .include 'iglobals.pasm'
     .local pmc interp, cfg
     interp = getinterp
     cfg = interp[.IGLOBALS_CONFIG_HASH]
     $S0 = cfg['VERSION']    # "0.3.0"
 
+=end PIR_FRAGMENT
+
 See F<config_lib.pasm> for all the keys in the config hash - or iterate over
 the config hash.
 

Modified: trunk/docs/intro.pod
==============================================================================
--- trunk/docs/intro.pod	Sat May 16 01:44:32 2009	(r38810)
+++ trunk/docs/intro.pod	Sat May 16 02:08:14 2009	(r38811)
@@ -277,28 +277,62 @@
 PIR provides a bit of syntactic sugar that makes it look more high level than
 assembly. For example:
 
+=begin PIR_FRAGMENT
+
+  .local pmc temp, i
   temp = i * i
 
+=end PIR_FRAGMENT
+
 Is just another way of writing the more assembly-ish:
 
+=begin PIR_FRAGMENT
+
+  .local pmc temp, i
   mul temp, i, i
 
+=end PIR_FRAGMENT
+
 And:
 
+=begin PIR_FRAGMENT
+
+  .local pmc i, maxnum
   if i <= maxnum goto loop
+  # ...
+  loop:
+
+=end PIR_FRAGMENT
 
 Is the same as:
 
+=begin PIR_FRAGMENT
+
+  .local pmc i, maxnum
   le i, maxnum, loop
+  # ...
+  loop:
+
+=end PIR_FRAGMENT
 
 And:
 
+=begin PIR_FRAGMENT
+
+  .local pmc temp, total
   total += temp
 
+=end PIR_FRAGMENT
+
 Is the same as:
 
+=begin PIR_FRAGMENT
+
+  .local pmc  temp, total
   add total, temp
 
+=end PIR_FRAGMENT
+
 As a rule, whenever a Parrot instruction modifies the contents of a register,
 that will be the first register when writing the instruction in assembly form.
 
@@ -361,9 +395,14 @@
 Much of what follows has been seen in previous examples, apart from the line
 reading:
 
+=begin PIR_FRAGMENT
+
+  .local pmc result, factorial
   result = factorial($I0)
 
-This single line of PIR actually represents a few lines of PASM. The assembler
+=end PIR_FRAGMENT
+
+The last line of PIR actually represents a few lines of PASM. The assembler
 builds a PMC that describes the signature, including which register the
 arguments are held in. A similar process happens for providing the registers
 that the return values should be placed in. Finally, the C<factorial> sub is 


More information about the parrot-commits mailing list