Initial import

This commit is contained in:
Andreas Rumpf 2008-06-22 16:14:11 +02:00
commit 405b86068e
324 changed files with 163599 additions and 0 deletions

296
tests/bench/GCBench.c Executable file
View file

@ -0,0 +1,296 @@
// This is adapted from a benchmark written by John Ellis and Pete Kovac
// of Post Communications.
// It was modified by Hans Boehm of Silicon Graphics.
// Translated to C++ 30 May 1997 by William D Clinger of Northeastern Univ.
// Translated to C 15 March 2000 by Hans Boehm, now at HP Labs.
//
// This is no substitute for real applications. No actual application
// is likely to behave in exactly this way. However, this benchmark was
// designed to be more representative of real applications than other
// Java GC benchmarks of which we are aware.
// It attempts to model those properties of allocation requests that
// are important to current GC techniques.
// It is designed to be used either to obtain a single overall performance
// number, or to give a more detailed estimate of how collector
// performance varies with object lifetimes. It prints the time
// required to allocate and collect balanced binary trees of various
// sizes. Smaller trees result in shorter object lifetimes. Each cycle
// allocates roughly the same amount of memory.
// Two data structures are kept around during the entire process, so
// that the measured performance is representative of applications
// that maintain some live in-memory data. One of these is a tree
// containing many pointers. The other is a large array containing
// double precision floating point numbers. Both should be of comparable
// size.
//
// The results are only really meaningful together with a specification
// of how much memory was used. It is possible to trade memory for
// better time performance. This benchmark should be run in a 32 MB
// heap, though we don't currently know how to enforce that uniformly.
//
// Unlike the original Ellis and Kovac benchmark, we do not attempt
// measure pause times. This facility should eventually be added back
// in. There are several reasons for omitting it for now. The original
// implementation depended on assumptions about the thread scheduler
// that don't hold uniformly. The results really measure both the
// scheduler and GC. Pause time measurements tend to not fit well with
// current benchmark suites. As far as we know, none of the current
// commercial Java implementations seriously attempt to minimize GC pause
// times.
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#ifdef GC
# include "gc.h"
#endif
#ifdef PROFIL
extern void init_profiling();
extern dump_profile();
#endif
// These macros were a quick hack for the Macintosh.
//
// #define currentTime() clock()
// #define elapsedTime(x) ((1000*(x))/CLOCKS_PER_SEC)
#define currentTime() stats_rtclock()
#define elapsedTime(x) (x)
/* Get the current time in milliseconds */
unsigned
stats_rtclock( void )
{
struct timeval t;
struct timezone tz;
if (gettimeofday( &t, &tz ) == -1)
return 0;
return (t.tv_sec * 1000 + t.tv_usec / 1000);
}
static const int kStretchTreeDepth = 18; // about 16Mb
static const int kLongLivedTreeDepth = 16; // about 4Mb
static const int kArraySize = 500000; // about 4Mb
static const int kMinTreeDepth = 4;
static const int kMaxTreeDepth = 16;
typedef struct Node0_struct {
struct Node0_struct * left;
struct Node0_struct * right;
int i, j;
} Node0;
#ifdef HOLES
# define HOLE() GC_NEW(Node0);
#else
# define HOLE()
#endif
typedef Node0 *Node;
void init_Node(Node me, Node l, Node r) {
me -> left = l;
me -> right = r;
}
#ifndef GC
void destroy_Node(Node me) {
if (me -> left) {
destroy_Node(me -> left);
}
if (me -> right) {
destroy_Node(me -> right);
}
free(me);
}
#endif
// Nodes used by a tree of a given size
static int TreeSize(int i) {
return ((1 << (i + 1)) - 1);
}
// Number of iterations to use for a given tree depth
static int NumIters(int i) {
return 2 * TreeSize(kStretchTreeDepth) / TreeSize(i);
}
// Build tree top down, assigning to older objects.
static void Populate(int iDepth, Node thisNode) {
if (iDepth<=0) {
return;
} else {
iDepth--;
# ifdef GC
thisNode->left = GC_NEW(Node0); HOLE();
thisNode->right = GC_NEW(Node0); HOLE();
# else
thisNode->left = calloc(1, sizeof(Node0));
thisNode->right = calloc(1, sizeof(Node0));
# endif
Populate (iDepth, thisNode->left);
Populate (iDepth, thisNode->right);
}
}
// Build tree bottom-up
static Node MakeTree(int iDepth) {
Node result;
if (iDepth<=0) {
# ifndef GC
result = calloc(1, sizeof(Node0));
# else
result = GC_NEW(Node0); HOLE();
# endif
/* result is implicitly initialized in both cases. */
return result;
} else {
Node left = MakeTree(iDepth-1);
Node right = MakeTree(iDepth-1);
# ifndef GC
result = malloc(sizeof(Node0));
# else
result = GC_NEW(Node0); HOLE();
# endif
init_Node(result, left, right);
return result;
}
}
static void PrintDiagnostics() {
#if 0
long lFreeMemory = Runtime.getRuntime().freeMemory();
long lTotalMemory = Runtime.getRuntime().totalMemory();
System.out.print(" Total memory available="
+ lTotalMemory + " bytes");
System.out.println(" Free memory=" + lFreeMemory + " bytes");
#endif
}
static void TimeConstruction(int depth) {
long tStart, tFinish;
int iNumIters = NumIters(depth);
Node tempTree;
int i;
printf("Creating %d trees of depth %d\n", iNumIters, depth);
tStart = currentTime();
for (i = 0; i < iNumIters; ++i) {
# ifndef GC
tempTree = calloc(1, sizeof(Node0));
# else
tempTree = GC_NEW(Node0);
# endif
Populate(depth, tempTree);
# ifndef GC
destroy_Node(tempTree);
# endif
tempTree = 0;
}
tFinish = currentTime();
printf("\tTop down construction took %d msec\n",
elapsedTime(tFinish - tStart));
tStart = currentTime();
for (i = 0; i < iNumIters; ++i) {
tempTree = MakeTree(depth);
# ifndef GC
destroy_Node(tempTree);
# endif
tempTree = 0;
}
tFinish = currentTime();
printf("\tBottom up construction took %d msec\n",
elapsedTime(tFinish - tStart));
}
int main() {
Node root;
Node longLivedTree;
Node tempTree;
long tStart, tFinish;
long tElapsed;
int i, d;
double *array;
#ifdef GC
// GC_full_freq = 30;
// GC_free_space_divisor = 16;
// GC_enable_incremental();
#endif
printf("Garbage Collector Test\n");
printf(" Live storage will peak at %d bytes.\n\n",
2 * sizeof(Node0) * TreeSize(kLongLivedTreeDepth) +
sizeof(double) * kArraySize);
printf(" Stretching memory with a binary tree of depth %d\n",
kStretchTreeDepth);
PrintDiagnostics();
# ifdef PROFIL
init_profiling();
# endif
tStart = currentTime();
// Stretch the memory space quickly
tempTree = MakeTree(kStretchTreeDepth);
# ifndef GC
destroy_Node(tempTree);
# endif
tempTree = 0;
// Create a long lived object
printf(" Creating a long-lived binary tree of depth %d\n",
kLongLivedTreeDepth);
# ifndef GC
longLivedTree = calloc(1, sizeof(Node0));
# else
longLivedTree = GC_NEW(Node0);
# endif
Populate(kLongLivedTreeDepth, longLivedTree);
// Create long-lived array, filling half of it
printf(" Creating a long-lived array of %d doubles\n", kArraySize);
# ifndef GC
array = malloc(kArraySize * sizeof(double));
# else
# ifndef NO_PTRFREE
array = GC_MALLOC_ATOMIC(sizeof(double) * kArraySize);
# else
array = GC_MALLOC(sizeof(double) * kArraySize);
# endif
# endif
for (i = 0; i < kArraySize/2; ++i) {
array[i] = 1.0/i;
}
PrintDiagnostics();
for (d = kMinTreeDepth; d <= kMaxTreeDepth; d += 2) {
TimeConstruction(d);
}
if (longLivedTree == 0 || array[1000] != 1.0/1000)
fprintf(stderr, "Failed\n");
// fake reference to LongLivedTree
// and array
// to keep them from being optimized away
tFinish = currentTime();
tElapsed = elapsedTime(tFinish-tStart);
PrintDiagnostics();
printf("Completed in %d msec\n", tElapsed);
# ifdef GC
printf("Completed %d collections\n", GC_gc_no);
printf("Heap size is %d\n", GC_get_heap_size());
# endif
# ifdef PROFIL
dump_profile();
# endif
}

266
tests/bench/GCBench.cpp Executable file
View file

@ -0,0 +1,266 @@
// This is adapted from a benchmark written by John Ellis and Pete Kovac
// of Post Communications.
// It was modified by Hans Boehm of Silicon Graphics.
// Translated to C++ 30 May 1997 by William D Clinger of Northeastern Univ.
//
// This is no substitute for real applications. No actual application
// is likely to behave in exactly this way. However, this benchmark was
// designed to be more representative of real applications than other
// Java GC benchmarks of which we are aware.
// It attempts to model those properties of allocation requests that
// are important to current GC techniques.
// It is designed to be used either to obtain a single overall performance
// number, or to give a more detailed estimate of how collector
// performance varies with object lifetimes. It prints the time
// required to allocate and collect balanced binary trees of various
// sizes. Smaller trees result in shorter object lifetimes. Each cycle
// allocates roughly the same amount of memory.
// Two data structures are kept around during the entire process, so
// that the measured performance is representative of applications
// that maintain some live in-memory data. One of these is a tree
// containing many pointers. The other is a large array containing
// double precision floating point numbers. Both should be of comparable
// size.
//
// The results are only really meaningful together with a specification
// of how much memory was used. It is possible to trade memory for
// better time performance. This benchmark should be run in a 32 MB
// heap, though we don't currently know how to enforce that uniformly.
//
// Unlike the original Ellis and Kovac benchmark, we do not attempt
// measure pause times. This facility should eventually be added back
// in. There are several reasons for omitting it for now. The original
// implementation depended on assumptions about the thread scheduler
// that don't hold uniformly. The results really measure both the
// scheduler and GC. Pause time measurements tend to not fit well with
// current benchmark suites. As far as we know, none of the current
// commercial Java implementations seriously attempt to minimize GC pause
// times.
#include <new.h>
#include <iostream.h>
#include <sys/time.h>
#ifdef GC
# include "gc.h"
#endif
// These macros were a quick hack for the Macintosh.
//
// #define currentTime() clock()
// #define elapsedTime(x) ((1000*(x))/CLOCKS_PER_SEC)
#define currentTime() stats_rtclock()
#define elapsedTime(x) (x)
/* Get the current time in milliseconds */
unsigned
stats_rtclock( void )
{
struct timeval t;
struct timezone tz;
if (gettimeofday( &t, &tz ) == -1)
return 0;
return (t.tv_sec * 1000 + t.tv_usec / 1000);
}
static const int kStretchTreeDepth = 18; // about 16Mb
static const int kLongLivedTreeDepth = 16; // about 4Mb
static const int kArraySize = 500000; // about 4Mb
static const int kMinTreeDepth = 4;
static const int kMaxTreeDepth = 16;
typedef struct Node0 *Node;
struct Node0 {
Node left;
Node right;
int i, j;
Node0(Node l, Node r) { left = l; right = r; }
Node0() { left = 0; right = 0; }
# ifndef GC
~Node0() { if (left) delete left; if (right) delete right; }
# endif
};
struct GCBench {
// Nodes used by a tree of a given size
static int TreeSize(int i) {
return ((1 << (i + 1)) - 1);
}
// Number of iterations to use for a given tree depth
static int NumIters(int i) {
return 2 * TreeSize(kStretchTreeDepth) / TreeSize(i);
}
// Build tree top down, assigning to older objects.
static void Populate(int iDepth, Node thisNode) {
if (iDepth<=0) {
return;
} else {
iDepth--;
# ifndef GC
thisNode->left = new Node0();
thisNode->right = new Node0();
# else
thisNode->left = new (GC_NEW(Node0)) Node0();
thisNode->right = new (GC_NEW(Node0)) Node0();
# endif
Populate (iDepth, thisNode->left);
Populate (iDepth, thisNode->right);
}
}
// Build tree bottom-up
static Node MakeTree(int iDepth) {
if (iDepth<=0) {
# ifndef GC
return new Node0();
# else
return new (GC_NEW(Node0)) Node0();
# endif
} else {
# ifndef GC
return new Node0(MakeTree(iDepth-1),
MakeTree(iDepth-1));
# else
return new (GC_NEW(Node0)) Node0(MakeTree(iDepth-1),
MakeTree(iDepth-1));
# endif
}
}
static void PrintDiagnostics() {
#if 0
long lFreeMemory = Runtime.getRuntime().freeMemory();
long lTotalMemory = Runtime.getRuntime().totalMemory();
System.out.print(" Total memory available="
+ lTotalMemory + " bytes");
System.out.println(" Free memory=" + lFreeMemory + " bytes");
#endif
}
static void TimeConstruction(int depth) {
long tStart, tFinish;
int iNumIters = NumIters(depth);
Node tempTree;
cout << "Creating " << iNumIters
<< " trees of depth " << depth << endl;
tStart = currentTime();
for (int i = 0; i < iNumIters; ++i) {
# ifndef GC
tempTree = new Node0();
# else
tempTree = new (GC_NEW(Node0)) Node0();
# endif
Populate(depth, tempTree);
# ifndef GC
delete tempTree;
# endif
tempTree = 0;
}
tFinish = currentTime();
cout << "\tTop down construction took "
<< elapsedTime(tFinish - tStart) << " msec" << endl;
tStart = currentTime();
for (int i = 0; i < iNumIters; ++i) {
tempTree = MakeTree(depth);
# ifndef GC
delete tempTree;
# endif
tempTree = 0;
}
tFinish = currentTime();
cout << "\tBottom up construction took "
<< elapsedTime(tFinish - tStart) << " msec" << endl;
}
void main() {
Node root;
Node longLivedTree;
Node tempTree;
long tStart, tFinish;
long tElapsed;
#ifdef GC
// GC_full_freq = 30;
GC_enable_incremental();
#endif
cout << "Garbage Collector Test" << endl;
cout << " Live storage will peak at "
<< 2 * sizeof(Node0) * TreeSize(kLongLivedTreeDepth) +
sizeof(double) * kArraySize
<< " bytes." << endl << endl;
cout << " Stretching memory with a binary tree of depth "
<< kStretchTreeDepth << endl;
PrintDiagnostics();
tStart = currentTime();
// Stretch the memory space quickly
tempTree = MakeTree(kStretchTreeDepth);
# ifndef GC
delete tempTree;
# endif
tempTree = 0;
// Create a long lived object
cout << " Creating a long-lived binary tree of depth "
<< kLongLivedTreeDepth << endl;
# ifndef GC
longLivedTree = new Node0();
# else
longLivedTree = new (GC_NEW(Node0)) Node0();
# endif
Populate(kLongLivedTreeDepth, longLivedTree);
// Create long-lived array, filling half of it
cout << " Creating a long-lived array of "
<< kArraySize << " doubles" << endl;
# ifndef GC
double *array = new double[kArraySize];
# else
double *array = (double *)
GC_MALLOC_ATOMIC(sizeof(double) * kArraySize);
# endif
for (int i = 0; i < kArraySize/2; ++i) {
array[i] = 1.0/i;
}
PrintDiagnostics();
for (int d = kMinTreeDepth; d <= kMaxTreeDepth; d += 2)
{
TimeConstruction(d);
}
if (longLivedTree == 0 || array[1000] != 1.0/1000)
cout << "Failed" << endl;
// fake reference to LongLivedTree
// and array
// to keep them from being optimized away
tFinish = currentTime();
tElapsed = elapsedTime(tFinish-tStart);
PrintDiagnostics();
cout << "Completed in " << tElapsed << " msec" << endl;
# ifdef GC
cout << "Completed " << GC_gc_no << " collections" <<endl;
cout << "Heap size is " << GC_get_heap_size() << endl;
# endif
}
};
main () {
GCBench x;
x.main();
}

