parrotcode: PMC compiler (Version 2) | |
Contents | Tools |
tools/build/pmc2c.pl - PMC compiler (Version 2)
Create src/pmc/foo.dump:
% perl tools/build/pmc2c.pl --dump src/pmc/foo.pmc ...
Create vtable.dump:
% perl tools/build/pmc2c.pl --vtable
Print a class tree for the specified PMCs:
% perl tools/build/pmc2c.pl --tree src/pmc/*.pmc
Create src/pmc/foo.c and pmc_foo.h
from src/pmc/foo.dump:
% perl tools/build/pmc2c.pl -c src/pmc/foo.pmc ...
Create fooX.c and pmc_fooX.h from fooX.dump files, also create libfoo.c containing the initialization function for all fooX PMCs.
% perl tools/build/pmc2c.pl --library libfoo -c \
src/pmc/foo1.pmc src/pmc/foo2.pmc ...
The job of the PMC compiler is to take .pmc files and create C files which can be compiled for use with the Parrot interpreter.
--debug
--verbose
--no-lines
--no-body
--include=/path/to/pmc
--library=libname
To see the internal data structures please run:
% perl tools/build/pmc2c.pl --c --deb --deb sarray.pmc | less
First, the program determines the names of the .c and .h files from the basename of the .pmc file (e.g. perlint.pmc -> perlint.c and perlint.h).
Next, the file is searched for /pmclass \w*/ which attempts to find the class being declared.
Once the class is found, all of its superclasses are scanned and their methods added to the methods of the current PMC. PMCs default to inheriting from 'default'. Only single inheritance is supported.
Once the superclass is determined, it is processed and its method names are extracted and saved.
Next, each method body is processed with various directives (see below) getting replaced by their appropriate values.
Finally, the .c and .h files are generated. The appropriate base class header files are included.
If the noinit
flag was used, then no init function is generated. Otherwise, one is generated which sets up the vtable and enters it into the Parrot_base_vtables
array.
The .c file is generated by appending the functions after the various directives have been replaced.
The basic syntax of a PMC file is
pmclass
declaration: pmclass PMCNAME [flags] {
where flags
are:
extends PMCPARENT
abstract
noinit
abstract
: No class_init
code is generated.const_too
need_ext
PMC_EXT
structure. For instance, any class using PMC_data
will have need_ext
.does interface
array : container PMC with numerically-keyed elements
event : PMC that can be used with event queue
hash : container PMC with string-keyed elements
library : PMC that corresponds to a dynamic library
ref : PMC that references another PMC
string : PMC that behaves similarly to the base string type
boolean : PMC that does true/false only.
integer : PMC that behaves similarly to the base int type
float : PMC that behaves similarly to the base number type
scalar : (only used by the sample src/dynpmc/foo.pmc)
dynpmc
class_init
routine suitable for dynamic loading at runtime. See the src/dynpmc directory for an example.group GROUP
lib LIB
hll HLL
maps Type
.HLL
usage. For example: pmcclass TclInt hll Tcl maps Integer
I
registers to PMCs.hll
flag.}
The vtable method bodies can use the following substitutions:
SELF
PMC *
.INTERP
OtherClass.SELF.method(a,b,c)
OtherClass
.SELF.method(a,b,c)
SELF
(in other words, calls another method defined in the same file).DYNSELF.method(a,b,c)
SELF
.DYNSELF(a,b,c)
OtherClass.SUPER(a,b,c)
OtherClass
.SUPER(a,b,c)
SELF
.DYNSUPER(a,b,c)
SELF
.Leopold Toetsch.
Cleaned up by Matt Diephouse.
Many thanks to the author of pmc2c.pl, many useful code pieces got reused.
|