Index: rcb-example/Makefile
===================================================================
--- rcb-example/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ rcb-example/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,24 @@
+CC=../../bin/cfa
+CFLAGS=-g
+
+%.i: %.c
+	-$(CC) $(CFLAGS) -CFA $< > $@
+
+%.o: %.i
+	$(CC) $(CFLAGS) -c -o $@ $<
+
+all: vector_test
+
+vector_test: vector_test.o vector_int.o fstream.o iostream.o array.o iterator.o
+fstream_test: fstream_test.o fstream.o iostream.o
+
+array.o: array.i array.h iterator.h
+iterator.o: iterator.i iterator.h iostream.h
+vector_test.o: vector_test.i vector_int.h iostream.h fstream.h
+vector_int.o: vector_int.i vector_int.h
+fstream_test.o: fstream_test.i iostream.h fstream.h
+fstream.o: fstream.i iostream.h fstream.h
+iostream.o: iostream.i iostream.h
+
+clean:
+	rm -f fstream_test vector_test *.i *.o
Index: rcb-example/array.c
===================================================================
--- rcb-example/array.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ rcb-example/array.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,28 @@
+// "cfa -c -o array.o array.c"
+// "cfa -CFA array.c > array_out.c"
+// "gcc32 array_out.c ../LibCfa/libcfa.a"
+
+#include "array.h"
+
+/// forall( type array_type, elt_type | bounded_array( array_type, elt_type ) )
+/// [ array_iterator begin, array_iterator end ]
+/// get_iterators( array_type array )
+/// {
+///   begin = 0;
+///   end = array_last( array );
+/// }
+
+forall( type array_type, type elt_type | bounded_array( array_type, elt_type ) )
+elt_type *
+get_begin( array_type array )
+{
+  return &array[ 0 ];
+}
+
+forall( type array_type, type elt_type | bounded_array( array_type, elt_type ) )
+elt_type *
+get_end( array_type array )
+{
+  return &array[ array_last( array ) ] + 1;
+}
+
Index: rcb-example/array.h
===================================================================
--- rcb-example/array.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ rcb-example/array.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,26 @@
+#ifndef ARRAY_H
+#define ARRAY_H
+
+#include "iterator.h"
+
+context array( type array_type, type elt_type )
+{
+  lvalue elt_type ?[?]( array_type, int );
+};
+
+context bounded_array( type array_type, type elt_type | array( array_type, elt_type ) )
+{
+  int array_last( array_type );
+};
+
+// implement iterator_for
+
+typedef int array_iterator;
+/// forall( type array_type, elt_type | bounded_array( array_type, elt_type ) )
+/// [ array_iterator begin, array_iterator end ] get_iterators( array_type );
+forall( type array_type, type elt_type | bounded_array( array_type, elt_type ) )
+elt_type *get_begin( array_type );
+forall( type array_type, type elt_type | bounded_array( array_type, elt_type ) )
+elt_type *get_end( array_type );
+
+#endif /* #ifndef ARRAY_H */
Index: rcb-example/fstream.c
===================================================================
--- rcb-example/fstream.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ rcb-example/fstream.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,137 @@
+// "cfa -E fstream.c > fstream_out.c"
+// "cfa -c -o fstream.o fstream.c"
+#include "fstream.h"
+
+#undef __cplusplus
+extern "C" {
+#include <stdio.h>
+#include <stdlib.h>
+}
+
+struct ofstream
+{
+  FILE *file;
+  int fail;
+};
+
+ofstream *
+write( ofstream *os, const char *data, streamsize_type size )
+{
+  if( !os->fail ) {
+    fwrite( data, size, 1, os->file );
+    os->fail = ferror( os->file );
+  }
+  return os;
+}
+
+int
+fail( ofstream *os )
+{
+  return os->fail;
+}
+
+static ofstream*
+make_ofstream()
+{
+  ofstream *new_stream = malloc( sizeof( ofstream ) );
+  new_stream->fail = 0;
+  return new_stream;
+}
+
+ofstream *
+ofstream_stdout()
+{
+  ofstream *stdout_stream = make_ofstream();
+  stdout_stream->file = stdout;
+  return stdout_stream;
+}
+
+ofstream *
+ofstream_stderr()
+{
+  ofstream *stderr_stream = make_ofstream();
+  stderr_stream->file = stderr;
+  return stderr_stream;
+}
+
+ofstream *
+ofstream_fromfile( const char *name )
+{
+  ofstream *file_stream = make_ofstream();
+  file_stream->file = fopen( name, "w" );
+  file_stream->fail = file_stream->file == 0;
+  return file_stream;
+}
+
+void
+ofstream_close( ofstream *os )
+{
+  if( os->file != stdout && os->file != stderr ) {
+    os->fail = fclose( os->file );
+  }
+  free( os );
+}
+
+struct ifstream
+{
+  FILE *file;
+  int fail;
+  int eof;
+};
+
+ifstream *
+read( ifstream *is, char *data, streamsize_type size )
+{
+  if( !is->fail && !is->eof ) {
+    fread( data, size, 1, is->file );
+    is->fail = ferror( is->file );
+    is->eof = feof( is->file );
+  }
+  return is;
+}
+  
+ifstream *unread( ifstream *is, char c )
+{
+  if( !is->fail ) {
+    if( EOF == ungetc( c, is->file ) ) {
+      is->fail = 1;
+    }
+  }
+  return is;
+}
+
+int fail( ifstream *is )
+{
+  return is->fail;
+}
+
+int eof( ifstream *is )
+{
+  return is->eof;
+}
+
+static ifstream*
+make_ifstream()
+{
+  ifstream *new_stream = malloc( sizeof( ifstream ) );
+  new_stream->fail = 0;
+  new_stream->eof = 0;
+  return new_stream;
+}
+
+ifstream *ifstream_stdin()
+{
+  ifstream *stdin_stream = make_ifstream();
+  stdin_stream->file = stdin;
+  return stdin_stream;
+}
+
+ifstream *
+ifstream_fromfile( const char *name )
+{
+  ifstream *file_stream = make_ifstream();
+  file_stream->file = fopen( name, "r" );
+  file_stream->fail = file_stream->file == 0;
+  return file_stream;
+}
+
Index: rcb-example/fstream.h
===================================================================
--- rcb-example/fstream.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ rcb-example/fstream.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,28 @@
+#ifndef FSTREAM_H
+#define FSTREAM_H
+
+#include "iostream.h"
+
+typedef struct ofstream ofstream;
+
+/* implement context ostream */
+ofstream *write( ofstream *, const char *, streamsize_type );
+int fail( ofstream * );
+
+ofstream *ofstream_stdout();
+ofstream *ofstream_stderr();
+ofstream *ofstream_fromfile( const char *name );
+void ofstream_close( ofstream *os );
+
+typedef struct ifstream ifstream;
+
+/* implement context istream */
+ifstream *read( ifstream *, char *, streamsize_type );
+ifstream *unread( ifstream *, char );
+int fail( ifstream * );
+int eof( ifstream * );
+
+ifstream *ifstream_stdin();
+ifstream *ifstream_fromfile( const char *name );
+
+#endif /* #ifndef FSTREAM_H */
Index: rcb-example/fstream_test.c
===================================================================
--- rcb-example/fstream_test.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ rcb-example/fstream_test.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,17 @@
+// "cfa -c -o fstream_test.o fstream_test.c"
+// "cfa -CFA fstream_test.c > fstream_test_out.c"
+// "gcc31 -c fstream_test_out.c"
+
+#include "fstream.h"
+
+int
+main()
+{
+  ofstream *sout = ofstream_stdout();
+  ifstream *sin = ifstream_stdin();
+  int nombre;
+  sout << "Appuyez un nombre, s'il vous plâit:\n";
+  sin >> &nombre;
+  sout << "Vous avez appuyé: " << nombre << "\n";
+  return 0;
+}
Index: rcb-example/fwrite.c
===================================================================
--- rcb-example/fwrite.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ rcb-example/fwrite.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,11 @@
+// "cfa -CFA fwrite.c > fwrite.i"
+// "cfa fwrite.i"
+
+#include <stdio.h>
+
+int
+main()
+{
+  fwrite( "test\n", 5, 1, stdout );
+  return 0;
+}
Index: rcb-example/hello.c
===================================================================
--- rcb-example/hello.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ rcb-example/hello.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,16 @@
+// "cfa hello.c fstream.c iostream.o"
+// "cfa -CFA hello.c > hello.i"
+// "cfa hello.i fstream.i iostream.o"
+
+extern "C" {
+int printf( const char*, ... );
+}
+
+#include "fstream.h"
+
+int main() {
+  ofstream *sout = ofstream_stdout();
+  write( sout, "test\n", 5 );
+  sout << "Bonjour au monde!\n";
+  return 0;
+}
Index: rcb-example/index.h
===================================================================
--- rcb-example/index.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ rcb-example/index.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,6 @@
+context index( type T )
+{
+  T ?+?( T, T );
+  T ?-?( T, T );
+  const T 0, 1;
+};
Index: rcb-example/iostream.c
===================================================================
--- rcb-example/iostream.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ rcb-example/iostream.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,67 @@
+// "cfa -c -o iostream.o iostream.c"
+// "cfa -v -E iostream.c > iostream_out.c"
+// "cfa -CFA iostream.c > iostream_out.c"
+// "cfa iostream_out.c"
+// "gcc32 iostream_out.c LibCfa/libcfa.a"
+
+#include "iostream.h"
+#undef __cplusplus
+extern "C" {
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+}
+
+forall( dtype ostype | ostream( ostype ) )
+ostype *
+?<<?( ostype *os, char c )
+{
+  return write( os, &c, 1 );
+}
+
+forall( dtype ostype | ostream( ostype ) )
+ostype *
+?<<?( ostype *os, int i )
+{
+  char buffer[20];      // larger than the largest integer
+  sprintf( buffer, "%d", i );
+  return write( os, buffer, strlen( buffer ) );
+}
+
+forall( dtype ostype | ostream( ostype ) )
+ostype *
+?<<?( ostype *os, const char *cp )
+{
+  return write( os, cp, strlen( cp ) );
+}
+
+forall( dtype istype | istream( istype ) )
+istype *
+?>>?( istype *is, char *cp )
+{
+  return read( is, cp, 1 );
+}
+
+forall( dtype istype | istream( istype ) )
+istype *
+?>>?( istype *is, int *ip )
+{
+  char cur;
+  
+  // skip some whitespace
+  do {
+    is >> &cur;
+    if( fail( is ) || eof( is ) ) return is;
+  } while( !( cur >= '0' && cur <= '9' ) );
+  
+  // accumulate digits
+  *ip = 0;
+  while( cur >= '0' && cur <= '9' ) {
+    *ip = *ip * 10 + ( cur - '0' );
+    is >> &cur;
+    if( fail( is ) || eof( is ) ) return is;
+  }
+  
+  unread( is, cur );
+  return is;
+}
Index: rcb-example/iostream.h
===================================================================
--- rcb-example/iostream.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ rcb-example/iostream.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,45 @@
+#ifndef IOSTREAM_H
+#define IOSTREAM_H
+
+typedef unsigned long streamsize_type;
+
+context ostream( dtype ostype )
+{
+  ostype *write( ostype *, const char *, streamsize_type );
+  int fail( ostype * );
+};
+
+context writeable( type T )
+{
+  forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, T );
+};
+
+// implement writable for some intrinsic types
+
+forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, char );
+
+forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, int );
+
+forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, const char * );
+
+
+context istream( dtype istype )
+{
+  istype *read( istype *, char *, streamsize_type );
+  istype *unread( istype *, char );
+  int fail( istype * );
+  int eof( istype * );
+};
+
+context readable( type T )
+{
+  forall( dtype istype | istream( istype ) ) istype * ?<<?( istype *, T );
+};
+
+forall( dtype istype | istream( istype ) )
+istype * ?>>?( istype *, char* );
+
+forall( dtype istype | istream( istype ) )
+istype * ?>>?( istype *, int* );
+
+#endif /* #ifndef IOSTREAM_H */
Index: rcb-example/iterator.c
===================================================================
--- rcb-example/iterator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ rcb-example/iterator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,28 @@
+// "cfa iterator.c"
+// "cfa -CFA iterator.c > iterator_out.c"
+// "gcc31 iterator_out.c ../LibCfa/libcfa.a"
+
+#include "iterator.h"
+
+/// forall( type iterator_type, type elt_type | iterator( iterator_type, elt_type ) )
+/// void
+/// for_each( iterator_type begin, iterator_type end, void (*func)( elt_type ) )
+/// {
+///   iterator_type i;
+///   for( i = begin; i != end; ++i ) {
+///     func( *i );
+///   }
+/// }
+
+forall( type elt_type | writeable( elt_type ),
+        type iterator_type | iterator( iterator_type, elt_type ),
+        dtype os_type | ostream( os_type ) )
+void
+write_all( iterator_type begin, iterator_type end, os_type *os )
+{
+  iterator_type i;
+  for( i = begin; i != end; ++i ) {
+    os << *i << ' ';
+  }
+}
+
Index: rcb-example/iterator.h
===================================================================
--- rcb-example/iterator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ rcb-example/iterator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,30 @@
+#ifndef ITERATOR_H
+#define ITERATOR_H
+
+#include "iostream.h"
+
+context iterator( type iterator_type, type elt_type )
+{
+  iterator_type ?++( iterator_type* );
+  iterator_type ++?( iterator_type* );
+  int ?==?( iterator_type, iterator_type );
+  int ?!=?( iterator_type, iterator_type );
+  lvalue elt_type *?( iterator_type );
+};
+
+context iterator_for( type iterator_type, type collection_type, type elt_type | iterator( iterator_type, elt_type ) )
+{
+///   [ iterator_type begin, iterator_type end ] get_iterators( collection_type );
+  iterator_type get_begin( collection_type );
+  iterator_type get_end( collection_type );
+};
+
+forall( type iterator_type, type elt_type | iterator( iterator_type, elt_type ) )
+void for_each( iterator_type begin, iterator_type end, void (*func)( elt_type ) );
+
+forall( type elt_type | writeable( elt_type ),
+        type iterator_type | iterator( iterator_type, elt_type ),
+        dtype os_type | ostream( os_type ) )
+void write_all( iterator_type begin, iterator_type end, os_type *os );
+
+#endif /* #ifndef ITERATOR_H */
Index: rcb-example/test.c
===================================================================
--- rcb-example/test.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ rcb-example/test.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,20 @@
+// "cfa -c -o test.o test.c"
+// "cfa -CFA test.c > test_out.c"
+// "gcc31 -c test_out.c -o test.o"
+
+#include "fstream.h"
+#include "vector_int.h"
+
+int
+main()
+{
+  ofstream *sout = ofstream_stdout();
+  vector_int vec = vector_int_allocate();
+  int index;
+  switch(1) {
+  case 1:
+    sout << vec[ index ];
+  }
+  sout << "\n";
+  return 0;
+}
Index: rcb-example/vector_int.c
===================================================================
--- rcb-example/vector_int.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ rcb-example/vector_int.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,67 @@
+// "cfa vector_int.c"
+
+#include "vector_int.h"
+
+#undef __cplusplus
+extern "C" {
+#include <stdlib.h>
+#include <assert.h>
+}
+
+#define DEFAULT_CAPACITY 20
+
+vector_int
+vector_int_allocate()
+{
+  return vector_int_allocate( DEFAULT_CAPACITY );
+}
+
+vector_int
+vector_int_allocate( int reserve )
+{
+  vector_int new_vector;
+  new_vector.last = -1;
+  new_vector.capacity = reserve;
+  new_vector.data = malloc( sizeof( int ) * reserve );
+  return new_vector;
+}
+
+void
+vector_int_deallocate( vector_int vec )
+{
+  free( vec.data );
+}
+
+void
+reserve( vector_int *vec, int reserve )
+{
+  if( reserve > vec->capacity ) {
+    vec->data = realloc( vec->data, sizeof( int ) * reserve );
+    vec->capacity = reserve;
+  }
+}
+
+void append( vector_int *vec, int element )
+{
+  vec->last++;
+  if( vec->last == vec->capacity ) {
+    vec->capacity *= 2;
+    vec->data = realloc( vec->data, sizeof( int ) * vec->capacity );
+  }
+  vec->data[ vec->last ] = element;
+}
+
+// implement bounded_array
+
+lvalue int
+?[?]( vector_int vec, int index )
+{
+  return vec.data[ index ];
+}
+
+int
+array_last( vector_int vec )
+{
+  return vec.last;
+}
+
Index: rcb-example/vector_int.h
===================================================================
--- rcb-example/vector_int.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ rcb-example/vector_int.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,24 @@
+#ifndef VECTOR_INT_H
+#define VECTOR_INT_H
+
+typedef struct vector_int
+{
+  int last;
+  int capacity;
+  int *data;
+} vector_int;
+
+
+vector_int vector_int_allocate();
+vector_int vector_int_allocate( int reserve );
+void vector_int_deallocate( vector_int );
+
+void reserve( vector_int *vec, int reserve );
+void append( vector_int *vec, int element );
+
+// implement bounded_array
+
+lvalue int ?[?]( vector_int vec, int index );
+int array_last( vector_int vec );
+
+#endif /* #ifndef VECTOR_INT_H */
Index: rcb-example/vector_test.c
===================================================================
--- rcb-example/vector_test.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ rcb-example/vector_test.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,34 @@
+// "cfa -c -o vector_test.o vector_test.c"
+// "cfa -CFA vector_test.c > vector_test_out.c"
+// "cfa -E vector_test.c > vector_test_out.c"
+// "gcc31 -c vector_test_out.c -o vector_test.o"
+
+#include "fstream.h"
+#include "vector_int.h"
+#include "array.h"
+
+extern "C" {
+int printf( const char *, ... );
+}
+
+int
+main()
+{
+  ofstream *sout = ofstream_stdout();
+  ifstream *sin = ifstream_stdin();
+  vector_int vec = vector_int_allocate();
+  int nombre;
+  for(;;) {
+    sin >> &nombre;
+    if( fail( sin ) || eof( sin ) ) break;
+    append( &vec, nombre );
+  }
+  sout << "Array elements: ";
+  write_all( get_begin( vec ), get_end( vec ), sout );
+///   int index;
+///   for( index = 0; index <= array_last( vec ); ++index ) {
+///     sout << vec[ index ] << " ";
+///   }
+  sout << "\n";
+  return 0;
+}
