Skip to content
tomahawkins edited this page Apr 6, 2011 · 12 revisions

ImProve programs simply read and write variables -- ImProve has no other notion of IO. As such, a classic "Hello World!" example is not possible. Instead we will present a trivial program than adds two numbers together and then show how to generate C code and integrate it with a larger C program.

To start, create a new Haskell file (Adder.hs) and import the the ImProve language:

module Main (main) where

import Language.ImProve

Next declare the variables used for the IO:

-- The 'input' function declares a new primary input variable.
a :: E Float
a = input float ["a"] 

b :: E Float
b = input float ["b"]

-- The 'global' function declares a new global variable, which can
-- either be for internal state or as a primary output.
x :: V Float
x = global float ["x"] 0 

Now create an ImProve program than assigns x = a + b:

adder :: Stmt ()
adder = do
  x <== a + b

Lastly, call the code function to generate C code:

main :: IO ()
main = code C "adder" adder

To compile, run the Haskell program (Adder.hs):

$ runhaskell Adder.hs

This results in two files: adder.h and adder.c. First adder.h:

/* Generated by ImProve. */

#ifdef __cplusplus
extern "C" {
#endif

extern struct {  /* adder_variables */
	float a                        ;  /* input */
	float b                        ;  /* input */
	float x                        ;
} adder_variables;

void adder(void);

#ifdef __cplusplus
}
#endif

And adder.c:

/* Generated by ImProve. */

#include <assert.h>

struct {  /* adder_variables */
	float a                        ;  /* input */
	float b                        ;  /* input */
	float x                        ;
} adder_variables =
    {   0.0              /* a */
	,   0.0              /* b */
	,   0.0              /* x */
	}  /* adder_variables */
;

void adder()
{
	adder_variables.x = (adder_variables.a + adder_variables.b);
}

ImProve generates a hierarchical structure (adder_variables) to hold the variables declared by the ImProve program, and a function (adder) that implements the ImProve program.

Integrating ImProve generated C into a larger program simply involves assigning values to the input variables in the variable structure, calling the generated function, then reading any necessary output variables, again from the variable structure. For example:

#include <stdio.h>

// Include the ImProve generated header.
#include "adder.h"

int main ()
{
        // Assign the ImProve function inputs.
        adder_variables.a = 1.0;
        adder_variables.b = 2.0;

        // Call the ImProve generated function.
        adder();

        // Read the ImProve function outputs.
        printf("%f\n", adder_variables.x);

        return 0;
}
Clone this wiki locally