[svn:parrot] r43012 - in trunk: . docs/pdds/draft

pmichaud at svn.parrot.org pmichaud at svn.parrot.org
Sat Dec 12 07:15:15 UTC 2009


Author: pmichaud
Date: Sat Dec 12 07:15:14 2009
New Revision: 43012
URL: https://trac.parrot.org/parrot/changeset/43012

Log:
[pdd]:  Add a proposed new draft for pdd31 -- HLL compiler and library interop

Added:
   trunk/docs/pdds/draft/pdd31_hll.pod   (contents, props changed)
Modified:
   trunk/MANIFEST

Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST	Sat Dec 12 06:52:02 2009	(r43011)
+++ trunk/MANIFEST	Sat Dec 12 07:15:14 2009	(r43012)
@@ -1,7 +1,7 @@
 # ex: set ro:
 # $Id$
 #
-# generated by tools/dev/mk_manifest_and_skip.pl Fri Dec 11 09:31:03 2009 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Sat Dec 12 07:06:36 2009 UT
 #
 # See below for documentation on the format of this file.
 #
@@ -493,6 +493,7 @@
 docs/pdds/draft/pdd14_numbers.pod                           []
 docs/pdds/draft/pdd16_native_call.pod                       []
 docs/pdds/draft/pdd29_compiler_tools.pod                    []
+docs/pdds/draft/pdd31_hll.pod                               []
 docs/pdds/draft/pdd31_hll_interop.pod                       []
 docs/pdds/pdd00_pdd.pod                                     []
 docs/pdds/pdd03_calling_conventions.pod                     []

