Improve lambda param handling.

Add (rand)
Clean up testing output.
tic-tac-toe.pbl QOL changes
This commit is contained in:
Sage Vaillancourt 2022-10-25 14:36:10 -04:00
parent 9b6b80f204
commit 6176e9eb4b
7 changed files with 92 additions and 36 deletions

View File

@ -131,7 +131,7 @@ struct Environment envForLambda(const Object* params, const Object* arguments, i
// Evaluate the `argument` list
const Object* param = params->list;
const Object* argument = arguments;
for (int i = 0; i < paramCount && param; i++) {
for (; param; param = param->forward) {
const char* paramName = param->string;
if (paramName[0] == '.' && paramName[1] == '.' && paramName[2] == '.' && paramName[3] != '\0') {
paramName = &paramName[3];
@ -144,6 +144,9 @@ struct Environment envForLambda(const Object* params, const Object* arguments, i
cleanObject(&varargs);
break;
}
if (!argument) {
break;
}
Object newEnvObj = eval(argument, outer);
@ -151,8 +154,7 @@ struct Environment envForLambda(const Object* params, const Object* arguments, i
cleanObject(&newEnvObj);
argument = argument ? argument->forward : NULL;
param = param->forward;
argument = argument->forward;
}
env.outer = outer;
@ -254,7 +256,8 @@ struct Environment defaultEnv()
pf(help),
pf(buildHashTable),
pf(addToHashTable),
pf(getFromHashTable)
pf(getFromHashTable),
pf(randomO)
#endif
};

View File

@ -174,6 +174,14 @@
(eval (rf file-name))
)))
(def any-in (fn (list f)
(> (len (fil f list)) 0)
))
(def none-in (fn (list f)
(not (any-in list f))
))
(def startsWith (fn (text pattern) (
(matches text (cat pattern "*"))
)))

View File

@ -6,11 +6,14 @@
" " " " " "
))
(def is-empty (fn (tile) (= " " tile)))
(def print-board (fn (board) (
(sys "clear")
(def '(a b c
d e f
g h i) board)
(prnl)
(prnl (cat " " a " | " b " | " c))
(prnl " -----------")
(prnl (cat " " d " | " e " | " f))
@ -18,36 +21,50 @@
(prnl (cat " " g " | " h " | " i))
)))
(def do-move (fn (board player) (
(def input (inp))
(def do-move (fn (board player warn) (
(prnl)
(if warn (prnl "You can't go there!") ())
(prnl "Your turn, " player "!")
(prnl "Where do you want to play?")
(def input (inp "1-9: "))
(def spot (eval input))
(def i 0)
(if (& (is-empty (at (- spot 1) board)) (> spot 0) (< spot 10))
(map (fn (piece) (
(set i (+ 1 i))
(if (= i spot) player piece)
)) board)
(
(print-board board)
(do-move board player T)
)
)
)))
(def winning-row (fn (row) (
(def is-winning-row (fn (row) (
(def '(a b c) row)
(& (not (= " " a)) (= a b c))
(& (not (is-empty a)) (= a b c))
)))
(def is-full-board (fn (board)
(none-in board is-empty)
))
(def get-winner (fn (board) (
(sys "clear")
(def '(a b c
d e f
g h i) board)
(if (winning-row (a b c)) a
(if (winning-row (d e f)) d
(if (winning-row (g h i)) g
(if (winning-row (a d g)) a
(if (winning-row (b e h)) b
(if (winning-row (c f i)) c
(if (winning-row (a e i)) a
(if (winning-row (c e g)) c
(if (is-winning-row (a b c)) a
(if (is-winning-row (d e f)) d
(if (is-winning-row (g h i)) g
(if (is-winning-row (a d g)) a
(if (is-winning-row (b e h)) b
(if (is-winning-row (c f i)) c
(if (is-winning-row (a e i)) a
(if (is-winning-row (c e g)) c
(if (is-full-board board) "Nobody"
" "
))))))))
)))))))))
)))
(def next-player (fn (current) (
@ -55,15 +72,15 @@
)))
(def game (fn (board player) (
(if (= " " (get-winner board)) (
(print-board board)
(def b (do-move board player))
(def winner (get-winner board))
(if (is-empty winner) (
(def b (do-move board player F))
(game b (next-player player))
) (
(print-board board)
(prnl "")
(prnl "Game over! " (next-player player) " wins!")
(prnl)
(prnl "Game over! " winner " wins!")
))
)))
(game empty-board "X")
(game empty-board (if (= 0 (rand 2)) "X" "O"))

View File

@ -49,6 +49,10 @@ Object typeCheck(const char* funcName, Object* params, int length,
if (FAILED) { \
return ERROR; \
}
#define verifyTypes(FUNC, TYPE_CHECKS) int FAILED; Object ERROR = typeCheck(FUNC ## Symbol, params, length, TYPE_CHECKS, length, &FAILED); \
if (FAILED) { \
return ERROR; \
}
#else
#define checkTypes(FUNC) ;
#endif

View File

@ -86,4 +86,20 @@ Object getEnvVar(Object* params, unused int length, unused struct Environment* e
}
return stringFromSlice("", 0);
}
#include <time.h>
int initializedRand = 0;
Object randomO(Object* params, unused int length, unused struct Environment* env)
{
if (!initializedRand) {
srand(time(0));
initializedRand = 1;
}
int num = rand();
if (length > 0 && params[0].type == TYPE_NUMBER) {
num = num % params[0].number;
}
return numberObject(num);
}
#endif // STANDALONE

View File

@ -60,6 +60,12 @@ tfn(getEnvVar, "env",
"(env HOME) => /home/sagevaillancourt"
);
tfn(randomO, "rand",
({ returns(isNumber) }),
"Returns a semi-random integer\n"
"(rand) => 2394568"
);
#endif //PEBBLISP_PC_H
#endif // STANDALONE

View File

@ -75,7 +75,9 @@ check() {
fi
local expected="$3"
if [ "$3" == "$regex" ]; then
expected="$4"
if [[ "$output" =~ ^$4$ ]]; then
pass "$1" $exit_code
return
@ -86,7 +88,7 @@ check() {
fi
fail "$1" "$2"
FAIL_OUTPUT="${FAIL_OUTPUT}\n  expected '$3' but received '$output'\n"
FAIL_OUTPUT="${FAIL_OUTPUT}\n  expected '$expected' but received '$output'\n"
}
echo "::SHELL TESTS::"