Author: coke
Date: Wed May 30 07:25:33 2007
New Revision: 18687
Modified:
trunk/ (props changed)
trunk/docs/compiler_faq.pod
Log:
cleanup
Modified: trunk/docs/compiler_faq.pod
==============================================================================
--- trunk/docs/compiler_faq.pod (original)
+++ trunk/docs/compiler_faq.pod Wed May 30 07:25:33 2007
@@ -22,25 +22,22 @@
Define a sub that takes as input a string, and returns something
invokable. The easiest way to create something invokable at the moment
-is to use the builtin C<PIR> or C<PASM> compilers.
+is to use another compiler object (for example, the C<PIR> compiler), which
+you can get with:
-See C<languages/tcl/tcl.pir_template>'s C<.sub _tcl_compile> as an example.
+ .local pmc pir_compiler
+ pir_compiler = compreg 'PIR'
-=head2 How do I embed source locations in my code for debugging?
-
-You can do this using either the C<setfile> and C<setline> opcodes or
-with C-like C<#line> comments:
- #line 27 "my_source.file"
+=head2 How do I embed source locations in my code for debugging?
-Simply set the source file name or line number whenever it changes.
-But note that currently (Parrot 0.3.0) both are ignored in the lexer.
+Right now you can't.
=head1 Subroutines
=head2 How do I generate a sub call in PIR?
-If you have a fixed-length parameter list, IMCC makes this blindingly easy:
+IMCC makes this easy, handling the calling conventions for you.
$P0( $P1, $P2, $P3 )
@@ -56,18 +53,19 @@
If the function name might collide with a Parrot opcode, quote it:
- i = "new"(42)
+ i = 'new'(42)
=head2 How do I generate a method call in PIR?
-Similar to function calls, just append C<.> to the object and the method:
+Similar to function calls, just append C<.> and the method name to the object.
+You should quote a literal method name to avoid confusion.
- ret_val = some_obj."some_meth"(arg)
+ ret_val = some_obj.'some_meth'(arg)
The method name may also be a string variable representing a method name:
.local string m
- m = "bold"
+ m = 'bold'
curses_obj.m()
=head2 How do I locate or create a subroutine object?
@@ -77,15 +75,15 @@
If the sub is in the same compilation unit use a Sub constant:
- .const .Sub foo = "foo"
+ .const .Sub foo = 'foo'
The subroutine object is available in PASM too with a similar syntax:
- .const .Sub P2 = "foo" # any P register will do
+ .const .Sub P2 = 'foo' # any P register will do
...
.pcc_sub foo: # denote a Sub constant
-If the PIR compiler finds a "foo" function during compiling a file,
+If the PIR compiler finds a 'foo' function during compiling a file,
then the syntax:
foo()
@@ -95,9 +93,9 @@
A more dynamic way is:
.local pmc foo
- foo = find_name "foo"
+ foo = find_name 'foo'
-This searches for a subroutine "foo" in the current lexical pad, in
+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
compiler can't figure out, where the function is.
@@ -105,9 +103,9 @@
If the subroutine is in a different namespace, use the C<find_global>
opcode:
- foo = find_global "Foo", "foo"
+ foo = find_global 'Foo', 'foo'
-This searches the sub "foo" in the "Foo" namespace.
+This searches the sub C<foo> in the C<Foo> namespace.
=head2 How do I create a Closure or Coroutine?
@@ -116,7 +114,7 @@
of it:
.local pmc coro
- coro = find_name "my_coro"
+ coro = find_name 'my_coro'
coro = clone coro
Any subroutine that contains a C<.yield> directive is automatically
@@ -148,7 +146,7 @@
If you have a variable amounts of arguments in an array, you can
pass all items of that array with the C<:flat> directive.
- ar = new .ResitablePMCArray
+ ar = new .ResizablePMCArray
push ar, "arg 1\n"
push ar, "arg 2\n"
...
@@ -192,7 +190,8 @@
=head2 How do I create nested subroutines?
-Please refer to L<docs/pdds/pdd20_lexical_vars.pod> for details.
+Please refer to L<docs/pdds/pdd20_lexical_vars.pod> for details: look for
+C<:outer>.
=head1 Variables
@@ -200,11 +199,11 @@
There are two possible ways. Either use the special PIR syntax:
- $P0 = global "name_of_the_global"
+ $P0 = global 'name_of_the_global'
or the C<find_global> op:
- find_global $P0, "name_of_the_global"
+ find_global $P0, 'name_of_the_global'
=head2 How can I delete a global?
@@ -212,15 +211,15 @@
.sub main :main
$P0 = new .Integer
- store_hll_global "foo", $P0
- store_hll_global ["Bar"], "baz", $P0
+ store_hll_global 'foo', $P0
+ store_hll_global ['Bar'], 'baz', $P0
# ...
.local pmc ns, Bar_ns
ns = get_hll_namespace
- delete ns["foo"] # delete from top level
- Bar_ns = ns["Bar"] # get Bar namespace
- delete Bar_ns["baz"]
- $P0 = get_hll_global ["Bar"], "baz"
+ delete ns['foo'] # delete from top level
+ Bar_ns = ns['Bar'] # get Bar namespace
+ delete Bar_ns['baz']
+ $P0 = get_hll_global ['Bar'], 'baz'
print "never\n"
.end
@@ -239,24 +238,24 @@
Use C<find_name>:
- $P0 = find_name "$x"
- find_name $P0, "foo" # same thing
+ $P0 = find_name '$x'
+ find_name $P0, 'foo' # same thing
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?
- find_lex $P0, "foo"
+ find_lex $P0, 'foo'
or much better, if possible just use the variable defined along with
-the '.lex' definition of "foo".
+the C<.lex> definition of C<foo>.
=head2 How do I fetch a variable from any nesting depth?
That is still the same:
- find_lex $P0, "foo"
+ find_lex $P0, 'foo'
This finds a C<foo> variable at any B<outer> depth starting from the top.
@@ -280,48 +279,58 @@
With the C<newclass> op:
- newclass $P0, "Animal"
+ newclass $P0, 'Animal'
=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:
- addattribute $P0, "legs"
+ addattribute $P0, 'legs'
=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:
- .namespace [ "Animal" ]
+ .namespace [ 'Animal' ]
- .sub __init :method
- $P0 = new .Integer
- setattribute self, "legs", $P0
- ...
- .end
.sub run :method
- ...
+ print "slow and steady\n"
+ .end
+
+=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.
+
+ .namespace [ 'NearlyPi' ]
+
+ .sub get_string :vtable
+ .return ('three and a half')
.end
+Now, given an instance of NearlyPi in $P0
+
+ $S0 = $P0
+ say $S0 # prints 'three and a half'
+
=head2 How do I access attributes?
-You can access attributes by a short name, a fully qualified name, or by an
-index.
+You can access attributes by a short name:
- $P0 = getattribute self, "legs"
+ $P0 = getattribute self, 'legs'
assign $P0, 4 # set attribute's value
-or
+a fully qualified name:
$P0 = getattribute self, "Animal\0legs"
assign $P0, 4 # set attribute's value
-or
+or by an index:
.local int offs
- offs = classoffset "Animal"
+ offs = classoffset 'Animal'
$I0 = offs + 0 # 1st attribute
$P0 = getattribute self, $I0
$I0 = offs + 1 # 2nd attribute
@@ -338,12 +347,12 @@
Either you use the PMC returned by the C<newclass> op if you created
the class, or use the C<getclass> op:
- getclass $P0, "Animal"
+ getclass $P0, 'Animal'
Then you can use the C<subclass> op to create a new class that is a
subclass of this class:
- subclass $P1, $P0, "Dog"
+ subclass $P1, $P0, 'Dog'
This stores the newly created class PMC in $P1.
@@ -359,44 +368,41 @@
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:
- getclass $P1, "Dog"
- subclass $P2, $P1, "SmallDog"
- getclass $P3, "Pet"
+ getclass $P1, 'Dog'
+ subclass $P2, $P1, 'SmallDog'
+ getclass $P3, 'Pet'
addparent $P2, $P3 # make "SmallDog" also a "Pet"
=head2 How can I specify the constructor of a class?
-Just define a method named C<__init> in the namespace of the class.
+Just override the init vtable for that class.
- newclass $P0, "Dog" # create a class named Dog
+ newclass $P0, 'Dog' # create a class named Dog
# ...
- .namespace ["Dog"]
+ .namespace ['Dog']
- .sub __init :method
+ .sub init :vtable
# ...
Or you can specify the constructor method by setting the BUILD
property of the class PMC:
- newclass $P0, "Dog" # create a class named Dog
+ 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
+ set $P1, 'initialise' # set it to the name of the constructor method
+ setprop $P0, 'BUILD', $P1 # set the BUILD property
=head2 How do I instantiate a class?
-First, you have to retrieve the type id of class you want to instantiate:
-
- find_type $I0, "Dog"
-
-Then, you can create an instance of Dog with the new op:
+You can either do so with an interger type id:
+ $I0 = find_type 'Dog'
new $P0, $I0 # creates a Dog object and stores it in register $P0
-or for short:
+or with the class name:
- new $P0, "Dog"
+ new $P0, 'Dog'
During the C<new> opcode the constructor is called.
@@ -407,10 +413,10 @@
key/value pairs:
new $P0, .Hash
- set $P0["greeting"], "hello"
- set $P0["size"], 1.23
+ set $P0['greeting'], 'hello'
+ set $P0['size'], 1.23
- find_type $I0, "Alien"
+ find_type $I0, 'Alien'
new $P1, $I0, $P0 # create an Alien object and pass
# the hash to the constructor
@@ -436,7 +442,7 @@
=head2 How do I throw an exception with an error message in PIR?
$P0 = new .Exception
- $P0["_message"] = "something happened"
+ $P0['_message'] = 'something happened'
throw $P0
=head2 How do I catch an exception in PIR?
@@ -444,8 +450,8 @@
Use C<push_eh> to push an exception handler onto the stack.
push_eh handler
- $P0 = new .Exception # or any other code ...
- throw $P0 # ... that might throw
+ $P0 = new .Exception # or any other code ...
+ throw $P0 # ... that might throw
clear_eh
exit 0
@@ -453,8 +459,10 @@
message. More information is available inside the exception 'object' (TBD).
handler:
- get_results '(0,0)', P0, S0 # PASM syntax
- print "Exception caught!\n"
+ .get_results ($P0, $S0)
+ print 'Exception caught:'
+ print $S0
+ print "\n"
exit 1
=head2 How do I let exceptions from C<exit> pass through my handler?
@@ -463,7 +471,7 @@
handler:
.include 'except_severity.pasm'
- get_results '(0,0)', $P0, $S0
+ .get_results ($P0, $S0)
$I0 = $P0[2]
if $I0 == .EXCEPT_EXIT goto unexceptional
print "Exception caught!\n"
@@ -475,7 +483,7 @@
push_eh handler
$P0 = new .Exception
- $P0["_message"] = "something happened"
+ $P0['_message'] = 'something happened'
throw $P0
clear_eh
exit 0
@@ -483,8 +491,8 @@
handler:
.local pmc exception
.local string message
- .get_results (exception, message) # PIR syntax
- print "Exception: "
+ .get_results (exception, message)
+ print 'Exception: '
print message
print "\n"
exit 1
@@ -518,7 +526,7 @@
Parrot supports dynamic op libraries. These allow for ops specific to one
language to be used without having to place them into the Parrot core itself.
-For examples of dynamic op libraries, see L<src/dynoplibs>.
+For examples of dynamic op libraries, see L<src/dynoplibs>.
To build dynamic op libraries, add something like the following to your
makefile:
@@ -550,11 +558,11 @@
=head2 How can I access Parrot's configuration?
- .include "iglobals.pasm"
+ .include 'iglobals.pasm'
.local pmc interp, cfg
interp = getinterp
cfg = interp[.IGLOBALS_CONFIG_HASH]
- $S0 = cfg['VERSION'] "0.3.0"
+ $S0 = cfg['VERSION'] # "0.3.0"
See F<config_lib.pasm> for all the keys in the config hash - or iterate over
the config hash.
@@ -579,4 +587,3 @@
STATUS
Look to existing languages for some examples.
-