2 This is the file that gets parsed and run by the Fabric
\r
7 empty formula returns nil
\r
16 -----------------------------
\r
28 -----------------------------
\r
38 -----------------------------
\r
48 -----------------------------
\r
58 -----------------------------
\r
68 -----------------------------
\r
78 -----------------------------
\r
88 -----------------------------
\r
96 %ret "he said \"foo\""
\r
98 -----------------------------
\r
106 %ret "he said \"foo\""
\r
108 -----------------------------
\r
119 -----------------------------
\r
129 -----------------------------
\r
139 -----------------------------
\r
141 Test List concatenation
\r
151 -----------------------------
\r
155 1 : 2 : 3 : 5 : nil;
\r
161 -----------------------------
\r
165 nil : 1 : 2 : nil : 3 : 5 : nil;
\r
171 ------------ variable assignment and reference -----------------
\r
182 -----------------------------
\r
186 foo := "x" : 1 : 2 : 3
\r
193 -----------------------------
\r
197 foo := "x" : 1 : 2 : 3
\r
205 -----------------------------
\r
209 foo := "some value";
\r
210 foo := "x" : 1 : 2 : 3;
\r
217 -----------------------------
\r
219 test result of assignment expression
\r
223 foo := "x" : 1 : 2 : 3;
\r
229 --------------- Branching --------------
\r
241 -----------------------------
\r
253 -----------------------------
\r
268 -----------------------------
\r
282 -----------------------------
\r
296 -----------------------------
\r
302 } else if (false) {
\r
310 -----------------------------
\r
316 } else if (false) {
\r
326 -----------------------------
\r
332 } else if (false) {
\r
342 -----------------------------
\r
358 -----------------------------
\r
364 } else if (false) {
\r
366 } else if (false) {
\r
376 -----------------------------
\r
382 } else if (false) {
\r
384 } else if (false) {
\r
388 } else if (false) {
\r
396 -----------------------------
\r
403 if(true, "foo", true, "bar", "baz") == "foo",_
\r
404 if(0, "foo", true, "bar", "baz") == "bar"_
\r
407 -------------comparision operators----------------
\r
413 "foo" : "bar" == "foo" : "bar",_
\r
423 "foo" == "foo" : "bar",_
\r
424 "foo" == "foo" : "foo",_
\r
425 "bar" : "foo" == "foo" : "bar"_
\r
431 "foo" != "foo" : "bar", _
\r
432 "foo" : "foo" != "foo" : "bar", _
\r
433 "foo" : "bar" != "foo", _
\r
434 "foo" : "foo" != "foo"_
\r
441 -------------comparision operators----------------
\r
447 z := "y" : "foo" : "bar";
\r
454 ASSERTFALSE("zsdf" in x)
\r
455 ASSERTFALSE("zsdf" in y)
\r
456 ASSERTFALSE("zsdf" in Z)
\r
457 ASSERTFALSE("zsdf" in nil)
\r
460 ASSERT("y" : "foo" in y)
\r
461 ASSERT("y" : "foo" in z)
\r
462 ASSERT("foo" : "bar" in z)
\r
464 ASSERTFALSE("y" : "foo" in x)
\r
465 ASSERTFALSE("foo" : "y" in y)
\r
466 ASSERTFALSE("foo" : "y" in z)
\r
467 ASSERTFALSE("y" : "bar" in z)
\r
471 -----------------------------
\r
473 Case insensitive list match.
\r
475 Returns index of first element in left list that
\r
476 matches a element on the right
\r
490 "foo" =^ "foo" : "foo",_
\r
491 "foo" =^ "FOO" : "FOO",_
\r
492 "FOO" : "FOO" =^ "foo",_
\r
494 1 : "2" =^ "1" : 2_
\r
498 -----------------------------
\r
545 1.0000000001 >= 1,_
\r
557 1 >= 1.0000000001,_
\r
566 1 <= 1.0000000001,_
\r
577 1.0000000001 <= 1,_
\r
582 -----------------------------
\r
584 Boolean Logic Operators
\r
628 // now lets test shortcircuit boolean evaluation
\r
632 1 && (x := 1); // (x := 1) should execute
\r
636 0 || (x := 2); // (x := 2) should execute
\r
644 0 && (x := 1); // (x := 1) shouldn't execute
\r
648 1 || (x := 1); // (x := 1) shouldn't execute
\r
654 -----------------------------
\r
660 foo := "a" : "b" : "c" : "d";
\r
671 foo[2,3] == "b" : "c",_
\r
673 foo[-3,-2] == nil,_
\r
674 foo[-3,3] == "a" : "b" : "c",_
\r
675 foo[0,4] == "a" : "b" : "c" : "d",_
\r
676 foo[1,4] == "a" : "b" : "c" : "d",_
\r
677 foo[1,5] == "a" : "b" : "c" : "d",_
\r
680 foo[-1000,4] == "a" : "b" : "c" : "d",_
\r
681 foo[1,-1000] == nil _
\r
685 -----------------------------
\r
687 string concatenation
\r
692 "foo" + "bar" == "foobar",_
\r
693 "" + "bar" == "bar",_
\r
694 "foo" + "" == "foo",_
\r
695 "foo" + "bar" + "baz" == "foobarbaz"_
\r
699 "foo" + "bar" == " foobar",_
\r
700 "" + "bar" == " bar",_
\r
701 "foo" + "" == " foo",_
\r
702 "foo" + "bar" + "baz" == " foobarbaz"_
\r
706 "foo" + "bar" != "foobar",_
\r
707 "" + "bar" != "bar",_
\r
708 "foo" + "" != "foo",_
\r
709 "foo" + "bar" + "baz" != "foobarbaz"_
\r
712 -----------------------------
\r
737 nil - nil == nil, _
\r
745 1.5 * 1.5 == 2.25,_
\r
765 -----------------------------
\r
767 Increment/decrement
\r
777 ASSERT(x++ == 4); // acts like c's pre-increment operator
\r
779 ASSERT(z++ == nil);
\r
791 // non-integers behave the same
\r
798 ASSERT(z-- == nil);
\r
800 -----------------------------
\r
813 x == "a" : "b" : "c",_
\r
814 y == "d" : "e" : "f",_
\r
815 z == "g" : "h" : "i"_
\r
824 -----------------------------
\r
834 ASSERT( x == "a" : "b" : "c");
\r
836 x := "1"; // local variables always have priority
\r
840 x := nil; // delete local variable
\r
842 ASSERT(x == "a" : "b" : "c");
\r
844 FIELD x := nil; // delete document variable
\r
846 FIELD y := foo // foo is nil (non-existant), and will cause y to be as well
\r
855 -----------------------------
\r
857 "initialize" operator
\r
873 -----------------------------
\r
899 -----------------------------
\r
901 docfields() getfield()
\r
915 ASSERT(count(docfields()) == 4)
\r
916 ASSERT("x1" in docfields())
\r
917 ASSERT("x2" in docfields())
\r
918 ASSERT("x4" in docfields())
\r
919 ASSERT("x5" in docfields())
\r
920 ASSERTFALSE("x3" in docfields())
\r
921 ASSERTFALSE("y" in docfields())
\r
924 ASSERT(getfield("x1") == "1")
\r
925 ASSERT(getfield("x2") == "2")
\r
926 ASSERT(getfield("x4") == "4")
\r
927 ASSERT(getfield("x5") == "5" : "6")
\r
928 ASSERT(getfield("x1" : "x2") == "1" : "2")
\r
929 ASSERT(getfield("x4" : "x5") == "4" : "5" : "6")
\r
930 ASSERT(getfield("x1" : "x2" : "x4" : "x5") == "1" : "2" : "4" : "5" : "6")
\r
931 ASSERT(getfield("x5" : "x4" : "x2" : "x1") == "5" : "6" : "4" : "2" : "1" )
\r
932 ASSERT(getfield("x3") == nil )
\r
933 ASSERT(getfield("y") == nil )
\r
935 -----------------------------
\r
951 x0..5 == "1" : "2" : "3" : "4" : "5"_
\r
955 x1..5 == "1" : "2" : "3" : "4" : "5",_
\r
957 x3..5 == "3" : "4" : "5",_
\r
958 x3..* == "3" : "4" : "5",_
\r
959 x1..* == "1" : "2" : "3" : "4" : "5",_
\r
960 x1..22 == "1" : "2" : "3" : "4" : "5"_
\r
964 x0..5 == "1" : "2" : "3" : "4" : "5",_
\r
966 x0..* == "1" : "2" : "3" : "4" : "5",_
\r
967 x0..22 == "1" : "2" : "3" : "4" : "5"_
\r
973 x3..* == "3" : "4" : "5" : "7",_
\r
974 x1..* == "1" : "2" : "3" : "4" : "5" : "7",_
\r
975 x1..22 == "1" : "2" : "3" : "4" : "5" : "7"_
\r
980 ASSERT(x1..y == "1" : "2" : "3"); // second arg can be any kind of expression
\r
983 ASSERT(x50..51 == nil); // out of range, nil
\r
985 ASSERT(x50..40 == nil); // underflow, nil
\r
987 ASSERT(z1..10 == nil); // no z, returns nil
\r
989 -----------------------------
\r
991 operator precedence
\r
1000 1 + 2 / 4 == 1.5,_
\r
1001 2 / 4 + 1 == 1.5,_
\r
1002 1 - 2 / 4 == 0.5,_
\r
1003 2 / 4 - 1 == -0.5,_
\r
1009 1 + 2 / 4 == 1.5,_
\r
1010 2 / 4 + 1 == 1.5,_
\r
1011 1 - 2 / 4 == 0.5,_
\r
1012 2 / 4 - 1 == -0.5,_
\r
1018 -----------------------------
\r
1029 -----------------------------
\r
1035 function Foo(a,b,c) {
\r
1039 ASSERT(%Foo("1", "2", "3") == "123")
\r
1042 function Factorial(x) {
\r
1043 if (x == 0, 1, %Factorial(x-1) * x);
\r
1046 function Factorial(x) {
\r
1050 %Factorial(x-1) * x;
\r
1055 ASSERT(%factorial(1) == 1);
\r
1056 ASSERT(%factorial(5) == 120);
\r
1057 ASSERT(%factorial(25) == 1.5511210043330986e+25);
\r
1060 function DeepRecursion(n) {
\r
1062 %DeepRecursion(n-1);
\r
1066 %DeepRecursion(1000);
\r
1069 function ArgCountFunc() {
\r
1073 ASSERT(%ArgCountFunc(1,1) == 2);
\r
1074 ASSERT(%ArgCountFunc(1,1,1) == 3);
\r
1075 ASSERT(%ArgCountFunc(1,1,1,1) == 4);
\r
1076 ASSERT(%ArgCountFunc(1,1,1,1,1) == 5);
\r
1077 ASSERT(%ArgCountFunc(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1) == 20);
\r
1079 function EarlyReturn(arg) {
\r
1087 ASSERT( %EarlyReturn("1") == "foo");
\r
1088 ASSERT( %EarlyReturn("0") == "bar");
\r
1090 -----------------------------
\r
1097 xlist := 1 : 2 : 3;
\r
1098 ylist := 10 : 20 : 30;
\r
1101 y := forall(x in xlist) {
\r
1105 ASSERT(y == 2 : 3 : 4);
\r
1107 foo := forall(x in xlist, y in ylist) {
\r
1111 ASSERT(foo == 11 : 22 : 33);
\r
1115 foo := forall( x in xlist, y in ylist, z in zlist) {
\r
1119 ASSERT(foo == 111 : 22 : 33);
\r
1122 nums := 1 : 2 : 3 : 4 : 5 : 6 : 7 : 8;
\r
1124 foo := forall(twonums in nums by 2) {
\r
1125 twonums[1] + twonums[2]
\r
1128 ASSERT(foo == 3 : 7 : 11 : 15)
\r
1130 nums := 1 : 2 : 3 : 4 : 5 : 6 : 7 : 8 : 9;
\r
1132 foo := forall(twonums in nums by 2) {
\r
1133 twonums[1] + twonums[2]
\r
1136 ASSERT(foo == 3 : 7 : 11 : 15 : 9)
\r
1139 -----------------------------
\r
1142 iserror(lists) -> bool list
\r
1145 userError := error("Foo", "Bar")
\r
1146 ASSERT(iserror("hi") == 0);
\r
1147 ASSERT(iserror(userError) == 1);
\r
1148 ASSERT(iserror(userError : "foo") == 1 : 0);
\r
1149 ASSERT(iserror(nil) == nil);
\r
1152 -----------------------------
\r
1163 SELECT X == "a" : "b" : "c"
\r
1173 %column "a" "b" "c"
\r
1177 -----------------------------
\r
1195 -----------------------------
\r
1214 -----------------------------
\r
1219 ASSERT( "Damien" =~ /Damien/)
\r
1220 ASSERTFALSE( "damien" =~/Damien/)
\r
1221 ASSERT( "damien" =~/Damien/i)
\r
1222 ASSERT( "dam" : "damien" =~/Dam.*/i)
\r
1223 ASSERT( "d" : "damien" =~/Dam.*/i) // only needs to match one element
\r
1226 -----------------------------
\r