182
tests/bench/GCBench.java Executable file
View file

@ -0,0 +1,182 @@
// This is adapted from a benchmark written by John Ellis and Pete Kovac
// of Post Communications.
// It was modified by Hans Boehm of Silicon Graphics.
//
// This is no substitute for real applications. No actual application
// is likely to behave in exactly this way. However, this benchmark was
// designed to be more representative of real applications than other
// Java GC benchmarks of which we are aware.
// It attempts to model those properties of allocation requests that
// are important to current GC techniques.
// It is designed to be used either to obtain a single overall performance
// number, or to give a more detailed estimate of how collector
// performance varies with object lifetimes. It prints the time
// required to allocate and collect balanced binary trees of various
// sizes. Smaller trees result in shorter object lifetimes. Each cycle
// allocates roughly the same amount of memory.
// Two data structures are kept around during the entire process, so
// that the measured performance is representative of applications
// that maintain some live in-memory data. One of these is a tree
// containing many pointers. The other is a large array containing
// double precision floating point numbers. Both should be of comparable
// size.
//
// The results are only really meaningful together with a specification
// of how much memory was used. It is possible to trade memory for
// better time performance. This benchmark should be run in a 32 MB
// heap, though we don't currently know how to enforce that uniformly.
//
// Unlike the original Ellis and Kovac benchmark, we do not attempt
// measure pause times. This facility should eventually be added back
// in. There are several reasons for omitting it for now. The original
// implementation depended on assumptions about the thread scheduler
// that don't hold uniformly. The results really measure both the
// scheduler and GC. Pause time measurements tend to not fit well with
// current benchmark suites. As far as we know, none of the current
// commercial Java implementations seriously attempt to minimize GC pause
// times.
//
// Known deficiencies:
// - No way to check on memory use
// - No cyclic data structures
// - No attempt to measure variation with object size
// - Results are sensitive to locking cost, but we dont
// check for proper locking
class Node {
Node left, right;
int i, j;
Node(Node l, Node r) { left = l; right = r; }
Node() { }
}
public class GCBench {
public static final int kStretchTreeDepth = 18; // about 16Mb
public static final int kLongLivedTreeDepth = 16; // about 4Mb
public static final int kArraySize = 500000; // about 4Mb
public static final int kMinTreeDepth = 4;
public static final int kMaxTreeDepth = 16;
// Nodes used by a tree of a given size
static int TreeSize(int i) {
return ((1 << (i + 1)) - 1);
}
// Number of iterations to use for a given tree depth
static int NumIters(int i) {
return 2 * TreeSize(kStretchTreeDepth) / TreeSize(i);
}
// Build tree top down, assigning to older objects.
static void Populate(int iDepth, Node thisNode) {
if (iDepth<=0) {
return;
} else {
iDepth--;
thisNode.left = new Node();
thisNode.right = new Node();
Populate (iDepth, thisNode.left);
Populate (iDepth, thisNode.right);
}
}
// Build tree bottom-up
static Node MakeTree(int iDepth) {
if (iDepth<=0) {
return new Node();
} else {
return new Node(MakeTree(iDepth-1),
MakeTree(iDepth-1));
}
}
static void PrintDiagnostics() {
long lFreeMemory = Runtime.getRuntime().freeMemory();
long lTotalMemory = Runtime.getRuntime().totalMemory();
System.out.print(" Total memory available="
+ lTotalMemory + " bytes");
System.out.println(" Free memory=" + lFreeMemory + " bytes");
}
static void TimeConstruction(int depth) {
Node root;
long tStart, tFinish;
int iNumIters = NumIters(depth);
Node tempTree;
System.out.println("Creating " + iNumIters +
" trees of depth " + depth);
tStart = System.currentTimeMillis();
for (int i = 0; i < iNumIters; ++i) {
tempTree = new Node();
Populate(depth, tempTree);
tempTree = null;
}
tFinish = System.currentTimeMillis();
System.out.println("\tTop down construction took "
+ (tFinish - tStart) + "msecs");
tStart = System.currentTimeMillis();
for (int i = 0; i < iNumIters; ++i) {
tempTree = MakeTree(depth);
tempTree = null;
}
tFinish = System.currentTimeMillis();
System.out.println("\tBottom up construction took "
+ (tFinish - tStart) + "msecs");
}
public static void main(String args[]) {
Node root;
Node longLivedTree;
Node tempTree;
long tStart, tFinish;
long tElapsed;
System.out.println("Garbage Collector Test");
System.out.println(
" Stretching memory with a binary tree of depth "
+ kStretchTreeDepth);
PrintDiagnostics();
tStart = System.currentTimeMillis();
// Stretch the memory space quickly
tempTree = MakeTree(kStretchTreeDepth);
tempTree = null;
// Create a long lived object
System.out.println(
" Creating a long-lived binary tree of depth " +
kLongLivedTreeDepth);
longLivedTree = new Node();
Populate(kLongLivedTreeDepth, longLivedTree);
// Create long-lived array, filling half of it
System.out.println(
" Creating a long-lived array of "
+ kArraySize + " doubles");
double array[] = new double[kArraySize];
for (int i = 0; i < kArraySize/2; ++i) {
array[i] = 1.0/i;
}
PrintDiagnostics();
for (int d = kMinTreeDepth; d <= kMaxTreeDepth; d += 2) {
TimeConstruction(d);
}
if (longLivedTree == null || array[1000] != 1.0/1000)
System.out.println("Failed");
// fake reference to LongLivedTree
// and array
// to keep them from being optimized away
tFinish = System.currentTimeMillis();
tElapsed = tFinish-tStart;
PrintDiagnostics();
System.out.println("Completed in " + tElapsed + "ms.");
}
} // class JavaGC

301
tests/bench/GCBench_OGC.cpp Executable file
View file

@ -0,0 +1,301 @@
// This is adapted from a benchmark written by John Ellis and Pete Kovac
// of Post Communications.
// It was modified by Hans Boehm of Silicon Graphics.
// Translated to C++ 30 May 1997 by William D Clinger of Northeastern Univ.
//
// This is no substitute for real applications. No actual application
// is likely to behave in exactly this way. However, this benchmark was
// designed to be more representative of real applications than other
// Java GC benchmarks of which we are aware.
// It attempts to model those properties of allocation requests that
// are important to current GC techniques.
// It is designed to be used either to obtain a single overall performance
// number, or to give a more detailed estimate of how collector
// performance varies with object lifetimes. It prints the time
// required to allocate and collect balanced binary trees of various
// sizes. Smaller trees result in shorter object lifetimes. Each cycle
// allocates roughly the same amount of memory.
// Two data structures are kept around during the entire process, so
// that the measured performance is representative of applications
// that maintain some live in-memory data. One of these is a tree
// containing many pointers. The other is a large array containing
// double precision floating point numbers. Both should be of comparable
// size.
//
// The results are only really meaningful together with a specification
// of how much memory was used. It is possible to trade memory for
// better time performance. This benchmark should be run in a 32 MB
// heap, though we don't currently know how to enforce that uniformly.
//
// Unlike the original Ellis and Kovac benchmark, we do not attempt
// measure pause times. This facility should eventually be added back
// in. There are several reasons for omitting it for now. The original
// implementation depended on assumptions about the thread scheduler
// that don't hold uniformly. The results really measure both the
// scheduler and GC. Pause time measurements tend to not fit well with
// current benchmark suites. As far as we know, none of the current
// commercial Java implementations seriously attempt to minimize GC pause
// times.
#include <new.h>
#include <iostream.h>
#include <sys/time.h>
#ifdef GC
# include "gc.h"
#endif
#ifdef OGC
# include "ogc.h"
#endif
// These macros were a quick hack for the Macintosh.
//
// #define currentTime() clock()
// #define elapsedTime(x) ((1000*(x))/CLOCKS_PER_SEC)
#define currentTime() stats_rtclock()
#define elapsedTime(x) (x)
/* Get the current time in milliseconds */
unsigned
stats_rtclock( void )
{
struct timeval t;
struct timezone tz;
if (gettimeofday( &t, &tz ) == -1)
return 0;
return (t.tv_sec * 1000 + t.tv_usec / 1000);
}
static const int kStretchTreeDepth = 18; // about 16Mb
static const int kLongLivedTreeDepth = 16; // about 4Mb
static const int kArraySize = 500000; // about 4Mb
static const int kMinTreeDepth = 4;
static const int kMaxTreeDepth = 16;
struct Node0 {
# ifdef OGC
gc_ptr<Node0> left;
gc_ptr<Node0> right;
Node0(gc_ptr<Node0> l, gc_ptr<Node0> r) { left = l; right = r; }
# else
Node0 * left;
Node0 * right;
Node0(Node0 *l, Node0 *r) { left = l; right = r; }
# endif
int i, j;
Node0() { left = 0; right = 0; }
# if !defined(GC) && !defined(OGC)
~Node0() { if (left) delete left; if (right) delete right; }
# endif
};
#ifdef OGC
typedef gc_ptr<Node0> Node;
#else
typedef struct Node0 *Node;
#endif
struct GCBench {
// Nodes used by a tree of a given size
static int TreeSize(int i) {
return ((1 << (i + 1)) - 1);
}
// Number of iterations to use for a given tree depth
static int NumIters(int i) {
return 2 * TreeSize(kStretchTreeDepth) / TreeSize(i);
}
// Build tree top down, assigning to older objects.
static void Populate(int iDepth, Node thisNode) {
if (iDepth<=0) {
return;
} else {
iDepth--;
# if defined(GC)
thisNode->left = new (GC_NEW(Node0)) Node0();
thisNode->right = new (GC_NEW(Node0)) Node0();
# elif defined(OGC)
thisNode->left = gc_new Node0();
thisNode->right = gc_new Node0();
# else
thisNode->left = new Node0();
thisNode->right = new Node0();
# endif
Populate (iDepth, thisNode->left);
Populate (iDepth, thisNode->right);
}
}
// Build tree bottom-up
static Node MakeTree(int iDepth) {
if (iDepth<=0) {
# if defined(GC)
return new (GC_NEW(Node0)) Node0();
# elif defined(OGC)
return gc_new Node0();
# else
return new Node0();
# endif
} else {
# if defined(GC)
return new (GC_NEW(Node0)) Node0(MakeTree(iDepth-1),
MakeTree(iDepth-1));
# elif defined(OGC)
# ifdef BROKEN_SMART_PTRS
Node left = MakeTree(iDepth-1);
Node right = MakeTree(iDepth-1);
return gc_new Node0(left, right);
# else
return gc_new Node0(MakeTree(iDepth-1),
MakeTree(iDepth-1));
# endif
# else
return new Node0(MakeTree(iDepth-1),
MakeTree(iDepth-1));
# endif
}
}
static void PrintDiagnostics() {
#if 0
long lFreeMemory = Runtime.getRuntime().freeMemory();
long lTotalMemory = Runtime.getRuntime().totalMemory();
System.out.print(" Total memory available="
+ lTotalMemory + " bytes");
System.out.println(" Free memory=" + lFreeMemory + " bytes");
#endif
}
static void TimeConstruction(int depth) {
long tStart, tFinish;
int iNumIters = NumIters(depth);
Node tempTree;
cout << "Creating " << iNumIters
<< " trees of depth " << depth << endl;
tStart = currentTime();
for (int i = 0; i < iNumIters; ++i) {
# if defined(GC)
tempTree = new (GC_NEW(Node0)) Node0();
# elif defined(OGC)
tempTree = gc_new Node0();
# else
tempTree = new Node0();
# endif
Populate(depth, tempTree);
# if !defined(GC) && !defined(OGC)
delete tempTree;
# endif
tempTree = 0;
}
tFinish = currentTime();
cout << "\tTop down construction took "
<< elapsedTime(tFinish - tStart) << " msec" << endl;
tStart = currentTime();
for (int i = 0; i < iNumIters; ++i) {
tempTree = MakeTree(depth);
# if !defined(GC) && !defined(OGC)
delete tempTree;
# endif
tempTree = 0;
}
tFinish = currentTime();
cout << "\tBottom up construction took "
<< elapsedTime(tFinish - tStart) << " msec" << endl;
}
void main() {
Node root;
Node longLivedTree;
Node tempTree;
long tStart, tFinish;
long tElapsed;
#ifdef GC
// GC_full_freq = 30;
GC_enable_incremental();
#endif
# ifdef OGC
GC::SetPolicy(100);
# endif
cout << "Garbage Collector Test" << endl;
cout << " Live storage will peak at "
<< 2 * sizeof(Node0) * TreeSize(kLongLivedTreeDepth) +
sizeof(double) * kArraySize
<< " bytes." << endl << endl;
cout << " Stretching memory with a binary tree of depth "
<< kStretchTreeDepth << endl;
PrintDiagnostics();
tStart = currentTime();
// Stretch the memory space quickly
tempTree = MakeTree(kStretchTreeDepth);
# if !defined(GC) && !defined(OGC)
delete tempTree;
# endif
tempTree = 0;
// Create a long lived object
cout << " Creating a long-lived binary tree of depth "
<< kLongLivedTreeDepth << endl;
# if defined(GC)
longLivedTree = new (GC_NEW(Node0)) Node0();
# elif defined(OGC)
longLivedTree = gc_new Node0();
# else
longLivedTree = new Node0();
# endif
Populate(kLongLivedTreeDepth, longLivedTree);
// Create long-lived array, filling half of it
cout << " Creating a long-lived array of "
<< kArraySize << " doubles" << endl;
# if defined(GC)
double *array = (double *)
GC_MALLOC(sizeof(double) * kArraySize);
# else
double *array = new double[kArraySize];
# endif
for (int i = 0; i < kArraySize/2; ++i) {
array[i] = 1.0/i;
}
PrintDiagnostics();
for (int d = kMinTreeDepth; d <= kMaxTreeDepth; d += 2)
{
TimeConstruction(d);
}
if (longLivedTree == 0 || array[1000] != 1.0/1000)
cout << "Failed" << endl;
// fake reference to LongLivedTree
// and array
// to keep them from being optimized away
tFinish = currentTime();
tElapsed = elapsedTime(tFinish-tStart);
PrintDiagnostics();
cout << "Completed in " << tElapsed << " msec" << endl;
# ifdef GC
cout << "Completed " << GC_gc_no << " collections" <<endl;
cout << "Heap size is " << GC_get_heap_size() << endl;
# endif
}
};
main () {
GCBench x;
x.main();
}

