NAME

docs/mmd.pod - Multimethod dispatch for binary opcode functions

CAVEATS

XXX - Part or all of this document is outdated. Especially the "the MMD system doesn't handle inheritance" bit. Please refer to PDD03 at this moment while we rewrite or merge this document. We apologize for the inconvenience.

SYNOPSIS

This system is set up to handle type-based dispatching for binary (i.e. two-arg) functions. This includes, though isn't necessarily limited to, binary operators such as addition or subtraction.

DESCRIPTION

The MMD system is straightforward, and currently must be explicitly invoked, for example by a vtable function. (We may reserve the right to use MMD in all circumstances, but currently do not)

API

For the purposes of the API, each MMD-able function is assigned a unique number which is used to find the correct function table. This is the func_num parameter in the following functions. While Parrot isn't restricted to a predefined set of functions, it does set things up so that all the binary vtable functions have a MMD table preinstalled for them, with default behaviour.

mmd_add_by_class(interp, func_num, left_class, right_class, funcptr)

Adds a new MMD function funcptr to the func_num function table that will be invoked when the left parameter is of class left_class and the right parameter is of class right_class. Both classes are STRING *s that hold the PMC class names for the left and right sides. If either class isn't yet loaded, Parrot will cache the information such that the function will be installed if at some point in the future both classes are available.

Currently this is done by just assigning class numbers to the classes, which the classes will pick up and use if they're later loaded, but we may later put the functions into a deferred table that we scan when PMC classes are loaded. Either way, the function will be guaranteed to be installed when it's needed.

The function table must exist, but if it is too small, it will automatically be expanded.

mmd_register(interp, func_num, left_type, right_type, funcptr)

Register a function funcptr for MMD function table func_num for classes left_type and right_type. The left and right types are INTVALs that represent the class ID numbers.

The function table must exist, but if it is too small, it will automatically be expanded.

Currently the MMD system doesn't handle inheritance and best match searching, as it assumes that all PMC types have no parent type. This can be considered a bug, and will be resolved at some point in the future.

mmd_dispatch_pmc(interp, left, right, dest, func_num)

Dispatch to a multimethod that "returns" a PMC. left, right, and dest are all PMC pointers, while func_num is the MMD table that should be used to do the dispatching.

The MMD system will figure out which function should be called based on the types of left and right and call it, passing in left, right, and dest like any other binary vtable function.

This function has a void return type, like all the "take two PMCs, return a PMC" vtable functions do.

STRING *mmd_dispatch_string(interp, left, right, func_num)

Dispatch to a multimethod that returns a string. left and right are PMC pointers, while func_num is the MMD table that should be used to do the dispatching. The function is responsible for creating the returned string.

INTVAL mmd_dispatch_intval(interp, left, right, func_num)

Like mmd_dispatch_string, only it returns an INTVAL.

FLOATVAL mmd_dispatch_floatval(interp, left, right, func_num)

Like mmd_dispatch_string, only it returns a FLOATVAL.

mmd_add_function(interp, func_num, default_func)

Add a new function table to the list of functions the MMD system knows of. func_num is the number of the new function, while default_func is the function to be called when the system doesn't know which function it should call. (Because, for example, there hasn't been a function installed that matches the left and right types for a call)

Constants

The following constants are defined to identify function tables:

MMD_ADD

Addition

MMD_SUBTRACT

Subtraction

MMD_MULTIPLY

Multiplication

MMD_DIVIDE

Division

MMD_MOD

Accurate modulus

MMD_CMOD

C-style modulus

MMD_BAND

Binary and

MMD_BOR

Binary or

MMD_BXOR

Binary xor

MMD_BSL

Bitshift left

MMD_BSR

Bitshift right

MMD_CONCAT

String concatenation

MMD_LAND

Short-circuiting logical and

MMD_LOR

Short-circuiting logical or

MMD_LXOR

Logical xor (not short-circuiting)

MMD_REPEAT

String repetition

MMD_NUMEQ

Numeric equality

MMD_STREQ

String equality

MMD_NUMCMP

Numeric comparison

MMD_STRCMP

String comparison

MMD_SOR

Bitwise or of the string value

MMD_SAND

Bitwise and of the string value

MMD_SXOR

Bitwise xor of the string value

Defaults

By default, functions are installed for all the functions that have constants associated with them. They are all functions suitable for calling with mmd_dispatch_pmc.

The math functions (add, subtract, multiply, and divide) all work on the float values of the left and right sides.

The cmod function does a plan C-style mod (the C % operator) on the integer value of the left and right sides.

The mod function does an fmod on the float values of the two sides.

The bitwise functions (and, or, xor, left shift, right shift) work on the integer values of the two sides.

The concat function concatenates the string values of the left and right sides.

The logical functions (and, or, xor) use the boolean values of the left and right sides to see whether they should set_pmc the destination to the left or right sides. The and and or functions short-circuit, xor does not.

The repeat function gets the string value of the left side and the integer value of the right.

The numeric equal and numeric comparison functions work on the float values of both sides.

The string equal and comparison functions work on the string values of both sides.

The string bitwise ops (and, or, xor) take the string values of both sides and do bitwise operations on the resulting bitstring.