<commit_before>#include "incs.h"
#include "tests.h"
#include "k.h"

//  Note:
//  
//  To test out-of-memory handling on determininistic calls, execute the string
//  and record the number of allocations n. Then simulate out of memory,
//  running the string each time for each i < n. Allocating functions such as
//  malloc, mmap, newK(), etc. will need to be overridden with debug versions.
//  This will be significantly slower.
//

Z I testsIO();
Z I tests02();
Z I tests01();
Z I testsBook();

#define TC_(x, y ) {S s=ts(tp(tc(x, y))); if(test_print) fprintf(stderr, "%s:%u: TC( " x " , " y " ) ... %s\n", __FILE__, __LINE__,s); test_print=0; }
#define TC(x,...) TC_(#x,#__VA_ARGS__)

I passed=0, skipped=0, failed=0;
I tests=0;
I test_print=0;
F testtime;

S ts(I x){ switch(x){CS(0,R "fail";) CS(1,R "OK")  CS(2,R "skipped")}; R 0;}
I tp(I x){ switch(x){CS(0,failed++)  CS(1,passed++)CS(2,skipped++)} tests++; R x;} //process the test

I tc(S a, S b) //test comparison .  R 0,1,2
{
  if(!(tests % 50)) O("t:%lld\n",tests); //commenting this causes an error. no idea why. fflush? macro stuff? >2 args bc of "skip" ?
  if(!SC("skip",a)) R 2;

  kreci=0;

  KTREE=Kd();
  K x = X(a);
  K y = X(b);
  I m=matchI(x,y);

  if(!m)
  {
    fprintf(stderr,"\nFailed. These are not equal:\n");
    fprintf(stderr,"%s , %s\n", a,b);
    fprintf(stderr,"********************************\n");
    show(x); fflush(stdout);
    fprintf(stderr,"--------------------------------\n");
    show(y); fflush(stdout);
    fprintf(stderr,"\n");
  }
  cd(x); cd(y);

  cd(KTREE);
  I c=0; DO(kreci, if(krec[i]) c++)
  if(!c) R m;

  fprintf(stderr,"Failed: Memory Leak - %s, %s \nAllocated K: %lld\nUnfreed K  : %lld\nLeak %%     : %f\n", a,b,kreci, c, c/(F)kreci);
  I j=-1;
  DO(c, do j++; while(!krec[j] && j < kreci); if(j>=kreci) break; K k=krec[j]; if(k){O("c:%lld t:%lld n:%lld | k:%p\n",k->c,k->t,k->n,k); show(k);} )
  R 0;
}

I test()
{ testtime=clock();

  testsBook();
  tests01();
  tests02();
  testsIO();  //could become slow - in the future may not want to test by default
  K x; x=_(567);if(!tp(x && *kI(x)==567))fprintf(stderr,"\n\nK string execution broken\n\n"); cd(x);

//done:
  testtime=(clock()-testtime)/CLOCKS_PER_SEC;
  F rate=passed/((F)tests-skipped);
  O("Test pass rate: %.4f, Total: %lld, Passed: %lld, Skipped: %lld, Failed: %lld, Time: %fs\n", rate,tests,passed,skipped,failed,testtime);
  I r=1==rate;
  O("%s\n", ts(r));
  testtime=0;
  R r;
}