172
tests/bench/gcbench.nim Executable file
View file

@ -0,0 +1,172 @@
# This is adapted from a benchmark written by John Ellis and Pete Kovac
# of Post Communications.
# It was modified by Hans Boehm of Silicon Graphics.
#
# This is no substitute for real applications. No actual application
# is likely to behave in exactly this way. However, this benchmark was
# designed to be more representative of real applications than other
# Java GC benchmarks of which we are aware.
# It attempts to model those properties of allocation requests that
# are important to current GC techniques.
# It is designed to be used either to obtain a single overall performance
# number, or to give a more detailed estimate of how collector
# performance varies with object lifetimes. It prints the time
# required to allocate and collect balanced binary trees of various
# sizes. Smaller trees result in shorter object lifetimes. Each cycle
# allocates roughly the same amount of memory.
# Two data structures are kept around during the entire process, so
# that the measured performance is representative of applications
# that maintain some live in-memory data. One of these is a tree
# containing many pointers. The other is a large array containing
# double precision floating point numbers. Both should be of comparable
# size.
#
# The results are only really meaningful together with a specification
# of how much memory was used. It is possible to trade memory for
# better time performance. This benchmark should be run in a 32 MB
# heap, though we don't currently know how to enforce that uniformly.
#
# Unlike the original Ellis and Kovac benchmark, we do not attempt
# measure pause times. This facility should eventually be added back
# in. There are several reasons for omitting it for now. The original
# implementation depended on assumptions about the thread scheduler
# that don't hold uniformly. The results really measure both the
# scheduler and GC. Pause time measurements tend to not fit well with
# current benchmark suites. As far as we know, none of the current
# commercial Java implementations seriously attempt to minimize GC pause
# times.
#
# Known deficiencies:
# - No way to check on memory use
# - No cyclic data structures
# - No attempt to measure variation with object size
# - Results are sensitive to locking cost, but we dont
# check for proper locking
#
import
io, strutils, times
type
PNode = ref TNode
TNode = record
left, right: PNode
i, j: int
proc newNode(l, r: PNode): PNode =
new(result)
result.left = l
result.right = r
const
kStretchTreeDepth = 18 # about 16Mb
kLongLivedTreeDepth = 16 # about 4Mb
kArraySize = 500000 # about 4Mb
kMinTreeDepth = 4
kMaxTreeDepth = 16
# Nodes used by a tree of a given size
proc TreeSize(i: int): int = return ((1 shl (i + 1)) - 1)
# Number of iterations to use for a given tree depth
proc NumIters(i: int): int =
return 2 * TreeSize(kStretchTreeDepth) div TreeSize(i)
# Build tree top down, assigning to older objects.
proc Populate(iDepth: int, thisNode: PNode) =
if iDepth <= 0:
return
else:
new(thisNode.left)
new(thisNode.right)
Populate(iDepth-1, thisNode.left)
Populate(iDepth-1, thisNode.right)
# Build tree bottom-up
proc MakeTree(iDepth: int): PNode =
if iDepth <= 0:
new(result)
else:
return newNode(MakeTree(iDepth-1),
MakeTree(iDepth-1))
proc PrintDiagnostics() =
var
FreeMemory = getFreeMem()
TotalMemory = getTotalMem()
echo("Total memory available: " & $TotalMemory & " bytes")
echo("Free memory: " & $FreeMemory & " bytes")
proc TimeConstruction(depth: int) =
var
root, tempTree: PNode
t: int
iNumIters: int
iNumIters = NumIters(depth)
echo("Creating " & $iNumIters & " trees of depth " & $depth)
t = getStartMilsecs()
for i in 0..iNumIters-1:
new(tempTree)
Populate(depth, tempTree)
tempTree = nil
echo("\tTop down construction took " &
$(getStartMilsecs() - t) & "msecs")
t = getStartMilsecs()
for i in 0..iNumIters-1:
tempTree = MakeTree(depth)
tempTree = nil
echo("\tBottom up construction took " &
$(getStartMilsecs() - t) & "msecs")
type
tMyArray = seq[float]
proc main() =
var
root, longLivedTree, tempTree: PNode
t: int
myarray: tMyArray
echo("Garbage Collector Test")
echo(" Stretching memory with a binary tree of depth " &
$kStretchTreeDepth)
PrintDiagnostics()
t = getStartMilsecs()
# Stretch the memory space quickly
tempTree = MakeTree(kStretchTreeDepth)
tempTree = nil
# Create a long lived object
echo(" Creating a long-lived binary tree of depth " &
$kLongLivedTreeDepth)
new(longLivedTree)
Populate(kLongLivedTreeDepth, longLivedTree)
# Create long-lived array, filling half of it
echo(" Creating a long-lived array of " & $kArraySize & " doubles")
myarray = []
setlength(myarray, kArraySize)
for i in 0..kArraySize div 2 -1:
myarray[i] = 1.0 / toFloat(i)
PrintDiagnostics()
var d = kMinTreeDepth
while d <= kMaxTreeDepth:
TimeConstruction(d)
inc(d, 2)
if longLivedTree == nil or myarray[1000] != 1.0/1000.0:
echo("Failed")
# fake reference to LongLivedTree
# and array to keep them from being optimized away
var elapsed = getStartMilsecs() - t
PrintDiagnostics()
echo("Completed in " & $elapsed & "ms.")
main()

63
tests/bench/prof.c Executable file
View file

@ -0,0 +1,63 @@
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
/* A very simple profiler. Note that it should be possible to */
/* get function level information by concatenating this with nm */
/* output and running the result through the sort utility. */
/* This assumes that all interesting parts of the executable */
/* are statically linked. */
static size_t buf_size;
static u_short *profil_buf;
# ifdef __i386__
# ifndef COMPRESSION
# define COMPRESSION 1
# endif
# define TEXT_START 0x08000000
# define PTR_DIGS 8
# endif
# ifdef __ia64__
# ifndef COMPRESSION
# define COMPRESSION 8
# endif
# define TEXT_START 0x4000000000000000
# define PTR_DIGS 16
# endif
extern int etext;
/*
* Note that the ith entry in the profile buffer corresponds to
* a PC value of TEXT_START + i * COMPRESSION * 2.
* The extra factor of 2 is not apparent from the documentation,
* but it is explicit in the glibc source.
*/
void init_profiling()
{
buf_size = ((size_t)(&etext) - TEXT_START + 0x10)/COMPRESSION/2;
profil_buf = calloc(buf_size, sizeof(u_short));
if (profil_buf == 0) {
fprintf(stderr, "Could not allocate profile buffer\n");
}
profil(profil_buf, buf_size * sizeof(u_short),
TEXT_START, 65536/COMPRESSION);
}
void dump_profile()
{
size_t i;
size_t sum = 0;
for (i = 0; i < buf_size; ++i) {
if (profil_buf[i] != 0) {
fprintf(stderr, "%0*lx\t%d !PROF!\n",
PTR_DIGS,
TEXT_START + i * COMPRESSION * 2,
profil_buf[i]);
sum += profil_buf[i];
}
}
fprintf(stderr, "Total number of samples was %ld !PROF!\n", sum);
}

9
tests/gc.bpf Executable file
View file

@ -0,0 +1,9 @@
USEUNIT("morc_gen\gctest.c");
USEUNIT("..\lib\dlmalloc.c");
USEUNIT("..\lib\morc_gen\io.c");
USEUNIT("..\lib\morc_gen\strutils.c");
USEUNIT("..\lib\morc_gen\system.c");
//---------------------------------------------------------------------------
This file is used by the project manager only and should be treated like the project file
main

85
tests/gc.bpr Executable file
View file

@ -0,0 +1,85 @@
<?xml version='1.0' encoding='utf-8' ?>
<!-- C++Builder XML Project -->
<PROJECT>
<MACROS>
<VERSION value="BCB.05.03"/>
<PROJECT value="gc.exe"/>
<OBJFILES value="morc_gen\gctest.obj ..\lib\dlmalloc.obj ..\lib\morc_gen\io.obj
..\lib\morc_gen\strutils.obj ..\lib\morc_gen\system.obj"/>
<RESFILES value=""/>
<DEFFILE value=""/>
<RESDEPEN value="$(RESFILES)"/>
<LIBFILES value=""/>
<LIBRARIES value=""/>
<SPARELIBS value=""/>
<PACKAGES value="Vcl50.bpi Vclx50.bpi bcbsmp50.bpi dclocx50.bpi bcb2kaxserver50.bpi"/>
<PATHCPP value=".;morc_gen;..\lib;..\lib\morc_gen"/>
<PATHPAS value=".;"/>
<PATHRC value=".;"/>
<PATHASM value=".;"/>
<DEBUGLIBPATH value="$(BCB)\lib\debug"/>
<RELEASELIBPATH value="$(BCB)\lib\release"/>
<LINKER value="tlink32"/>
<USERDEFINES value="_DEBUG"/>
<SYSDEFINES value="NO_STRICT;_NO_VCL;_RTLDLL;USEPACKAGES"/>
<MAINSOURCE value="gc.bpf"/>
<INCLUDEPATH value="..\lib\morc_gen;..\lib;morc_gen;$(BCB)\include;$(BCB)\include\vcl"/>
<LIBPATH value="..\lib\morc_gen;..\lib;morc_gen;$(BCB)\lib\obj;$(BCB)\lib"/>
<WARNINGS value="-w-par"/>
</MACROS>
<OPTIONS>
<CFLAG1 value="-tWC -tWM- -Od -H=$(BCB)\lib\vcl50.csm -Hc -Vx -Ve -X- -r- -a8 -b- -k -y
-v -vi- -c"/>
<PFLAGS value="-$YD -$W -$O- -v -JPHNE -M"/>
<RFLAGS value=""/>
<AFLAGS value="/mx /w2 /zd"/>
<LFLAGS value="-Tpe -ap -D&quot;&quot; -x -Gn -v"/>
</OPTIONS>
<LINKER>
<ALLOBJ value="c0x32.obj $(PACKAGES) $(OBJFILES)"/>
<ALLRES value="$(RESFILES)"/>
<ALLLIB value="$(LIBFILES) $(LIBRARIES) import32.lib cw32i.lib"/>
</LINKER>
<IDEOPTIONS>
[Version Info]
IncludeVerInfo=0
AutoIncBuild=0
MajorVer=1
MinorVer=0
Release=0
Build=0
Debug=0
PreRelease=0
Special=0
Private=0
DLL=0
Locale=1031
CodePage=1252
[Version Info Keys]
CompanyName=
FileDescription=
FileVersion=1.0.0.0
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=1.0.0.0
Comments=
[Debugging]
DebugSourceDirs=$(BCB)\source\vcl
[Parameters]
RunParams=
HostApplication=
RemoteHost=
RemotePath=
RemoteDebug=0
[Compiler]
ShowInfoMsgs=0
LinkDebugVcl=0
</IDEOPTIONS>
</PROJECT>

161
tests/gctest.nim Executable file
View file

