We shall call this Greetings.kt. Now, where should this be placed? We know that greetings fall under
common sayings, so let's place this in the CommonSayings folder. Now, the package can be referenced
by using import CommonSayings.Greetings in any Kite application. Let's try it:

Caution:import will only load a class once during runtime. If you need to reload
the package for any reason, you'll currently need to restart Kite. (This is on the TODO for future
releases.)

4.2 Compiled Extensions

Compiled extensions are the second route to extending Kite. There are two routes to doing this:
native extensions and using the interface.language.c class.

4.2.1 Native Kite extensions

Native Kite extensions allow a user to write a Kite module in the C programming language
(or any language that can export a C interface). This is useful for those that require
extra speed, or to add support for libraries and modules that were originally written in
C or other programming languages.

4.2.1.1 A Simple Example: Greeting in C

Here is a simple example of a Kite module in C. We want to have a method called "write" that
outputs a greeting to the user on standard output. Let's create a file called "greeting.c" with
the following lines:

#include <stdio.h>
#include <stdlib.h>
#include <kite_object.h>

kite_object.h is mandatory in order to use Kite language features. Now, we need to write the
method. We'll call it Greeting_write, although it can be called anything:

KITE_NO_ARGS and KITE_THIS_NOT_USED are helper macros designed to remove
spurious compile warnings. kite_vm_return is how we return values to the user;
all code generally returns some value, even if it's simply null. As you can see, this method
simply writes a message to standard output.

Now we need to let Kite know of this method and the object. We'll set up an initializer
function, as shown here:

The code above creates a new class that inherits System.object and contains one
method called "write" that takes no arguments. It then adds the class to the parent class,
which in this case, is the root class.

Now that we've written our object, we need to compile it. On Linux, we can do the following:

gcc -shared -I/usr/local/include -fPIC -g -o greeting.so greeting.c

and write some Kite code to test:

import "greeting";
greeting|write;

Now, when we run Kite on the test code, we'll get:

$ kite test.kt
Hello, world!
$

4.2.1.2 For Further Information

If you have Doxygen, you can generate documentation
for all of the Kite internals by running doxygen Doxyfile from the top of the distribution.
It should place HTML and LaTeX files in docs/html and docs/latex, respectively. A
version of the Doxygen documentation can also be found here.

4.2.2 Using interface.language.c

Please note: This method only works on platforms supported by C/Invoke.
At this writing (July 2008), the supported platforms are Windows (32-bit Intel), OS X (PPC and Intel)
and Linux/*BSD (32 and 64-bit Intel).

interface.language.c is a module that allows one to interface with compiled modules on his
or her system. No experience with C/C++ or Kite internals is necessary.

Structures and callback functions are also supported. Here is a longer example that implements both.
First, we'll create a quick and simple dynamic library called libtest. Here are the contents of libtest.c:

More information on interface.language.c can be found in the
kdoc documentation for the current version.

4.3 Embedding Kite In An Application

Kite can also be embedded into a compiled application. As with creating a compiled module, you'll
first need to include kite_object.h:

#include <kite_object.h>

In order to access Kite, you'll need to create a new virtual machine. Virtual machines are the
fundamental unit that represents a single instance of the Kite interpreter. These can be created
using the kite_new_vm function. Let's do that now inside of our main():

Also note that you'll need to call kite_app_init() before using any Kite functions.
This is necessary to initialize the garbage collector, for those versions of Kite compiled
with Boehm GC support.

kite_new_vm requires a single argument, a pointer to an array of strings. This represents
the command-line arguments passed into Kite at the command prompt; passing argv should work fine.
You'll also notice that we delete the virtual machine after we've finished using it by using
the kite_free_vm function. This function sets the VM object to NULL on completion.

At this point, we have a virtual machine object, but it's not currently doing any useful work.
We'd like it to run some code for us. To do that, we'll need to compile some code:

kite_vm_creator_thread above returns the very first thread created by the virtual machine.
This will usually be the thread that initially runs any code you write. kite_vm_compile_from_string
is one of the functions that can be used to compile code. This compiles a snippet of code into a Kite
object and returns the object. Errors start from line 1. Other compile methods exist as well, including
ones that compile from a file.

To ensure there are no errors, we check for the existence of an exception object in thd->exception.
If this property is NULL, code we've run did not throw an exception. Also, most functions will return
FALSE or NULL on error.

Since we now have a compiled form of the Kite code we've entered above, we can run it. To do that, we can
call kite_start_bytecode:

kite_start_bytecode(thd, obj);
if (thd->exception) ...

The return value from executed Kite code, if any, is on the top of the running stack. This can be retrieved
by using kite_vm_pop(), but we'll ignore it for our example. To make sure everything's cleaned up,
we should wait for our thread to terminate:

kite_dereference_object(obj);
kite_join_thread(vm, thd);

kite_dereference_object() is an important function when it comes to Kite memory management. It decrements
the reference count of a given object, and when the reference count reaches zero, it is scheduled for
deletion. The destructor is generally called when this occurs. If you need to pass references to Kite objects
around, you should always increment the reference count by using the analogous kite_reference_object()
function.