* net/loveruby/cflat/compiler/CodeGenerator.java: should handle global string literal.

* net/loveruby/cflat/asm/Assembler.java (_long, _quad): should handle label.
* test/run.sh: new test runner.
* test/shunit.sh: library function name must not start with "test_" because they are treated as test case definition.
* test/test.sh: split tests in to multiple functions.
* test/initializer.cb: test string initializer.
* test/comm.cb: ditto.
* test/scomm.cb: ditto.
* test/slvar.cb: ditto.
* test/gvar.cb: ditto.
* test/sgvar.cb: ditto.
* test/slcomm.cb: : ditto.


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@3967 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2008-08-29 07:35:31 +00:00
parent 85f2af8c84
commit 40720e76cf
13 changed files with 412 additions and 209 deletions

View File

@ -1,3 +1,32 @@
Fri Aug 29 16:35:39 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/CodeGenerator.java: should handle
global string literal.
* net/loveruby/cflat/asm/Assembler.java (_long, _quad): should
handle label.
* test/run.sh: new test runner.
* test/shunit.sh: library function name must not start with
"test_" because they are treated as test case definition.
* test/test.sh: split tests in to multiple functions.
* test/initializer.cb: test string initializer.
* test/comm.cb: ditto.
* test/scomm.cb: ditto.
* test/slvar.cb: ditto.
* test/gvar.cb: ditto.
* test/sgvar.cb: ditto.
* test/slcomm.cb: : ditto.
Tue Aug 19 19:18:00 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/CodeGenerator.java

View File

@ -110,10 +110,18 @@ public class Assembler {
line(".long\t" + n);
}
public void _long(Label label) {
line(".long\t" + label);
}
public void _quad(long n) {
line(".quad\t" + n);
}
public void _quad(Label label) {
line(".quad\t" + label);
}
public void _string(String str) {
line("\t.string\t" + TextUtils.escapeString(str));
}

View File

@ -119,16 +119,29 @@ static public void p(String s) { System.err.println(s); }
/** Generates immediate values for .data section */
// #@@range/compileImmediates{
protected void compileImmediate(Type type, ExprNode n) {
// FIXME: support other constants
IntegerLiteralNode expr = (IntegerLiteralNode)n;
switch ((int)type.allocSize()) {
case 1: _byte(expr.value()); break;
case 2: _value(expr.value()); break;
case 4: _long(expr.value()); break;
case 8: _quad(expr.value()); break;
default:
throw new Error("entry size is not 1,2,4,8");
protected void compileImmediate(Type type, ExprNode node) {
if (node instanceof IntegerLiteralNode) {
IntegerLiteralNode expr = (IntegerLiteralNode)node;
switch ((int)type.allocSize()) {
case 1: _byte(expr.value()); break;
case 2: _value(expr.value()); break;
case 4: _long(expr.value()); break;
case 8: _quad(expr.value()); break;
default:
throw new Error("entry size must be 1,2,4,8");
}
}
else if (node instanceof StringLiteralNode) {
StringLiteralNode expr = (StringLiteralNode)node;
switch ((int)type.allocSize()) {
case 4: _long(expr.label()); break;
case 8: _quad(expr.label()); break;
default:
throw new Error("pointer size must be 4,8");
}
}
else {
throw new Error("unknown literal node type" + node.getClass());
}
}
// #@@}
@ -888,7 +901,9 @@ comment("compileLHS: }");
public void _byte(long n) { as._byte(n); }
public void _value(long n) { as._value(n); }
public void _long(long n) { as._long(n); }
public void _long(Label label) { as._long(label); }
public void _quad(long n) { as._quad(n); }
public void _quad(Label label) { as._quad(label); }
public void _string(String str) { as._string(str); }
public void label(String sym) { as.label(sym); }
public void label(Label label) { as.label(label); }

View File

@ -1,13 +1,21 @@
import stdio;
int i;
int global_int;
char *global_string;
int
main(int argc, char **argv)
{
i = 1;
printf("%d", i);
i = 2;
printf(";%d\n", i);
global_int = 1;
printf("%d", global_int);
global_int = 2;
printf(";%d", global_int);
global_string = "OK";
printf(";%s", global_string);
global_string = "NEW";
printf(";%s", global_string);
puts("");
return 0;
}

View File

@ -1,12 +1,19 @@
import stdio;
int i = 1;
int global_int = 1;
char *global_string = "OK";
int
main(int argc, char **argv)
{
printf("%d", i);
i = 2;
printf(";%d\n", i);
printf("%d", global_int);
global_int = 2;
printf(";%d", global_int);
printf(";%s", global_string);
global_string = "NEW";
printf(";%s", global_string);
puts("");
return 0;
}

View File

@ -6,6 +6,9 @@ main(int argc, char **argv)
int i = 4;
int x = i * 5 * i;
int y = (x - x) * x;
int z = printf("%d;%d;%d\n", i, x, y);
int z = printf("%d;%d;%d", i, x, y);
char *s = "local";
printf(";%s", s);
puts("");
return 0;
}

41
test/run.sh Executable file
View File

@ -0,0 +1,41 @@
#!/usr/bin/ksh
main() {
cd "$(dirname "$0")"
. ./shunit.sh
. ./test.sh
case "$1" in
-t)
# run specified tests
shift
local pattern="$1"; shift
defined_tests | grep "$pattern" | sort | run_tests
;;
*)
# run all defined tests
defined_tests | sort | run_tests
;;
esac
}
run_tests() {
local pattern="$1"
local f
while read f
do
$f
done
shunit_report_result
}
defined_tests() {
defined_functions | grep '^test_'
}
defined_functions() {
typeset +f
}
main "$@"