@ -0,0 +1,161 @@
# Test the garbage collector:
# This file is not in the test suite because it takes too much time.
import
strutils
type
PNode = ref TNode
TNode = record
le, ri: PNode
data: string
TTable = record
counter, max: int
data: seq[string]
TBNode = record
other: PNode # a completely different tree
data: string
sons: seq[TBNode] # directly embedded!
t: TTable
TCaseKind = enum nkStr, nkList
PCaseNode = ref TCaseNode
TCaseNode = record
case kind: TCaseKind
of nkStr: data: string
of nkList: sons: seq[PCaseNode]
proc newCaseNode(data: string): PCaseNode =
new(result)
result.kind = nkStr
result.data = data
proc newCaseNode(a, b: PCaseNode): PCaseNode =
new(result)
result.kind = nkList
result.sons = [a, b]
proc caseTree(lvl: int = 0): PCaseNode =
if lvl == 3: result = newCaseNode("data item")
else: result = newCaseNode(caseTree(lvl+1), caseTree(lvl+1))
proc finalizeBNode(n: TBNode) = writeln(stdout, n.data)
proc finalizeNode(n: PNode) =
assert(n != nil)
writeln(stdout, n.data)
var
id: int = 1
proc buildTree(depth = 1): PNode =
if depth == 7: return nil
new(result, finalizeNode)
result.le = buildTree(depth+1)
result.ri = buildTree(depth+1)
result.data = $id
inc(id)
proc returnTree(): PNode =
writeln(stdout, "creating id: " & $id)
new(result, finalizeNode)
result.data = $id
new(result.le, finalizeNode)
result.le.data = $id & ".1"
new(result.ri, finalizeNode)
result.ri.data = $id & ".2"
inc(id)
# now create a cycle:
writeln(stdout, "creating id (cyclic): " & $id)
var cycle: PNode
new(cycle, finalizeNode)
cycle.data = $id
cycle.le = cycle
cycle.ri = cycle
inc(id)
#writeln(stdout, "refcount: " & $refcount(cycle))
#writeln(stdout, "refcount le: " & $refcount(cycle.le))
#writeln(stdout, "refcount ri: " & $refcount(cycle.ri))
proc printTree(t: PNode) =
if t == nil: return
writeln(stdout, "printing")
writeln(stdout, t.data)
printTree(t.le)
printTree(t.ri)
proc unsureNew(result: var PNode) =
writeln(stdout, "creating unsure id: " & $id)
new(result, finalizeNode)
result.data = $id
new(result.le, finalizeNode)
result.le.data = $id & ".1"
new(result.ri, finalizeNode)
result.ri.data = $id & ".2"
inc(id)
proc setSons(n: var TBNode) =
n.sons = [] # free memory of the sons
n.t.data = []
var
m: seq[string]
m = []
setLen(m, len(n.t.data) * 2)
for i in 0..high(m):
m[i] = "..."
n.t.data = m
proc buildBTree(father: var TBNode) =
father.data = "father"
father.other = nil
father.sons = []
for i in 1..10:
var n: TBNode
n.other = returnTree()
n.data = "B node: " & $i
if i mod 1 == 0: n.sons = [] # nil and [] need to be handled correctly!
add father.sons, n
father.t.counter = 0
father.t.max = 3
father.t.data = ["ha", "lets", "stress", "it"]
setSons(father)
proc main() =
var
father: TBNode
for i in 1..1_00:
buildBTree(father)
for i in 1..1_00:
var t = returnTree()
var t2: PNode
unsureNew(t2)
write(stdout, "now building bigger trees: ")
var t2: PNode
for i in 1..100:
t2 = buildTree()
printTree(t2)
write(stdout, "now test sequences of strings:")
var s: seq[string] = []
for i in 1..100:
add s, "hohoho" # test reallocation
writeln(stdout, s[89])
write(stdout, "done!\n")
#main()
#GC_disable()
writeln(stdout, repr(caseTree()))
var
father: TBNode
buildBTree(father)
write(stdout, repr(father))
var t = buildTree()
write(stdout, repr(t^))
write(stdout, "starting main...\n")
main()
write(stdout, "finished\n")

14
tests/gtk/ex1.nim Executable file
View file

@ -0,0 +1,14 @@
import
cairo, glib2, gtk2
proc destroy(widget: pGtkWidget, data: pgpointer) {.cdecl.} =
gtk_main_quit()
var
window: pGtkWidget
gtk_nimrod_init()
window = gtk_window_new(GTK_WINDOW_TOPLEVEL)
discard gtk_signal_connect(GTKOBJECT(window), "destroy",
GTK_SIGNAL_FUNC(destroy), nil)
gtk_widget_show(window)
gtk_main()

21
tests/gtk/ex2.nim Executable file
View file

@ -0,0 +1,21 @@
import
glib2, gtk2
proc destroy(widget: pGtkWidget, data: pgpointer){.cdecl.} =
gtk_main_quit()
var
window: PGtkWidget
button: PGtkWidget
gtk_nimrod_init()
window = gtk_window_new(GTK_WINDOW_TOPLEVEL)
button = gtk_button_new_with_label("Click me")
gtk_container_set_border_width(GTK_CONTAINER(Window), 5)
gtk_container_add(GTK_Container(window), button)
discard gtk_signal_connect(GTKOBJECT(window), "destroy",
GTK_SIGNAL_FUNC(destroy), nil)
gtk_widget_show(button)
gtk_widget_show(window)
gtk_main()

39
tests/gtk/ex3.nim Executable file
View file

@ -0,0 +1,39 @@
import
glib2, gtk2
proc newbutton(ALabel: cstring): PGtkWidget =
Result = gtk_button_new_with_label(ALabel)
gtk_widget_show(result)
proc destroy(widget: pGtkWidget, data: pgpointer){.cdecl.} =
gtk_main_quit()
var
window, totalbox, hbox, vbox: PgtkWidget
gtk_nimrod_init()
window = gtk_window_new(GTK_WINDOW_TOPLEVEL) # Box to divide window in 2 halves:
totalbox = gtk_vbox_new(true, 10)
gtk_widget_show(totalbox) # A box for each half of the screen:
hbox = gtk_hbox_new(false, 5)
gtk_widget_show(hbox)
vbox = gtk_vbox_new(true, 5)
gtk_widget_show(vbox) # Put boxes in their halves
gtk_box_pack_start(GTK_BOX(totalbox), hbox, true, true, 0)
gtk_box_pack_start(GTK_BOX(totalbox), vbox, true, true, 0) # Now fill boxes with buttons.
# Horizontal box
gtk_box_pack_start(GTK_BOX(hbox), newbutton("Button 1"), false, false, 0)
gtk_box_pack_start(GTK_BOX(hbox), newbutton("Button 2"), false, false, 0)
gtk_box_pack_start(GTK_BOX(hbox), newbutton("Button 3"), false, false, 0) #
# Vertical box
gtk_box_pack_start(GTK_BOX(vbox), newbutton("Button A"), true, true, 0)
gtk_box_pack_start(GTK_BOX(vbox), newbutton("Button B"), true, true, 0)
gtk_box_pack_start(GTK_BOX(vbox), newbutton("Button C"), true, true, 0) # Put
# totalbox in window
gtk_container_set_border_width(GTK_CONTAINER(Window), 5)
gtk_container_add(GTK_Container(window), totalbox)
discard gtk_signal_connect(GTKOBJECT(window), "destroy",
GTK_SIGNAL_FUNC(destroy), nil)
gtk_widget_show(window)
gtk_main()

31
tests/gtk/ex4.nim Executable file
View file

@ -0,0 +1,31 @@
import
glib2, gtk2
proc newbutton(ALabel: cstring): PGtkWidget =
Result = gtk_button_new_with_label(ALabel)
gtk_widget_show(result)
proc destroy(widget: pGtkWidget, data: pgpointer){.cdecl.} =
gtk_main_quit()
var
window, maintable: PgtkWidget
proc AddToTable(Widget: PGtkWidget, Left, Right, Top, Bottom: guint) =
gtk_table_attach_defaults(GTK_TABLE(MainTable), Widget, Left, right, top,
bottom)
gtk_nimrod_init()
window = gtk_window_new(GTK_WINDOW_TOPLEVEL)
Maintable = gtk_table_new(6, 6, True)
gtk_widget_show(MainTable)
AddToTable(newbutton("1,1 At 1,1"), 1, 2, 1, 2)
AddToTable(newbutton("2,2 At 3,1"), 3, 5, 1, 3)
AddToTable(newbutton("4,1 At 4,1"), 1, 5, 4, 5) # Put all in window
gtk_container_set_border_width(GTK_CONTAINER(Window), 5)
gtk_container_add(GTK_Container(window), maintable)
discard gtk_signal_connect(GTKOBJECT(window), "destroy",
GTK_SIGNAL_FUNC(destroy), nil)
gtk_widget_show(window)
gtk_main()

24
tests/gtk/ex5.nim Executable file
View file

@ -0,0 +1,24 @@
import
glib2, gtk2
proc destroy(widget: pGtkWidget, data: pgpointer){.cdecl.} =
gtk_main_quit()
var
window: PGtkWidget
button: PGtkWidget
gtk_nimrod_init()
window = gtk_window_new(GTK_WINDOW_TOPLEVEL)
button = gtk_button_new_with_label("Click me")
gtk_container_set_border_width(GTK_CONTAINER(Window), 5)
gtk_container_add(GTK_Container(window), button)
discard gtk_signal_connect(GTKOBJECT(window), "destroy",
GTK_SIGNAL_FUNC(destroy), nil)
discard gtk_signal_connect_object(GTKOBJECT(button), "clicked",
GTK_SIGNAL_FUNC(gtk_widget_destroy),
GTKOBJECT(window))
gtk_widget_show(button)
gtk_widget_show(window)
gtk_main()

52
tests/gtk/ex6.nim Executable file
View file

@ -0,0 +1,52 @@
import
glib2, gtk2
type
TButtonSignalState = record
Obj: PgtkObject
SignalID: int32
Disable: bool
PButtonSignalState = ptr TButtonSignalState
proc destroy(widget: pGtkWidget, data: pgpointer){.cdecl.} =
gtk_main_quit()
proc disablesignal(widget: pGtkWidget, data: pgpointer){.cdecl.} =
if PButtonSignalState(Data).Disable:
gtk_signal_handler_block(PButtonSignalState(Data).Obj, SignalID)
else:
gtk_signal_handler_unblock(PButtonSignalState(Data).Obj, SignalID)
PButtonSignalState(Data).disable = not PButtonSignalState(Data).disable
var
window: PGtkWidget
quitbutton: PGtkWidget
disablebutton: PGTKWidget
windowbox: PGTKWidget
quitsignal: guint
QuitState: TButtonSignalState
gtk_nimrod_init()
window = gtk_window_new(GTK_WINDOW_TOPLEVEL)
quitbutton = gtk_button_new_with_label("Quit program")
disablebutton = gtk_button_new_with_label("Disable button")
windowbox = gtk_vbox_new(TRUE, 10)
gtk_box_pack_start(GTK_BOX(windowbox), disablebutton, True, false, 0)
gtk_box_pack_start(GTK_BOX(windowbox), quitbutton, True, false, 0)
gtk_container_set_border_width(GTK_CONTAINER(Window), 10)
gtk_container_add(GTK_Container(window), windowbox)
gtk_signal_connect(GTKOBJECT(window), "destroy",
GTK_SIGNAL_FUNC(destroy), nil)
QuitState.Obj = GTKObject(QuitButton)
SignalID = gtk_signal_connect_object(QuitState.Obj, "clicked", GTK_SIGNAL_FUNC(
gtk_widget_destroy), GTKOBJECT(window))
QuitState.Disable = True
discard gtk_signal_connect(GTKOBJECT(disablebutton), "clicked",
GTK_SIGNAL_FUNC(disablesignal), addr(QuitState))
gtk_widget_show(quitbutton)
gtk_widget_show(disablebutton)
gtk_widget_show(windowbox)
gtk_widget_show(window)
gtk_main()

43
tests/gtk/ex7.nim Executable file
View file

@ -0,0 +1,43 @@
import
gdk2, glib2, gtk2
proc destroy(widget: pGtkWidget, data: pgpointer){.cdecl.} =
gtk_main_quit()
const
Inside: cstring = "Mouse is over label"
OutSide: cstring = "Mouse is not over label"
var
OverLabel: bool
window, box1, box2, stackbox, label1, Label2: PGtkWidget
proc ChangeLabel(P: PGtkWidget, Event: PGdkEventCrossing,
Data: var bool){.cdecl.} =
if not Data: gtk_label_set_text(GTKLABEL(Label2), Inside)
else: gtk_label_set_text(GTKLABEL(Label2), Outside)
Data = not Data
gtk_nimrod_init()
window = gtk_window_new(GTK_WINDOW_TOPLEVEL)
stackbox = gtk_vbox_new(TRUE, 10)
box1 = gtk_event_box_new()
label1 = gtk_label_new("Move mouse over label")
gtk_container_add(GTK_CONTAINER(box1), label1)
box2 = gtk_event_box_new()
label2 = gtk_label_new(OutSide)
gtk_container_add(GTK_CONTAINER(box2), label2)
gtk_box_pack_start(GTK_BOX(stackbox), box1, TRUE, TRUE, 0)
gtk_box_pack_start(GTK_BOX(stackbox), box2, TRUE, TRUE, 0)
gtk_container_set_border_width(GTK_CONTAINER(Window), 5)
gtk_container_add(GTK_Container(window), stackbox)
discard gtk_signal_connect(GTKOBJECT(window), "destroy",
GTK_SIGNAL_FUNC(destroy), nil)
overlabel = False
discard gtk_signal_connect(GTKOBJECT(box1), "enter_notify_event",
GTK_SIGNAL_FUNC(ChangeLabel), addr(Overlabel))
discard gtk_signal_connect(GTKOBJECT(box1), "leave_notify_event",
GTK_SIGNAL_FUNC(ChangeLabel), addr(Overlabel))
gtk_widget_show_all(window)
gtk_main()

32
tests/gtk/ex8.nim Executable file
View file

