minid.types

The main header file of the MiniD interpreter. This file defines all the basic types of MiniD, as well as the MDState type, which is the interpreter (and doubles as the 'thread' type for coroutines).

It makes me sad to have to have so much stuff in one file, but D just can't handle circular imports (which would be necessary for splitting this up) without throwing up all over itself in a flurry of forward declaration/reference errors. Sigh, if only it followed the spec where it says "things to drop: forward declarations."

License:
Copyright (c) 2007 Jarrett Billingsley

This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.

2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.

3. This notice may not be removed or altered from any source distribution.

class MDException : object.Exception;
The root of the MiniD exception hierarchy.

All exceptions in MiniD derive from this class. In order to be compatible with the scripting language, where values of any type can be thrown as exceptions, it has a public member which exposes this value.

MDValue value ;
The MiniD value which is used if the exception is caught by a catch statement in MiniD code.

this(char[] fmt,...);
Construct an MDException using a format string and a list of arguments, using Tango-style formatting. The string will be formatted, and assigned into the value member as well.

this(char[] fmt, TypeInfo[] arguments, void* argptr);
Like above, but for when you already have the two variadic parameters from another variadic function.

this(MDValue val);
Construct an MDException from an MDValue. It will be assigned to the value member, and the string representation of it (not calling toString metamethods) will be used as the exception message.

this(MDValue * val);
Like above, but for MDValue pointers instead.

class MDCompileException : minid.types.MDException;
Thrown by the compiler whenever there's a compilation error.

The message will be in the form "filename(line:colunm): error message".

bool atEOF ;
Indicates whether the compiler threw this at the end of the file or not. If this is true, this might be because the compiler ran out of input, in which case the code could be made to compile by adding more code.

this(Location loc, char[] fmt,...);
Takes the location of the error, and a variadic list of Tango-style formatted arguments.

class MDRuntimeException : minid.types.MDException;
Thrown to indicate an error at run-time, often by the interpreter but not always.

This class includes a location of where the exception was thrown.

Location location ;
The location of where the exception was thrown. This may not be entirely accurate, depending on whether or not debug information was compiled into the bytecode, who threw the exception etc.

this(Location loc, MDValue * val);
Constructs the exception from a location and an MDValue pointer to the value to be thrown.

this(Location loc, char[] fmt,...);
Constructs the exception from a location and Tango-style formatted arguments.

this(Location loc, char[] fmt, TypeInfo[] arguments, void* argptr);
Like above, but takes the variadic function parameters instead.

char[] toUtf8 ();
Overridden to include the location in the error message. Note that the result of this is in the format "filename(line:instruction): error message". The 'instruction' in this message is the index of the instruction in the bytecode that caused the exception, and is mostly meant for low-level debugging.

struct MDValue ;
The basic variant data type which represents a MiniD value.

This structure is the underlying representation of every variable, array slot, table key/value etc. that appears in the language. It is a variant type which can hold any of the language types. It's a simple tagged union, with a 4-byte type and an 8-byte data segment (large enough to hold a double-precision floating-point value, the largest type that it can hold).

enum Type ;
Enumerates the basic datatypes of MiniD. See the 'Types' section of the spec for more info.

static MDValue nullValue ;
A static MDValue instance which should always, always hold 'null'. There is an invariant which ensures this. This is mostly used by functions which need to return a pointer to a null MDValue, rather than returning an actual null pointer. You can also use this any time you need a null MDValue in your D code.

MDValue opCall (T)(T value);
The "constructor" for the struct. It's templated based on the parameter, and all it does is call opAssign, so see opAssign for more info.

int opEquals (MDValue * other);
Returns true if this and the other value are exactly the same type and the same value. The semantics of this are exactly the same as the 'is' expression in MiniD.

int opCmp (MDValue * other);
This is mostly overridden for using MDValues as AA keys. You probably shouldn't use this for comparing MDValues in general, because (1) it will return 'less' or 'greater' for values which are different types, which doesn't really make sense, and (2) will not call opCmp metamethods.

int compare (MDValue * other);
Compares this to another MDValue in a more sensible way. If the two objects are different types, and are not both numeric types (int or float), an exception will be thrown. Integers will automatically be cast to floats when comparing an int and a float. This function still does not call opCmp metamethods, however; you should use the APIs in the MDState class for the best comparison.

uint toHash ();
Overridden to allow the use of MDValues as AA keys.

uint length ();
Gets the length of the MDValue, which will fail (throw an exception) if getting the length makes no sense for the MDValue's type. Does not call opLength metamethods.

Type type ();
Returns the current type of this value, as a value from the MDValue.Type enumeration.

static dchar[] typeString (Type type);
A static method which, given a value from the MDValue.Type enumeration, will give the string representation of that type.

dchar[] typeString ();
Gets a string representation of the type of this value. Differs from passing the type into the static typeString () function in that it will include the name of the class if this is a class or instance value.

bool isNull ();
bool isBool ();
bool isNum ();
bool isInt ();
bool isFloat ();
bool isChar ();
bool isObj ();
bool isString ();
bool isTable ();
bool isArray ();
bool isFunction ();
bool isClass ();
bool isInstance ();
bool isNamespace ();
bool isThread ();
These return true if this is the given type, and false otherwise.

bool isFalse ();
Returns true if this value is false (null, 'false', an integer with the value 0, a float with the value 0.0, or a NUL ('\0') character).

bool isTrue ();
Returns the opposite of isFalse().

