Base Library
The base library is a set of functions dealing with some language aspects which aren't covered by the syntax of the language, as well as miscellaneous functions that don't really fit anywhere else. The base library is always loaded when you create an instance of the MiniD VM.
There are also three sub-libraries which are always loaded, just like the base library. They are the Modules library, the Thread library, and the GC library.
Table of Contents
- Functional Things
- Reflection Functions
- findGlobal(name: string)
- isSet(name: string)
- typeof(value)
- nameOf(value: class|function|namespace)
- fieldsOf(value: class|instance)
- allFieldsOf(value: class|instance)
- hasField(value, name: string)
- hasMethod(value, name: string)
- findField(o: class|instance, name: string)
- rawSetField(o: instance, name: string, value)
- rawGetField(o: instance, name: string)
- getFuncEnv(f: function)
- setFuncEnv(f: function, env: namespace)
- isXxx(o)
- attrs(o: function|class|namespace, t: table)
- hasAttributes(value)
- attributesOf(value)
- Conversions
- Console IO
- Dynamic Compilation
- Function metamethods
- Weak References
- Classes
Functional Things
curry(func: function, param)
This function takes a function and a parameter, and returns a new function which takes one less parameter. The new function, when called, will call the old function with the given parameter as its first parameter, and will pass along any other parameters. Example:
function foo(x, y) { writefln("foo: ", x, ", ", y); } foo(4, 5); // prints "foo: 4, 5" local func = curry(foo, 8); func(9); // prints "foo: 8, 9"
The curried function will also pass along the 'this' parameter to the old function.
bindContext(func: function, context)
This is similar to curry, but instead of returning a function which takes one less parameter, it returns a function which will always use the same context ('this' parameter), regardless of how it's called. This allows you to create D-style "delegates", that is, a closure which has an associated object.
Here's an example:
class Listener { this(num) :num = num function receive() writefln("Listener {} got a message!", :num) function callable() = bindContext(:receive, this) // creates a function which, when called, calls this.receive } class Emitter { this() :listeners = {} function opCatAssign(o: function) :listeners[o] = true function opCall() foreach(l, _; :listeners) l() } local e = Emitter() e ~= Listener(1).callable() e ~= Listener(2).callable() e ~= Listener(3).callable() e ~= function() writeln("I'm just a normal function.") e() // prints each listener getting a message
You might imagine bindContext being used in a GUI environment, where you need a callback that is the member function of a class instance.
Reflection Functions
findGlobal(name: string)
Looks for the global with the given name. If found, returns the namespace that contains it; otherwise, returns null.
isSet(name: string)
Similar to findGlobal, except returns a boolean value: true if the global exists, false otherwise.
typeof(value)
This will get the type of the passed-in value and return it as a string. Possible return values are "null", "bool", "int", "float", "char", "string", "table", "array", "function", "class", "instance", "namespace", "thread", "nativeobj", and "weakref".
nameOf(value: class|function|namespace)
Returns the name of the given value as a string. This is the name that the class, function, or namespace was declared with, or an autogenerated one if it wasn't declared with a name.
fieldsOf(value: class|instance)
Returns a namespace that holds the fields of the given class or instance. Each class or instance has its own unique field namespace. Note, however, that since the fields are lazily created (i.e. a class or instance will not have a field unless it has been assigned into it), you won't necessarily get all the fields that can be accessed from the class or instance, only those which have been set in it. If you want to get all the fields, use the allFieldsOf iterator function.
allFieldsOf(value: class|instance)
Returns an iterator function that will iterate through all fields accessible from the given class or instance, traversing the base class links up to the root. This iterator actually gives up to three indices: the first is the name of the field, the second its value, and the third the class or instance that owns it. Example use:
class A { x = 5 function foo() {} } class B : A { x = 10 } foreach(k, v; allFieldsOf(A)) writefln("{}: {}", k, v) // prints "x: 5" and "foo: script function foo" writeln() foreach(k, v, o; allFieldsOf(B)) writefln("{}: {} (owned by {})", k, v, o); // this time prints 10 for x, and the owner is B; foo's owner is A
Note in the second example that both B and its base class A have a field 'x', but only the 'x' accessible from B with value 10 is printed.
hasField(value, name: string)
Sees if value contains the field name. Works for tables, namespaces, classes, and instances. For any other type, always returns false.
hasMethod(value, name: string)
Sees if the method named name can be called on value. Looks in metatables as well, for i.e. strings and arrays. Works for all types.
findField(o: class|instance, name: string)
Searches the given class or instance's inheritance chain for the class or instance that holds the field with the given name. Returns the holding object, or null if the given field name was not found.
rawSetField(o: instance, name: string, value)
Sets a field into an instance bypassing any opFieldAssign metamethods.
rawGetField(o: instance, name: string)
Gets a field from an instance bypassing any opField metamethods.
getFuncEnv(f: function)
Returns the environment namespace associated with the given function.
setFuncEnv(f: function, env: namespace)
Sets the given function's environment namespace to env. Returns the function's old environment namespace.
isXxx(o)
This isn't a single function, but a whole family of functions:
- isNull
- isBool
- isInt
- isFloat
- isChar
- isString
- isTable
- isArray
- isFunction
- isClass
- isInstance
- isNamespace
- isThread
- isNativeObj
- isWeakRef
All these functions return true if the passed-in value is of the given type, and false otherwise. The fastest way to test if something is null, however, is to use "x is null".
attrs(o: function|class|namespace, t: table)
This is a decorator function which is used to set attributes on an object when declaring it. Classes, namespaces, and functions may have an attribute table associated with them which is entirely for custom use. You use this decorator function like so:
@attrs({ x = 5 doc = "This is some documentation!" }) function foo() = 12
You can check if an object has attributes and retrieve them using the following functions.
hasAttributes(value)
Returns whether or not the given value has an attributes table. Works for all types, but only functions, namespaces, and classes can have attributes.
attributesOf(value)
Returns the attributes table of value, or null if it has none.
Conversions
toString(value, style: char = 'd')
This is like rawToString, but it will call any toString metamethods defined for the value. Arrays have a toString metamethod defined for them if the array stdlib is loaded, and any toString methods defined in tables and instances will be used.
The optional style parameter only has meaning if the value is an integer. It can be one of the following:
- 'd': Default: signed base 10.
- 'b': Binary.
- 'o': Octal.
- 'x': Lowercase hexadecimal.
- 'X': Uppercase hexadecimal.
- 'u': Unsigned base 10.
rawToString(value)
This returns a string representation of the given value depending on its type, as follows:
- null: the string "null".
- bool: "true" or "false".
- int: The decimal representation of the number.
- float: The decimal representation of the number, to about 7 digits of precision.
- char: A string with just one character, the character that was passed in.
- string: The string itself.
- table: A string in the format "table 0x00000000" where 0x00000000 is the address of the table.
- array: A string in the format "array 0x00000000" where 0x00000000 is the address of the array.
- function: If the function is native code, a string formatted as "native function <name>"; if script code, a string formatted as "script function <name>(<location>)".
- class: A string formatted as "class <name> (0x00000000)", where 0x00000000 is the address of the class.
- instance: A string formatted as "instance of class <name> (0x00000000)"`, where 0x00000000 is the address of the instance.
- namespace: A string formatted as "namespace <names>", where <name> is the hierarchical name of the namespace.
- thread: A string formatted as "thread 0x00000000", where 0x00000000 is the address of the thread.
- nativeobj: A string formatted as "nativeobj 0x00000000", where 0x00000000 is the address of the native object that it references.
- weakref: A string formatted as "weakref 0x00000000", where 0x00000000 is the address of the weak reference object.
toBool(value)
This returns the truth value of the given value. null, false, integer 0, and float 0.0 will all return false; all other values and types will return true.
toInt(value: bool|int|float|char|string)
This will convert a value into an integer. Only the following types can be converted:
- bool: Converts true to 1 and false to 0.
- int: Just returns the value.
- float: Truncates the fraction and returns the integer portion.
- char: Returns the UTF-32 character code of the character.
- string: Attempts to convert the string to an integer, and assumes it's in base 10. Throws an error if it fails. If you want to convert a string to an integer with a base other than 10, use the string object's toInt method.
toFloat(value: bool|int|float|char|string)
This will convert a value into a float. Only the following types can be converted:
- bool: Converts true to 1.0 and false to 0.0.
- int: Returns the value cast to a float.
- float: Just returns the value.
- char: Returns a float holding the UTF-32 character code of the character.
- string: Attempts to convert the string to a float. Throws an error if it fails.
Other types will throw an error.
toChar(value: int)
This will convert an integer value to a single character. Only integer parameters are allowed.
format(fmt: string, vararg)
Functions much like Tango's tango.text.convert.Layout class. fmt is a formatting string, in which may be embedded formatting specifiers, which use the same '{}' syntax as found in Tango, .Net, and ICU.
By default, when you format an item, it will call any toString metamethod defined for it. If you want to use the "raw" formatting for a parameter instead, write a lowercase 'r' immediately after the opening brace of a format specifier. So something like "format("{r}", [1, 2, 3])" will call rawToString on the array parameter, resulting in something like "array 0x00000000" instead of a string representation of the contents of the array.
Just about everything else works exactly as it does in Tango. You can use any field width and formatting characters that Tango allows.
MiniD's writef and writefln functions (as well as their analogues in the IO library) use the same internal formatting as this function, so any rules that apply here apply for those functions as well.
Console IO
write(vararg)
Prints out all its arguments to the console without any formatting (i.e. strings will not be searched for formatting specifiers). It would be the same as using "{}" for all arguments to writef.
writeln(vararg)
Same as write, but prints a newline after the text has been output.
writef(vararg)
Formats the arguments into a string using the same formatting rules as format, then outputs the resulting string to the console. No newline is printed.
writefln(vararg)
Just like writef, but prints a newline after the text has been output.
dumpVal(value, printNewline: bool = true)
Dumps an exhaustive string representation of the given value to the console. This will recurse (safely, you don't need to worry about infinite recursion) into arrays and tables, as well as escape non-printing characters in strings and character values. It will also print out the names of the fields in namespaces, though it won't recurse into them. If a table has a toString metamethod, it will be called instead of recursing into the table. All other values will basically have toString called on them.
If the printNewline parameter is passed false, no newline will be printed after the dumped representation. Defaults to true.
readln()
Reads one line of input (up to a linefeed) from the console and returns it as a string, without any trailing linefeed characters.
Dynamic Compilation
If you want to compile an entire module, have a look at `modules.compile`.
loadString(code: string [, name: string][, environment: namespace])
Compiles the given string containing MiniD source code into a function and returns that function. The code string is treated like the body of a function that takes variadic arguments, so the vararg expression is legal within the code string.
You can optionally pass a name for the function. If no name is passed, a default name is given to the function.
Because of the way MiniD is implemented, the dynamically-compiled function cannot access any locals or upvalues from the context in which it is loaded. It can, however, access globals in the environment in which it is created. If the environment parameter is given, it will use that environment; otherwise, it will use the environment of the calling function.
eval(code: string [, environment: namespace])
Compiles and evaluates an expression, returning its result. Note that just like loadString, eval can only access globals in its environment, and not locals or upvalues.
The optional environment parameter works just like loadString. If it is not given, it defaults to the environment of the calling function.
loadJSON(data: string)
JSON is a standard for structured data interchange based on the JavaScript object notation. This function will take a string containing JSON formatted data, parse it directly into a value, and return the top-level table or array. This is a safe parser: it only accepts strictly conforming JSON data, so you don't have to worry about malicious code being embedded in the data being compiled or executed. It's also a strictly-conforming parser, and will not accept for instance objects with unquoted names.
toJSON(value: table|array, pretty: bool = false)
The opposite of loadJSON, this function will convert either a MiniD table or array into a JSON string which adheres to the specification. The value you pass must be either a table or array, and the only values they can contain are null, bool, int, float, char (these are converted into single-character strings in the output), string, table, and array. Any cycles in the data are detected and are an error. The return value is a string containing the formatted JSON data. If the pretty parameter is false (the default), the string will have as little whitespace as possible while still adhering to the spec; this makes the data slightly smaller for transmission. If pretty is true, it will insert line breaks and tabs as necessary to make it look a little more human-readable.
Function metamethods
Metamethods for function objects. These are accessed as methods of functions.
isNative()
Returns a bool telling if the function is implemented in native code or in MiniD.
numParams()
Returns an integer telling how many non-variadic parameters the function takes. For native functions, always returns 0.
isVararg()
Returns a bool telling whether or not the function takes variadic parameters. For native functions, always returns true.
Weak References
weakref(o)
This function is used to create weak reference objects. If the given object is a value type (null, bool, int, float, or char), it simply returns them as-is. Otherwise returns a weak reference object that refers to the object. For each object, there will be exactly one weak reference object that refers to it. This means that if two objects are identical, their weak references will be identical and vice versa.
deref(o: null|bool|int|float|char|weakref)
The parameter types for this might look a bit odd, but it's because this function acts as the inverse of weakref(). If you pass a value type into the function, it will return it as-is. Otherwise, it will dereference the weak reference and return that object. If the object that the weak reference referred to has been collected, it will return null.
Classes
class Object
The root of the class hierarchy, Object, is declared here. It has no methods defined right now. It is the only class in MiniD which has no base class (that is, "Object.super" returns null).
class Vector
A typed, fast array of native numeric values. Go to this class's documentation
class StringBuffer : Vector
A mutable string type, derived from Vector. Go to this class's documentation