Z I testsIO()
{
  return 0;
  //binary - 1: 2:
  TC(1,t:`testfile00; a:(1;1.0;"c";`d;1 2;3.0 4.0;"ef";`g`h;();(1;`z)); t 1: a;  &/ a ~/: (1:t;2:t)) //leaves a file
}
 
Z I tests02()
{
  TC(`b,(`a`b)[1])
  TC(2, {1+1} 0)
  TC(2, {a:1;a+a} _n )
  TC(_n, {a:1;a+a}0;a)
  TC(99#1, {1}/:!99)
  TC({x^2}, f:{x^2};.`f)
  TC(1, (1+)~(1+))
  TC(0, (1+)~(2+))
  TC(1, {x} ~ {x})
  TC(0, {x} ~ {x })
  TC(1+2+3, {b:1;c:2;d:3;b+c+d} 0)
  TC(_n, {1;;;} 0 )
  TC({_f}, {_f} 0)
  TC(2 6 24, {:[x<2;1;_f[x-1]*x]}/: 2 3 4)  //paired with below
  TC(2 6 24, {:[x<2;1;x* _f[x-1]]}/: 2 3 4) //regression
  TC(60.0,   {:[(x<2)&(y<2);2;(x^2)+(y^2)+_f[x-1;y-1]]}[4;4]) //tests _f cache handled correctly
  TC(skip, (1;"stack") , .[{_f _f};0;:] ) //this test works but it takes 3x the other 600 tests
  TC(_n , _f) //nice not necessary
  TC(7, {[a;b;cc]q:0;z:1; a+b*cc}[1;2;3])
  TC(1, {x} 1)
  TC(2, {x+y}[1;1])
  TC(3, {z+y+x}[1;1;1])
  TC(12, f:{x+y}; f[1;2];f[8;4])
  TC(4, {4} 0)
  TC(5, {[] 2+3} 0)
  TC(1 2, a: 1 2;{a} 0) //Context is visible
  TC(1 2, a: 1 2;{a:3} 0;a)//Local changes are not applied to context
  TC(3 4, a: 1 2;{a+:2} 0; a)
  TC(_n, b:9;{b:b} 0)
  TC((2 4) , ((1+)[1]; (1+|+)[1;2]) )
  TC((),=!0) // =: Group had a bug with one element lists 
  TC((,,0),=,1)
  TC((,0;,1),=1 2)
  TC((,0;,1),=2 1)
  TC((2#,(,0;,1)), =:/:(1 2;2 1)) //Nice extension to K3.2, which errs on both =/: and =:/:

  //Projections
  TC((1;"valence"),@[.:;"{x}[1;]";:])
  TC((1;"valence"),@[.:;"+[1;2;;;]";:])
  TC(skip, (1;"valence"), .[+[1;2;;;]; 5;:] ) //fill in error trap //this has a problem?  +[1;2;;;;] causing valence when shouldn't?

  TC({x+y}[1;],{x+y}[1;])
  TC({x+y}[;1],{x+y}[;1])
  TC(!3, {x,y,z}[;;2][;1][0])
  TC(1 2 3 4, {x[z;y]}[,][3 4;1 2])
  TC(!3, f:{[a;b;c]a,b,c}; g:f 0; h:g 1; h 2)
  TC(skip, {[a;b;c;d;e]a+b+c+d+e}[;;1;1;1]'[;1] , {[a;b;c;d;e]a+b+c+d+e}[;;1;1;1]'[;1])
  TC((1 0;1 3) , a:(1 0;3 2); f:{a[x;y]}; (a[]0;f[]0)) //Cross-sectional indexing inconsistent with simple composition/projection
  TC(2 1, f:![1;]; f 1 2)
  TC(3, f:+[;]; g:f 1; g 2)
  TC(8.0, f:^[;]; g:f[;3]; g 2)
  TC(4 5, +[3;]/:1 2)
  TC_("7 8", "+[3;]\'[4 5]")

  //Global Assignment
  TC(7, {a::7} 0; a)
  TC(7, a::[1;7];a) //Mix with conditionals
  TC(7, {a:::[1;7]}0;a)
  TC(7, {a::[1;7];a} 0)

  //Subfunctions
  TC( 3, {b:3; g:{b}; b:4; g[]}0)       // inheritance: same var in prnt&child  child res
  TC( 4, {b:3; g:{b}; b:4; b}0)         // inheritance: same var in prnt&child  prnt res
  TC(_n, {b:3; g:{a}; b:4; g[]}0)       // inheritance: diff var in prnt/child, child res
  TC( 4, {b:3; g:{a}; b:4; b}0)         // inheritance: diff var in prnt/child, prnt res
  TC( 1, {g:{b:1}; g[]}0)               // :: subf-asgn, no prnt-asgn
  TC(12, {g:{b:1}; b::12; g[]}0;b)      // :: gl-asgn, gl-res (no prnt-asgn)
  TC( 1, {g:{b:1}; b::12; g[]}0)        // :: gl-asgn, child-res (no prnt-asgn)
  TC( 1, {g:{b:1}; c::12; g[]}0)        // :: gl-asgn, child-res (diff gl variable)
  TC( 4, {g:{b:1}; b::12; b:4; b}0)     // :: gl-asgn, prnt-res (prnt-asgn after gl-asgn)
  TC(_n, {g:{b:1}; b::12; b:4; b}0;b)   // :: gl-asgn, glbl-res (prnt-asgn after gl-asgn)
  TC(12, {g:{b:1}; b::12; b}0)          // :: gl-asgn, prnt-res (no prnt-asgn)
  TC(12, {g:{b:1}; b:4; b::12; b}0)     // :: gl-asgn, prnt-res (prnt-asgn before gl-asgn)
  TC(_n, {g:{b:1}; b:4; b::12; b}0;b)   // :: gl-asgn, glbl-res (prnt-asgn before gl-asgn)
  TC(12, b:3;{g:{b:1};b::12;g[]} 0;b)   // :: gl-asgn, pre-existing gl
  TC( 1, {g:{b:1;b}; b:12; g[]}0)       // :  prnt-asgn, child res
  TC( 3, {b:3; {b:4; b}0; b}0)          // :  prnt-asgn, prnt res
  TC( 3, {[a;b]{[c;d]c+d}[a;b]}[1;2])   // 2 explicit bracket args
  TC( 2, {[a;a]a+a}[1;9])               // oddly enough (no subfunction)
  TC( 1 10, {a:10; {x,a}x}1)            // 1 implicit arg: x
  TC( 1 2 10, {a:10;{x,y,a}[x;y]}[1;2]) // 2 implicit args x,y
  TC( 7, {{x+y+z}[x;y;z]+1}[1;2;3])     // 3 implict args: x,y,z
  TC( 8, {x+{b:3;g:{b};b:4;g[]}0}5)     // Depth-2 and inheritance
  TC( 4, {x-{x+{b:3;g:{b};b:4;g[]}0}5}12)  // Depth-3 and inheritance
  TC(3 5, {x+y,{x-{x+{b:3;g:{b};b:4;g[]}0}5}12}[1;2])  // Depth-4
  TC( 9, {+/x,{x+y,4}[1;2]}1)           // 2-level implicit args
  TC( 9, {+/x,{x+y,{x-{x+{b:3; g:{b}; b:4; g[]}0}5}12}[1;2]}1) // Depth-5
  TC( 5, {+/x,{x+y,{x-{x+{b:3; g:{b}; b:4; :7; g[]}0}5}12}[1;2]}1) // early-return in level-5
  TC( 7, {+/x,{x+y,{x-{x+{b:3; g:{b}; b:4; g[]}0}5}12}[1;2]; :7}1) // early-return in level-1
  TC( 3, {{b:3; g:{b}; b:4; g[]}0}0)    // unbuffered double braces
  TC( 4, {1+{b:3; g:{b}; b:4; g[]}0}0)  // buffered double braces 
  TC( 8, {({b:3;g:{b};b:4;g[]}0) + {b:5;g:{b};b:6;g[]}0}0) //double independent subfuncs
  TC( 3, b:9; {b:3;g:{b};b:4;g[]}0)     // pre-existing K-Tree entry
  TC(25, {{+/x,{x+y,{x-{x+{b:3;g:{b};b:4;g[]}0}5}12}[1;2]}1 + {x+{b:3;g:{b};b:4;g[]}0}5 + {x-{x+{b:3;g:{b};b:4;g[]}0}5}12 + x}4)
         // 4 stacks: depth-5, depth-2, depth-3, and implicit
  TC(1 3 10 3 10, g:1; do[2;{a:10; g::g,{x,a}x}3]; g) // do[2;] loop with subfunction (implicit arg) 
  TC( 7, f:{x+y+z}; g:f[1;;3]; {b:3; h:{b}; b:4; g[h[ ] ] }0) // projection and subfunction
  TC( 3, {:[x<2;1;_f[x-1]*x]}/: 2 3 4; {b:3; g:{b}; b:4; g[]}0) // muti-statement combo test
  TC(120, {b:3; g:{b}; a::{:[x<2; 1; _f[x-1]*x]}5; g[ ]}0; a) // embedded _f with atom-arg
  TC(2 6 24, {b:3; g:{b}; a::{:[x<2; 1; _f[x-1]*x]}/:2 3 4; g[ ]}0; a) // embedded _f with list-arg
  TC( 5, {x + {[a] a+a} y}[1;2])        // Leon Baum test
  TC( 5, {[a;b] a + {x+x} b}[1;2])      // Leon Baum test-2
  TC( 3, {[n]a:n;{x}a}3 )               // Variable scope problem
  TC_("(7 0;7 1;7 2)", "{a:5;{(7;x)}'[!3]}[]")

  //Error trap: {[a;b][c;d] a+b} -> parse error ; { {[a][b] }} -> parse error
  TC(.[*; (3;4); :], (0;12) )
  TC(.[*;3 4 5;:], (1;"valence"))
  TC((.[-1 -2 _; ,!9; :]) , (1;"domain"))<commit_msg>better documenation of target test cases<commit_after>#include "incs.h"
#include "tests.h"
#include "k.h"

//  Note:
//  
//  To test out-of-memory handling on determininistic calls, execute the string
//  and record the number of allocations n. Then simulate out of memory,
//  running the string each time for each i < n. Allocating functions such as
//  malloc, mmap, newK(), etc. will need to be overridden with debug versions.
//  This will be significantly slower.
//

Z I testsIO();
Z I tests02();
Z I tests01();
Z I testsBook();

#define TC_(x, y ) {S s=ts(tp(tc(x, y))); if(test_print) fprintf(stderr, "%s:%u: TC( " x " , " y " ) ... %s\n", __FILE__, __LINE__,s); test_print=0; }
#define TC(x,...) TC_(#x,#__VA_ARGS__)

I passed=0, skipped=0, failed=0;
I tests=0;
I test_print=0;
F testtime;

S ts(I x){ switch(x){CS(0,R "fail";) CS(1,R "OK")  CS(2,R "skipped")}; R 0;}
I tp(I x){ switch(x){CS(0,failed++)  CS(1,passed++)CS(2,skipped++)} tests++; R x;} //process the test

I tc(S a, S b) //test comparison .  R 0,1,2
{
  if(!(tests % 50)) O("t:%lld\n",tests); //commenting this causes an error. no idea why. fflush? macro stuff? >2 args bc of "skip" ?
  if(!SC("skip",a)) R 2;

  kreci=0;

  KTREE=Kd();
  K x = X(a);
  K y = X(b);
  I m=matchI(x,y);

  if(!m)
  {
    fprintf(stderr,"\nFailed. These are not equal:\n");
    fprintf(stderr,"%s , %s\n", a,b);
    fprintf(stderr,"********************************\n");
    show(x); fflush(stdout);
    fprintf(stderr,"--------------------------------\n");
    show(y); fflush(stdout);
    fprintf(stderr,"\n");
  }
  cd(x); cd(y);

  cd(KTREE);
  I c=0; DO(kreci, if(krec[i]) c++)
  if(!c) R m;

  fprintf(stderr,"Failed: Memory Leak - %s, %s \nAllocated K: %lld\nUnfreed K  : %lld\nLeak %%     : %f\n", a,b,kreci, c, c/(F)kreci);
  I j=-1;
  DO(c, do j++; while(!krec[j] && j < kreci); if(j>=kreci) break; K k=krec[j]; if(k){O("c:%lld t:%lld n:%lld | k:%p\n",k->c,k->t,k->n,k); show(k);} )
  R 0;
}

I test()
{ testtime=clock();

  testsBook();
  tests01();
  tests02();
  testsIO();  //could become slow - in the future may not want to test by default
  K x; x=_(567);if(!tp(x && *kI(x)==567))fprintf(stderr,"\n\nK string execution broken\n\n"); cd(x);

//done:
  testtime=(clock()-testtime)/CLOCKS_PER_SEC;
  F rate=passed/((F)tests-skipped);
  O("Test pass rate: %.4f, Total: %lld, Passed: %lld, Skipped: %lld, Failed: %lld, Time: %fs\n", rate,tests,passed,skipped,failed,testtime);
  I r=1==rate;
  O("%s\n", ts(r));
  testtime=0;
  R r;
}

Z I testsIO()
{
  return 0;
  //binary - 1: 2:
  TC(1,t:`testfile00; a:(1;1.0;"c";`d;1 2;3.0 4.0;"ef";`g`h;();(1;`z)); t 1: a;  &/ a ~/: (1:t;2:t)) //leaves a file
}
 
Z I tests02()
{
  TC(`b,(`a`b)[1])
  TC(2, {1+1} 0)
  TC(2, {a:1;a+a} _n )
  TC(_n, {a:1;a+a}0;a)
  TC(99#1, {1}/:!99)
  TC({x^2}, f:{x^2};.`f)
  TC(1, (1+)~(1+))
  TC(0, (1+)~(2+))
  TC(1, {x} ~ {x})
  TC(0, {x} ~ {x })
  TC(1+2+3, {b:1;c:2;d:3;b+c+d} 0)
  TC(_n, {1;;;} 0 )
  TC({_f}, {_f} 0)
  TC(2 6 24, {:[x<2;1;_f[x-1]*x]}/: 2 3 4)  //paired with below
  TC(2 6 24, {:[x<2;1;x* _f[x-1]]}/: 2 3 4) //regression
  TC(60.0,   {:[(x<2)&(y<2);2;(x^2)+(y^2)+_f[x-1;y-1]]}[4;4]) //tests _f cache handled correctly
  TC(skip, (1;"stack") , .[{_f _f};0;:] ) //this test works but it takes 3x the other 600 tests
  TC(_n , _f) //nice not necessary
  TC(7, {[a;b;cc]q:0;z:1; a+b*cc}[1;2;3])
  TC(1, {x} 1)
  TC(2, {x+y}[1;1])
  TC(3, {z+y+x}[1;1;1])
  TC(12, f:{x+y}; f[1;2];f[8;4])
  TC(4, {4} 0)
  TC(5, {[] 2+3} 0)
  TC(1 2, a: 1 2;{a} 0) //Context is visible
  TC(1 2, a: 1 2;{a:3} 0;a)//Local changes are not applied to context
  TC(3 4, a: 1 2;{a+:2} 0; a)
  TC(_n, b:9;{b:b} 0)
  TC((2 4) , ((1+)[1]; (1+|+)[1;2]) )
  TC((),=!0) // =: Group had a bug with one element lists 
  TC((,,0),=,1)
  TC((,0;,1),=1 2)
  TC((,0;,1),=2 1)
  TC((2#,(,0;,1)), =:/:(1 2;2 1)) //Nice extension to K3.2, which errs on both =/: and =:/:

  //Projections
  TC((1;"valence"),@[.:;"{x}[1;]";:])
  TC((1;"valence"),@[.:;"+[1;2;;;]";:])
  TC(skip, (1;"valence"), .[+[1;2;;;]; 5;:] ) //fill in error trap //this has a problem?  +[1;2;;;;] causing valence when shouldn't?

  TC({x+y}[1;],{x+y}[1;])
  TC({x+y}[;1],{x+y}[;1])
  TC(!3, {x,y,z}[;;2][;1][0])
  TC(1 2 3 4, {x[z;y]}[,][3 4;1 2])
  TC(!3, f:{[a;b;c]a,b,c}; g:f 0; h:g 1; h 2)
  TC(skip, {[a;b;c;d;e]a+b+c+d+e}[;;1;1;1]'[;1] , {[a;b;c;d;e]a+b+c+d+e}[;;1;1;1]'[;1])
  TC((1 0;1 3) , a:(1 0;3 2); f:{a[x;y]}; (a[]0;f[]0)) //Cross-sectional indexing inconsistent with simple composition/projection
  TC(2 1, f:![1;]; f 1 2)
  TC(3, f:+[;]; g:f 1; g 2)
  TC(8.0, f:^[;]; g:f[;3]; g 2)
  TC(4 5, +[3;]/:1 2)
  TC_("7 8", "+[3;]\'[4 5]")

  //Global Assignment
  TC(7, {a::7} 0; a)
  TC(7, a::[1;7];a) //Mix with conditionals
  TC(7, {a:::[1;7]}0;a)
  TC(7, {a::[1;7];a} 0)

  //Subfunctions
  TC( 3, {b:3; g:{b}; b:4; g[]}0)       // inheritance: same var in prnt&child  child res
  TC( 4, {b:3; g:{b}; b:4; b}0)         // inheritance: same var in prnt&child  prnt res
  TC(_n, {b:3; g:{a}; b:4; g[]}0)       // inheritance: diff var in prnt/child, child res
  TC( 4, {b:3; g:{a}; b:4; b}0)         // inheritance: diff var in prnt/child, prnt res
  TC( 1, {g:{b:1}; g[]}0)               // :: subf-asgn, no prnt-asgn
  TC(12, {g:{b:1}; b::12; g[]}0;b)      // :: gl-asgn, gl-res (no prnt-asgn)
  TC( 1, {g:{b:1}; b::12; g[]}0)        // :: gl-asgn, child-res (no prnt-asgn)
  TC( 1, {g:{b:1}; c::12; g[]}0)        // :: gl-asgn, child-res (diff gl variable)
  TC( 4, {g:{b:1}; b::12; b:4; b}0)     // :: gl-asgn, prnt-res (prnt-asgn after gl-asgn)
  TC(_n, {g:{b:1}; b::12; b:4; b}0;b)   // :: gl-asgn, glbl-res (prnt-asgn after gl-asgn)
  TC(12, {g:{b:1}; b::12; b}0)          // :: gl-asgn, prnt-res (no prnt-asgn)
  TC(12, {g:{b:1}; b:4; b::12; b}0)     // :: gl-asgn, prnt-res (prnt-asgn before gl-asgn)
  TC(_n, {g:{b:1}; b:4; b::12; b}0;b)   // :: gl-asgn, glbl-res (prnt-asgn before gl-asgn)
  TC(12, b:3;{g:{b:1};b::12;g[]} 0;b)   // :: gl-asgn, pre-existing gl
  TC( 1, {g:{b:1;b}; b:12; g[]}0)       // :  prnt-asgn, child res
  TC( 3, {b:3; {b:4; b}0; b}0)          // :  prnt-asgn, prnt res
  TC( 3, {[a;b]{[c;d]c+d}[a;b]}[1;2])   // 2 explicit bracket args
  TC( 2, {[a;a]a+a}[1;9])               // oddly enough (no subfunction)
  TC( 1 10, {a:10; {x,a}x}1)            // 1 implicit arg: x
  TC( 1 2 10, {a:10;{x,y,a}[x;y]}[1;2]) // 2 implicit args x,y
  TC( 7, {{x+y+z}[x;y;z]+1}[1;2;3])     // 3 implict args: x,y,z
  TC( 8, {x+{b:3;g:{b};b:4;g[]}0}5)     // Depth-2 and inheritance
  TC( 4, {x-{x+{b:3;g:{b};b:4;g[]}0}5}12)  // Depth-3 and inheritance
  TC(3 5, {x+y,{x-{x+{b:3;g:{b};b:4;g[]}0}5}12}[1;2])  // Depth-4
  TC( 9, {+/x,{x+y,4}[1;2]}1)           // 2-level implicit args
  TC( 9, {+/x,{x+y,{x-{x+{b:3; g:{b}; b:4; g[]}0}5}12}[1;2]}1) // Depth-5
  TC( 5, {+/x,{x+y,{x-{x+{b:3; g:{b}; b:4; :7; g[]}0}5}12}[1;2]}1) // early-return in level-5
  TC( 7, {+/x,{x+y,{x-{x+{b:3; g:{b}; b:4; g[]}0}5}12}[1;2]; :7}1) // early-return in level-1
  TC( 3, {{b:3; g:{b}; b:4; g[]}0}0)    // unbuffered double braces
  TC( 4, {1+{b:3; g:{b}; b:4; g[]}0}0)  // buffered double braces 
  TC( 8, {({b:3;g:{b};b:4;g[]}0) + {b:5;g:{b};b:6;g[]}0}0) //double independent subfuncs
  TC( 3, b:9; {b:3;g:{b};b:4;g[]}0)     // pre-existing K-Tree entry
  TC(25, {{+/x,{x+y,{x-{x+{b:3;g:{b};b:4;g[]}0}5}12}[1;2]}1 + {x+{b:3;g:{b};b:4;g[]}0}5 + {x-{x+{b:3;g:{b};b:4;g[]}0}5}12 + x}4)
         // 4 stacks: depth-5, depth-2, depth-3, and implicit
  TC(1 3 10 3 10, g:1; do[2;{a:10; g::g,{x,a}x}3]; g) // do[2;] loop with subfunction (implicit arg) 
  TC( 7, f:{x+y+z}; g:f[1;;3]; {b:3; h:{b}; b:4; g[h[ ] ] }0) // projection and subfunction
  TC( 3, {:[x<2;1;_f[x-1]*x]}/: 2 3 4; {b:3; g:{b}; b:4; g[]}0) // muti-statement combo test
  TC(120, {b:3; g:{b}; a::{:[x<2; 1; _f[x-1]*x]}5; g[ ]}0; a) // embedded _f with atom-arg
  TC(2 6 24, {b:3; g:{b}; a::{:[x<2; 1; _f[x-1]*x]}/:2 3 4; g[ ]}0; a) // embedded _f with list-arg
  TC( 5, {x + {[a] a+a} y}[1;2])        // Leon Baum test
  TC( 5, {[a;b] a + {x+x} b}[1;2])      // Leon Baum test-2
  TC_("(7 0;7 1;7 2)", "f:{(7;x)};{[n]a:n;f'[!a]}[3]") // Variable scope
  TC_("(7 0;7 1;7 2)", "{a:5;{(7;x)}'[!3]}[]")         // More complicated variable scope

  //Error trap: {[a;b][c;d] a+b} -> parse error ; { {[a][b] }} -> parse error
  TC(.[*; (3;4); :], (0;12) )
  TC(.[*;3 4 5;:], (1;"valence"))
  TC((.[-1 -2 _; ,!9; :]) , (1;"domain"))
{'fraction_non_alphanumeric': 0.30876458271014057, 'fraction_numerical': 0.07215076278791505, 'mean_word_length': 3.228687073109031, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2285036', 'n_tokens_mistral': 9350, 'n_tokens_neox': 8603, 'n_words': 1939}