Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

222 lines (194 sloc) 7.396 kb
/*
The Rosella namespace is the base namespace of the Rosella library. All
Rosella libraries are in their own namespaces nested under the ["Rosella"]
namespace.
This namespace provides a handful of basic functions which are used
throughout rosella for some base functionality. These functions can be
broken into two general groups: functions for creating new objects, and
functions for working with types.
*/
namespace Rosella
{
function get_winxed_compiler()
{
var c = compreg("winxed");
if (c != null)
return c;
load_language("winxed");
c = compreg("winxed");
if (c != null)
return c;
Rosella.Error.error("Cannot get Winxed compiler object");
}
/* Allocation / Construction Functions
These functions allocate a new object using some kind of proto-
or meta-object. This meta-object can be a Class PMC, a PMC which can
be used to look up a class (String, String array, NameSpace, Key),
or something from the P6object system (P6metaclass, P6protoobject)
*/
// Allocate a fresh new object from the meta-object. Do not manipulate it,
// initialize it, or call any methods on it.
function alloc(var proto)
{
if (proto == null)
Rosella.Error.error("type may not be null");
var object;
if (proto instanceof 'P6protoobject')
object = proto.new();
else {
var obj_class = get_type_class(proto);
object = new_pmc(obj_class);
}
return object;
}
// P6-ish initializer routine. Allocate a new object and call the BUILD
// method on it, if it is defined.
function build(var proto, var pos [slurpy], var named [slurpy, named])
{
var object = alloc(proto);
var method = find_named_method(object, "BUILD");
if (method != null)
object.*method(pos:[flat], named:[flat,named]);
return object;
}
// Construct a new object. Allocate a fresh object of the given type and
// call the class constructor. The class constructor is a method with the
// same name as the short name of the Class.
function construct(var proto, var pos [slurpy], var named [slurpy,named])
{
var object = alloc(proto);
var class_obj = get_type_class(proto);
var method = find_named_method(object, class_obj.name());
if (method != null)
object.*method(pos:[flat], named:[flat,named]);
return object;
}
/* Type Manipulation Functions
These functions take a meta-object (one of the types listed above)
and extracts useful information from them in a common way.
*/
// Get the fully-qualified string name of the type
function get_type_name(var type)
{
if (type == null)
Rosella.Error.error("type may not be null");
if (type instanceof "String")
return type;
if (type instanceof "P6protoobject")
type = type.HOW().get_parrotclass(type).get_namespace();
else if (type instanceof "P6metaclass")
type = type.get_parrotclass(type).get_namespace();
else if (type instanceof "Class")
type = type.get_namespace();
else if (type instanceof "Key")
type = get_namespace(type);
if (type instanceof "NameSpace")
return join(";", type.get_name());
if (does(type, "array"))
return join(";", type);
return string(type);
}
// Get the Parrot Class PMC associated with the type.
function get_type_class(var type)
{
if (type == null)
Rosella.Error.error("type may not be null");
if (type instanceof "P6metaclass")
return type.get_parrotclass(type);
if (type instanceof "P6protoobject")
return type.HOW().get_parrotclass(type);
if (type instanceof "Class")
return type;
if (type instanceof "String")
type = split(";", type);
return get_class(type);
}
// Determine if the given object is an instance of the given type.
function isa_type(var type, var object)
{
if (type == null)
Rosella.Error.error("type may not be null");
var class_test = get_type_class(type);
return isa(object, class_test);
}
/* Bytecode Management Functions
*/
// Initialize the Rosella library, loading in any necessary files.
function initialize_rosella(var libs [slurpy])
{
var core = load_packfile("rosella/core.pbc");
init_bytecode(core, "load");
__load_rosella_libraries(libs);
}
// Load a Rosella library, by name
function load_rosella_library(var libs [slurpy])
{
__load_rosella_libraries(libs);
}
// Load an array of rosella libraries
inline __load_rosella_libraries(var libs)
{
for (string lib in libs) {
string lib_name = sprintf("rosella/%s.pbc", [lib]);
var pf = load_packfile(lib_name);
init_bytecode(pf, "load");
}
}
// Load in the bytecode library, executing the given trigger, if any.
function load_bytecode_file(string file, string trigger = null)
{
var pf = load_packfile(file);
if (trigger != "" && trigger != null)
init_bytecode(pf, trigger);
return pf;
}
// Initialize the bytecode, executing subs with the given trigger
function init_bytecode(var pf, string trigger)
{
if (!pf.is_initialized(trigger)) {
pf.mark_initialized(trigger);
var subs = pf.subs_by_tag(trigger);
for (var sub in subs)
sub();
}
}
/* Method-Utility Functions
These functions help do things with functions and methods. These are
NOT part of the standard API of the Rosella namespace, they only exist
to help deal with shortcomings in various parts of the toolchain.
These functions will disappear when they are no longer needed
*/
// find a method PMC on the given object without throwing an exception on
// failure.
function find_named_method(var object, string meth_name)
{
if (object == null || meth_name == null)
Rosella.Error.error("object and meth_name may not be null");
if (!can(object, meth_name))
return null;
return find_method(object, meth_name);
}
// Invoke the given method on the object with the given parameters.
// The method parameter can be a method object or a String with the name
// of the method to lookup.
function invoke_method(var obj, var method, var p, var n)
{
if (method instanceof 'String') {
var real_method = find_named_method(obj, method);
if (real_method == null)
Rosella.Error.error("Cannot find method '%s'", method);
method = real_method;
}
return obj.*method(p:[flat], n:[flat,named]);
}
// Get a unique count number, which is guaranteed to be unique throughout
// the Rosella library for the duration of the program.
function get_unique_count()
{
int i = 0;
while(1) {
i = i + 1;
yield i;
}
}
}
Jump to Line
Something went wrong with that request. Please try again.