@ -0,0 +1,32 @@
import
glib2, gtk2
proc destroy(widget: pGtkWidget, data: pgpointer){.cdecl.} =
gtk_main_quit()
var
window, stackbox, label1, Label2: PGtkWidget
labelstyle: pgtkstyle
gtk_nimrod_init()
window = gtk_window_new(GTK_WINDOW_TOPLEVEL)
stackbox = gtk_vbox_new(TRUE, 10)
label1 = gtk_label_new("Red label text")
labelstyle = gtk_style_copy(gtk_widget_get_style(label1))
LabelStyle.fg[GTK_STATE_NORMAL].pixel = 0
LabelStyle.fg[GTK_STATE_NORMAL].red = 0x0000FFFF
LabelStyle.fg[GTK_STATE_NORMAL].blue = 0
LabelStyle.fg[GTK_STATE_NORMAL].green = 0
gtk_widget_set_style(label1, labelstyle) # Uncomment this to see the effect of setting the default style.
#
# gtk_widget_set_default_style(labelstyle)
label2 = gtk_label_new("Black label text")
gtk_box_pack_start(GTK_BOX(stackbox), label1, TRUE, TRUE, 0)
gtk_box_pack_start(GTK_BOX(stackbox), label2, TRUE, TRUE, 0)
gtk_container_set_border_width(GTK_CONTAINER(Window), 5)
gtk_container_add(GTK_Container(window), stackbox)
discard gtk_signal_connect(GTKOBJECT(window), "destroy",
GTK_SIGNAL_FUNC(destroy), nil)
gtk_widget_show_all(window)
gtk_main()

47
tests/gtk/ex9.nim Executable file
View file

@ -0,0 +1,47 @@
import
gdk2, glib2, gtk2
proc destroy(widget: pGtkWidget, data: pgpointer){.cdecl.} =
gtk_main_quit()
const
Inside: cstring = "Mouse is over label"
OutSide: cstring = "Mouse is not over label"
var
window, button1, Button2, Alabel, stackbox: PGtkWidget
buttonstyle: pgtkstyle
OverButton: bool
proc ChangeLabel(P: PGtkWidget, Event: PGdkEventCrossing, Data: var bool){.cdecl.} =
if Not Data: gtk_label_set_text(GTKLABEL(ALabel), Inside)
else: gtk_label_set_text(GTKLABEL(ALabel), Outside)
Data = Not Data
gtk_nimrod_init()
window = gtk_window_new(GTK_WINDOW_TOPLEVEL)
stackbox = gtk_vbox_new(TRUE, 10)
button1 = gtk_button_new_with_label("Move mouse over button")
buttonstyle = gtk_style_copy(gtk_widget_get_style(Button1))
ButtonStyle.bg[GTK_STATE_PRELIGHT].pixel = 0
ButtonStyle.bg[GTK_STATE_PRELIGHT].red = 0x0000FFFF
ButtonStyle.bg[GTK_STATE_PRELIGHT].blue = 0
ButtonStyle.bg[GTK_STATE_PRELIGHT].green = 0
gtk_widget_set_style(button1, buttonstyle)
button2 = gtk_button_new()
ALabel = gtk_label_new(Outside)
gtk_container_add(GTK_CONTAINER(button2), ALAbel)
gtk_box_pack_start(GTK_BOX(stackbox), button1, TRUE, TRUE, 0)
gtk_box_pack_start(GTK_BOX(stackbox), button2, TRUE, TRUE, 0)
gtk_container_set_border_width(GTK_CONTAINER(Window), 5)
gtk_container_add(GTK_Container(window), stackbox)
discard gtk_signal_connect(GTKOBJECT(window), "destroy",
GTK_SIGNAL_FUNC(destroy), nil)
overbutton = False
discard gtk_signal_connect(GTKOBJECT(button1), "enter_notify_event",
GTK_SIGNAL_FUNC(ChangeLabel), addr(OverButton))
discard gtk_signal_connect(GTKOBJECT(button1), "leave_notify_event",
GTK_SIGNAL_FUNC(ChangeLabel), addr(OverButton))
gtk_widget_show_all(window)
gtk_main()

10
tests/hallo.bpf Executable file
View file

@ -0,0 +1,10 @@
USEUNIT("rod_gen\thallo.c");
USEUNIT("..\lib\rod_gen\os.c");
USEUNIT("..\lib\rod_gen\strutils.c");
USEUNIT("..\lib\rod_gen\system.c");
USEUNIT("..\lib\rod_gen\times.c");
USEUNIT("..\lib\dlmalloc.c");
//---------------------------------------------------------------------------
This file is used by the project manager only and should be treated like the project file
main

102
tests/hallo.bpr Executable file
View file

@ -0,0 +1,102 @@
<?xml version='1.0' encoding='utf-8' ?>
<!-- C++Builder XML Project -->
<PROJECT>
<MACROS>
<VERSION value="BCB.05.03"/>
<PROJECT value="hallo.exe"/>
<OBJFILES value="rod_gen\thallo.obj ..\lib\rod_gen\os.obj ..\lib\rod_gen\strutils.obj
..\lib\rod_gen\system.obj ..\lib\rod_gen\times.obj ..\lib\dlmalloc.obj"/>
<RESFILES value=""/>
<DEFFILE value=""/>
<RESDEPEN value="$(RESFILES)"/>
<LIBFILES value=""/>
<LIBRARIES value=""/>
<SPARELIBS value=""/>
<PACKAGES value="Vcl50.bpi Vclx50.bpi bcbsmp50.bpi dclocx50.bpi bcb2kaxserver50.bpi"/>
<PATHCPP value=".;rod_gen;..\lib\rod_gen;..\lib"/>
<PATHPAS value=".;"/>
<PATHRC value=".;"/>
<PATHASM value=".;"/>
<DEBUGLIBPATH value="$(BCB)\lib\debug"/>
<RELEASELIBPATH value="$(BCB)\lib\release"/>
<LINKER value="tlink32"/>
<USERDEFINES value="_DEBUG"/>
<SYSDEFINES value="NO_STRICT;_NO_VCL;_RTLDLL;USEPACKAGES"/>
<MAINSOURCE value="hallo.bpf"/>
<INCLUDEPATH value="..\lib\rod_gen;rod_gen;$(BCB)\include;$(BCB)\include\vcl;..\lib"/>
<LIBPATH value="..\lib;..\lib\rod_gen;rod_gen;$(BCB)\lib\obj;$(BCB)\lib"/>
<WARNINGS value="-w-par"/>
</MACROS>
<OPTIONS>
<CFLAG1 value="-Od -H=$(BCB)\lib\vcl50.csm -Hc -Vx -Ve -X- -r- -a8 -b- -k -y -v -vi- -tWC
-tWM- -c"/>
<PFLAGS value="-$YD -$W -$O- -v -JPHNE -M"/>
<RFLAGS value=""/>
<AFLAGS value="/mx /w2 /zd"/>
<LFLAGS value="-D&quot;&quot; -ap -Tpe -x -Gn -v"/>
</OPTIONS>
<LINKER>
<ALLOBJ value="c0x32.obj $(PACKAGES) $(OBJFILES)"/>
<ALLRES value="$(RESFILES)"/>
<ALLLIB value="$(LIBFILES) $(LIBRARIES) import32.lib cw32i.lib"/>
</LINKER>
<IDEOPTIONS>
[Version Info]
IncludeVerInfo=0
AutoIncBuild=0
MajorVer=1
MinorVer=0
Release=0
Build=0
Debug=0
PreRelease=0
Special=0
Private=0
DLL=0
Locale=1031
CodePage=1252
[Version Info Keys]
CompanyName=
FileDescription=
FileVersion=1.0.0.0
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=1.0.0.0
Comments=
[HistoryLists\hlIncludePath]
Count=2
Item0=..\lib\rod_gen;rod_gen;$(BCB)\include;$(BCB)\include\vcl;E:\nimrod\lib
Item1=..\lib\rod_gen;rod_gen;$(BCB)\include;$(BCB)\include\vcl
[HistoryLists\hlLibraryPath]
Count=1
Item0=..\lib\rod_gen;rod_gen;$(BCB)\lib\obj;$(BCB)\lib
[HistoryLists\hlDebugSourcePath]
Count=1
Item0=$(BCB)\source\vcl
[HistoryLists\hlConditionals]
Count=1
Item0=_DEBUG
[Debugging]
DebugSourceDirs=$(BCB)\source\vcl
[Parameters]
RunParams=
HostApplication=
RemoteHost=
RemotePath=
RemoteDebug=0
[Compiler]
ShowInfoMsgs=0
LinkDebugVcl=0
</IDEOPTIONS>
</PROJECT>

10
tests/iotest.bpf Executable file
View file

@ -0,0 +1,10 @@
USEUNIT("tio.c");
USEUNIT("..\lib\refcgc.c");
USEUNIT("..\lib\io.c");
USEUNIT("..\lib\morbase.c");
USEUNIT("..\lib\morlib.c");
//---------------------------------------------------------------------------
This file is used by the project manager only and should be treated like the project file
main

84
tests/iotest.bpr Executable file
View file

@ -0,0 +1,84 @@
<?xml version='1.0' encoding='utf-8' ?>
<!-- C++Builder XML Project -->
<PROJECT>
<MACROS>
<VERSION value="BCB.05.03"/>
<PROJECT value="iotest.exe"/>
<OBJFILES value="tio.obj ..\lib\refcgc.obj ..\lib\io.obj ..\lib\morbase.obj ..\lib\morlib.obj"/>
<RESFILES value=""/>
<DEFFILE value=""/>
<RESDEPEN value="$(RESFILES)"/>
<LIBFILES value=""/>
<LIBRARIES value=""/>
<SPARELIBS value=""/>
<PACKAGES value="Vcl50.bpi Vclx50.bpi bcbsmp50.bpi dclocx50.bpi bcb2kaxserver50.bpi"/>
<PATHCPP value=".;..\lib"/>
<PATHPAS value=".;"/>
<PATHRC value=".;"/>
<PATHASM value=".;"/>
<DEBUGLIBPATH value="$(BCB)\lib\debug"/>
<RELEASELIBPATH value="$(BCB)\lib\release"/>
<LINKER value="tlink32"/>
<USERDEFINES value="_DEBUG"/>
<SYSDEFINES value="NO_STRICT;_NO_VCL;_RTLDLL;USEPACKAGES"/>
<MAINSOURCE value="iotest.bpf"/>
<INCLUDEPATH value="..\lib;$(BCB)\include;$(BCB)\include\vcl"/>
<LIBPATH value="..\lib;$(BCB)\lib\obj;$(BCB)\lib"/>
<WARNINGS value="-w-par"/>
</MACROS>
<OPTIONS>
<CFLAG1 value="-Od -H=$(BCB)\lib\vcl50.csm -Hc -w- -Vx -Ve -X- -r- -a8 -b- -k -y -v -vi-
-tWC -tWM- -c"/>
<PFLAGS value="-$YD -$W -$O- -v -JPHNE -M"/>
<RFLAGS value=""/>
<AFLAGS value="/mx /w2 /zd"/>
<LFLAGS value="-D&quot;&quot; -ap -Tpe -x -Gn -v"/>
</OPTIONS>
<LINKER>
<ALLOBJ value="c0x32.obj $(PACKAGES) $(OBJFILES)"/>
<ALLRES value="$(RESFILES)"/>
<ALLLIB value="$(LIBFILES) $(LIBRARIES) import32.lib cw32i.lib"/>
</LINKER>
<IDEOPTIONS>
[Version Info]
IncludeVerInfo=0
AutoIncBuild=0
MajorVer=1
MinorVer=0
Release=0
Build=0
Debug=0
PreRelease=0
Special=0
Private=0
DLL=0
Locale=1031
CodePage=1252
[Version Info Keys]
CompanyName=
FileDescription=
FileVersion=1.0.0.0
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=1.0.0.0
Comments=
[Debugging]
DebugSourceDirs=$(BCB)\source\vcl
[Parameters]
RunParams=
HostApplication=
RemoteHost=
RemotePath=
RemoteDebug=0
[Compiler]
ShowInfoMsgs=0
LinkDebugVcl=0
</IDEOPTIONS>
</PROJECT>

9
tests/mambsym1.nim Executable file
View file

@ -0,0 +1,9 @@
import mambsym2 # import TExport
type
TExport* = enum x, y, z
proc ha() =
var
x: TExport # no error
nil

2
tests/mambsym2.nim Executable file
View file

@ -0,0 +1,2 @@
type
TExport* = enum x, y, z # exactly the same type!

7
tests/mambsys1.nim Executable file
View file

@ -0,0 +1,7 @@
import mambsys2 # import TExport
type
TExport* = enum x, y, z
proc foo*(x: int) =
nil

4
tests/mambsys2.nim Executable file
View file

@ -0,0 +1,4 @@
type
TExport* = enum x, y, z # exactly the same type!
proc foo*(x: int) = nil

6
tests/minit.nim Executable file
View file

@ -0,0 +1,6 @@
# Test the new initialization for modules
import
io
write(stdout, "Hallo from module! ")

2
tests/mnamspc1.nim Executable file
View file

@ -0,0 +1,2 @@
import mnamspc2

3
tests/mnamspc2.nim Executable file
View file

@ -0,0 +1,3 @@
# export an identifier:
var
global*: int

5
tests/mopaque.nim Executable file
View file

@ -0,0 +1,5 @@
type
TLexer* = record
line*: int
filename*: string
buffer: cstring

1
tests/mrecmod.nim Executable file
View file

@ -0,0 +1 @@
import trecmod

6
tests/mvarious.nim Executable file
View file

@ -0,0 +1,6 @@
# Test a submodule
#type
# TStringArr = array [0.. *] of string
proc exportme* = nil

28
tests/readme.txt Executable file
View file

