Improve lambda param handling.
Add (rand) Clean up testing output. tic-tac-toe.pbl QOL changes
This commit is contained in:
parent
9b6b80f204
commit
6176e9eb4b
11
src/env.c
11
src/env.c
|
@ -131,7 +131,7 @@ struct Environment envForLambda(const Object* params, const Object* arguments, i
|
||||||
// Evaluate the `argument` list
|
// Evaluate the `argument` list
|
||||||
const Object* param = params->list;
|
const Object* param = params->list;
|
||||||
const Object* argument = arguments;
|
const Object* argument = arguments;
|
||||||
for (int i = 0; i < paramCount && param; i++) {
|
for (; param; param = param->forward) {
|
||||||
const char* paramName = param->string;
|
const char* paramName = param->string;
|
||||||
if (paramName[0] == '.' && paramName[1] == '.' && paramName[2] == '.' && paramName[3] != '\0') {
|
if (paramName[0] == '.' && paramName[1] == '.' && paramName[2] == '.' && paramName[3] != '\0') {
|
||||||
paramName = ¶mName[3];
|
paramName = ¶mName[3];
|
||||||
|
@ -144,6 +144,9 @@ struct Environment envForLambda(const Object* params, const Object* arguments, i
|
||||||
cleanObject(&varargs);
|
cleanObject(&varargs);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (!argument) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Object newEnvObj = eval(argument, outer);
|
Object newEnvObj = eval(argument, outer);
|
||||||
|
|
||||||
|
@ -151,8 +154,7 @@ struct Environment envForLambda(const Object* params, const Object* arguments, i
|
||||||
|
|
||||||
cleanObject(&newEnvObj);
|
cleanObject(&newEnvObj);
|
||||||
|
|
||||||
argument = argument ? argument->forward : NULL;
|
argument = argument->forward;
|
||||||
param = param->forward;
|
|
||||||
}
|
}
|
||||||
env.outer = outer;
|
env.outer = outer;
|
||||||
|
|
||||||
|
@ -254,7 +256,8 @@ struct Environment defaultEnv()
|
||||||
pf(help),
|
pf(help),
|
||||||
pf(buildHashTable),
|
pf(buildHashTable),
|
||||||
pf(addToHashTable),
|
pf(addToHashTable),
|
||||||
pf(getFromHashTable)
|
pf(getFromHashTable),
|
||||||
|
pf(randomO)
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -174,6 +174,14 @@
|
||||||
(eval (rf file-name))
|
(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) (
|
(def startsWith (fn (text pattern) (
|
||||||
(matches text (cat pattern "*"))
|
(matches text (cat pattern "*"))
|
||||||
)))
|
)))
|
||||||
|
@ -184,4 +192,4 @@
|
||||||
|
|
||||||
(def endsWith (fn (text pattern) (
|
(def endsWith (fn (text pattern) (
|
||||||
(matches text (cat "*" pattern))
|
(matches text (cat "*" pattern))
|
||||||
)))
|
)))
|
||||||
|
|
|
@ -6,48 +6,65 @@
|
||||||
" " " " " "
|
" " " " " "
|
||||||
))
|
))
|
||||||
|
|
||||||
|
(def is-empty (fn (tile) (= " " tile)))
|
||||||
|
|
||||||
(def print-board (fn (board) (
|
(def print-board (fn (board) (
|
||||||
(sys "clear")
|
(sys "clear")
|
||||||
(def '(a b c
|
(def '(a b c
|
||||||
d e f
|
d e f
|
||||||
g h i) board)
|
g h i) board)
|
||||||
(prnl (cat " " a " | " b " | " c))
|
(prnl)
|
||||||
(prnl "-----------")
|
(prnl (cat " " a " | " b " | " c))
|
||||||
(prnl (cat " " d " | " e " | " f))
|
(prnl " -----------")
|
||||||
(prnl "-----------")
|
(prnl (cat " " d " | " e " | " f))
|
||||||
(prnl (cat " " g " | " h " | " i))
|
(prnl " -----------")
|
||||||
|
(prnl (cat " " g " | " h " | " i))
|
||||||
)))
|
)))
|
||||||
|
|
||||||
(def do-move (fn (board player) (
|
(def do-move (fn (board player warn) (
|
||||||
(def input (inp))
|
(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 spot (eval input))
|
||||||
(def i 0)
|
(def i 0)
|
||||||
(map (fn (piece) (
|
(if (& (is-empty (at (- spot 1) board)) (> spot 0) (< spot 10))
|
||||||
(set i (+ 1 i))
|
(map (fn (piece) (
|
||||||
(if (= i spot) player piece)
|
(set i (+ 1 i))
|
||||||
)) board)
|
(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)
|
(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) (
|
(def get-winner (fn (board) (
|
||||||
(sys "clear")
|
|
||||||
(def '(a b c
|
(def '(a b c
|
||||||
d e f
|
d e f
|
||||||
g h i) board)
|
g h i) board)
|
||||||
(if (winning-row (a b c)) a
|
(if (is-winning-row (a b c)) a
|
||||||
(if (winning-row (d e f)) d
|
(if (is-winning-row (d e f)) d
|
||||||
(if (winning-row (g h i)) g
|
(if (is-winning-row (g h i)) g
|
||||||
(if (winning-row (a d g)) a
|
(if (is-winning-row (a d g)) a
|
||||||
(if (winning-row (b e h)) b
|
(if (is-winning-row (b e h)) b
|
||||||
(if (winning-row (c f i)) c
|
(if (is-winning-row (c f i)) c
|
||||||
(if (winning-row (a e i)) a
|
(if (is-winning-row (a e i)) a
|
||||||
(if (winning-row (c e g)) c
|
(if (is-winning-row (c e g)) c
|
||||||
|
(if (is-full-board board) "Nobody"
|
||||||
" "
|
" "
|
||||||
))))))))
|
)))))))))
|
||||||
)))
|
)))
|
||||||
|
|
||||||
(def next-player (fn (current) (
|
(def next-player (fn (current) (
|
||||||
|
@ -55,15 +72,15 @@
|
||||||
)))
|
)))
|
||||||
|
|
||||||
(def game (fn (board player) (
|
(def game (fn (board player) (
|
||||||
(if (= " " (get-winner board)) (
|
(print-board board)
|
||||||
(print-board board)
|
(def winner (get-winner board))
|
||||||
(def b (do-move board player))
|
(if (is-empty winner) (
|
||||||
|
(def b (do-move board player F))
|
||||||
(game b (next-player player))
|
(game b (next-player player))
|
||||||
) (
|
) (
|
||||||
(print-board board)
|
(prnl)
|
||||||
(prnl "")
|
(prnl "Game over! " winner " wins!")
|
||||||
(prnl "Game over! " (next-player player) " wins!")
|
|
||||||
))
|
))
|
||||||
)))
|
)))
|
||||||
|
|
||||||
(game empty-board "X")
|
(game empty-board (if (= 0 (rand 2)) "X" "O"))
|
||||||
|
|
|
@ -49,6 +49,10 @@ Object typeCheck(const char* funcName, Object* params, int length,
|
||||||
if (FAILED) { \
|
if (FAILED) { \
|
||||||
return ERROR; \
|
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
|
#else
|
||||||
#define checkTypes(FUNC) ;
|
#define checkTypes(FUNC) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -86,4 +86,20 @@ Object getEnvVar(Object* params, unused int length, unused struct Environment* e
|
||||||
}
|
}
|
||||||
return stringFromSlice("", 0);
|
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
|
#endif // STANDALONE
|
|
@ -60,6 +60,12 @@ tfn(getEnvVar, "env",
|
||||||
"(env HOME) => /home/sagevaillancourt"
|
"(env HOME) => /home/sagevaillancourt"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
tfn(randomO, "rand",
|
||||||
|
({ returns(isNumber) }),
|
||||||
|
"Returns a semi-random integer\n"
|
||||||
|
"(rand) => 2394568"
|
||||||
|
);
|
||||||
|
|
||||||
#endif //PEBBLISP_PC_H
|
#endif //PEBBLISP_PC_H
|
||||||
|
|
||||||
#endif // STANDALONE
|
#endif // STANDALONE
|
||||||
|
|
|
@ -75,7 +75,9 @@ check() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
local expected="$3"
|
||||||
if [ "$3" == "$regex" ]; then
|
if [ "$3" == "$regex" ]; then
|
||||||
|
expected="$4"
|
||||||
if [[ "$output" =~ ^$4$ ]]; then
|
if [[ "$output" =~ ^$4$ ]]; then
|
||||||
pass "$1" $exit_code
|
pass "$1" $exit_code
|
||||||
return
|
return
|
||||||
|
@ -86,7 +88,7 @@ check() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
fail "$1" "$2"
|
fail "$1" "$2"
|
||||||
FAIL_OUTPUT="${FAIL_OUTPUT}\n [31m expected '$3' but received '$output'\n"
|
FAIL_OUTPUT="${FAIL_OUTPUT}\n [31m expected '$expected' but received '$output'\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "[1;34m::SHELL TESTS::[0;m"
|
echo "[1;34m::SHELL TESTS::[0;m"
|
||||||
|
|
Loading…
Reference in New Issue