bool canCastTo (T)();
A templated method which checks if this value can be converted to the given D type. Array and AA types will check the entire contents of the Array or Table (if the value is one) to make sure all the elements can be cast as well, so this can be a non-trivial operation for the container types. . canCastTo !(floating point type)() will return true if the value is either a float or an int. If the value is an instance, it will check that it can be downcast to the given class instance type.

T as (T)();
A templated method which converts this value to the given D type. This is kind of a power-user method, used for converting a MiniD value to a D value as long as you know in advance that this conversion can be done. If the conversion can't be done, an assertion will be thrown in debug builds, but the behavior is undefined in release builds.

T to (T)();
A 'safer' version of .as(), this will do basically the same thing, but will throw an exception on a failed conversion.

void setNull ();
Sets this value to null. You can also set a value to null by assigning it the D 'null' value.

void opAssign (T)(T src);
A templated opAssign which allows the assignment of many D types into an MDValue. All reasonable assignments are valid. Assignment of an array or AA to an MDValue will convert it into a MiniD array or table. You can assign 'null' into an MDValue as well. An invalid type will trigger a compile-time error.

char[] toUtf8 ();
Returns the string representation of the value. Does not call toString metamethods.

class MDObject ;
The base class for all the object (reference) types in MiniD.

static int compare (MDObject o1, MDObject o2);
Given two MDObject references, compares them. Doesn't call opCmp metamethods, and throws an exception if the two objects are of different types.

class MDString : minid.types.MDObject;
The class that represents the MiniD 'string' type.

This holds an immutable string. The hash for this string is calculated once upon creation, improving speed when used as the key to an AA (which, in MiniD, is very often -- all namespaces use MDStrings as keys). Immutability also avoids the problem of using a string as an AA key and then changing it, which would result in undefined behavior.

this(dchar[] data);
this(wchar[] data);
this(char[] data);
These construct an MDString from the given D string. The data is duplicated, so you don't have to worry about changing the source data after the MDString has been created.