@ -0,0 +1,28 @@
Note: Most test cases are not up to date to the current Nimrod
version. Only ``thallo`` is frequently tested! The best test is
to bootstrap, anyway.
This directory contains the test cases.
Each test must have a filename of the form: ``t*.nim``
The testcases may contain the directives ``#ERROR``, ``#ERROR_IN``,
``#ERROR_MSG`` or ``#OUT``.
``#ERROR`` is used to indicate that the compiler should report
an error in the marked line (the line that contains the ``#ERROR``
directive.)
The format for ``#ERROR_IN`` is::
#ERROR_IN filename linenumber
You can omit the extension of the filename (``.nim`` is then assumed).
The format for ``#ERROR_MSG`` is::
#ERROR_MSG message
This directive specifies the error message Nimrod shall produce.
Tests which contain none of the ``#ERROR*`` directives should compile.
Thus they are executed after successful compilation and their output
is compared to the expected results (specified with the ``#OUT``
directive). Tests which require user interaction are currently not
possible.

6
tests/rectest/rectest.nim Executable file
View file

@ -0,0 +1,6 @@
# Test the error message
proc main() =
main()
main()

62
tests/scantest.nim Executable file
View file

@ -0,0 +1,62 @@
# We start with a comment
# This is the same comment
# This is a new one!
# This should not be allowed!
export
main
import
lexbase, os, strutils
type
TMyRec = record # describes a record
x, y: int # coordinates
c: char # a character
a: int32 # an integer
PMyRec = ref TMyRec # a reference to `TMyRec`
proc splitText(txt: string): seq[string] # splits a text into several lines
# the comment continues here
# this is not easy to parse!
proc anotherSplit(txt: string): list[string] =
# the comment should belong to `anotherSplit`!
# another problem: comments are statements!
const
x = 0B0_10001110100_0000101001000111101011101111111011000101001101001001'f64 # x ~~ 1.72826e35
myNan = 0B01111111100000101100000000001000'f32 # NAN
y = """
a rather long text.
Over many
lines.
"""
s = "\xff"
a = {0..234}
b = {0..high(int)}
v = 0'i32
z = 6767566'f32
# small test program for lexbase
proc main*(infile: string, a, b: int, someverylongnamewithtype = 0,
anotherlongthingie = 3) =
var
myInt: int = 0
a b = 9
s: sequence[string]
# this should be an error!
if initBaseLexer(L, infile, 30): nil
else:
writeln(stdout, "could not open: " & infile)
writeln(stdout, "Success!")
call(3, # we use 3
12, # we use 12
43 # we use 43
)
main(ParamStr(1))

26
tests/sdltest.nim Executable file
View file

@ -0,0 +1,26 @@
# Test the SDL interface:
import
SDL
var
screen, greeting: PSDL_Surface
r: TSDL_Rect
if SDL_Init(SDL_INIT_VIDEO) == 0:
screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE or SDL_ANYFORMAT)
if screen == nil:
write(stdout, "screen is nil!\n")
else:
greeting = SDL_LoadBmp("backgrnd.bmp")
if greeting == nil:
write(stdout, "greeting is nil!")
r.x = 0
r.y = 0
discard SDL_blitSurface(greeting, nil, screen, addr(r))
discard SDL_flip(screen)
SDL_Delay(3000)
else:
write(stdout, "SDL_Init failed!\n")
SDL_Quit()

8
tests/seqcon.bpf Executable file
View file

@ -0,0 +1,8 @@
USEUNIT("tseqcon.c");
USEUNIT("..\lib\io.c");
USEUNIT("..\lib\morsys.c");
//---------------------------------------------------------------------------
This file is used by the project manager only and should be treated like the project file
main

84
tests/seqcon.bpr Executable file
View file

@ -0,0 +1,84 @@
<?xml version='1.0' encoding='utf-8' ?>
<!-- C++Builder XML Project -->
<PROJECT>
<MACROS>
<VERSION value="BCB.05.03"/>
<PROJECT value="seqcon.exe"/>
<OBJFILES value="tseqcon.obj ..\lib\io.obj ..\lib\morsys.obj"/>
<RESFILES value=""/>
<DEFFILE value=""/>
<RESDEPEN value="$(RESFILES)"/>
<LIBFILES value=""/>
<LIBRARIES value=""/>
<SPARELIBS value=""/>
<PACKAGES value="Vcl50.bpi Vclx50.bpi bcbsmp50.bpi dclocx50.bpi bcb2kaxserver50.bpi"/>
<PATHCPP value=".;..\lib"/>
<PATHPAS value=".;"/>
<PATHRC value=".;"/>
<PATHASM value=".;"/>
<DEBUGLIBPATH value="$(BCB)\lib\debug"/>
<RELEASELIBPATH value="$(BCB)\lib\release"/>
<LINKER value="tlink32"/>
<USERDEFINES value="_DEBUG"/>
<SYSDEFINES value="NO_STRICT;_NO_VCL;_RTLDLL;USEPACKAGES"/>
<MAINSOURCE value="seqcon.bpf"/>
<INCLUDEPATH value="..\lib;$(BCB)\include;$(BCB)\include\vcl"/>
<LIBPATH value="..\lib;$(BCB)\lib\obj;$(BCB)\lib"/>
<WARNINGS value="-w-par"/>
</MACROS>
<OPTIONS>
<CFLAG1 value="-Od -H=$(BCB)\lib\vcl50.csm -Hc -Vx -Ve -X- -r- -pr -a8 -b- -k -y -v -vi-
-tWC -tWM- -c"/>
<PFLAGS value="-$YD -$W -$O- -v -JPHNE -M"/>
<RFLAGS value=""/>
<AFLAGS value="/mx /w2 /zd"/>
<LFLAGS value="-D&quot;&quot; -ap -Tpe -x -Gn -v"/>
</OPTIONS>
<LINKER>
<ALLOBJ value="c0x32.obj $(PACKAGES) $(OBJFILES)"/>
<ALLRES value="$(RESFILES)"/>
<ALLLIB value="$(LIBFILES) $(LIBRARIES) import32.lib cw32i.lib"/>
</LINKER>
<IDEOPTIONS>
[Version Info]
IncludeVerInfo=0
AutoIncBuild=0
MajorVer=1
MinorVer=0
Release=0
Build=0
Debug=0
PreRelease=0
Special=0
Private=0
DLL=0
Locale=1031
CodePage=1252
[Version Info Keys]
CompanyName=
FileDescription=
FileVersion=1.0.0.0
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=1.0.0.0
Comments=
[Debugging]
DebugSourceDirs=$(BCB)\source\vcl
[Parameters]
RunParams=
HostApplication=
RemoteHost=
RemotePath=
RemoteDebug=0
[Compiler]
ShowInfoMsgs=0
LinkDebugVcl=0
</IDEOPTIONS>
</PROJECT>

18
tests/tack.nim Executable file
View file

@ -0,0 +1,18 @@
# the Ackermann function
import
io
proc ack(x, y: int): int =
if x != 0:
if y != 0:
return ack(x-1, ack(x, y-1))
return ack(x-1, 1)
else:
return y + 1
# if x == 0: return y + 1
# elif y == 0: return ack(x-1, 1)
# else: return ack(x-1, ack(x, y-1))
# echo(ack(0, 0))
write(stdout, ack(3, 4)) #OUT 125

6
tests/tambsym.nim Executable file
View file

@ -0,0 +1,6 @@
# Test ambigious symbols
import mambsym1, mambsym2
var
v: TExport #ERROR_MSG ambigious identifier

7
tests/tambsys.nim Executable file
View file

@ -0,0 +1,7 @@
# Test ambigious symbols
import mambsys1, mambsys2
var
v: mambsys1.TExport
mambsys2.foo(3) #OUT

32
tests/tarray.nim Executable file
View file

@ -0,0 +1,32 @@
# simple check for one dimensional arrays
import
io
type
TMyArray = array[0..2, int]
TMyRecord = record
x, y: int
proc sum(a: TMyarray): int =
result = 0
var i = 0
while i < length(a):
inc(result, a[i])
inc(i)
proc sum(a: openarray[int]): int =
result = 0
var i = 0
while i < length(a):
inc(result, a[i])
inc(i)
proc getPos(r: TMyRecord): int =
result = r.x + r.y
write(stdout, sum([1, 2, 3, 4]))
write(stdout, sum([]))
write(stdout, getPos( (x: 5, y: 7) ))
#OUT 10012

13
tests/tarrindx.nim Executable file
View file

@ -0,0 +1,13 @@
# test another strange bug ... (I hate this compiler; it is much too buggy!)
proc putEnv(key, val: string) =
# XXX: we have to leak memory here, as we cannot
# free it before the program ends (says Borland's
# documentation)
var
env: ptr array[0..500000, char]
env = alloc(length(key) + length(val) + 2)
for i in 0..length(key)-1: env[i] = key[i]
env[length(key)] = '='
for i in 0..length(val)-1:
env[length(key)+1+i] = val[i]

19
tests/tassert.nim Executable file
View file

@ -0,0 +1,19 @@
# test assert and exception handling
import
io
proc callB() = assert(False)
proc callA() = callB()
proc callC() = callA()
try:
callC()
except EAssertionFailed:
io.write(stdout, "assertion failure!\n")
except:
io.write(stdout, "unknown exception!\n")
finally:
io.write(stdout, "this shall be always written\n")
assert(false)

34
tests/tassign.nim Executable file
View file

@ -0,0 +1,34 @@
# Test the assignment operator for complex types which need RTTI
import
io
type
TRec = record
x, y: int
s: string
seq: seq[string]
arr: seq[seq[array[0..3, string]]]
TRecSeq = seq[TRec]
proc test() =
var
a, b: TRec
a.x = 1
a.y = 2
a.s = "Hallo!"
a.seq = ["abc", "def", "ghi", "jkl"]
a.arr = []
setLength(a.arr, 4)
a.arr[0] = []
a.arr[1] = []
b = a # perform a deep copy here!
b.seq = ["xyz", "huch", "was", "soll"]
writeln(stdout, length(a.seq))
writeln(stdout, a.seq[3])
writeln(stdout, length(b.seq))
writeln(stdout, b.seq[3])
writeln(stdout, b.y)
test()

15
tests/tblock1.nim Executable file
View file

@ -0,0 +1,15 @@
# check for forward label and
# for failure when label is not declared
import
io
proc main =
block endLess:
break endLess
write(stdout, "Muaahh!\N")
break ha #ERROR
main()

20
tests/tcasestm.nim Executable file
View file

@ -0,0 +1,20 @@
# Test the case statment
type
tenum = enum eA, eB, eC
var
x: string
y: Tenum = eA
case y
of eA: write(stdout, "a\n")
of eB, eC: write(stdout, "b oder c\n")
x = readLine(stdin)
case x
of "Andreas", "Rumpf": write(stdout, "Hallo Meister!\n")
of "aa", "bb": write(stdout, "Du bist nicht mein Meister\n")
of "cc", "hash", "when": nil
of "will", "it", "finally", "be", "generated": nil
else: write(stdout, "das sollte nicht passieren!\N")

14
tests/tcmdline.nim Executable file
View file

@ -0,0 +1,14 @@
# Test the command line
import
os, strutils
var
i: int
params = paramCount()
i = 0
writeln(stdout, "This exe: " & getApplicationFilename())
writeln(stdout, "Number of parameters: " & $params)
while i <= params:
writeln(stdout, paramStr(i))
i = i + 1

29
tests/tconstr1.nim Executable file
View file

@ -0,0 +1,29 @@
# Test array, record constructors
import
io
type
TComplexRecord = record
s: string
x, y: int
z: float
chars: set[Char]
proc testSem =
var
things: array [0..1, TComplexRecord] = [
(chars: {'a', 'b', 'c'}, s: "hi", x: 69, y: 45, z: 0.0),
(chars: {'a', 'b', 'c'}, s: "hi", x: 69, y: 45, z: 1.0)
]
write(stdout, things[0].x)
const
things: array [0..] of TComplexRecord = [
(chars: {'a', 'b', 'c'}, s: "hi", x: 69, y: 45, z: 0.0),
(chars: {'a', 'b', 'c'}, s: "hi", x: 69, y: 45) #ERROR
]
otherThings = [ # the same
(chars: {'a', 'b', 'c'}, s: "hi", x: 69, y: 45, z: 0.0),
(chars: {'a', 'b', 'c'}, s: "hi", x: 69, y: 45)
]

20
tests/tconstr2.nim Executable file
View file

@ -0,0 +1,20 @@
# Test array, record constructors
type
TComplexRecord = record
s: string
x, y: int
z: float
chars: set[char]
const
things: array [0.., TComplexRecord] = [
(chars: {'a', 'b', 'c'}, s: "hi", x: 69, y: 45, z: 0.0),
(chars: {'a', 'b', 'c'}, s: "hi", x: 69, z: 0.3, y: 45)]
otherThings = [ # the same
(chars: {'a', 'b', 'c'}, s: "hi", x: 69, y: 45, z: 0.0),
(z: 0.0, chars: {'a', 'b', 'c'}, s: "hi", x: 69, y: 45)]
write(stdout, things[0].x)
#OUT 69

19
tests/tcopy.nim Executable file
View file

@ -0,0 +1,19 @@
# tests the copy proc
import
strutils, io
proc main() =
const
example = r"TEMP=C:\Programs\xyz\bin"
var
a, b: string
p: int
p = findSubStr("=", example)
a = copy(example, 0, p-1)
b = copy(example, p+1)
writeln(stdout, a & '=' & b)
#writeln(stdout, b)
main()
#OUT TEMP=C:\Programs\xyz\bin

17
tests/tdialogs.nim Executable file
View file

@ -0,0 +1,17 @@
# Test the dialogs module
import dialogs, gtk2
gtk_nimrod_init()
var x = ChooseFilesToOpen(nil)
for a in items(x):
writeln(stdout, a)
info(nil, "start with an info box")
warning(nil, "now a warning ...")
error(nil, "... and an error!")
writeln(stdout, ChooseFileToOpen(nil))
writeln(stdout, ChooseFileToSave(nil))
writeln(stdout, ChooseDir(nil))

3
tests/tendian.nim Executable file
View file

@ -0,0 +1,3 @@
# test the new endian magic
writeln(stdout, repr(system.cpuEndian))

8
tests/tenum.nim Executable file
View file

