[svn:parrot] r38809 - trunk/docs/user/pir
coke at svn.parrot.org
coke at svn.parrot.org
Sat May 16 01:33:11 UTC 2009
Author: coke
Date: Sat May 16 01:33:10 2009
New Revision: 38809
URL: https://trac.parrot.org/parrot/changeset/38809
Log:
[docs] Test more PIR/PASM.
Eliminate one sample that was broken into chunks, and just have the whole version.
Probably not the best for didactic purposes, but certainly easier for testing our own samples.
Modified:
trunk/docs/user/pir/exceptions.pod
trunk/docs/user/pir/intro.pod
trunk/docs/user/pir/objects.pod
Modified: trunk/docs/user/pir/exceptions.pod
==============================================================================
--- trunk/docs/user/pir/exceptions.pod Fri May 15 23:44:45 2009 (r38808)
+++ trunk/docs/user/pir/exceptions.pod Sat May 16 01:33:10 2009 (r38809)
@@ -10,43 +10,36 @@
including two pasm files that define constants for exception type and
severity.
- .include 'except_types.pasm'
- .include 'except_severity.pasm'
-
You create exceptions just like you create any other object, with
C<new>.
- .local pmc ex
- ex = new 'Exception'
-
You usually want to at least set a descriptive message about what went
wrong.
- ex = "Everything is horrible, dood."
-
You also usually want to set a severity and sometimes a type. You can
find these in L<runtime/parrot/include/except_severity.pasm>.
- ex['severity'] = .EXCEPT_DOOMED
- ex['type'] = .CONTROL_ERROR
-
You actually throw the exception by using the C<throw> op.
- throw ex
-
Put all together, it looks like this:
-=head3 Throw Example
+=begin PIR_FRAGMENT
.include 'except_types.pasm'
.include 'except_severity.pasm'
+
.local pmc ex
ex = new 'Exception'
+
ex = "Everything is horrible, dood."
+
ex['severity'] = .EXCEPT_DOOMED
ex['type'] = .CONTROL_ERROR
+
throw ex
+=end PIR_FRAGMENT
+
=head2 Catching exceptions
Parrot maintains a stack of exception handlers. When an exception is
@@ -59,27 +52,35 @@
You create exception handlers just like you create any other object, with
C<new>.
+=begin PIR_FRAGMENT
+
.local pmc eh
eh = new 'ExceptionHandler'
+=end PIR_FRAGMENT
+
You set the target of the exception handler (the code that will be
invoked) with the C<set_attr> opcode. Usually this will be a label.
You manipulate the exception handler stack with the C<push_eh> and
C<pop_eh> opcodes. This is a fairly standard use of exception handlers:
+=begin PIR_FRAGMENT
+
.local pmc eh
eh = new 'ExceptionHandler'
set_addr eh, handler
push_eh eh
- ... # code that might throw an exception
+ # code that might throw an exception
pop_eh
.return (1) # Success!
handler:
.local pmc ex
.get_results (ex)
- ... # code that prints a warning, logs an error, whatever
+ # code that prints a warning, logs an error, whatever
.return (0) # Failure!
+=end PIR_FRAGMENT
+
Sometimes you want to be more specific in what you catch. You can set
filters on the exception handler based on exception type and severity.
The methods you use include C<.min_severity()>, C<.max_severity()>,
Modified: trunk/docs/user/pir/intro.pod
==============================================================================
--- trunk/docs/user/pir/intro.pod Fri May 15 23:44:45 2009 (r38808)
+++ trunk/docs/user/pir/intro.pod Sat May 16 01:33:10 2009 (r38809)
@@ -116,25 +116,37 @@
Parrot C<set> opcode to put values into registers, and the C<add>
opcode to add them, like this:
+=begin PIR_FRAGMENT
+
set $I1, 5
set $I2, 3
add $I0, $I1, $I2 # $I0 yields 5+3
+=end PIR_FRAGMENT
+
PIR includes infix operators for these common opcodes. I could write
this same code as
+=begin PIR_FRAGMENT
+
$I1 = 5
$I2 = 3
$I0 = $I1 + $I2
+=end PIR_FRAGMENT
+
There are the four arithmetic operators as you should be expecting, as
well as the six different comparison operators, which return a boolean
value:
+=begin PIR_FRAGMENT
+
$I1 = 5
$I2 = 3
$I0 = $I1 <= $I2 # $I0 yields 0 (false)
+=end PIR_FRAGMENT
+
I can also use the short accumulation-like operators, like C<+=>.
Another PIR perk is that local variable names may be declared and used
@@ -142,9 +154,13 @@
variable using the C<.local> keyword with any of the four data
types available on PIR: C<int>, C<string>, C<num> and C<pmc>:
+=begin PIR_FRAGMENT
+
.local int size
size = 5
+=end PIR_FRAGMENT
+
Note that all registers, both numbered and named, are consolidated by
the Parrot register allocator, assigning these "virtual registers" to
actual registers as needed. The register allocator even coalesces two
@@ -166,12 +182,24 @@
test a condition and jump to another place in the code, I would write
the following PASM code:
- le $I1, $I2, LESS_EQ
+=begin PASM
+
+ le I1, I2, LESS_EQ
+ # ...
+ LESS_EQ:
+
+=end PASM
Meaning, if C<$I1> is less or equal than C<$I2>, jump to label
C<LESS_EQ>. In PIR I would write it in a more legible way:
+=begin PIR_FRAGMENT
+
if $I1 <= $I2 goto LESS_EQ
+ # ...
+ LESS_EQ:
+
+=end PIR_FRAGMENT
PIR includes the C<unless> keyword as well.
@@ -219,19 +247,33 @@
To return values from PIR subroutines I use the C<.return> keyword,
followed by one or more arguments, just like this:
- .return (10, 20, 30)
+=begin PIR
+
+ .sub _
+ .return (10, 20, 30)
+ .end
+
+=end PIR
The calling subroutine can accept these values. If you want to retrieve
only one value (or only the first value, in case multiple values are
returned), write this:
+=begin PIR_FRAGMENT
+
$I0 = compute_it($I8, $I9)
+=end PIR_FRAGMENT
+
To accept multiple values from such a function, use a parenthesized
results list:
+=begin PIR_FRAGMENT
+
($I1, $I2, $I3) = compute_it($I8, $I9)
+=end PIR_FRAGMENT
+
=head2 Factorial Example
Now, for a little more complicated example, let me show how I would
@@ -269,8 +311,13 @@
As before, I need to use C<.param> for each named argument, but you need to
specify a flag indicating the parameter is named:
+=begin PIR
+
.sub func
.param int a :named("foo")
+ .end
+
+=end PIR
The subroutine will receive an integer named "foo", and inside of the
subroutine that integer will be known as "a".
@@ -278,9 +325,13 @@
When calling the function, I need to pass the names of the
arguments. For that there are two syntaxes:
+=begin PIR_FRAGMENT
+
func( 10 :named("foo") ) # or
func( "foo" => 10 )
+=end PIR_FRAGMENT
+
Note that with named arguments, you may rearrange the order of your
parameters at will.
@@ -297,11 +348,15 @@
This subroutine may be called in any of the following ways:
+=begin PIR_FRAGMENT
+
foo( "Fred", 35, "m" )
foo( "gender" => "m", "name" => "Fred", "age" => 35 )
foo( "age" => 35, "gender" => "m", "name" => "Fred" )
foo( "m" :named("gender"), 35 :named("age"), "name" => "Fred" )
+=end PIR_FRAGMENT
+
and any other permutation you can think of as long as you use the named
argument syntax. Note that any positional parameters must be passed
before the named parameters. So, the following is allowed:
@@ -318,21 +373,33 @@
Whereas the following is not:
+=begin PIR_INVALID
+
.sub main
.param int a :named("name")
.param int b # cannot declare positional parameter after a named parameter
# ...
.end
+=begin PIR_INVALID
+
It's also possible to use named syntax when returning values from
subroutines. Into the C<.return> command I'll use:
+=begin PIR
+
.return ( "bar" => 20, "foo" => 10)
+=end PIR
+
and when calling the function, I will do:
+=begin PIR
+
("foo" => $I0, "bar" => $I1) = func()
+=end PIR
+
And C<$I0> will yield 10, and C<$I1> will yield 20, as expected.
=head2 Concluding
@@ -343,15 +410,23 @@
pass it a string register or variable where you wish the characters
read to be placed and the number of characters you wish to read:
+=begin PIR
+
read $S1, 100
+=end PIR
+
This line will read 100 characters (or until the end of the line) and
put the read string into C<$S1>. In case you need a number, just
assign the string to the correct register type:
+=begin PIR
+
read $S1, 100
$I1 = $S1
+=end PIR
+
With the PIR syntax shown in this article you should be able to start
writing simple programs. Next article we will look into available
Polymorphic Containers (PMCs), and how they can be used.
Modified: trunk/docs/user/pir/objects.pod
==============================================================================
--- trunk/docs/user/pir/objects.pod Fri May 15 23:44:45 2009 (r38808)
+++ trunk/docs/user/pir/objects.pod Sat May 16 01:33:10 2009 (r38809)
@@ -161,14 +161,24 @@
the quotes, then the identifier is assumed to be a declared
C<.local> symbol. So, instead of writing:
+=begin PIR_FRAGMENT
+
+ .local pmc elsie
elsie.'speak'()
+=end PIR_FRAGMENT
+
you could also have written:
+=begin PIR_FRAGMENT
+
+ .local pmc elsie
.local string speak
speak = 'speak'
elsie.speak()
+=end PIR_FRAGMENT
+
Another example of this is shown below.
=head3 Example 4: variable methods
@@ -305,18 +315,22 @@
=head3 Example 6: inheriting
- ...
+=begin PIR_FRAGMENT
+
$P0 = newclass "Animal"
addattribute $P0, "name"
$P0 = subclass "Animal", "Cow"
$P0 = subclass "Animal", "Dog"
$P0 = subclass "Animal", "Pig"
- ...
+ # ...
+ .local pmc cow
cow = new 'Cow'
cow.'setname'("Elsie")
- ...
+ # ...
cow.'getname'()
+=end PIR_FRAGMENT
+
Each subclass will contain an attribute called "name" that can be
used to store the name of the animal. The C<setname> method
abstracts out the process of creating a C<String> PMC and
More information about the parrot-commits
mailing list