                       The Voodoo Compiler


Introduction
============

The Voodoo compiler is a compiler for the Voodoo programming language.
Voodoo is a programming language designed to be a thin abstraction
layer over CPUs' native instruction sets and operating systems'
calling conventions.  Operations provided by Voodoo closely correspond
to those of common CPU instruction sets, allowing programs to be
expressed with a minimum of overhead.  At the same time, Voodoo is not
tied to a specific instruction set, and support for new CPUs and
operating systems can easily be added.  The Voodoo programming
language is described in more detail in doc/language.html.


Building and Installation
=========================

Short summary:

  $ ./configure
  $ make
  $ make install

The Voodoo compiler can be built by issuing the commands
"./configure" followed by "make" from the top-level directory.

It is possible to specify a location to install to using the --prefix
parameter to configure. By default, the Voodoo compiler is installed to
/usr/local. To install to /usr instead, use

  $ ./configure --prefix /usr

The Voodoo compiler can be installed using "make install" from the
top-level directory.

As an alternative to running "make install", when RubyGems is installed,
a gem can be created by running "make gem", and installed using
"gem install voodoo*.gem".


Usage
=====

There are two ways to use the Voodoo compiler: as a run-time code
generator, or using the stand-alone compiler.

Run-Time Code Generation
------------------------

To use the Voodoo compiler as a run-time code generator, require
'voodoo/code_generator' and instantiate a code generator using
Voodoo::CodeGenerator.get_generator, passing :architecture and
:format parameters. E.g.

  require 'voodoo/code_generator'

  generator = Voodoo::CodeGenerator.get_generator :architecture => :i386,
                                                  :format => :elf

The :architecture and :format parameters can be omitted if the defaults
determined by ./configure are acceptable. Typically, the default is
to create an object file for architecture that the compiler is being
run on.

Code and data can be sent to the generator using the methods add, and
add_function.  The following is an example of the generation of a
simple program:

  generator.add :data, [:label, :msg], [:string, "Hello, world!\x00"]

  generator.add :functions, [:import, :puts], [:export, :main], [:label, :main]
  generator.add_function [:argc, :argv],
                         [:call, :puts, :msg],
			 [:return, 0]

Finally, output from the generator can be written to a file using the
write method. For example:

  File.open('example.o', 'w') do |file|
    generator.write file
  end

Using voodooc
-------------

The program voodooc is a compiler that can be used to compile source
code written in Voodoo to object files or assembly code. The compiler
requires the name of the source file to be compiled as an argument.
Additionally, the output file name can be specified using the "-o"
option, and the output format and architecture may be specified using
the "-f" and "-a" options. Some examples:

  $ voodooc -o example.o example.voo

  $ voodooc -f nasm -o example.asm example.voo

  $ voodooc --architecture i386 -f elf -o example.o example.voo

Specifying "-" as the input file name causes voodooc to read
Voodoo code to be compiled from standard input.

Creating Executables
--------------------

The Voodoo compiler produces object files (or assembly code that can
be turned into object files). To create executable programs from
object files, the object files must be linked. The linking steps
to be performed depend on the operating system and the libraries
to be linked with.

The following example uses the C compiler to link an object file
example.o with the C library to produce an executable named example:

  $ cc example.o -o example

This is not the only way to get a working executable.  Voodoo programs
can use other libraries than the C library, or even no library at
all. Linking with the C library is just used as a convenient way to
get a working puts function.