@ -0,0 +1,8 @@
# Test enums
type
E = enum a, b, c, x, y, z
var
en: E
en = a

6
tests/tformat.nim Executable file
View file

@ -0,0 +1,6 @@
# Tests the new format proc (including the & and &= operators)
import strutils, io
echo("Hi $1! How do you feel, $2?\n" % ["Andreas", "Rumpf"])
#OUT Hi Andreas! How do you feel, Rumpf?

9
tests/tforwty.nim Executable file
View file

@ -0,0 +1,9 @@
# Test 13: forward types
type
PSym = ref TSym
TSym = record
next: PSym
var s: PSym

30
tests/tforwty2.nim Executable file
View file

@ -0,0 +1,30 @@
# Test for a hard to fix internal error
# occured in the SDL library
{.push dynlib: "SDL.dll", callconv: cdecl.}
when defined(windows):
type
PSDL_semaphore = ptr TSDL_semaphore
TSDL_semaphore = record
id: uint32
count: UInt32
elif defined(linux):
type
PSDL_semaphore = ptr TSDL_semaphore
TSDL_semaphore = record
sem: Pointer #PSem_t;
when not defined(USE_NAMED_SEMAPHORES):
sem_data: int
when defined(BROKEN_SEMGETVALUE):
# This is a little hack for MacOS X -
# It's not thread-safe, but it's better than nothing
sem_value: cint
type
PSDL_Sem = ptr TSDL_Sem
TSDL_Sem = TSDL_Semaphore
proc SDL_CreateSemaphore(initial_value: UInt32): PSDL_Sem
{.import: "SDL_CreateSemaphore".}

96
tests/tgeneric.nim Executable file
View file

@ -0,0 +1,96 @@
struct vector3d
{
float V[3];
inline float Evaluate( const int I ) const { return V[I]; }
template< class ta >
inline const vector3d& operator = ( const ta& Exp )
{
V[0] = Exp.Evaluate( 0 );
V[1] = Exp.Evaluate( 1 );
V[2] = Exp.Evaluate( 2 );
}
};
type
TVector3D = record
v: array [0..2, float]
TSum[A, B] = record
TVecExpr2[A, B, op] = record
proc eval(a: TVector3d, i: int): float = a.v[i]
proc eval[T, S](a: T, b: S, i: int): float = eval(a, i) + eval(b, i)
proc `+` [T, S](a, b: TVector3d): TSum[T, S] = return vecExpr2[a, b, TSum]
proc `=` [T](a: var TVector3d, b: T) =
a.v[0] = eval(b, 0)
a.v[1] = eval(b, 1)
a.v[2] = eval(b, 2)
macro `=` (a: var TVector3d, b: expr) =
proc doSomething(a, b: TVector3d): TVector3d =
eliminateTemps:
result = a +^ b +^ a *^ a *^ 7
# result = a
# result +^= b
# tmp = a
# tmp *^= a
# tmp *^= 7
# result +^= tmp
macro vectorOptimizeExpr(n: expr): stmt =
# load the expr n[1] into n[0]
var e = n[1]
if binOp(e) and Operator(e) == "+^":
var m = flattenTree(n[1])
result = newAst(nkStmtList) # ``newAst`` is built-in for any macro
add(result, newAst(nkAsgn, n[0], m[1]))
var tmp: PNode = nil
for i in 2..m.len-1:
if BinOp(m[i]):
if tmp = nil: tmp = getTemp() # reuse temporary if possible
vectorOptimizeExpr(newAst(nkAsgn, tmp, m[i]))
add(result, newAst(nkCall, Operator(m) & "=", n[0], tmp))
else:
add(result, newAst(nkCall, Operator(m) & "=", n[0], m[i]))
macro eliminateTemps(s) {.check.} =
case s.kind
of nkAsgnStmt:
result = vectorOptimizeExpr(s)
else:
result = s
for i in 0..s.sons.len-1: result[i] = eliminateTemps(s[i])
struct sum
{
template< class ta, class tb >
static inline float Evaluate( const int I, const ta& A, const tb& B )
{ return A.Evaluate( I ) + B.Evaluate( I ); }
};
template< class ta_a, class ta_b, class ta_eval >
class vecexp_2
{
const ta_a Arg1;
const ta_b Arg2;
public:
inline vecexp_2( const ta_a& A1, const ta_b& A2 )
: Arg1( A1 ), Arg2( A2 ) {}
inline const float Evaluate ( const int I ) const
{ return ta_eval::Evaluate( I, Arg1, Arg2 ); }
};
template< class ta, class tb > inline
vecexp_2< ta, tb, sum >
inline operator + ( const ta& A, const tb& B )
{
return vecexp_2< const ta, const tb, sum >( A, B );
}

61
tests/tgtk.nim Executable file
View file

@ -0,0 +1,61 @@
import
gtk2, glib2, atk, gdk2, gdk2pixbuf, libglade2, pango,
pangoutils
proc hello(widget: PGtkWidget, data: pointer) {.cdecl.} =
write(stdout, "Hello World\n")
proc delete_event(widget: PGtkWidget, event: PGdkEvent,
data: pointer): bool {.cdecl.} =
# If you return FALSE in the "delete_event" signal handler,
# GTK will emit the "destroy" signal. Returning TRUE means
# you don't want the window to be destroyed.
# This is useful for popping up 'are you sure you want to quit?'
# type dialogs.
write(stdout, "delete event occurred\n")
# Change TRUE to FALSE and the main window will be destroyed with
# a "delete_event".
return false
# Another callback
proc destroy(widget: PGtkWidget, data: pointer) {.cdecl.} =
gtk_main_quit()
proc main() =
# GtkWidget is the storage type for widgets
var
window: PGtkWindow
button: PGtkButton
gtk_nimrod_init()
window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL))
discard g_signal_connect(window, "delete_event",
Gcallback(delete_event), nil)
discard g_signal_connect(window, "destroy", Gcallback(destroy), nil)
# Sets the border width of the window.
gtk_container_set_border_width(window, 10)
# Creates a new button with the label "Hello World".
button = GTK_BUTTON(gtk_button_new_with_label("Hello World"))
discard g_signal_connect(button, "clicked", Gcallback(hello), nil)
# This will cause the window to be destroyed by calling
# gtk_widget_destroy(window) when "clicked". Again, the destroy
# signal could come from here, or the window manager.
discard g_signal_connect_swapped(button, "clicked",
Gcallback(gtk_widget_destroy), window)
# This packs the button into the window (a gtk container).
gtk_container_add(window, button)
# The final step is to display this newly created widget.
gtk_widget_show(button)
# and the window
gtk_widget_show(window)
gtk_main()
main()

6
tests/thallo.dot Executable file
View file

@ -0,0 +1,6 @@
digraph thallo {
times -> strutils;
os -> strutils;
os -> times;
thallo -> os;
}

30
tests/thallo.nim Executable file
View file

@ -0,0 +1,30 @@
# Hallo
import
os
when isMainModule:
{.hint: "this is the main file".}
proc fac[T](x: T): T =
# test recursive generic procs
if x <= 1: return 1
else: return x * fac(x-1)
#GC_disable()
echo("This was compiled by Nimrod version " & system.nimrodVersion)
echo(["a", "b", "c", "d"].len)
for x in items(["What's", "your", "name", "?"]):
echo(x = x)
var `name` = readLine(stdin)
{.breakpoint.}
echo("Hi " & thallo.name & "!\n")
for i in 2..6:
for j in countdown(i+4, 2):
echo(fac(i * j))
when isMainModule:
{.hint: "this is the main file".}

12
tests/tillrec.nim Executable file
View file

@ -0,0 +1,12 @@
# test illegal recursive types
type
TLegal = record
x: int
kids: seq[TLegal]
TIllegal = record
y: Int
x: array[0..3, TIllegal]
#ERROR_MSG illegal recursion in type 'TIllegal'

6
tests/tinit.nim Executable file
View file

@ -0,0 +1,6 @@
# Test the new init section in modules
import minit, io
write(stdout, "Hallo from main module!\n")
#OUT Hallo from module! Hallo from main module!

9
tests/tinout.nim Executable file
View file

@ -0,0 +1,9 @@
# Test in out checking for parameters
proc abc(x: out int) =
x = 0
proc b() =
abc(3) #ERROR
b()

8
tests/tinvwhen.nim Executable file
View file

@ -0,0 +1,8 @@
# This was parsed even though it should not!
proc chdir(path: CString): cint {.import: "chdir", header: "dirHeader".}
proc getcwd(buf: CString, buflen: cint): CString
when defined(unix): {.import: "getcwd", header: "<unistd.h>".} #ERROR
elif defined(windows): {.import: "getcwd", header: "<direct.h>"}
else: {.error: "os library not ported to your OS. Please help!".}

10
tests/tio.nim Executable file
View file

@ -0,0 +1,10 @@
# test the file-IO
import
io
proc main() =
for line in lines("thallo.mor"):
writeln(stdout, line)
main()

39
tests/titer.nim Executable file
View file

@ -0,0 +1,39 @@
# Test the new iterators
import
io
iterator xrange(fromm, to: int, step = 1): (a: int) =
a = fromm
while a <= to:
yield a
inc(a, step)
iterator interval[T](a, b: T): (x: T)
iterator interval[T](a, b: T): (x: T) =
x = a
while x <= b:
yield x
inc(x)
#
#iterator lines(filename: string): (line: string) =
# var
# f: tTextfile
# shouldClose = open(f, filename)
# if shouldClose:
# setSpace(line, 256)
# while readTextLine(f, line):
# yield line
# finally:
# if shouldClose: close(f)
#
for i in xrange(0, 5):
for k in xrange(1, 7):
write(stdout, "test")
for j in interval(45, 45):
write(stdout, "test2!")
write(stdout, "test3?")

16
tests/tlastmod.nim Executable file
View file

@ -0,0 +1,16 @@
# test the new LastModificationTime() proc
import
io, os, times
proc main() =
var
a, b: TTime
a = getLastModificationTime(ParamStr(1))
b = getLastModificationTime(ParamStr(2))
if a < b:
Write(stdout, "b is newer than a\n")
else:
Write(stdout, "a is newer than b\n")
main()

67
tests/tloops.nim Executable file
View file

@ -0,0 +1,67 @@
# Test nested loops and some other things
import
io
proc andTest() =
var a = 0 == 5 and 6 == 6
proc incx(x: var int) = # is built-in proc
x = x + 1
proc decx(x: var int) =
x = x - 1
proc First(y: var int) =
var x: int
i_ncx(x)
if x == 10:
y = 0
else:
if x == 0:
incx(x)
else:
x=11
proc TestLoops() =
var i, j: int
while i >= 0:
if i mod 3 == 0:
break
i = i + 1
while j == 13:
j = 13
break
break
while True:
break
proc Foo(n: int): int =
var
a, old: int
b, c: bool
F_irst(a)
if a == 10:
a = 30
elif a == 11:
a = 22
elif a == 12:
a = 23
elif b:
old = 12
else:
a = 40
#
b = false or 2 == 0 and 3 == 9
a = 0 + 3 * 5 + 6 + 7 + +8 # 36
while b:
a = a + 3
a = a + 5
io.write(stdout, "Hallo!")
# We should come till here :-)
discard Foo(345)

21
tests/tlowhigh.nim Executable file
View file

@ -0,0 +1,21 @@
# Test the magic low() and high() procs
import
io
type
myEnum = enum e1, e2, e3, e4, e5
var
a: array [myEnum, int]
for i in low(a) .. high(a):
a[i] = 0
proc sum(a: openarray[int]): int =
result = 0
for i in low(a)..high(a):
inc(result, a[i])
write(stdout, sum([1, 2, 3, 4]))
#OUT 10

92
tests/tmath.nim Executable file
View file

@ -0,0 +1,92 @@
# tests for the interpreter
import
io
proc loops(a: out int) =
nil
#var
# b: int
#b = glob
#while b != 0:
# b = b + 1
#a = b
proc mymax(a, b: int): int =
#loops(result)
result = a
if b > a: result = b
proc test(a, b: int) =
var
x, y: int
x = 0
y = 7
if x == a + b * 3 - 7 or
x == 8 or
x == y and y > -56 and y < 699:
y = 0
elif y == 78 and x == 0:
y = 1
elif y == 0 and x == 0:
y = 2
else:
y = 3
type
TTokType = enum
tkNil, tkType, tkConst, tkVar, tkSymbol, tkIf,
tkWhile, tkFor, tkLoop, tkCase, tkLabel, tkGoto
proc testCase(t: TTokType): int =
case t
of tkNil, tkType, tkConst: result = 0
of tkVar: result = 1
of tkSymbol: result = 2
of tkIf..tkFor: result = 3
of tkLoop: result = 56
else: result = -1
test(0, 9) # test the call
proc TestLoops() =
var
i, j: int
while i >= 0:
if i mod 3 == 0:
break
i = i + 1
while j == 13:
j = 13
break
break
while True:
break
var
glob: int
a: array [0..5, int]
proc main() =
#glob = 0
#loops( glob )
var
res: int
s: string
#write(stdout, mymax(23, 45))
write(stdout, "Hallo! Wie heißt du? ")
s = readLine(stdin)
# test the case statement
case s
of "Andreas": write(stdout, "Du bist mein Meister!\n")
of "Rumpf": write(stdout, "Du bist in der Familie meines Meisters!\n")
else: write(stdout, "ich kenne dich nicht!\n")
write(stdout, "Du heisst " & s & "\n")
# [[
proc main2() =
main()
main()
#]]

5
tests/tnamspc.nim Executable file
View file

@ -0,0 +1,5 @@
# Test17 - test correct handling of namespaces
import mnamspc1
global = 9 #ERROR

21
tests/tnestif.nim Executable file
View file

@ -0,0 +1,21 @@
# test nested ifs
import
io
var
x, y: int
x = 2
if x == 0:
write(stdout, "i == 0")
if y == 0:
write(stdout, x)
else:
write(stdout, y)
elif x == 1:
write(stdout, "i == 1")
elif x == 2:
write(stdout, "i == 2")
else:
write(stdout, "looks like Python")
#OUT i == 2

