aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authoralon@honor <none@none>2010-08-25 21:01:10 -0700
committeralon@honor <none@none>2010-08-25 21:01:10 -0700
commita9256705ada4ae335870cdb60ae7f9c8373038e3 (patch)
tree2c7aeabbdf38a9fea035d6680f8ad31b2a7e0d46 /tests
parentf6d98e5d038ee80177b9414e5e34ddc05857627b (diff)
the code
Diffstat (limited to 'tests')
-rw-r--r--tests/fannkuch.cpp159
-rw-r--r--tests/fannkuch.js70
-rw-r--r--tests/fasta.cpp180
-rw-r--r--tests/fasta.js71
-rw-r--r--tests/runner.py473
-rw-r--r--tests/settings.cfg16
6 files changed, 969 insertions, 0 deletions
diff --git a/tests/fannkuch.cpp b/tests/fannkuch.cpp
new file mode 100644
index 00000000..c2fcfaa2
--- /dev/null
+++ b/tests/fannkuch.cpp
@@ -0,0 +1,159 @@
+/*
+ * The Computer Language Benchmarks Game
+ * http://shootout.alioth.debian.org/
+ *
+ * Contributed by Eckehard Berns
+ * Based on code by Heiner Marxen
+ * and the ATS version by Hongwei Xi
+ *
+ * Modified for emscripten by azakai
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+struct worker_args {
+ int i, n;
+ struct worker_args *next;
+};
+
+int
+fannkuch_worker(void *_arg)
+{
+ struct worker_args *args = (worker_args*)_arg;
+ int *perm1, *count, *perm;
+ int maxflips, flips, i, n, r, j, k, tmp;
+
+ maxflips = 0;
+ n = args->n;
+ perm1 = (int*)malloc(n * sizeof(int));
+ perm = (int*)malloc(n * sizeof(int));
+ count = (int*)malloc(n * sizeof(int));
+ for (i = 0; i < n; i++)
+ perm1[i] = i;
+ perm1[args->i] = n - 1;
+ perm1[n - 1] = args->i;
+ r = n;
+
+ for (;;) {
+ for (; r > 1; r--)
+ count[r - 1] = r;
+ if (perm1[0] != 0 && perm1[n - 1] != n - 1) {
+ for (i = 0; i < n; i++)
+ perm[i] = perm1[i];
+ flips = 0;
+ k = perm[0];
+ do {
+ for (i = 1, j = k - 1; i < j; i++, j--) {
+ tmp = perm[i];
+ perm[i] = perm[j];
+ perm[j] = tmp;
+ }
+ flips++;
+ tmp = perm[k];
+ perm[k] = k;
+ k = tmp;
+ } while (k);
+ if (maxflips < flips)
+ maxflips = flips;
+ }
+ for (;;) {
+ if (r >= n - 1) {
+ free(perm1);
+ free(perm);
+ free(count);
+ return maxflips;
+ }
+
+ {
+ int p0 = perm1[0];
+ for (i = 0; i < r; i++)
+ perm1[i] = perm1[i + 1];
+ perm1[i] = p0;
+ }
+ if (--count[r] > 0)
+ break;
+ r++;
+ }
+ }
+}
+
+static int
+fannkuch(int n)
+{
+ struct worker_args *args, *targs;
+ int showmax = 30;
+ int *perm1, *count, i, r, maxflips, flips;
+
+ args = NULL;
+ for (i = 0; i < n - 1; i++) {
+ targs = (worker_args*)malloc(sizeof(struct worker_args));
+ targs->i = i;
+ targs->n = n;
+ targs->next = args;
+ args = targs;
+ }
+
+ perm1 = (int*)malloc(n * sizeof(int));
+ count = (int*)malloc(n * sizeof(int));
+
+ for (i = 0; i < n; i++)
+ perm1[i] = i;
+
+ r = n;
+ for (;;) {
+ if (showmax) {
+ for (i = 0; i < n; i++)
+ printf("%d", perm1[i] + 1);
+ printf("\n");
+ showmax--;
+ } else
+ goto cleanup;
+
+ for (; r > 1; r--)
+ count[r - 1] = r;
+
+ for (;;) {
+ if (r == n)
+ goto cleanup;
+ {
+ int p0 = perm1[0];
+ for (i = 0; i < r; i++)
+ perm1[i] = perm1[i + 1];
+ perm1[i] = p0;
+ }
+ if (--count[r] > 0)
+ break;
+
+ r++;
+ }
+ }
+
+ cleanup:
+ free(perm1);
+ free(count);
+ maxflips = 0;
+ while (args != NULL) {
+ flips = (int)fannkuch_worker(args);
+ if (maxflips < flips)
+ maxflips = flips;
+ targs = args;
+ args = args->next;
+ free(targs);
+ }
+ return maxflips;
+}
+
+int
+main(int ac, char **av)
+{
+ int n = ac > 1 ? atoi(av[1]) : 0;
+
+ if (n < 1) {
+ printf("Wrong argument.\n");
+ return 1;
+ }
+ printf("Pfannkuchen(%d) = %d.\n", n, fannkuch(n));
+ return 0;
+}
+
diff --git a/tests/fannkuch.js b/tests/fannkuch.js
new file mode 100644
index 00000000..f8554270
--- /dev/null
+++ b/tests/fannkuch.js
@@ -0,0 +1,70 @@
+/* The Computer Language Benchmarks Game
+ http://shootout.alioth.debian.org/
+ contributed by Isaac Gouy
+ modified by Matthew Wilson */
+
+function fannkuch(n) {
+ var check = 0;
+ var perm = Array(n);
+ var perm1 = Array(n);
+ var count = Array(n);
+ var maxPerm = Array(n);
+ var maxFlipsCount = 0;
+ var m = n - 1;
+
+ for (var i = 0; i < n; i++) perm1[i] = i;
+ var r = n;
+
+ while (true) {
+ // write-out the first 30 permutations
+ if (check < 30){
+ var s = "";
+ for(var i=0; i<n; i++) s += (perm1[i]+1).toString();
+ print(s);
+ check++;
+ }
+
+ while (r != 1) { count[r - 1] = r; r--; }
+ if (!(perm1[0] == 0 || perm1[m] == m)) {
+ for (var i = 0; i < n; i++) perm[i] = perm1[i];
+
+ var flipsCount = 0;
+ var k;
+
+ while (true) {
+ k = perm[0]
+ if (k == 0) break;
+ var k2 = (k + 1) >> 1;
+ for (var i = 0; i < k2; i++) {
+ var temp = perm[i]; perm[i] = perm[k - i]; perm[k - i] = temp;
+ }
+ flipsCount++;
+ }
+
+ if (flipsCount > maxFlipsCount) {
+ maxFlipsCount = flipsCount;
+ for (var i = 0; i < n; i++) maxPerm[i] = perm1[i];
+ }
+ }
+
+ while (true) {
+ if (r == n) return maxFlipsCount;
+ var perm0 = perm1[0];
+ var i = 0;
+ while (i < r) {
+ var j = i + 1;
+ perm1[i] = perm1[j];
+ i = j;
+ }
+ perm1[r] = perm0;
+
+ count[r] = count[r] - 1;
+ if (count[r] > 0) break;
+ r++;
+ }
+ }
+}
+
+var n = parseInt(arguments[0]);
+print("Pfannkuchen(" + n.toString() + ") = " + fannkuch(n).toString());
+
diff --git a/tests/fasta.cpp b/tests/fasta.cpp
new file mode 100644
index 00000000..7954feef
--- /dev/null
+++ b/tests/fasta.cpp
@@ -0,0 +1,180 @@
+/* The Computer Language Benchmarks Game
+ http://shootout.alioth.debian.org/
+ contributed by Andrew Moon
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct Random {
+ enum { IM = 139968, IA = 3877, IC = 29573 };
+ Random() : last(42) {}
+ float get( float max = 1.0f ) {
+ last = ( last * IA + IC ) % IM;
+ return max * last / IM;
+ }
+protected:
+ unsigned int last;
+} rng;
+
+struct IUB {
+ int c;
+ double p;
+ unsigned int pi;
+};
+
+struct Cumulative {
+ enum { slots = 512, };
+
+ Cumulative( IUB *start ) {
+ double p = 0;
+ for ( IUB *iter = start; iter->c; ++iter ) {
+ p += iter->p;
+ iter->p = p < 1.0 ? p : 1.0;
+ iter->pi = (unsigned int )( iter->p * slots );
+ }
+
+ for ( unsigned int i = 0; i <= slots; i++ ) {
+ while ( i > start->pi ) {
+ ++start;
+ }
+
+ table[i] = start;
+ }
+ }
+
+ const char operator[] ( float pct ) const {
+ IUB *iter = table[(unsigned int )( pct * slots )];
+ while ( iter->p < pct )
+ ++iter;
+ return iter->c;
+ }
+
+protected:
+ IUB *table[slots + 1];
+};
+
+static const size_t lineLength = 60;
+
+struct LineBuffer {
+ LineBuffer() : lastN(0) {}
+ LineBuffer &genrand( Cumulative &table, size_t N ) {
+ //assert(N <= lineLength);
+ for ( size_t i = 0; i < N; i++ )
+ buffer[i] = table[rng.get()];
+ buffer[N] = '\n';
+ buffer[N+1] = '\0';
+ lastN = N + 1;
+ return *this;
+ }
+ void writeline() { puts(buffer); }
+protected:
+ char buffer[lineLength + 2];
+ size_t lastN;
+};
+
+struct RotatingString {
+ RotatingString( const char *in ) : pos(0) {
+ size = strlen( in );
+ buffer = new char[size + lineLength];
+ memcpy( buffer, in, size );
+ memcpy( buffer + size, in, lineLength );
+ }
+ ~RotatingString() { delete[] buffer; }
+ void write( size_t bytes ) {
+ char* temp = new char[bytes+2];
+ memcpy(temp, buffer + pos, bytes);
+ temp[bytes] = '\n';
+ temp[bytes] = '\0';
+ puts(temp);
+ delete temp;
+ pos += bytes;
+ if ( pos > size )
+ pos -= size;
+ }
+protected:
+ char *buffer;
+ size_t size, pos;
+};
+
+template< class Output >
+void makeFasta( const char *id, const char *desc, size_t N, Output &output ) {
+ while ( N ) {
+ const size_t bytes = N < lineLength ? N : lineLength;
+ output.writeline( bytes );
+ N -= bytes;
+ }
+}
+
+struct Repeater {
+ Repeater( const char *alu ) : rot(alu) {}
+ void writeline( size_t bytes ) { rot.write( bytes ); }
+ void run( const char *id, const char *desc, size_t N ) {
+ makeFasta( id, desc, N, *this );
+ }
+protected:
+ RotatingString rot;
+};
+
+struct Randomized {
+ Randomized( IUB *start ) : table(start) {}
+ void writeline( size_t bytes ) { line.genrand(table, bytes).writeline(); }
+ void run( const char *id, const char *desc, size_t N ) {
+ makeFasta( id, desc, N, *this );
+ }
+protected:
+ Cumulative table;
+ LineBuffer line;
+};
+
+IUB iub[] = {
+ { 'a', 0.27, 0 },
+ { 'c', 0.12, 0 },
+ { 'g', 0.12, 0 },
+ { 't', 0.27, 0 },
+
+ { 'B', 0.02, 0 },
+ { 'D', 0.02, 0 },
+ { 'H', 0.02, 0 },
+ { 'K', 0.02, 0 },
+ { 'M', 0.02, 0 },
+ { 'N', 0.02, 0 },
+ { 'R', 0.02, 0 },
+ { 'S', 0.02, 0 },
+ { 'V', 0.02, 0 },
+ { 'W', 0.02, 0 },
+ { 'Y', 0.02, 0 },
+ { 0, 0, 0 },
+};
+
+IUB homosapiens[] = {
+ { 'a', 0.3029549426680, 0 },
+ { 'c', 0.1979883004921, 0 },
+ { 'g', 0.1975473066391, 0 },
+ { 't', 0.3015094502008, 0 },
+ { 0, 0, 0 },
+};
+
+static const char alu[] =
+ "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG"
+ "GGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGA"
+ "GACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAA"
+ "AATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT"
+ "CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAAC"
+ "CCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTG"
+ "CACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
+
+int main( int argc, const char *argv[] ) {
+ const size_t n = ( argc > 1 ) ? atoi( argv[1] ) : 512;
+
+ Repeater(alu)
+ .run( "ONE", "Homo sapiens alu", n*2 );
+ Randomized(iub)
+ .run( "TWO", "IUB ambiguity codes", n*3 );
+ Randomized(homosapiens)
+ .run( "THREE", "Homo sapiens frequency", n*5 );
+
+ return 0;
+}
+
diff --git a/tests/fasta.js b/tests/fasta.js
new file mode 100644
index 00000000..f8bca39c
--- /dev/null
+++ b/tests/fasta.js
@@ -0,0 +1,71 @@
+// The Computer Language Benchmarks Game
+// http://shootout.alioth.debian.org
+//
+// Contributed by Ian Osgood
+// Largely rewritten by Matthew Wilson
+
+function fastaRepeat(n, seq) {
+ var seqi = 0, len = seq.length, i, j, k, l, block,
+ str = Array(len*60+1).join(seq), lines = Array(i=j=len*len);
+ while (--j>-1) { lines[j] = str.substr(60*j, 60) }
+ block = lines.join("\n");
+ for (j=0, k=Math.floor((l=Math.floor(n/60))/i); j<k; ++j) { print(block) }
+ for (j = 0, k = l % i; j < k; ++j) { print(lines[j]) }
+ if (n % 60 > 0) { print(lines[k].substr(0, n % 60)) }
+}
+
+var rand=(function() {
+ var Last = 42;
+ return function() { return (Last=(Last * 3877 + 29573) % 139968) / 139968 }
+})();
+
+function printLineMaker(table) {
+ var h = 0, k = [], v = [], c, l=0;
+ for (c in table) { l = v[h] = table[k[h++] = c]+=l; }
+ return function(x) {
+ var line = "";
+ next: for (var i=0; i<x; ++i) {
+ var r = rand(), j=0;
+ for (;;++j) {
+ if (r < v[j]) {
+ line += k[j];
+ continue next;
+ }
+ }
+ }
+ print(line);
+ }
+}
+
+function fastaRandom(n, table) {
+ var printLine=printLineMaker(table);
+ while ((n -= 60) > -1) { printLine(60) }
+ if (n<0 && n>-60) { printLine(60 + n) }
+}
+
+(function main(n) {
+ var ALU = "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG" +
+ "GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA" +
+ "CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT" +
+ "ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA" +
+ "GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG" +
+ "AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC" +
+ "AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
+
+ var IUB = { a:0.27, c:0.12, g:0.12, t:0.27, B:0.02, D:0.02, H:0.02, K:0.02,
+ M:0.02, N:0.02, R:0.02, S:0.02, V:0.02, W:0.02, Y:0.02 }
+
+ var HomoSap = {
+ a:0.3029549426680, c:0.1979883004921, g:0.1975473066391, t:0.3015094502008
+ }
+
+ print(">ONE Homo sapiens alu")
+ fastaRepeat(2*n, ALU)
+
+ print(">TWO IUB ambiguity codes")
+ fastaRandom(3*n, IUB)
+
+ print(">THREE Homo sapiens frequency")
+ fastaRandom(5*n, HomoSap)
+}).call(this, 1*arguments[0]*1)
+
diff --git a/tests/runner.py b/tests/runner.py
new file mode 100644
index 00000000..e675815d
--- /dev/null
+++ b/tests/runner.py
@@ -0,0 +1,473 @@
+'''
+Simple test runner
+
+See settings.cfg file for options&params. Edit as needed.
+'''
+
+from subprocess import Popen, PIPE, STDOUT
+import os, unittest, tempfile, shutil, time
+
+# Params
+
+def path_from_root(pathelems):
+ return os.path.join(os.path.sep, *(((os.path.abspath(os.path.dirname(__file__)).split(os.sep)))[:-1] + pathelems))
+
+exec(open(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'settings.cfg'), 'r').read())
+
+def timeout_run(proc, timeout, note):
+ start = time.time()
+ while time.time() - start < timeout and proc.poll() is None:
+ time.sleep(0.1)
+ if proc.poll() is None:
+ proc.kill()
+ raise Exception("Timed out: " + note)
+ return proc.communicate()[0]
+
+class T(unittest.TestCase):
+ def do_test(self, src, expected_output, args=[], output_nicerizer=None, no_python=False, no_build=False):
+ global DEBUG
+ dirname = TEMP_DIR + '/tmp' # tempfile.mkdtemp(dir=TEMP_DIR)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+ filename = os.path.join(dirname, 'src.cpp')
+ if not no_build:
+ f = open(filename, 'w')
+ f.write(src)
+ f.close()
+ if DEBUG: print "[[C++ => LLVM]]"
+ output = Popen([LLVM_GCC, '-emit-llvm', '-c', filename, '-o', filename + '.o'], stdout=PIPE, stderr=STDOUT).communicate()[0]
+ if DEBUG: print output
+ if DEBUG: print "[[LLVM => JS]]"
+ if False:
+ # Use an llc backend, written in C++, to generate JS
+ output = Popen([LLC, '-march='+LLVM_BACKEND, filename + '.o', '-o=' + filename + '.o.cpp'], stdout=PIPE, stderr=STDOUT).communicate()[0]
+ elif False:
+ # Use python parser to generate JS from disassembled llvm
+ output = Popen([LLVM_DIS, filename + '.o', '-o=' + filename + '.o.llvm'], stdout=PIPE, stderr=STDOUT).communicate()[0]
+ if DEBUG: print output
+ output = Popen(['python', PY_PARSER, filename + '.o.llvm'], stdout=open(filename + '.o.js', 'w'), stderr=STDOUT).communicate()[0]
+ else:
+ # JS parser/compiler
+ output = Popen([LLVM_DIS, filename + '.o', '-o=' + filename + '.o.llvm'], stdout=PIPE, stderr=STDOUT).communicate()[0]
+ if DEBUG: print output
+ cwd = os.getcwd()
+ os.chdir(path_from_root(['src']))
+ output = timeout_run(Popen([PARSER_ENGINE] + PARSER_OPTS + [JS_COMPILER], stdin=open(filename + '.o.llvm', 'r'), stdout=open(filename + '.o.js', 'w'), stderr=STDOUT), 20, 'Parser')
+ os.chdir(cwd)
+ # return
+ if DEBUG: print output
+ output = open(filename + '.o.js').read()
+ if output is not None and 'Traceback' in output: print output; assert (0) # 'generating JavaScript failed'
+ if DEBUG: print "\nGenerated JavaScript:\n\n===\n\n%s\n\n===\n\n" % output
+ # if not DEBUG:
+ js_output = timeout_run(Popen([JS_ENGINE] + JS_ENGINE_OPTS + [filename + '.o.js'] + args, stdout=PIPE, stderr=STDOUT), 20, 'Execution')
+ if output_nicerizer is not None:
+ js_output = output_nicerizer(js_output)
+ # else:
+ # print "[[JS output]]"
+ # ret = "Output shown on screen, test not actually run!"
+ # Popen([JS_ENGINE, filename + '.o.js'] + args, stderr=STDOUT).communicate()[0]
+ self.assertContained(expected_output, js_output)
+ self.assertNotContained('ERROR', js_output)
+ return
+
+ if not no_python:
+ #DEBUG = True
+ SPIDERMONKEY = True
+ if SPIDERMONKEY:
+ if DEBUG: print "[[RJS ==> SpiderMonkey parsed tree]]"
+ args = [SPIDERMONKEY_SHELL, '-e', 'parse(snarf(\"%s\"))' % (filename + '.o.js')]
+ output = Popen(args, stdout=PIPE, stderr=STDOUT).communicate()[0]
+ f = open(filename + 'o.js.sm', 'w')
+ f.write(output)
+ f.close()
+ else:
+ if DEBUG: print "[[RJS ==> RPython]]"
+ output = Popen(['python', RJS_RPYTHON, filename + '.o.js', filename + '.o.js.py'], stdout=PIPE, stderr=STDOUT).communicate()[0]
+ if DEBUG: print output
+
+ py_output = Popen(['python', filename + '.o.js.py'] + args, stdout=PIPE, stderr=STDOUT).communicate()[0]
+ if output_nicerizer is not None:
+ py_output = output_nicerizer(py_output)
+ self.assertContained(expected_output, py_output)
+ if js_output != py_output:
+ print "WARNING: js and py outputs not identical (but each is similar enough to the expected_output)"
+
+ PYPY = True
+# PYPY = False
+ if PYPY:
+ pypy_source = filename.replace('.', '_') + '_o_js_py.py'
+ if DEBUG: print "[[RPython ==> PyPy]]"
+ output = Popen(['python', RJS_PYPY, filename + '.o.js.py', pypy_source], stdout=PIPE, stderr=STDOUT).communicate()[0]
+ print output
+
+# # Python on pypy-ready source
+ # pypy_output = Popen(['python', pypy_source] + args, stdout=PIPE, stderr=STDOUT).communicate()[0]
+ # if output_nicerizer is not None:
+ # pypy_output = output_nicerizer(pypy_output)
+ # self.assertContained(expected_output, pypy_output)
+ # if js_output != pypy_output:
+ # print "WARNING: js and PYpy outputs not identical (but each is similar enough to the expected_output)"
+
+ # PyPy compilation of source to binary
+
+# shutil.rmtree(dirname)
+
+ def assertContained(self, value, string):
+ if value not in string:
+ print "Expected to find '%s' in '%s'" % (value, string)
+ self.assertTrue(value in string)
+
+ def assertNotContained(self, value, string):
+ if value in string:
+ print "Expected to NOT find '%s' in '%s'" % (value, string)
+ self.assertTrue(value not in string)
+
+ def test_hello_world(self):
+ src = '''
+ #include <stdio.h>
+ int main()
+ {
+ printf("hello, world!\\n");
+ return 0;
+ }
+ '''
+ self.do_test(src, 'hello, world!')
+
+ def test_intvars(self):
+ src = '''
+ #include <stdio.h>
+ int main()
+ {
+ int x = 5;
+ int y = x+17;
+ int z = (y-1)/2; // Should stay an integer after division!
+ y += 1;
+ int w = x*3+4;
+ int k = w < 15 ? 99 : 101;
+ int i = k > 100; // Should be an int, not a bool!
+ printf("*%d,%d,%d,%d,%d,%d*\\n", x, y, z, w, k,i);
+ return 0;
+ }
+ '''
+ self.do_test(src, '*5,23,10,19,101,1*')
+
+ def test_if(self):
+ src = '''
+ #include <stdio.h>
+ int main()
+ {
+ int x = 5;
+ if (x > 3) {
+ printf("*yes*\\n");
+ }
+ return 0;
+ }
+ '''
+ self.do_test(src, '*yes*')
+
+ def test_loop(self):
+ src = '''
+ #include <stdio.h>
+ int main()
+ {
+ int x = 5;
+ for (int i = 0; i < 6; i++)
+ x += x*i;
+ printf("*%d*\\n", x);
+ return 0;
+ }
+ '''
+ self.do_test(src, '*3600*')
+
+ def test_strings(self):
+ src = '''
+ #include <stdio.h>
+ #include <stdlib.h>
+ int main(int argc, char **argv)
+ {
+ printf("*%d", argc);
+ puts(argv[1]);
+ puts(argv[2]);
+ printf("%d*", atoi(argv[3])+2);
+ return 0;
+ }
+ '''
+ self.do_test(src, '*4*wowie*too*76*', ['wowie', 'too', '74'], lambda x: x.replace('\n', '*'))
+
+ def test_funcs(self):
+ src = '''
+ #include <stdio.h>
+ int funcy(int x)
+ {
+ return x*9;
+ }
+ int main()
+ {
+ printf("*%d,%d*\\n", funcy(8), funcy(10));
+ return 0;
+ }
+ '''
+ self.do_test(src, '*72,90*')
+
+ def test_structs(self):
+ src = '''
+ #include <stdio.h>
+ struct S
+ {
+ int x, y;
+ };
+ int main()
+ {
+ S a, b;
+ a.x = 5; a.y = 6;
+ b.x = 101; b.y = 7009;
+ S *c, *d;
+ c = &a;
+ c->x *= 2;
+ c = &b;
+ c->y -= 1;
+ d = c;
+ d->y += 10;
+ printf("*%d,%d,%d,%d,%d,%d,%d,%d*\\n", a.x, a.y, b.x, b.y, c->x, c->y, d->x, d->y);
+ return 0;
+ }
+ '''
+ self.do_test(src, '*10,6,101,7018,101,7018,101,7018*')
+
+ gen_struct_src = '''
+ #include <stdio.h>
+ #include <stdlib.h>
+ struct S
+ {
+ int x, y;
+ };
+ int main()
+ {
+ S* a = {{gen_struct}};
+ a->x = 51; a->y = 62;
+ printf("*%d,%d*\\n", a->x, a->y);
+ {{del_struct}}(a);
+ return 0;
+ }
+ '''
+
+ def test_mallocstruct(self):
+ self.do_test(self.gen_struct_src.replace('{{gen_struct}}', '(S*)malloc(sizeof(S))').replace('{{del_struct}}', 'free'), '*51,62*')
+
+ def test_newstruct(self):
+ self.do_test(self.gen_struct_src.replace('{{gen_struct}}', 'new S').replace('{{del_struct}}', 'delete'), '*51,62*')
+
+ def test_addr_of_stacked(self):
+ src = '''
+ #include <stdio.h>
+ void alter(int *y)
+ {
+ *y += 5;
+ }
+ int main()
+ {
+ int x = 2;
+ alter(&x);
+ printf("*%d*\\n", x);
+ return 0;
+ }
+ '''
+ self.do_test(src, '*7*')
+
+ def test_linked_list(self):
+ src = '''
+ #include <stdio.h>
+ struct worker_args {
+ int value;
+ struct worker_args *next;
+ };
+ int main()
+ {
+ worker_args a;
+ worker_args b;
+ a.value = 60;
+ a.next = &b;
+ b.value = 900;
+ b.next = NULL;
+ worker_args* c = &a;
+ int total = 0;
+ while (c) {
+ total += c->value;
+ c = c->next;
+ }
+ printf("*%d*\\n", total);
+ return 0;
+ }
+ '''
+ self.do_test(src, '*960*')
+
+ def test_class(self):
+ src = '''
+ #include <stdio.h>
+ struct Random {
+ enum { IM = 139968, IA = 3877, IC = 29573 };
+ Random() : last(42) {}
+ float get( float max = 1.0f ) {
+ last = ( last * IA + IC ) % IM;
+ return max * last / IM;
+ }
+ protected:
+ unsigned int last;
+ } rng1;
+ int main()
+ {
+ Random rng2;
+ int count = 0;
+ for (int i = 0; i < 100; i++) {
+ float x1 = rng1.get();
+ float x2 = rng2.get();
+ printf("%f, %f\\n", x1, x2);
+ if (x1 != x2) count += 1;
+ }
+ printf("*%d*\\n", count);
+ return 0;
+ }
+ '''
+ self.do_test(src, '*0*')
+
+ def test_inherit(self):
+ src = '''
+ #include <stdio.h>
+ struct Parent {
+ int x1, x2;
+ };
+ struct Child : Parent {
+ int y;
+ };
+ int main()
+ {
+ Parent a;
+ a.x1 = 50;
+ a.x2 = 87;
+ Child b;
+ b.x1 = 78;
+ b.x2 = 550;
+ b.y = 101;
+ Child* c = (Child*)&a;
+ c->x1 ++;
+ c = &b;
+ c->y --;
+ printf("*%d,%d,%d,%d,%d,%d,%d*\\n", a.x1, a.x2, b.x1, b.x2, b.y, c->x1, c->x2);
+ return 0;
+ }
+ '''
+ self.do_test(src, '*51,87,78,550,100,78,550*')
+
+ def test_polymorph(self):
+ src = '''
+ #include <stdio.h>
+ struct Parent {
+ virtual int getit() { return 11; };
+ };
+ struct Child : Parent {
+ int getit() { return 74; }
+ };
+ int main()
+ {
+ Parent *x = new Parent();
+ Parent *y = new Child();
+ printf("*%d,%d*\\n", x->getit(), y->getit());
+ return 0;
+ }
+ '''
+ self.do_test(src, '*11,74*')
+
+ def zzzzzzzzzzzzzzztest_constglobalstructs(self): # TODO: make this work
+ src = '''
+ #include <stdio.h>
+ struct IUB {
+ int c;
+ double p;
+ unsigned int pi;
+ };
+
+ IUB iub[] = {
+ { 'a', 0.27, 5 },
+ { 'c', 0.15, 4 },
+ { 'g', 0.12, 3 },
+ { 't', 0.27, 2 },
+ };
+
+ int main( int argc, const char *argv[] ) {
+ printf("*%d,%d,%d*\\n", iub[0].c, int(iub[1].p*100), iub[2].pi);
+ return 0;
+ }
+ '''
+ self.do_test(src, '*97,15,3*')
+
+ def test_conststructs(self):
+ src = '''
+ #include <stdio.h>
+ struct IUB {
+ int c;
+ double p;
+ unsigned int pi;
+ };
+
+ int main( int argc, const char *argv[] ) {
+ IUB iub[] = {
+ { 'a', 0.27, 5 },
+ { 'c', 0.15, 4 },
+ { 'g', 0.12, 3 },
+ { 't', 0.27, 2 },
+ };
+ printf("*%d,%d,%d*\\n", iub[0].c, int(iub[1].p*100), iub[2].pi);
+// printf("*%d*\\n", int(iub[1].p*100));
+ return 0;
+ }
+ '''
+ self.do_test(src, '*97,15,3*')
+
+
+ def test_memcpy(self):
+ src = '''
+ #include <stdio.h>
+ #include <string.h>
+
+ int main( int argc, const char *argv[] ) {
+ int *a = new int[10];
+ int *b = new int[1];
+ int *c = new int[10];
+ for (int i = 0; i < 10; i++)
+ a[i] = 2;
+ *b = 5;
+ for (int i = 0; i < 10; i++)
+ c[i] = 8;
+ printf("*%d,%d,%d,%d,%d*\\n", a[0], a[9], *b, c[0], c[9]);
+ // Should overwrite a, but not touch b!
+ memcpy(a, c, 10*sizeof(int));
+ printf("*%d,%d,%d,%d,%d*\\n", a[0], a[9], *b, c[0], c[9]);
+ return 0;
+ }
+ '''
+ self.do_test(src, '*2,2,5,8,8*\n*8,8,5,8,8*')
+
+ def test_fannkuch(self):
+ results = [ (1,0), (2,1), (3,2), (4,4), (5,7), (6,10), (7, 16), (8,22) ]
+ for i, j in results:
+ src = open(path_from_root(['tests', 'fannkuch.cpp']), 'r').read()
+ self.do_test(src, 'Pfannkuchen(%d) = %d.' % (i,j), [str(i)], no_build=i>1)
+
+ def zzztest_fasta(self):
+ results = [ (1,'''GG*ctt**tgagc**'''), (20,'''GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTT*cttBtatcatatgctaKggNcataaaSatgtaaaDcDRtBggDtctttataattcBgtcg**tacgtgtagcctagtgtttgtgttgcgttatagtctatttgtggacacagtatggtcaaa**tgacgtcttttgatctgacggcgttaacaaagatactctg**'''),
+(50,'''GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA*TCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACAT*cttBtatcatatgctaKggNcataaaSatgtaaaDcDRtBggDtctttataattcBgtcg**tactDtDagcctatttSVHtHttKtgtHMaSattgWaHKHttttagacatWatgtRgaaa**NtactMcSMtYtcMgRtacttctWBacgaa**agatactctgggcaacacacatacttctctcatgttgtttcttcggacctttcataacct**ttcctggcacatggttagctgcacatcacaggattgtaagggtctagtggttcagtgagc**ggaatatcattcgtcggtggtgttaatctatctcggtgtagcttataaatgcatccgtaa**gaatattatgtttatttgtcggtacgttcatggtagtggtgtcgccgatttagacgtaaa**ggcatgtatg**''') ]
+ for i, j in results:
+ src = open(path_from_root(['tests', 'fasta.cpp']), 'r').read()
+ self.do_test(src, j, [str(i)], lambda x: x.replace('\n', '*'), no_python=True, no_build=i>1)
+
+if __name__ == '__main__':
+ if DEBUG: print "LLVM_GCC:", LLVM_GCC
+ if DEBUG: print "LLC:", LLC
+ if DEBUG: print "PARSER:", PARSER
+ if DEBUG: print "JS_ENGINE:", JS_ENGINE
+ for cmd in [LLVM_GCC, JS_ENGINE]:
+ if DEBUG: print "Checking for existence of", cmd
+ assert(os.path.exists(cmd))
+ unittest.main()
+
diff --git a/tests/settings.cfg b/tests/settings.cfg
new file mode 100644
index 00000000..34f90c87
--- /dev/null
+++ b/tests/settings.cfg
@@ -0,0 +1,16 @@
+DEBUG=False
+TEMP_DIR='/dev/shm'
+LLVM_GCC=os.path.expanduser('~/Dev/llvm/llvm-gcc-27/cbuild/bin/bin/llvm-g++')
+LLVM_DIS=os.path.expanduser('~/Dev/llvm/llvm-27/cbuild/bin/llvm-dis')
+PY_PARSER=path_from_root(['llvm-parser', 'parser.py'])
+SPIDERMONKEY_SHELL=os.path.expanduser(os.path.expanduser('~/Dev/tracemonkey/js/src/js'))
+V8_ENGINE=os.path.expanduser('~/Dev/v8/d8') # Note: Fails in test_strings etc. due to commandline arguments parsing
+JS_ENGINE=SPIDERMONKEY_SHELL
+JS_ENGINE_OPTS=[]#['-j']
+PARSER_ENGINE=SPIDERMONKEY_SHELL
+PARSER_OPTS=[]#['-j']
+#PARSER_ENGINE=V8_ENGINE
+#PARSER_OPTS = []
+#JS_ENGINE=V8_ENGINE
+JS_COMPILER=path_from_root(['src', 'parser.js'])
+