#!/bin/bash VALCOM="valgrind -q --leak-check=full --track-origins=yes" TOTAL_PASSES=0 TOTAL_FAILS=0 FAILS=0 FAIL_OUTPUT="" VALGRIND=false DISABLED=false CURRENT_BLOCK="" if [ "$1" == "-val" ]; then VALGRIND=true fi endBlock() { echo "" if (($FAILS != 0)); then echo -e "$FAIL_OUTPUT" FAIL_OUTPUT="" fi FAILS=0 DISABLED=false } title() { echo -n "[$1] " if [[ "$2" == "disable" ]]; then echo -n "DISABLED" DISABLED=true fi } pass() { echo -n "✓" ((TOTAL_PASSES++)) } fail() { echo -n "X" FAIL_OUTPUT="$FAIL_OUTPUT $1 FAILED\n When running \"$2\"" ((FAILS++)) ((TOTAL_FAILS++)) } check() { if $DISABLED; then return 1 fi if $VALGRIND; then echo -ne "\n $1\r" local output="$($VALCOM ./pl "(loadfile \"examples/lib.pbl\") $2")" else local output="$(./pl "(loadfile \"examples/lib.pbl\") $2")" fi if [ "$output" == "$3" ]; then pass "$1" else fail "$1" "$2" FAIL_OUTPUT="${FAIL_OUTPUT}\n  expected '$3' but received '$output'\n" fi } echo "STARTING TESTS" title "Plain returns" check "PlainRet" "10" "10" check "StrRetrn" "\"hey\"" "hey" check "SingleStrRetrn" "\"hey\"" "hey" check "HexReturn" "0x0f0f0" "61680" check "BinaryReturn" "0b011010011010011" "13523" endBlock title "Arithmetic" check "Addition" "(+ 1093 102852)" "103945" check "Multiply" "(*1000 10000)" "10000000" check "Division" "(/ 6418425 65)" "98745" check "ChainAdd" "(+ 3917 17304 1293844 400 100000)" "1415465" check "ChainMul" "(* 8263 23 123)" "23376027" check "ChainDiv" "(/ 1493856 741 96 7)" "3" check "ListAddi" "(+ 5 (1 2 3 (+ 10 10)))" "( 6 7 8 25 )" check "ListModu" "(% 5 (1 2 3 (* 11 11)))" "( 1 2 3 1 )" check "ListsMul" "(* (10 20 30) (1 20 300))" "( 10 400 9000 )" endBlock title "Comparison" check "GratrThn" "(> 23847123 19375933)" "T" check "LessThan" "(< 23847123 19375933)" "F" check "Equality" "(= 987654321 987654321 )" "T" check "StringEquality" "(= \"Bean\" \"Bean\" )" "T" check "StringInequality" "(= \"Beans\" \"Bean\" )" "F" check "NullInequality" "(= \"Beans\" \"\" )" "F" endBlock title "TypeCheck" check "IsNum" "(isnum 23847123)" "T" check "IsntNum" "(isnum \"WORDS\")" "F" check "IsString" "(isstr \"words\")" "T" check "IsStringEmpty" "(isstr \"\")" "T" check "NumNotString" "(isstr 5)" "F" check "ListNotString" "(isstr (\"hello\"))" "F" endBlock title "Ifs/Bools" check "IfReturn" "(if (T) 123456789 987654321)" "123456789" check "IfRetTwo" "(if F 123456789 987654321)" "987654321" check "EmptyCnd" "(if () T F)" "F" check "EtyLstLt" "(if (()) T F)" "T" endBlock title "Lists" check "RegLists" "(1 2 3 4 5)" "( 1 2 3 4 5 )" check "MultiTypeList" "(10 20 \"rascals\")" "( 10 20 rascals )" check "EmptyLst" "()" "( )" check "EmptLst2" "( )" "( )" check "ListIndex" "(at (+ 1 1) (1 2 1000 4 5))" "1000" check "EvalElems" "((* 10 10) 7)" "( 100 7 )" check "AppendToList" "(ap (1 20 300 4000 50000) 600000)" "( 1 20 300 4000 50000 600000 )" check "AppndToEnvList" "(def l (50000 4000 300 20)) (def l (ap l 1)) l" "( 50000 4000 300 20 1 )" check "PrependToList" "(pre (1 20 300 4000 50000) 600000)" "( 600000 1 20 300 4000 50000 )" check "PrepndToEnvList" "(def l (50000 4000 300 20)) (def l (pre l 1)) l" "( 1 50000 4000 300 20 )" check "Rest(Tail)OfList" "(def l (50000 4000 300 20)) (rest l)" "( 4000 300 20 )" check "ListLength" "(def l (1 20 3 \"abc\" \"banana\" (+ 10 5))) (len l)" "6" endBlock title "Spacing" check "DenseSpc" "(+1093 102852)" "103945" check "WideSpac" "( + 1093 102852 )" "103945" check "VWidwSpc" " ( + 1093 102852 ) " "103945" endBlock title "DemoFunctions" check "Squaring" "(sq 9876)" "97535376" check "Cubing" "(cube 81)" "531441" check "Exponent" "(exp 9 9)" "387420489" check "MaxRight" "(max 5 20)" "20" check "MaxLeft" "(max 135890 98372)" "135890" check "MinRight" "(min 8429 192449)" "8429" check "MinLeft" "(min 17294722 17294721)" "17294721" endBlock title "Lambdas" check "MultStmt" "(def yee (fn (a) (* 10 a))) ; (yee 5)" "50" check "DefinMap" "(def yee (fn (a) (* 10 a))) ; (map yee (5 10 2 (+ 12 0)))" "( 50 100 20 120 )" check "AnonymousLambda" "\ (map (fn (a) (* a a)) (5 6 7))" "( 25 36 49 )" check "FbnciSeq" "\ (def fib (fn (a) \ (if (< a 2) \ a \ (+ (fib (- a 1)) (fib (- a 2))) \ )));\ (fib 11)" "89" check "Factorial" "\ (def fac (fn (a) \ (if (= a 1) \ 1 \ (* a (fac (- a 1)) ) \ )));\ (fac 11)" "39916800" check "LambdaClone" "(def y (fn (a) (* 10 a))) (def b y) (def y 12345) ((b 5) y)" "( 50 12345 )" check "Duplicate" "(def dupe (fn (a) (() (a a a))));(dupe (*10 10))" "( 100 100 100 )" endBlock title "Cat" check "ExplicitCat" "(cat \"Big\" \" Kitty\")" "Big Kitty" check "CatNums" "(cat \"There are \" (+ 2 3) \" kitties\")" "There are 5 kitties" check "ImplicitCat" "(+ \"There are \" (* 5 4) \" bonks\")" "There are 20 bonks" # Mixing of `+` and implicit cat currently expected but not recommended: check "CatAssocLeft" "(+ 10 20 \" rascals\")" "30 rascals" endBlock title "Filtering" check "Filtering" "(fil (< 321) (30 300 90 1200 135 801))" "( 1200 801 )" check "FilterEval" "(fil (= 1000) ((+ 450 550) (* 20 50) (/ 30 3) (- 10000 100)))" "( 1000 1000 )" check "MapFilter" "(fil (< 50) (map sq (1 2 3 4 5 6 7 8 9 10 11 12)))" "( 64 81 100 121 144 )" endBlock title "HigherOrder" check "FuncReturningAFunc" "(def plusser (fn (outer) (fn (inner) (+ outer inner))))\ (def plusFive (plusser 5))\ (plusFive 10)" "15" endBlock title "ShouldError" check "LenOfNotList" "(len 5)" "NOT_A_LIST" check "NoMapList" "(map sq)" "( )" check "UnevenLists" "(+ (1 2) (1 2 3))" "LISTS_NOT_SAME_SIZE" check "BadNumber" "(5df)" "BAD_NUMBER" check "BadHex" "(0x0zf)" "BAD_NUMBER" check "BadBinary" "(0b01120)" "BAD_NUMBER" check "BadParens" "(hey()" \ "'MISMATCHED_PARENS': (loadfile \"examples/lib.pbl\") (hey()" check "BadParens2" "(hey)(" \ "'MISMATCHED_PARENS': (loadfile \"examples/lib.pbl\") (hey)(" check "BadParens3" "((hey(" \ "'MISMATCHED_PARENS': (loadfile \"examples/lib.pbl\") ((hey(" check "BadParens4" ")))hey" \ "'MISMATCHED_PARENS': (loadfile \"examples/lib.pbl\") )))hey" check "BadParens5" "hey))(" \ "'MISMATCHED_PARENS': (loadfile \"examples/lib.pbl\") hey))(" endBlock title "Eval" check "BasicNumberEval" "(eval \"5\")" "5" check "BasicOpEval" "(eval \"(+ 5 10)\")" "15" check "MapFilter" "(eval \"(fil (< 50) (map sq (1 2 3 4 5 6 7 8 9 10 11 12)))\")" "( 64 81 100 121 144 )" endBlock title "Forbble" disable check "BasicForbbleOp" "(loadfile \"examples/forbble.pbl\") (feval (10 10 * .)) \"\"" "100" check "FibForbble" "(loadfile \"examples/forbble.pbl\") (feval (1 1 _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f .)) \"\"" "28657" check "ForbbleDefine" "(loadfile \"examples/forbble.pbl\") (feval ( : \"cubed\" dup dup * * $ )) (feval (4 cubed .)) \"\"" "64" endBlock title "Environment" check "EnvStressTestEarly" "(def a 1)(def b 20)(def c \"yee\")(def d \"yeehunnid\")(def e 3) (a)" "( 1 )" check "EnvStressTestLate" "(def a 1)(def b 2)(def c 3)(def d 4)(def e 5)(def g 6)(def n 40) n" "40" endBlock echo "" if [ "$TOTAL_FAILS" -ne "0" ]; then echo -n "" fi echo "$TOTAL_FAILS Tests Failed" if [ "$TOTAL_PASSES" -ne "0" ]; then echo -n "" fi echo "$TOTAL_PASSES Tests Passed" echo ""