View File

@ -1,6 +1,7 @@
import stdio;
static int static_common_symbol;
static char *static_common_string;
int
main(int argc, char **argv)
@ -8,6 +9,13 @@ main(int argc, char **argv)
static_common_symbol = 1;
printf("%d", static_common_symbol);
static_common_symbol = 2;
printf(";%d\n", static_common_symbol);
printf(";%d", static_common_symbol);
static_common_string = "OK";
printf(";%s", static_common_string);
static_common_string = "NEW";
printf(";%s", static_common_string);
puts("");
return 0;
}

View File

@ -1,12 +1,17 @@
import stdio;
static int static_global_variable = 1;
static char *static_global_string = "OK";
int
main(int argc, char **argv)
{
printf("%d", static_global_variable);
static_global_variable = 2;
printf(";%d\n", static_global_variable);
printf(";%d", static_global_variable);
printf(";%s", static_global_string);
static_global_string = "NEW";
printf(";%s", static_global_string);
puts("");
return 0;
}

View File

@ -6,7 +6,7 @@
n_tests=0
n_failed=0
test_finished() {
shunit_report_result() {
rm -rf tc.*
echo
if [ "$n_failed" = "0" ]
@ -37,7 +37,7 @@ begin_test() {
n_tests=`expr $n_tests "+" 1`
}
test_failed() {
assertion_failed() {
n_failed=`expr $n_failed "+" 1`
}
@ -59,7 +59,7 @@ assert_status() {
if [ "$really" != "$expected" ]
then
echo "shunit[$@]: status $expected expected but was: $really"
test_failed
assertion_failed
return 1
fi
return 0
@ -73,7 +73,7 @@ assert_error() {
if [ "$really" = "0" ]
then
echo "shunit[$@]: non-zero status expected but was: $really"
test_failed
assertion_failed
return 1
fi
return 0
@ -86,7 +86,7 @@ assert_eq() {
if [ "$really" != "$expected" ]
then
echo "shunit: <$expected> expected but is: <$really>"
test_failed
assertion_failed
return 1
fi
return 0
@ -118,7 +118,7 @@ assert_equal() {
fi
if [ "$_f" = "yes" ]
then
test_failed
assertion_failed
return 1
fi
return 0
@ -138,7 +138,7 @@ assert_equal_stdout() {
echo "stdout differ: \"$excmd\" and \"$mycmd\""
diff -u tc.out.expected tc.out.real
echo "----"
test_failed
assertion_failed
fi
return 0
}
@ -155,7 +155,7 @@ assert_stdout() {
echo "stdout differ: string \"$expected\" and cmd \"$@\""
diff -u tc.out.expected tc.out.real
echo "----"
test_failed
assertion_failed
fi
return 0
}
@ -167,7 +167,7 @@ assert_not_coredump() {
then
echo "core dumped: $mycmd"
echo "----"
test_failed
assertion_failed
return 1
fi
rm -f core
@ -181,7 +181,7 @@ assert_not_exist() {
then
echo "exists: $file"
echo "----"
test_failed
assertion_failed
return 1
fi
return 0
@ -194,7 +194,7 @@ assert_directory() {
then
echo "not directory: $dir"
echo "----"
test_failed
assertion_failed
return 1
fi
return 0

View File

@ -4,11 +4,16 @@ int
main(int argc, char **argv)
{
static int static_variable;
static char *static_string;
static_variable = 1;
printf("%d", static_variable);
static_variable = 2;
printf(";%d", static_variable);
static_string = "OK";
printf(";%s", static_string);
static_string = "NEW";
printf(";%s", static_string);
puts("");
return 0;
}

View File

@ -4,10 +4,14 @@ int
main(int argc, char **argv)
{
static int static_variable = 1;
static char *static_string = "OK";
printf("%d", static_variable);
static_variable = 2;
printf(";%d", static_variable);
printf(";%s", static_string);
static_string = "NEW";
printf(";%s", static_string);
puts("");
return 0;
}

422
test/test.sh Executable file → Normal file
View File

@ -1,9 +1,246 @@
#!/bin/sh
#
# test.sh
#
cd `dirname $0`
. ./shunit.sh
CBC=../cbc
test_01_exec() {
assert_stat 0 ./zero
assert_stat 1 ./one
}
test_02_print() {
assert_out "Hello, World!" ./hello
assert_out "Hello, World!" ./hello2
assert_out "Hello, World!" ./hello3
assert_out "Hello, World!" ./hello4
}
test_03_integer() {
assert_out "0;0;0;1;1;1;9;9;9;17;17;17" ./integer
}
test_04_funcall() {
assert_stat 0 ./funcall0
assert_stat 0 ./funcall1
assert_stat 0 ./funcall2
assert_stat 0 ./funcall3
assert_stat 0 ./funcall4
assert_out "1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;30;31;32;33;34;35;36;37;38;39;40;41;42;43;44;45;46;47;48;49;50;51;52;53;54;55" ./funcall5
}
test_05_string() {
assert_out "$(/bin/echo -e ';;a;aa;b;";'\'';\a\b\0033\f\n\r\t\v;ABCabc')" ./string
# assert_out "..." ./mbc # FIXME
}
test_06_variables() {
assert_out "1;2" ./param
assert_out "1;2" ./lvar1
assert_out "1;2;3;4;5" ./lvar2
assert_out "4;80;0;local" ./initializer
assert_out "1;2;OK;NEW" ./comm
assert_public comm global_int
assert_public comm global_string
assert_out "1;2;OK;NEW" ./scomm
assert_private scomm static_common_symbol
assert_private scomm static_common_string
assert_out "1;2;OK;NEW" ./gvar
assert_public comm global_int
assert_public comm global_string
assert_out "1;2;OK;NEW" ./sgvar
assert_private sgvar static_global_variable
assert_private sgvar static_global_string
assert_out "1;2;OK;NEW" ./slvar
assert_private slvar static_variable
assert_private slvar static_string
assert_out "1;2;OK;NEW" ./slcomm
assert_private slcomm static_variable
assert_private slcomm static_string
}
test_07_arithmetic() {
assert_out "-1;0;1" ./unaryminus
assert_out "1;0;-1" ./unaryplus
assert_out "1;2;3;4;5;6;7;8;9;10;11" ./add
assert_out "1;2;3;4;5;6;7;8;9;10;11;12;13" ./sub
assert_out "1;4;15" ./mul
assert_out "1;2;2;2" ./div
assert_out "0;0;1;4;7" ./mod
assert_out "3" ./assoc
}
test_08_bitop() {
assert_out "0;1;2;3;4" ./bitand
assert_out "0;1;2;3;2;6;8;10" ./bitor
assert_out "1;2;0;0;2" ./bitxor
assert_out "-1;-2;0" ./bitnot
assert_out "1;2;4;8;16" ./lshift
assert_out "16;8;4;2;1" ./rshift
}
test_09_cmp() {
assert_out "0;1;0" ./eq
assert_out "1;0;1" ./neq
assert_out "1;0;0" ./gt
assert_out "0;0;1" ./lt
assert_out "1;1;0" ./gteq
assert_out "0;1;1" ./lteq
}
test_10_assign() {
assert_out "2;2;3;4;5;6;7;8;9;10;11;777" ./assign
assert_out "3;4;3;12;4;1;1;7;5;1;4" ./opassign
assert_out "0;1;2;2;3;3;4" ./inc
assert_out "4;3;2;2;1;1;0" ./dec
}
test_12_if() {
assert_ok ./if1
assert_ok ./if2
}
test_13_logical() {
assert_out "1;0;0" ./logicalnot
assert_out "OK;OK;OK;OK" ./condexpr
assert_out "0;0;0;2" ./logicaland
assert_out "0;1;1;1" ./logicalor
}
test_14_while() {
assert_ok ./while1
assert_ok ./while2
assert_out "3;3;2;1;0" ./while3
assert_ok ./while-break
assert_ok ./while-continue
}
test_15_dowhile() {
assert_ok ./dowhile1
assert_ok ./dowhile2
assert_out "3;3;2;1;0" ./dowhile3
assert_ok ./dowhile-break
assert_ok ./dowhile-continue
}
test_16_for() {
assert_out "3;3;2;1;0" ./for1
assert_ok ./for-break
assert_ok ./for-continue
}
test_17_jump() {
assert_compile_error break-semcheck.cb
assert_compile_error continue-semcheck.cb
}
test_18_array() {
assert_out "1;5;9" ./array
assert_out "0;0;0" ./array2
assert_compile_error aref-semcheck.cb
assert_compile_error array-semcheck1.cb
assert_compile_error array-semcheck2.cb
}
test_19_struct() {
assert_out "11;22" ./struct
assert_stat 0 ./struct-semcheck
assert_status 0 $CBC empstruct.cb
assert_compile_error struct-semcheck2.cb
assert_compile_error struct-semcheck3.cb
assert_compile_error struct-semcheck4.cb
assert_compile_error struct-semcheck5.cb
assert_compile_error struct-semcheck6.cb
assert_compile_error struct-semcheck7.cb
assert_compile_error struct-semcheck8.cb
assert_compile_error struct-semcheck9.cb
assert_compile_error struct-semcheck10.cb
}
test_20_union() {
assert_out "1;2;513" ./union # little endian
assert_stat 0 ./union-semcheck
assert_compile_error union-semcheck2.cb
assert_compile_error union-semcheck3.cb
assert_compile_error union-semcheck4.cb
assert_compile_error union-semcheck5.cb
assert_compile_error union-semcheck6.cb
assert_compile_error union-semcheck7.cb
assert_compile_error union-semcheck8.cb
assert_compile_error union-semcheck9.cb
assert_compile_error union-semcheck10.cb
}
test_21_typedef() {
assert_out "1;2;1;1;3;4;5;6;OK" ./usertype
assert_compile_error recursivetypedef.cb
}
test_22_pointer() {
assert_out "5;5" ./pointer
assert_out "777" ./pointer2
assert_out "1;777;3;4;1;777;3;4" ./pointer3
assert_out "777" ./pointer4
assert_out "1;2;3;4;5;6" ./ptrmemb
assert_compile_error deref-semcheck1.cb
assert_compile_error deref-semcheck2.cb
assert_compile_error deref-semcheck3.cb
assert_compile_error deref-semcheck4.cb
assert_compile_error deref-semcheck5.cb
}
test_23_limits() {
assert_out "2;64;-128;0" ./charops
assert_out "2;64;128;0" ./ucharops
assert_out "2;16384;-32768;0" ./shortops
assert_out "2;16384;32768;0" ./ushortops
assert_out "2;1073741824;-2147483648;0" ./intops
assert_out "2;1073741824;2147483648;0" ./uintops
assert_out "1;2;1073741824;-2147483648;0" ./longops # 32bit
assert_out "1;2;1073741824;2147483648;0" ./ulongops # 32bit
}
test_24_cast() {
assert_out "25000000" ./cast
assert_out "777;666" ./cast2
assert_out "666;777" ./cast3
}
test_25_block() {
assert_out "2" ./block
assert_out "1;2;3" ./defvar
}
test_26_funcptr() {
assert_out "OK" ./funcptr
assert_out "OK" ./funcptr2
assert_compile_error defun-semcheck.cb
assert_compile_error defun-semcheck2.cb
assert_compile_error defun-semcheck3.cb
assert_compile_error defun-semcheck4.cb
assert_compile_error defun-semcheck5.cb
assert_compile_error defun-semcheck6.cb
assert_compile_error defun-semcheck7.cb
assert_compile_error defun-semcheck8.cb
assert_compile_error funcall-semcheck.cb
assert_compile_error funcall-semcheck2.cb
}
test_28_syntax() {
assert_out "1, 2, 0" ./test2
assert_status 0 $CBC test3.cb
assert_stat 0 ./test4
}
###
### Local Assertions
###
assert_compile() {
assert_status 0 $CBC "$@"
}
@ -34,6 +271,10 @@ symbol_visibility() {
fi
}
assert_public() {
assert_eq "public" `symbol_visibility $1 $2`
}
assert_private() {
assert_eq "private" `symbol_visibility $1 $2`
}
@ -43,7 +284,7 @@ assert_compile_error() {
if eval "$CBC $@" >tc.out 2>&1
then
echo "shunit[$@]: compile error not occured"
test_failed
assertion_failed
return 1
fi
assert_not_coredump || return
@ -51,179 +292,8 @@ assert_compile_error() {
then
echo "shunit[$@]: abnormal cbc error; error message is:"
cat tc.out
test_failed
assertion_failed
return 1
fi
return 0
}
assert_stat 0 ./zero
assert_stat 1 ./one
assert_out "Hello, World!" ./hello
assert_out "Hello, World!" ./hello2
assert_out "Hello, World!" ./hello3
assert_out "Hello, World!" ./hello4
assert_out "0;0;0;1;1;1;9;9;9;17;17;17" ./integer
assert_stat 0 ./funcall0
assert_stat 0 ./funcall1
assert_stat 0 ./funcall2
assert_stat 0 ./funcall3
assert_stat 0 ./funcall4
assert_out "1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;30;31;32;33;34;35;36;37;38;39;40;41;42;43;44;45;46;47;48;49;50;51;52;53;54;55" ./funcall5
assert_out "$(/bin/echo -e ';;a;aa;b;";'\'';\a\b\0033\f\n\r\t\v;ABCabc')" ./string
assert_out "1;2" ./param
assert_out "1;2" ./lvar1
assert_out "1;2;3;4;5" ./lvar2
assert_out "1;2" ./comm
assert_out "1;2" ./scomm
assert_private scomm static_common_symbol
assert_out "1;2" ./gvar
assert_out "1;2" ./sgvar
assert_private sgvar static_global_variable
assert_out "1;2" ./slvar
assert_private slvar static_variable
assert_out "1;2" ./slcomm
assert_private slcomm static_variable
assert_out "1;2;3;4;5;6;7;8;9;10;11" ./add
assert_out "1;2;3;4;5;6;7;8;9;10;11;12;13" ./sub
assert_out "1;4;15" ./mul
assert_out "1;2;2;2" ./div
assert_out "0;0;1;4;7" ./mod
assert_out "0;1;2;3;4" ./bitand
assert_out "0;1;2;3;2;6;8;10" ./bitor
assert_out "1;2;0;0;2" ./bitxor
assert_out "-1;-2;0" ./bitnot
assert_out "1;2;4;8;16" ./lshift
assert_out "16;8;4;2;1" ./rshift
assert_out "1;0;0" ./logicalnot
assert_out "-1;0;1" ./unaryminus
assert_out "1;0;-1" ./unaryplus
assert_out "0;1;0" ./eq
assert_out "1;0;1" ./neq
assert_out "1;0;0" ./gt
assert_out "0;0;1" ./lt
assert_out "1;1;0" ./gteq
assert_out "0;1;1" ./lteq
assert_out "2;2;3;4;5;6;7;8;9;10;11;777" ./assign
assert_out "3;4;3;12;4;1;1;7;5;1;4" ./opassign
assert_out "0;1;2;2;3;3;4" ./inc
assert_out "4;3;2;2;1;1;0" ./dec
assert_ok ./if1
assert_ok ./if2
assert_out "OK;OK;OK;OK" ./condexpr
assert_out "0;0;0;2" ./logicaland
assert_out "0;1;1;1" ./logicalor
assert_ok ./while1
assert_ok ./while2
assert_out "3;3;2;1;0" ./while3
assert_ok ./while-break
assert_ok ./while-continue
assert_ok ./dowhile1
assert_ok ./dowhile2
assert_out "3;3;2;1;0" ./dowhile3
assert_ok ./dowhile-break
assert_ok ./dowhile-continue
assert_out "3;3;2;1;0" ./for1
assert_ok ./for-break
assert_ok ./for-continue
assert_compile_error break-semcheck.cb
assert_compile_error continue-semcheck.cb
assert_out "1;5;9" ./array
assert_out "0;0;0" ./array2
assert_compile_error aref-semcheck.cb
assert_compile_error array-semcheck1.cb
assert_compile_error array-semcheck2.cb
assert_out "11;22" ./struct
assert_stat 0 ./struct-semcheck
assert_status 0 $CBC empstruct.cb
assert_compile_error struct-semcheck2.cb
assert_compile_error struct-semcheck3.cb
assert_compile_error struct-semcheck4.cb
assert_compile_error struct-semcheck5.cb
assert_compile_error struct-semcheck6.cb
assert_compile_error struct-semcheck7.cb
assert_compile_error struct-semcheck8.cb
assert_compile_error struct-semcheck9.cb
assert_compile_error struct-semcheck10.cb
assert_out "1;2;513" ./union # little endian
assert_stat 0 ./union-semcheck
assert_compile_error union-semcheck2.cb
assert_compile_error union-semcheck3.cb
assert_compile_error union-semcheck4.cb
assert_compile_error union-semcheck5.cb
assert_compile_error union-semcheck6.cb
assert_compile_error union-semcheck7.cb
assert_compile_error union-semcheck8.cb
assert_compile_error union-semcheck9.cb
assert_compile_error union-semcheck10.cb
assert_out "1;2;1;1;3;4;5;6;OK" ./usertype
assert_compile_error recursivetypedef.cb
assert_out "5;5" ./pointer
assert_out "777" ./pointer2
assert_out "1;777;3;4;1;777;3;4" ./pointer3
assert_out "777" ./pointer4
assert_out "1;2;3;4;5;6" ./ptrmemb
assert_compile_error deref-semcheck1.cb
assert_compile_error deref-semcheck2.cb
assert_compile_error deref-semcheck3.cb
assert_compile_error deref-semcheck4.cb
assert_compile_error deref-semcheck5.cb
assert_out "2;64;-128;0" ./charops
assert_out "2;64;128;0" ./ucharops
assert_out "2;16384;-32768;0" ./shortops
assert_out "2;16384;32768;0" ./ushortops
assert_out "2;1073741824;-2147483648;0" ./intops
assert_out "2;1073741824;2147483648;0" ./uintops
assert_out "1;2;1073741824;-2147483648;0" ./longops # 32bit
assert_out "1;2;1073741824;2147483648;0" ./ulongops # 32bit
assert_out "25000000" ./cast
assert_out "777;666" ./cast2
assert_out "666;777" ./cast3
assert_out "2" ./block
assert_out "1;2;3" ./defvar
assert_out "OK" ./funcptr
assert_out "OK" ./funcptr2
assert_compile_error defun-semcheck.cb
assert_compile_error defun-semcheck2.cb
assert_compile_error defun-semcheck3.cb
assert_compile_error defun-semcheck4.cb
assert_compile_error defun-semcheck5.cb
assert_compile_error defun-semcheck6.cb
assert_compile_error defun-semcheck7.cb
assert_compile_error defun-semcheck8.cb
assert_compile_error funcall-semcheck.cb
assert_compile_error funcall-semcheck2.cb
#assert_out "..." ./mbc # FIXME
assert_out "3" ./assoc
assert_out "4;80;0" ./initializer
assert_out "1, 2, 0" ./test2
assert_status 0 $CBC test3.cb
assert_stat 0 ./test4
test_finished