uint length ();
Gets the length of the string in characters (codepoints? code units? it's all so confusing).

int opIn_r (dchar c);
If the given character is in the string, returns the index of its first occurrence; otherwise returns -1.

MDString opCat (MDString other);
Concatenates two MDStrings, resulting in a new MDString.

MDString opCat (dchar c);
MDString opCat_r (dchar c);
Concatenates an MDString with a single character, resulting in a new MDString.

uint toHash ();
Returns the hash of the string (which was computed at construction).

int opEquals (Object o);
Returns true if this and another string are identical; false otherwise. Checks to see if the hashes diff first, which can save a lot of time.

int opEquals (char[] v);
int opEquals (wchar[] v);
int opEquals (dchar[] v);
Returns true if this MDString's data is identical to the given D string; false otherwise.

int opCmp (Object o);
Compares this string to another MDString by character values (i.e. it doesn't do a full lexicographical language-correct comparison).

int opCmp (char[] v);
int opCmp (wchar[] v);
int opCmp (dchar[] v);
Same as above, but for D string arguments.

dchar opIndex (uint index);
Gets the character at the given index.

MDString opSlice (uint lo, uint hi);
Slices this string, returning a new MDString. Thanks to immutability, the new string's data will simply point into the old string's, meaning the only memory allocation is for the new string's instance.

char[] asUTF8 ();
wchar[] asUTF16 ();
dchar[] asUTF32 ();
These convert this string into the given UTF encoding. The returned value will never reference the data inside the instance, to preserve immutability.

char[] toUtf8 ();
Returns the UTF-8 string representation of the string; basically just returns .asUTF8().

class MDClosure : minid.types.MDObject;
The class which represents the MiniD 'function' type.

This is a closure, that is a function and all the environment it needs to execute correctly. It can hold either a MiniD closure (a "script closure"), or a reference to a native D function (a "native closure"). In virtually all cases this distinction is transparent, except when it comes to coroutines. You cannot yield out of a coroutine across the boundary of a native function call.

In addition to their executable function, closures also have what's called the "environment." In the global lookup process (in script functions, that is), the first step is to check if the global exists in the 'this' parameter. If it doesn't, the next step goes to the closure's environment. This is a namespace which usually is the module in which the function was defined. Global lookup begins at the environment, and travels up the chain of namespaces (since each namespace can have a parent namespace) until the chain is exhausted. The environment is important for global lookup in script closures, but it's usually not that important in native closures. Furthermore, if a function is called as a non-method (a plain function call), and is not given an explicit context with the 'with' keyword, its environment will be passed as the 'this' parameter.

this(MDNamespace environment, MDFuncDef def);
Constructs a script closure.

Params:
MDNamespace environment The environment of the closure. See the description of this class for info.
MDFuncDef def The MDFuncDef, which was either loaded from a file or just compiled, which holds the bytecode representation of the closure.

this(MDNamespace environment, int delegate(MDState, uint) dg, dchar[] name, MDValue [] upvals = null);
this(MDNamespace environment, int(* func)(MDState, uint), dchar[] name, MDValue [] upvals = null);
Constructs a native closure. Both function pointers and delegates are allowed; using delegates will be slightly faster when the closure is called.

All native functions which interact with the API follow the same signature. They take two Params: an MDValue which represents the thread from which this closure was called, and the number of parameters (not including the context 'this' parameter, which is always present) with which the function was called. The MDState parameter contains all the parameters which were passed to the function, as well as being a very important interface through which much of the native API is used. Native functions return an integer, which is how many values they are returning (which were pushed onto the MDState's stack prior to returning).

Params:
MDNamespace environment The environment of the closure. See the description of this class for info.
int delegate(MDState, uint) dg (or func) The delegate or function pointer of the native function.
dchar[] name The name of the function, which will be used in error messages and when its toString is called.
MDValue [] upvals An optional array of MDValues which serve as the upvalues to the closure. In MiniD, upvalues are automatic, and are simply local variables declared in enclosing functions. In native code, you can achieve similar results by either creating an instance of a struct on the heap and using one of its methods as the delegate for the closure, and keep the closure's upvalues in there; or by passing an array of MDValues to this constructor. The array of upvalues will be available through the MDState parameter to the native function.

uint length ();
Getting the length of a closure makes no sense; this just throws an exception.

char[] toUtf8 ();
Gets a string representation of the closure. For native closures, it looks something like "native function name"; for script closures, "script function name(location defined)".

bool isNative ();
Returns whether or not this is a native closure.

MDNamespace environment ();
void environment (MDNamespace env);
Gets or sets the environment of the closure. See the class description for info.

class MDTable : minid.types.MDObject;
The class which represents the MiniD 'table' type.

This is basically an AA which is indexed by and holds MDValues. Null MDValues cannot be used as indices. Assigning a null value to a key-value pair removes that pair from the table, and accessing a key which doesn't exist will return a null value.

this();
Creates a new table.

MDTable create (T...)(T args);
Create a table from a templated list of variadic arguments. There must be an even number of arguments. Each pair of arguments is interpreted as a key-value pair, and the types of these must be convertible to MiniD types.

MDTable fromAA (K,V)(V[K] aa);
Create a table from an associative array. The key and value types must be convertible to MiniD types.

uint length ();
Gets the number of key-value pairs in the table.

MDTable dup ();
Creates a shallow copy of the table. The keys and values in the new table will be the same; they are not recursively duplicated.

MDArray keys ();
Gets an MDArray of all the keys of the table.

MDArray values ();
Gets an MDArray of all the values of the table.

void remove (ref MDValue index);
Removes a key-value pair from the table with the given key. If the key doesn't exist, this simply returns. You can also remove a pair by assigning a null value to it.

MDValue * opIn_r (ref MDValue index);
Returns a pointer to the value given the key. Returns a null pointer if the key doesn't exist.

MDValue * opIndex (ref MDValue index);
Returns a pointer to the value given the key. Throws an exception if the key is a null MDValue. Never returns a null MDValue*; if the key doesn't exist, returns a pointer to a null MDValue instead.

void opIndexAssign (ref MDValue value, ref MDValue index);
Assigns a value to a key-value pair. Throws an exception if the key is a null MDValue. Removes the pair, if it exists, if the value is a null MDValue.

int opApply (int delegate(ref MDValue key, ref MDValue value) dg);
Overloaded opApply so you can use a foreach loop on an MDTable. They key and value are both MDValues.

char[] toUtf8 ();
Returns a string representation of the table, in the format "table 0x00000000", where the number is the hexidecimal representation of the 'this' pointer.

class MDArray : minid.types.MDObject;
The class which represents the MiniD 'array' type.

This is a very simple and straightforward class. It's basically a mutable, resizable array of MDValues.

this(uint size);
Construct this array with a given size. All the elements will be the null MDValue.

MDArray create (T...)(T args);
Create an MDArray from a templated list of variadic arguments. All the arguments must have types which are convertible to MiniD types.

MDArray fromArray (T)(T[] array);
Create an MDArray from a D array. The element type must be convertible to a MiniD type. Multi-dimensional arrays work as well.

uint length ();
Gets the number of elements in the array.

uint length (int newLength);
Sets the length of the array. If the new length is longer than the old, the new elements will be filled in with the null MDValue.

void sort ();
Sorts the array. All the elements must be the same type for this to succeed; throws an exception on failure.

void sort (bool delegate(MDValue , MDValue ) predicate);
Sorts the array, using a custom predicate. This predicate takes two values and should return 'true' if the first is less than the second, and 'false' otherwise.

void reverse ();
Reverses the order of the array.

MDArray dup ();
Performs a shallow copy of the array.

int opCmp (Object o);
Compares this array to another array. Comparison works just like on D arrays. As long as the length and data are identical, the arrays will compare equal. If all the elements of both arrays are the same type, you can even compare for ordering; smaller arrays and arrays with smaller elements will compare less than larger arrays. If the elements are different types, comparing for ordering doesn't make much sense, but equality still works.

int opEquals (Object o);
Sees if this array is identical to another array.

int opIn_r (ref MDValue v);
If the given value is in the array, returns the index of the first instance; otherwise, returns -1.

int opApply (int delegate(ref MDValue value) dg);
int opApply (int delegate(ref uint index, ref MDValue value) dg);
opApply overloads to allow using foreach on an MDArray. Both index-value and value-only forms are available. The value type is an MDValue.

MDArray opCat (MDArray other);
Concatenates two arrays into a new array. The data is always copied from the source arrays.

MDArray opCat (ref MDValue elem);
MDArray opCat_r (ref MDValue elem);
Concatenates an array with a single element. Always copies from the source array.

MDArray opCatAssign (MDArray other);
Appends another array onto the end of this one. No new array is created; this array is just resized.

MDArray opCatAssign (ref MDValue elem);
Appends a single element to the end of this array.

MDValue * opIndex (int index);
Gets a pointer to the value stored at the given index. Returns a pointer instead of a plain MDValue so that the array data can be updated after the fact.

void opIndexAssign (ref MDValue value, uint index);
Assigns a value into the given index.

MDArray opSlice (uint lo, uint hi);
Creates a new array which is a slice into this array's data. Modifying the contents of the sliced array will modify the contents of this array (unless this array is resized, in which case it may not).

void opSliceAssign (ref MDValue value, uint lo, uint hi);
Assigns a single value to a range of indices.

void opSliceAssign (MDArray arr, uint lo, uint hi);
Copies the data from another MDArray into this one. The length of the other array must be the same as the length of the slice indicated by the indices.

void opSliceAssign (ref MDValue value);
Assigns a single value to every element of this array.

void opSliceAssign (MDArray arr);
Copies the data from another array into this one. Both arrays must have the same length.

char[] toUtf8 ();
Returns a string representation of the array, in the format "array 0x00000000", where the number is the hexidecimal representation of the 'this' pointer.

class MDClass : minid.types.MDObject;
The class which represents the MiniD 'class' type.

Classes hold two namespaces: one for fields and one for methods. The method namespace is shared among all instances of the class, while the field namespace is duplicated for each instance. Classes can inherit from other classes.

When assigning members to the class, they will automatically be put into the proper namespace based on their type -- closures go into the method namespace, all others into the fields namespace. You can also get references to each of these namespaces.

this(dchar[] guessedName, MDClass baseClass = cast(MDClass)null);
Creates a new class.

Params:
dchar[] guessedName The name of the class. This is called "guessed" mostly because in MiniD code, classes do not have any intrinsic name associated with them, and sometimes the compiler will generate a name for an anonymous class. For any classes that you create from native code, though, you'll probably given them a real name.
MDClass baseClass An optional base class from which this one should derive. If you skip this parameter or pass null, the class will have no base class. Otherwise, it will copy the fields and methods from the base class into its own namespaces, which you can then overwrite (override) with your own versions.

uint length ();
Throws an exception since classes do not have a length .

MDValue superClass ();
Returns an MDValue containing the base class. Returns a null MDValue if it has no base class.

MDInstance newInstance ();
Creates a new instance of this class; this doesn't, however, run the constructor, so the instance may be incompletely initialized. The fields are copied from the class into the new instance; the instance's method namespace simply points to this class's method namespace.

MDValue * opIndex (MDString index);
MDValue * opIndex (dchar[] index);
Look up a member of the class. This will look in the methods, the fields, and then continue the search in the base class if there is any. Returns a null pointer (not a pointer to a null MDValue) if the member wasn't found.

void opIndexAssign (ref MDValue value, MDString index);
void opIndexAssign (ref MDValue value, dchar[] index);
Sets a member of a class. If the value is a function, it'll be put into the methods namespace; otherwise, it'll be put into the fields namespace.

dchar[] getName ();
Returns the guessed name (a duplicate of the internal name, so it can't be corrupted).

MDNamespace fields ();
Returns the namespace that contains the fields for this class. Manually adding members to the returned namespace is not recommended, as this bypasses some caching logic that MDClass performs with a normal member add.

MDNamespace methods ();
Returns the namespace that contains the methods for this class. Manually adding members to the returned namespace is not recommended, as this bypasses some caching logic that MDClass performs with a normal member add.

char[] toUtf8 ();
Returns a string representation of the class in the form "class name".

class MDInstance : minid.types.MDObject;
The class which represents the MiniD 'instance' type.

Instances are a bit different from other types in that they also have a class type from which they were instantiated. This class defines the methods which can be called on its instances, as well as the fields which they given when they are created. You can query the runtime type of an instance, as well as see if a given class is anywhere in its inheritance hierarchy (or if it is an instance of that class itself).

Instances must be created through a class; you cannot instantiate an instance on its own.

uint length ();
Getting the length of an instance could make sense, if the instance had an opLength method. However, none of these class methods call (or can call) metamethods, so this just throws an exception.

MDValue * opIndex (MDString index);
MDValue * opIndex (dchar[] index);
Looks up a member in the instance. If the member doesn't exist, returns a null pointer.

void opIndexAssign (ref MDValue value, MDString index);
void opIndexAssign (ref MDValue value, dchar[] index);
Sets a member in an instance. You cannot reassign instance methods; attempting to do so will result in an exception being thrown. You also can't add fields to the class instance which it didn't have to begin with (also throws an error).

char[] toUtf8 ();
Gets a string representation of the instance, in the form "instance of class classname". Does not call toString metamethods.

bool castToClass (MDClass cls);
Given a reference to a class, sees if this instance can be cast to the given class.

Returns:
'this' if it can be cast; null otherwise.

MDNamespace fields ();
Get a reference to the field namespace of this instance. Every instance has its own field namespace.

MDNamespace methods ();
Get a reference to the method namespace of this instance. All instances of a class and the class itself share the method namespace.

MDClass getClass ();
Gets a reference to the owning class.

class MDNamespace : minid.types.MDObject;
The class which represents the MiniD 'namespace' type.

Namespaces are kind of like tables, but have somewhat different semantics. They are a mapping from strings to values; only string keys are allowed. Namespaces may hold null values, so assigning a null value to a key-value pair does not remove that pair from the namespace. Accessing a key-value pair which has not yet been inserted will throw an exception instead of returning null as tables do. Namespaces can have a name. Lastly namespaces can also have a parent namespace, which is used in global lookup.

Namespaces are used as symbol tables throughout MiniD. Modules, packages, class fields, and class methods are all held in namespaces. They are also used as function closure environments. When global lookup reaches the closure's environment, it looks up the global in that namespace; if it's not found, it goes to that namespace's parent namespace, all the way up the chain of namespaces until either the global is found or the namespace chain ends.

this(dchar[] name = null, MDNamespace parent = cast(MDNamespace)null);
Construct a new namespace.

Params:
dchar[] name The optional name of the namespace. It can be null, in which case the namespace will be anonymous. class method and field namespaces are anonymous, for example.
MDNamespace parent The optional parent of the namespace. The parent is used for global lookup (see the description of this class). If the namespace won't be being used as the environment for a function, the parent is mostly purposeless, except for debugging, when the parent's name will be included in the namespace's name. The parent can be null, which means global lookup will terminate after searching this namespace.

MDNamespace create (T...)(dchar[] name, MDNamespace parent, T args);
Create a namespace from a variadic list of arguments. This is similar to the MDTable. create () function, in that there must be an even number of arguments, and each pair is interpreted as a key-value pair. This has the additional requirement that the keys must all be strings. The name and parent parameters are the same as in the constructor.

void addList (T...)(T args);
Similar to create(), but just adds a list of key-value pairs to an already-created namespace.

uint length ();
Gets the number of key-value pairs in the namespace.

dchar[] name ();
Gets the name of the namespace (not including the parent's name ).

MDNamespace parent ();
Gets the parent of this namespace.

MDValue * opIn_r (MDString key);
MDValue * opIn_r (dchar[] key);
Looks up a value in the namespace from a string key. As usual for D's 'in', returns null if the value isn't found, and a pointer to the value if it is.

MDNamespace dup ();
Duplicate this namespace, performing a shallow copy of all the key-value pairs.

MDArray keys ();
Gets an MDArray of all the keys in the namespace.

MDArray values ();
Gets an MDArray of all the values in the namespace.

MDValue * opIndex (MDString key);
MDValue * opIndex (dchar[] key);
Looks up a value from the namespace. Returns a null pointer if the key doesn't exist.

void opIndexAssign (ref MDValue value, MDString key);
void opIndexAssign (ref MDValue value, dchar[] key);
Assigns a value to a key n the namespace. Will insert the pair if the key doesn't exist already. Assigning a null value to a key-value pair will not remove the pair from the namespace as it does with tables.

void remove (MDString key);
void remove (dchar[] key);
Remove the given key from the namespace. Throws an exception if they key does not exist.

int opApply (int delegate(ref MDString, ref MDValue ) dg);
Overload of opApply to allow using foreach over a namespace. The keys are MDStrings, and the values are MDValues.

dchar[] nameString ();
Gets a more complete name of the namespace, including the name of all parent namespaces. So if namespace 'b's parent is namespace 'a', this will return a string like "a.b".

char[] toUtf8 ();
Gets a string representation of the namespace in the form "namespace full.name".

struct Location ;
A struct that holds a location (a filename, a line number, and a column number) of a piece of code. Used by the compiler and in runtime debug locations.

static Location opCall (dchar[] fileName, int line = 1, int column = 1);
Create a location with the given filename, line, and column. Lines and columns start at 1. A line, column pair of -1, -1 has the special meaning of "in a native function."

char[] toUtf8 ();
Gets a string representation of the location. If the line and column are both -1, the string is formatted like "fileName(native)", meaning that the location came from a native function (i.e. a native function may have thrown an exception). Otherwise, it's in the form "fileName(line:column)". For runtime debug locations, 'column' is actually replaced by the index of the bytecode instruction.

class MDModuleDef ;
A definition of a MiniD module.

This is really just a name and the code for the top-level function of the module. This can be serialized and deserialized using the minid.utils serialization protocol. This can also be loaded by the MDContext class, but that's a very low-level API.

dchar[] name ();
Gets the name of the module. This is the name given in the module declaration.

void serialize (IWriter s);
Serialize this module to some kind of output. To be used with the minid.utils serialization protocol.

static MDModuleDef deserialize (IReader s);
Deserialize this module from some kind of input. To be used with the minid.utils serialization protocol.

static MDModuleDef loadFromFile (char[] filename);
Load a module definition from a filename. This is a low-level API that you probably won't have to deal with.

void writeToFile (char[] filename);
Save this module to a filename.

class MDFuncDef ;
A class which holds a script function's byte code, as well as all (most) of the information needed to instantiate a closure of it, and some debug info as well.

You probably won't need to worry about using this class that much.

class MDContext ;
A class which represents an execution context for MiniD code. It holds a global namespace hierarchy into which modules can be imported, as well as a set of type metatables. Also provides a state which can be used to run code.

You can create multiple, independent MiniD execution contexts. These are not the same as states. A state is simply a thread of execution, and there can be multiple states associated with a single context. When you create a context, a default state (its "main thread") is created for you. This thread can spawn other threads with the creation of coroutines.

A context is useful for creating a "sandbox." What you can do is create a context, and only load into it libraries which you know are safe. Then you can execute untrusted code in this sandbox, and it won't have access to potentially dangerous functionality. Then you can have a separate context for executing trusted code.

You can instantiate this class directly, and then load the standard libraries into it manually, but there is minid.minid.NewContext, a helper function which will load standard libraries into the context based on a flags parameter, which is a bit more compact.

struct _Globals ;
This struct isn't meant to be used as a type in its own right; it's just a helper for accessing globals.

T opIndex (T = MDValue*)(dchar[] name);
alias get ;
Attempts to get a global of the given name from the global namespace. Throws an exception if the global does not exist. This is a templated function and returns an MDValue* by default. If you want to get another type, you can use the 'get' alias to this function and call it as a templated method.

void opIndexAssign (T)(T value, dchar[] name);
Set a global in the global namespace.

MDNamespace ns ();
Get the underlying MDNamespace which actually holds the globals.

_Globals globals ;
An instance of the above struct. You can access globals by writing things like "context.globals["x"d] = 5".

final MDNamespace getMetatable (Type type);
final void setMetatable (Type type, MDNamespace table);
Gets or sets the metatable for the given type. Every type has a metatable associated with it where metamethods are looked up after any normal method indexing mechanisms fail. For example, the 'string' standard library sets itself as the metatable for the 'string' type, making it possible to call the library functions as if they were methods of the string objects themselves.

final MDState mainThread ();
Gets the main thread of execution. This thread is created when the context is created, and is the default thread of execution.

final MDClosure newClosure (MDFuncDef def);
Create a new closure in the global namespace from the given script function definition.

final MDClosure newClosure (int delegate(MDState, uint) dg, dchar[] name, MDValue [] upvals = null);
final MDClosure newClosure (int(* func)(MDState, uint), dchar[] name, MDValue [] upvals = null);
Create a new closure in the global namespace from the given native closure information. See MDClosure.this() for info on these parameters.

final void addImportPath (char[] path);
Add a path to be searched when performing an import. See importModule() for information on the import mechanism.

final void setModuleLoader (dchar[] name, MDClosure loader);
Sets a module loader for a given module name. The name should be in the format of a module declaration name, such as "fork.knife.spoon".

The closure takes two Params: the name of the module to load (so that multiple modules can be loaded by the same function), and a namespace in which to place the loaded module symbols. It is not expected to return anything.

final MDNamespace importModule (dchar[] name, MDState s = cast(MDState)null);
Import a given module. The process goes something like this.

1. See if the module has been loaded. Module names are case sensitive. If the module name is found in the internal list of loaded modules, the process stops here.

2. If the module hasn't been loaded, see if a loader was registered for it with setModuleLoader(). If one has been, the loader is called with the module name and the namespace in which to place the module's symbols. The process ends here if this succeeds.

3. If there's no registered loader, it attempts to load the module from disk, from either a source file or a compiled binary module file. This is where the search paths come in. The first path it attempts is the current working directory. If the module's name is multipartite, the parts before the final part become directory names. So for example, the name is "fork.knife.spoon", it will look in "fork/knife/" for both "spoon.md" and "spoon.mdm". If both a source and a binary file are found, it will load the one with the more recent modification time. After the current directory is tried, it will go through the list of custom directories (in no particular order) attempting the same process.

4. Not implemented in this release. If no source or binary module could be found, the last attempt is to try to load a dynamic library with the same name as the module (with a similar pattern as with the source/binary search; "fork.knife.spoon" will look in fork/knife for the module named "spoon").

If all these steps fail, the import process fails.

Params:
dchar[] name The name of the module to load, in the format "fork.knife.spoon".
MDState s The state to use to load the module. This is used when calling any custom module loader functions, or if the module being loaded is a script module, in which case the top-level function will be called. Defaults to null, in which case the main thread will be used.

Returns:
The namespace which holds the module's symbols.

final MDNamespace initializeModule (MDState s, MDModuleDef def, MDValue [] params);
Initialize a module given the module's definition and a list of parameters which will be passed as vararg parameters to the top-level function. This is a very low-level API.

Params:
MDState s The state to use to call the top-level module function.
MDModuleDef def The module definition, which was compiled from source or loaded from a file.
MDValue [] params An array of parameters which will be passed as varargs to the top-level function.

Returns:
The namespace of the module.

final char[] getTracebackString ();
Gets traceback info of the most recently-thrown exception, and clears the traceback info. This method is here because exceptions can propagate through multiple states and through coroutine calls.

class MDState : minid.types.MDObject;
The class which represents the MiniD 'thread' type. Also probably the singularly most important class in the native API, this is passed as a "context" to all native functions and contains the script interpreter. Also keeps track of the script call call stack and locals stack.

enum State ;
An enumeration of all the valid states a thread can be in, for coroutine support.

Initial
Means the coroutine has been instantiated, but not yet called with the initial parameters. When called, the context parameter that is passed will be saved, and the coroutine's function will begin execution.

Waiting
Means that the coroutine resumed another coroutine and is waiting for it to yield or return.

Running
Means that the coroutine is currently executing. You can only get this state if a coroutine queries its own state.

Suspended
Means that the coroutine executed a yield expression, and is waiting to be resumed.

Dead
Means that the coroutine was exited, either by returning or by having an exception propagate out of the coroutine. The coroutine can be reset to the initial state and restarted.

this(MDContext context);
this(MDContext context, MDClosure coroFunc);
Construct a new thread. A default thread of execution, the 'main thread', is created for you by MDContext, so you'll really only need this for creating coroutines.

If you pass a script function closure to this constructor, this thread will be a coroutine. It can then be subsequently resumed by calling it with another MDState (just like how you call threads to resume them in MiniD).

Attempting to pass a native function closure will throw an exception.

Passing null as the closure (the default) will simply create a new state with no special properties. Not all that useful.

uint length ();
You can't get the length of a state. Throws an exception.

char[] toUtf8 ();
Returns a string representation of the thread, in the form "thread 0x00000000", where the number is the hexadecimal representation of the 'this' pointer.

final State state ();
Gets the current coroutine state of the state as a member of the State enumeration.

final MDString stateString ();
Gets a string representation of the current state of the coroutine.

final uint pushNull ();
Push a null value onto the value stack.

Returns:
The stack index of the just-pushed value.

uint push (T)(T value);
Push a value onto the value stack. This is a templated method which can accept any type which can be converted to a MiniD type.

Params:
value The value to push .

Returns:
The stack index of the just-pushed value.

T pop (T = MDValue)();
Pop a value off the value stack. This is templated so that you can pop any type that can be converted from a MiniD type, but it defaults to MDValue.

uint easyCall (F,T...)(F func, int numReturns, MDValue context, T params);
Call any callable MiniD type with a simple interface. There are multiple callable types in MiniD. Functions are the most obvious. You can also call threads, which will resume them. You can call classes to create instances of them. And you can call any object which has an opCall metamethod.

Once the call completes, you must pop any return values off the stack.

Params:
func Any callable type. This is templated to allow any type.
numReturns How many return values you want from this function call. If >= 0, will leave exactly that many values on the value stack which you can then pop. If this is -1, indicates that you want as many return values that the call gives back, in which case you can get how many it returned by getting the return value of this method.
context All calls require a context which will be passed as the 'this' parameter to the function. Only significant for functions. Classes, threads, and objects with opCall will overwrite the context with their own value, so it's alright to pass null as the context for those.
params A variadic list of parameters to be passed to the function. All values must be convertible to MiniD types.

Returns:
The number of return values from this call. If the numReturns parameter was >= 0, this is the same as that parameter, and isn't particularly useful. But if the numReturns parameter was -1, this is very useful, as it indicates how many values the call gave back.

uint callMethod (T...)(ref MDValue val, dchar[] methodName, int numReturns, T params);
uint callMethod '); (T...)(ref MDValue val, MDString methodName, int numReturns, T params);
Very similar to the easyCall method, this will call a method of any object.

Params:
val The object whose method you would like to call.
methodName The name of the method to call.
numReturns See easyCall for a description of this parameter.
params See easyCall for a description of this parameter.

Returns:
See easyCall for a description of the return value.

final uint call (uint slot, int numParams, int numReturns);
Perform a slightly lower-level call to any callable type.

This interface makes slightly less code bloat than the easyCall, as it doesn't require the use of a variadic templated function. The protocol for calling something is as follows:

	// 1. Push the object you're calling onto the stack, and save its stack index.
	auto funcIdx = s.push(something);

	// 2. Push the context.  You must always have a context.
	s.push(someContext);

	// 3. Push any parameters.
	s.push(param1);
	s.push(param2);

	// 4. Make the call.
	s.call(funcIdx, 3, 1);

	// 5. Pop any return values.
	auto ret = s.pop!(int);


Params:
uint slot The stack slot of the object to call . Usually you get this from a push.
int numParams How many parameters, including the context, you are passing to the function. Since you always need context, this must always be at least 1.
int numReturns See easyCall for an explanation of this parameter.

Returns:
See easyCall for an explanation of this return value.

void setUpvalue (T)(uint index, T value);
This is to be used from native closures which were created with a list of upvalues. Sets the value of the upvalue at the given integer index (upvalues are like an array).

Params:
index The index of the upvalue to set.
value The value, which must have a type convertible to a MiniD type, to be set to the upvalue.

T getUpvalue (T = MDValue*)(uint index);
The opposite of setUpvalue. This is templated to return any type, and by default will return an MDValue*. You can then modify the contents of this return value and the changes will be reflected in the internal upvalue array.

Params:
index The index of the upvalue to get.

Returns:
The value of the upvalue, templated to return whatever you'd like it to. Defaults to MDValue*.

bool isParam (char[] type)(uint index);
A quirky function which lets you check if the parameter at the given index is of a certain type. This is a templated method which takes a string that indicates the type you'd like to check for. Possible values are "null", "bool", "int", "float", "char", "string", "table", "array", "function", "class", "instance", "namespace", and "thread". Any other value will give a compile-time error.

Params:
index The 0-based index of the parameter whose type you'd like to check. Throws an error if this index is invalid.

Returns:
True if the parameter is of the given type; false otherwise.

T getParam (T = MDValue)(uint index);
Gets the value of a parameter off the stack.

Params:
index The index of the parameter to get. Throws an error if this index is invalid.

Returns:
The value of the parameter, templated to whatever type you'd like. Throws an error if it can't be converted to your desired type. Defaults to MDValue.

T getContext (T = MDValue)();
Gets the context (what would be the 'this' pointer in MiniD code) with which the function was called. The context, being special, is not included with the rest of the parameters.

Returns:
The context, whose type is templated to whatever you'd like.

final MDValue [] getParams (int lo, int hi);
Gets a slice of the parameters as an array. Throws an error if the slice boundaries are invalid.

Params:
int lo The low index of the slice. Can be negative, which means "from the end," i.e. -1 would mean "begin at the very last parameter." Inclusive.
int hi The high index of the slice. Can be negative, which means "from the end," i.e. -1 would mean "end after the very last parameter". Noninclusive.

Returns:
An array containing the parameter values. Because of the way the stack works, this is not (and cannot be) a slice into the internal stack, but is instead a copy.

final MDValue [] getAllParams ();
Gets all the parameters passed to the function as an array. Equivalent to calling getParams(0, -1).

Returns:
An array of all the parameters. It's a copy of the internal stack.

T safeCode (T)(lazy T code);
An odd sort of protective function. You can use this function to wrap a call to a library function etc. which could throw an exception, but when you don't want to have to bother with catching the exception yourself. Useful for writing native MiniD libraries.

Say you had a function which opened a file:

	File f = OpenFile("filename");
Say this function could throw an exception if it failed. Since the interpreter can only catch (and make meaningful stack traces about) exceptions which derive from MDException, any exceptions that this throws would just percolate up out of the interpreter stack. You could catch the exception yourself, but that's kind of tedious, especially when you call a lot of native functions.

Instead, you can wrap the call to this unsafe function with a call to safeCode ().

	File f = s.safeCode(OpenFile("filename"));
What safeCode () does is it tries to execute the code it is passed. If it succeeds, it simply returns any value that the code returns. If it throws an exception derived from MDException, it rethrows the exception. And if it throws an exception that derives from Exception, it throws a new MDException with the original exception's message as the message.

safeCode () is templated to allow any return value.

Params:
code The code to be executed. This is a lazy parameter, so it's not actually executed until inside the call to safeCode .

Returns:
Whatever the code parameter returns.

final void throwRuntimeException (MDValue * val);
final void throwRuntimeException (char[] fmt,...);
Throws a new runtime exception, starting the debug traceback with the current debug location.

final MDNamespace environment (int depth = 0);
Gets the environment of a closure on the call stack.

Params:
int depth The depth into the call stack of the closure whose environment to get. Defaults to 0, which means the currently-executing closure. A depth of 1 would mean the closure which called this closure, 2 the closure that called that one etc.

Returns:
The closure's environment .

final uint callDepth ();
Gets the current call depth, that is, how many functions are currently on the call stack which have yet to return.

final MDString valueToString (ref MDValue value);
Get a string representation of any MiniD value. This is different from MDValue.toUtf8() in that it will call any toString metamethods defined for the object.

Params:

Returns:
The string representation of the value.

final bool opin (ref MDValue a, ref MDValue b);
Determines if the value a is in the container b. Returns true if so, false if not.

final int cmp (ref MDValue a, ref MDValue b);
Compares the two values, calling any opCmp metamethods, and returns the result.

final MDValue idx (ref MDValue src, ref MDValue index);
Indexes src with index, and gives the result. Like writing src[index] in MiniD. Calls metamethods.

final void idxa (ref MDValue dest, ref MDValue index, ref MDValue src);
Index-assigns src into the index slot of dest. Like writing dest[index] = src in MiniD. Calls metamethods.

final MDValue len (ref MDValue val);
Gets the length of val. Like #val in MiniD. Calls metamethods.

final MDValue slice (ref MDValue src, ref MDValue lo, ref MDValue hi);
Slice src from lo to hi. Like src[lo .. hi] in MiniD. Calls metamethods.

final void slicea (ref MDValue dest, ref MDValue lo, ref MDValue hi, ref MDValue src);
Assign a slice src to dest from lo to hi. Like dest[lo .. hi] = src in MiniD. Calls metamethods.

final MDValue add (ref MDValue a, ref MDValue b);
final MDValue sub (ref MDValue a, ref MDValue b);
final MDValue mul (ref MDValue a, ref MDValue b);
final MDValue div (ref MDValue a, ref MDValue b);
final MDValue mod (ref MDValue a, ref MDValue b);
Performs an arithmetic operation on the two values and returns the result. Calls metamethods.

final MDValue neg (ref MDValue a);
Negates the argument. Calls metamethods.

final void addeq (ref MDValue a, ref MDValue b);
final void subeq (ref MDValue a, ref MDValue b);
final void muleq (ref MDValue a, ref MDValue b);
final void diveq (ref MDValue a, ref MDValue b);
final void modeq (ref MDValue a, ref MDValue b);
Performs a reflexive arithmetic operation on a, with b as the right hand side. Calls metamethods.

final MDValue and (ref MDValue a, ref MDValue b);
final MDValue or (ref MDValue a, ref MDValue b);
final MDValue xor (ref MDValue a, ref MDValue b);
final MDValue shl (ref MDValue a, ref MDValue b);
final MDValue shr (ref MDValue a, ref MDValue b);
final MDValue ushr (ref MDValue a, ref MDValue b);
Performs a binary operation on the two values and returns the result. Calls metamethods.

final MDValue com (ref MDValue a);
Performs a bitwise complement of the argument. Calls metamethods.

final void andeq (ref MDValue a, ref MDValue b);
final void oreq (ref MDValue a, ref MDValue b);
final void xoreq (ref MDValue a, ref MDValue b);
final void shleq (ref MDValue a, ref MDValue b);
final void shreq (ref MDValue a, ref MDValue b);
final void ushreq (ref MDValue a, ref MDValue b);
Performs a reflexive bitwise operation on a, with b as the right hand side. Calls metamethods.

final MDValue cat (MDValue [] vals);
Concatenates the list of values (which must be at least two items long) into a single value and returns it. Calls metamethods.

final void cateq (ref MDValue dest, MDValue [] vals);
Appends the list of values (which must have at least one item) to the end of the value held in dest. Calls metamethods.

final uint yield (uint numReturns, MDValue [] values...);
Yields from a native function acting as a coroutine, just like using the yield () expression in MiniD.

Params:
uint numReturns How many returns you'd like to get from the yield operation. -1 means as many values as are passed to this coroutine when it's resumed, in which case the return value of this method becomes significant.
MDValue [] values A list of values to yield .

Returns:
The number of return values to be popped off the stack. If numReturns was -1, this is how many values you must pop. If numReturns was >= 0, it's the same as numReturns.

final void reset ();
Resets this coroutine. Only works if this coroutine is in the Dead state.

final MDContext context ();
Gets the context which owns this thread.

Page was generated with on Sun Nov 18 11:04:09 2007