Added: trunk/docs/pdds/draft/pdd31_hll.pod
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/docs/pdds/draft/pdd31_hll.pod	Sat Dec 12 07:15:14 2009	(r43012)
@@ -0,0 +1,351 @@
+# Copyright (C) 2009, Parrot Foundation.
+# $Id$
+
+=head1 [DRAFT] PDD 31: HLL Compilers and Libraries
+
+=head2 Version
+
+$Revision$
+
+=head2 Abstract
+
+This PDD describes the standard compiler API and support for
+cross-library communication between high-level languages (HLLs).
+
+=head2 Description
+
+Parrot's support for HLL interoperability is primarily focused on
+enabling programs written in one language to be able to use libraries
+and code written in a different language.  At the same time, language
+implementors should not be overly restricted by a global specification.
+
+This PDD describes an API for HLL compiler objects to use to
+promote library sharing among languages.  It's intended to make it
+easy for a program to request loading of a local or foreign module,
+determine the capabilities provided by the module, and potentially
+import and integrate them into its own namespaces.  In general,
+the API treats library-level interoperability as a negotiation
+among HLL compiler objects, with each HLL compiler maintaining
+primary control over the operations performed in its HLL space.
+
+In particular, this HLL API does not attempt to prescribe how
+languages should organize their internal capabilities, PMCs,
+namespaces, methods, data structures, and the like.
+
+=head2 Implementation
+
+=head3 Compiler API
+
+This section describes the abstract API for HLL compiler objects.
+
+=head4 Locating a compiler object
+
+Generally HLL compilers are loaded via the C<load_language>
+opcode, and register themselves using the C<compreg> opcode.
+By convention, each HLL compiler should at minimum register
+itself using the name of its HLL namespace (see PDD 26),
+although a compiler can choose to register itself under other
+names as well.
+
+=head4 Methods
+
+=over 4
+
+=item C<compile>
+
+=begin PIR_FRAGMENT
+
+    $P0 = compiler.'compile'(source [, options :named :slurpy])
+
+=end PIR_FRAGMENT
+
+Return the result of compiling C<source> according to C<options>.
+Common options include:
+
+=over 4
+
+=item target
+
+Stop the compilation process when the stage given by target
+has been reached.  Common values for target include "parse",
+"past", "pir", and "pbc".
+
+=item outer_ctx
+
+Use the supplied context as the outer (lexical) context for
+the compilation.  Some languages require this option to be
+able to look up lexical symbols in outer scopes when performing
+a dynamic compilation at runtime.
+
+=back
+
+=item C<eval>
+
+=begin PIR_FRAGMENT
+
+    $P0 = compiler.'eval'(source [, options :named :slurpy])
+
+=end PIR_FRAGMENT
+
+Compile and evaluate (execute) the code given by C<source>
+according to C<options>.  The available options are generally
+the same as for the C<compile> method above; in particular,
+the C<outer_ctx> option can be used to specify the outer lexical
+context for the evaluated source.
+
+=item C<parse_name>
+
+=begin PIR_FRAGMENT
+
+    $P0 = compiler.'parse_name'(name)
+
+=end PIR_FRAGMENT
+
+Parse the string C<name> using the rules specific to C<compiler>,
+and return an array of individual name elements.
+
+For example, a Java compiler would turn 'C<a.b.c>' to C<['a','b','c']>,
+while a Perl compiler would turn 'C<a::b::c>' into the same result.
+Perl's sigil rules would likely turn 'C<$a::b::c>' into C<['a','b','$c']>.
+
+=item C<load_module>
+
+=begin PIR_FRAGMENT
+
+    module = compiler.'load_module'(name)
+
+=end PIR_FRAGMENT
+
+Locate and load the module given by C<name> using the rules for
+libraries specific to C<compiler>, and return a C<module> handle for
+the module just loaded.  The C<name> argument is typically an array
+or a string to be processed as in C<parse_name> above.  In general
+the module handle returned should be considered opaque by the
+caller, but specific HLL compilers are allowed to specify the
+nature of the handle returned (e.g., a namespace for the loaded
+module, or a specific "handle" object).
+
+=item C<get_module>
+
+=begin PIR_FRAGMENT
+
+    module = compiler.'get_module'(name)
+
+=end PIR_FRAGMENT
+
+Similar to C<load_module> above, this method returns a handle
+to an already-loaded module given by C<name>.
+
+=item C<get_exports>
+
+=begin PIR_FRAGMENT
+
+    $P0 = compiler.'get_exports'(module [,name,name,...] [, 'tagset'=>tagset])
+
+=end PIR_FRAGMENT
+
+Requests the exported objects given by C<name> and/or C<tagset> for
+C<module> within the given C<compiler>.  The C<module> argument
+should be a module handle as obtained by C<load_module> or
+C<get_module> above.
+
+A C<tagset> argument provides an identifier that a compiler and/or
+module can use to supply their own lists of items to be exported.
+By convention, a C<tagset> of "DEFAULT" refers to the default set
+of exported items for the module, while "ALL" returns all available
+exports.  Compilers and modules are free to define their own custom
+tagsets beyond these.
+
+Any C<name> arguments supplied generally limit the export list to
+the tagset items corresponding to the supplied names (as determined by
+the compiler invocant).  If names are provided without an explicit
+tagset, then "ALL" is assumed.  If neither names nor a tagset are
+provided, then symbols from "DEFAULT" are returned.
+
+The returned export list is a hash of hashes; each entry in the
+top level hash has a key identifying the type of exported
+object (one of C<'namespace'>, C<'sub'>, or C<'var'>) and a
+value hash containing the corresponding exported symbol names
+and objects.  This hash-of-hashes approach is intended to generally
+correspond to the "Typed Interface" section of PDD 21 ("Namespaces"),
+and allows the module's source HLL to indicate the type of exported
+object to the caller.  The hash-of-hash approach also accommodates
+languages where a single name might be used to refer to several
+objects that differ in type.  (This PDD explicitly rejects the
+notion that a HLL should be directly exporting or injecting symbols
+into a foreign HLL's namespaces.)
+
+=back
+
+=head3 HLL::Compiler class
+
+HLL::Compiler is a common base class for compiler objects
+based on the Parrot Compiler Toolkit (PCT) and NQP (Not Quite Perl)
+libraries.  It provides a default implementation of the abstract
+Compiler API above, plus some additional methods for simple symbol
+table export and import.  The default methods are intended to support
+importing and exporting symbols using standard Parrot namespace
+objects (PDD 21).  However, it's normal (and expected) that
+languages will subclass HLL::Compiler to provide language-specific
+semantics where needed.
+
+=head4 Methods
+
+=over 4
+
+=item C<language>
+
+=begin PIR_FRAGMENT
+
+    $S0 = compiler.'language'([name])
+
+=end PIR_FRAGMENT
+
+If C<name> is provided, sets the language name of the invocant
+and registers the invocant as the compiler for C<name> via
+the C<compreg> opcode.
+
+Returns the language name of the compiler.
+
+=item C<parse_name>
+
+=begin PIR_FRAGMENT
+
+    $P0 = compiler.'parse_name'(name)
+
+=end PIR_FRAGMENT
+
+Splits a name based on double-colons, such that "C<A::B::C>"
+becomes C<['A','B','C']>.
+
+=item C<get_module>
+
+=begin PIR_FRAGMENT
+
+    module = compiler.'get_module'(name)
+
+=end PIR_FRAGMENT
+
+Returns a handle to the HLL namespace associated with C<name>
+(which is processed via the invocant's C<parse_name> method
+if needed).
+
+=item C<load_module>
+
+=begin PIR_FRAGMENT
+
+    module = compiler.'load_module'(name)
+
+=end PIR_FRAGMENT
+
+Loads a module C<name> via the C<load_bytecode> opcode
+using both ".pbc" and ".pir" extensions.  Parrot's standard
+library paths for C<load_bytecode> are searched.
+
+Returns the HLL namespace associated with C<name> (which may
+be PMCNULL if loading failed or if the requested module did
+not create an associated namespace).
+
+=item C<get_exports>
+
+=begin PIR_FRAGMENT
+
+    $P0 = compiler.'get_exports'(module [,name,name,...] [, 'tagset'=>tagset])
+
+=end PIR_FRAGMENT
+
+Implements a simple exporting interface that meets the "Compiler API"
+above.  The C<module> argument is expected to be something that
+supports a hash interface, such as NameSpace or LexPad.  (Note
+that this is what gets returned by the default C<get_module>
+and C<load_module> methods above.)  The C<module["EXPORT"]> entry
+should return another hash-like object keyed by tagset names; each
+of those tagset names then identify the exportable symbols
+associated with that tagset.
+
+With this default arrangement, it's entirely possible for a
+module to indicate its tagsets by using symbol entries in
+namespaces.  For example, a module with namespace C<['XYZ']>
+can define its default exports by binding symbols in the
+C<['XYZ';'EXPORT';'DEFAULT']> namespace.  (Modules aren't
+required to use exactly this mechanism; it's just one possibility
+of many.)
+
+If the "ALL" tagset is requested and there is no "ALL" entry
+in the C<module['EXPORT']> hash, then C<module> itself is used
+as the source of exportable symbols for this method.  This
+enables C<get_exports> to be used to obtain symbols from
+modules that do not follow the "EXPORT" convention above
+(e.g., core Parrot modules).
+
+As described in the Compiler API section above, the return value
+from C<get_exports> is a hash-of-hashes with exported namespaces
+in the C<namespace> hash, exported subroutines in the C<sub> hash,
+and all other exports in the C<var> hash.
+
+=item C<import>
+
+=begin PIR_FRAGMENT
+
+    compiler.'import'(target, export_hash)
+
+=end PIR_FRAGMENT
+
+Import the entries from C<export_hash> (typically obtained
+via C<get_exports> above) into C<target> according to the rules
+for C<compiler>.  Any entries in C<export_hash['namespace']>
+are imported first, followed by entries in C<export_hash['sub']>,
+followed by entries in C<export_hash['var']>.
+
+For each entry, import takes place by calling a C<import_[type]>
+method on the compiler object if one exists (where C<[type]> is one of
+"namespace", "sub", or "var").  This represents a "typed import",
+and allows the compiler object to perform any name mangling or
+other operations needed to complete the import.
+
+If the compiler object doesn't define an C<import_[type]> method,
+C<import> attempts to use any C<add_[type]> that exists for
+C<target> (e.g., for the case where C<target> is a namespace PMC
+supporting the typed interface defined in PDD 21).
+
+If neither of these methods are available, then C<import>
+simply binds the symbol using C<target>'s hash interface.
+
+=back
+
+=head3 Examples
+
+=head4 Importing a module Acme::Boom from language xyz into language abc
+
+=begin PIR_FRAGMENT
+
+    # Load the HLL library and get its compiler
+    .local pmc xyzcompiler, module, exports
+    load_language 'xyz'
+    xyzcompiler = compreg 'xyz'
+
+    # load xyz's module "Acme::Boom"
+    module = xyzcompiler.'load_module'("Acme::Boom")
+
+    # get the default exports for the module
+    # (note that 'tagset'=>'DEFAULT' is optional here
+    exports = xyzcompiler.'get_exports'(module, 'tagset'=>'DEFAULT')
+
+    # import into current namespace
+    .local pmc abccompiler
+    abccompiler = compreg 'abc'
+    $P0 = get_namespace
+    abccompiler.'import'($P0, exports)
+
+=end PIR_FRAGMENT
+
+=head2 References
+
+L<pdd21_namespaces.pod>
+
+=cut
+
+__END__
+Local Variables:
+  fill-column:78
+End:


More information about the parrot-commits mailing list