10
tests/tnew.bpf Executable file
View file

@ -0,0 +1,10 @@
USEUNIT("tnew.c");
USEUNIT("..\lib\io.c");
USEUNIT("..\lib\markstck.c");
USEUNIT("..\lib\morsys.c");
USEUNIT("..\lib\dlmalloc.c");
//---------------------------------------------------------------------------
This file is used by the project manager only and should be treated like the project file
main

84
tests/tnew.bpr Executable file
View file

@ -0,0 +1,84 @@
<?xml version='1.0' encoding='utf-8' ?>
<!-- C++Builder XML Project -->
<PROJECT>
<MACROS>
<VERSION value="BCB.05.03"/>
<PROJECT value="tnew.exe"/>
<OBJFILES value="tnew.obj ..\lib\io.obj ..\lib\markstck.obj ..\lib\morsys.obj
..\lib\dlmalloc.obj"/>
<RESFILES value=""/>
<DEFFILE value=""/>
<RESDEPEN value="$(RESFILES)"/>
<LIBFILES value=""/>
<LIBRARIES value=""/>
<SPARELIBS value=""/>
<PACKAGES value="Vcl50.bpi Vclx50.bpi bcbsmp50.bpi dclocx50.bpi bcb2kaxserver50.bpi"/>
<PATHCPP value=".;..\lib"/>
<PATHPAS value=".;"/>
<PATHRC value=".;"/>
<PATHASM value=".;"/>
<DEBUGLIBPATH value="$(BCB)\lib\debug"/>
<RELEASELIBPATH value="$(BCB)\lib\release"/>
<LINKER value="tlink32"/>
<USERDEFINES value="_DEBUG"/>
<SYSDEFINES value="NO_STRICT;_NO_VCL;_RTLDLL;USEPACKAGES"/>
<MAINSOURCE value="tnew.bpf"/>
<INCLUDEPATH value="..\lib;$(BCB)\include;$(BCB)\include\vcl"/>
<LIBPATH value="..\lib;$(BCB)\lib\obj;$(BCB)\lib"/>
<WARNINGS value="-w-par"/>
</MACROS>
<OPTIONS>
<CFLAG1 value="-Od -Vx -Ve -X- -r- -pr -a8 -b- -k -y -v -vi- -tWC -tWM- -c"/>
<PFLAGS value="-$YD -$W -$O- -v -JPHNE -M"/>
<RFLAGS value=""/>
<AFLAGS value="/mx /w2 /zd"/>
<LFLAGS value="-D&quot;&quot; -ap -Tpe -x -Gn -v"/>
</OPTIONS>
<LINKER>
<ALLOBJ value="c0x32.obj $(PACKAGES) $(OBJFILES)"/>
<ALLRES value="$(RESFILES)"/>
<ALLLIB value="$(LIBFILES) $(LIBRARIES) import32.lib cw32i.lib"/>
</LINKER>
<IDEOPTIONS>
[Version Info]
IncludeVerInfo=0
AutoIncBuild=0
MajorVer=1
MinorVer=0
Release=0
Build=0
Debug=0
PreRelease=0
Special=0
Private=0
DLL=0
Locale=1031
CodePage=1252
[Version Info Keys]
CompanyName=
FileDescription=
FileVersion=1.0.0.0
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=1.0.0.0
Comments=
[Debugging]
DebugSourceDirs=$(BCB)\source\vcl
[Parameters]
RunParams=
HostApplication=
RemoteHost=
RemotePath=
RemoteDebug=0
[Compiler]
ShowInfoMsgs=0
LinkDebugVcl=0
</IDEOPTIONS>
</PROJECT>

49
tests/tnew.nim Executable file
View file

@ -0,0 +1,49 @@
# Test the implementation of the new operator
# and the code generation for gc walkers
# (and the garbage collector):
type
PNode = ref TNode
TNode = object
data: int
str: string
le, ri: PNode
TStressTest = ref array [0..45, array [1..45, TNode]]
proc finalizer(n: PNode) =
write(stdout, n.data)
write(stdout, " is now freed\n")
proc newNode(data: int, le, ri: PNode): PNode =
new(result, finalizer)
result.le = le
result.ri = ri
result.data = data
# now loop and build a tree
proc main() =
var
i = 0
p: TStressTest
while i < 1000:
var n: PNode
n = newNode(i, nil, newNode(i + 10000, nil, nil))
inc(i)
#new(p)
write(stdout, "Simple tree node allocation worked!\n")
i = 0
while i < 1000:
var m = newNode(i + 20000, nil, nil)
var k = newNode(i + 30000, nil, nil)
m.le = m
m.ri = k
k.le = m
k.ri = k
inc(i)
write(stdout, "Simple cycle allocation worked!\n")
main()

6
tests/tnewsets.nim Executable file
View file

@ -0,0 +1,6 @@
# new test for sets:
const elem = ' '
var s: set[char] = {elem}
assert(elem in s and 'a' not_in s and 'c' not_in s )

12
tests/tnewuns.nim Executable file
View file

@ -0,0 +1,12 @@
# test the new unsigned operations:
import
strutils
var
x, y: int
x = 1
y = high(int)
writeln(stdout, $ ( x +% y ) )

6
tests/tnoop.nim Executable file
View file

@ -0,0 +1,6 @@
# Tests the new check in the semantic pass
var
a: int
a() #ERROR

24
tests/tobject2.nim Executable file
View file

@ -0,0 +1,24 @@
# Tests the object implementation
import
io
type
TPoint2d = object
x, y: int
TPoint3d = object of TPoint2d
z: int # added a field
proc getPoint(var p: TPoint2d) =
{.breakpoint.}
writeln(stdout, p.x)
var
p: TPoint3d
TPoint2d(p).x = 34
p.y = 98
p.z = 343
getPoint(p)

48
tests/tobjects.nim Executable file
View file

@ -0,0 +1,48 @@
import
io
type
TBase = object
x, y: int
TSubclass = object of TBase
c: int
case c
of 0, 1, 2, 3:
a, b: int
of 4:
d, e, f: char
n: bool
var
global: int
var
s: string
r: float = 0.0
i: int = 500 + 400
case i
of 500..999: write(stdout, "ha!\n")
of 1000..3000, 12: write(stdout, "ganz schön groß\n")
of 1, 2, 3: write(stdout, "1 2 oder 3\n")
else: write(stdout, "sollte nicht passieren\n")
case r
of 0.0, 0.125..0.4444: write(stdout, "kleiner als 0.5\n")
else: write(stdout, "weiß nicht\n")
case readLine(stdin)
of "Rumpf": write(stdout, "Hallo Meister!\n")
of "Andreas": write(stdout, "Hallo Meister!\n")
else: write(stdout, "Nicht mein Meister!\n")
global = global + 1
write(stdout, "Hallo wie heißt du? \n")
s = readLine(stdin)
i = 0
while i < length(s):
if s[i] == 'c': write(stdout, "'c' in deinem Namen gefunden\n")
i = i + 1
write(stdout, "Du heißt " & s)

11
tests/topaque.nim Executable file
View file

@ -0,0 +1,11 @@
# Test the new opaque types
import
mopaque
var
L: TLexer
L.filename = "ha"
L.line = 34
L.buffer[0] = '\0' #ERROR_MSG undeclared field: 'buffer'

29
tests/toptions.nim Executable file
View file

@ -0,0 +1,29 @@
# Converted by Pas2mor v1.54
# Used command line arguments:
# -m -q -o bootstrap\options.mor options.pas
#
#
# The Morpork Compiler
# (c) Copyright 2004 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
type
# please make sure we have under 32 options (improves code efficiency!)
TOption = enum
optNone, optForceFullMake, optBoehmGC, optRefcGC, optRangeCheck,
optBoundsCheck, optOverflowCheck, optNilCheck, optAssert, optLineDir,
optWarns, optHints, optDeadCodeElim, optListCmd, optCompileOnly,
optSafeCode, # only allow safe code
optStyleCheck, optOptimizeSpeed, optOptimizeSize, optGenDynLib,
optGenGuiApp, optStackTrace
TOptionset = set[TOption]
var
gOptions: TOptionset = {optRefcGC, optRangeCheck, optBoundsCheck,
optOverflowCheck, optAssert, optWarns, optHints, optLineDir, optStackTrace}
compilerArgs: int
gExitcode: uint8

18
tests/toverflw.nim Executable file
View file

@ -0,0 +1,18 @@
# Tests emc's ability to detect overflows
import
io
{.push overflowChecks: on.}
var
a, b: int
a = high(int)
b = -2
try:
writeln(stdout, b - a)
except EOverflow:
writeln(stdout, "the computation overflowed")
{.pop.} # overflow check
#OUT the computation overflowed

7
tests/toverl.nim Executable file
View file

@ -0,0 +1,7 @@
# Test for overloading
type
TNone {.export: "_NONE".} = record
proc
TNone(a, b: int) = nil #ERROR_MSG attempt to redefine 'TNone'

13
tests/toverlop.nim Executable file
View file

@ -0,0 +1,13 @@
# Test operator overloading
import
io
proc % (a, b: int): int =
return a mod b
var x, y: int
x = 15
y = 6
write(stdout, x % y)
#OUT 3

7
tests/toverwr.nim Executable file
View file

@ -0,0 +1,7 @@
# Test the overloading resolution in connection with a qualifier
proc write(t: tTextFile, s: string) =
nil # a nop
system.write(stdout, "hallo")
#OUT hallo

20
tests/tovfint.nim Executable file
View file

@ -0,0 +1,20 @@
# this tests the new overflow literals
import
io
var
i: int
i = cast[int](0xffffffff)
when defined(cpu64):
if i == 4294967295:
write(stdout, "works!\n")
else:
write(stdout, "broken!\n")
else:
if i == -1:
write(stdout, "works!\n")
else:
write(stdout, "broken!\n")
#OUT works!

4
tests/tparedef.nim Executable file
View file

@ -0,0 +1,4 @@
# This test is now superfluous:
proc a(a: int) =
return

32
tests/tpos.nim Executable file
View file

@ -0,0 +1,32 @@
# test this particular function
import
io
proc mypos(sub, s: string, start: int = 0): int =
var
i, j, M, N: int
M = sub.len
N = s.len
i = start
j = 0
if i >= N:
result = -1
else:
while True:
if s[i] == sub[j]:
Inc(i)
Inc(j)
else:
i = i - j + 1
j = 0
if (j >= M) or (i >= N): break
if j >= M:
result = i - M
else:
result = -1
var sub = "hallo"
var s = "world hallo"
write(stdout, mypos(sub, s))
#OUT 6

13
tests/tposix.nim Executable file
View file

@ -0,0 +1,13 @@
# Test Posix interface
import posix
var
u: Tutsname
discard uname(u)
writeln(stdout, u.sysname)
writeln(stdout, u.nodename)
writeln(stdout, u.release)
writeln(stdout, u.machine)

28
tests/tprep.nim Executable file
View file

@ -0,0 +1,28 @@
# Test the features that used to belong to the preprocessor
import
io, times
{.warning: "This is only a test warning!".}
{.define: case2.}
{.define: case3.}
when defined(case1):
{.hint: "Case 1".}
when defined(case3):
{.hint: "Case 1.3".}
elif defined(case2):
{.hint: "Case 2".}
when defined(case3):
{.hint: "Case 2.3".}
elif defined(case3):
{.hint: "Case 3".}
else:
{.hint: "unknown case".}
var
s: string
write(stdout, "compiled at " & system.compileDate &
" " & compileTime & "\n")
echo getDateStr()
echo getClockStr()

10
tests/tprintf.nim Executable file
View file

@ -0,0 +1,10 @@
# Test a printf proc
proc printf(file: TTextFile, args: openarray[string]) =
var i = 0
while i < args.len:
write(file, args[i])
inc(i)
printf(stdout, ["Andreas ", "Rumpf\n"])
#OUT Andreas Rumpf

17
tests/tprocvar.nim Executable file
View file

@ -0,0 +1,17 @@
# test variables of type proc
import
io
var
x: proc (a, b: int): int {.cdecl.}
proc ha(c, d: int): int {.cdecl.} =
echo(c + d)
result = c + d
x = ha
discard x(3, 4)
#OUT 7

18
tests/tpush.nim Executable file
View file

@ -0,0 +1,18 @@
# test the new pragmas
import
io
{.push warnings: off, hints: off.}
proc noWarning() =
var
x: int
echo(x)
{.pop.}
proc WarnMe() =
var
x: int
echo(x)

9
tests/tquit.nim Executable file
View file

@ -0,0 +1,9 @@
# Test the new beforeQuit variable:
import
io
proc myExit() {.noconv.} =
write(stdout, "just exiting...\n")
addQuitProc(myExit)

5
tests/trawstr.nim Executable file
View file

@ -0,0 +1,5 @@
# Test the new raw strings:
const
xxx = r"This is a raw string!"
yyy = "This not\" #ERROR

15
tests/treadln.nim Executable file
View file

@ -0,0 +1,15 @@
# test the improved readline handling that does not care whether its
# Macintosh, Unix or Windows text format.
import
io
var
inp: tTextFile
line: string
if openFile(inp, "readme.txt"):
while not EndOfFile(inp):
line = readLine(inp)
echo("#" & line & "#")
closeFile(inp)

2
tests/trecmod.nim Executable file
View file

@ -0,0 +1,2 @@
# recursive module
import mrecmod

15
tests/trectype.nim Executable file
View file

@ -0,0 +1,15 @@
# Test recursive type descriptions
# (mainly for the C code generator)
type
PA = ref TA
TA = array [0..2, PA]
PRec = ref TRec
TRec = record
a, b: TA
P1 = ref T1
PB = ref TB
TB = array [0..3, P1]
T1 = array [0..6, PB]

Some files were not shown because too many files have changed in this diff Show more