diff --git a/src/examples/lib.pbl b/src/examples/lib.pbl index de746d2..bdee7c2 100644 --- a/src/examples/lib.pbl +++ b/src/examples/lib.pbl @@ -9,7 +9,8 @@ ; Otherwise invoke ))) -(def first-where (fn (list condition) ( +(def first-where (fn (list condition) + "Get the first element from the given list that matches the given condition. Halts on first error." ( (def next (first list)) (if (iserr next) () (if (condition next) next (first-where (rest list) condition)) diff --git a/src/examples/tic-tac-toe.pbl b/src/examples/tic-tac-toe.pbl new file mode 100755 index 0000000..af24434 --- /dev/null +++ b/src/examples/tic-tac-toe.pbl @@ -0,0 +1,69 @@ +#!/usr/bin/pl + +(def empty-board ( + " " " " " " + " " " " " " + " " " " " " +)) + +(def print-board (fn (board) ( + (sys "clear") + (def '(a b c + d e f + g h i) board) + (prnl (cat " " a " | " b " | " c)) + (prnl "-----------") + (prnl (cat " " d " | " e " | " f)) + (prnl "-----------") + (prnl (cat " " g " | " h " | " i)) +))) + +(def do-move (fn (board player) ( + (def input (inp)) + (def spot (eval input)) + (def i 0) + (map (fn (piece) ( + (set i (+ 1 i)) + (if (= i spot) player piece) + )) board) +))) + +(def winning-row (fn (row) ( + (def '(a b c) row) + (& (not (= " " a)) (= a b c)) +))) + +(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 + " " + )))))))) +))) + +(def next-player (fn (current) ( + (if (= current "X") "O" "X") +))) + +(def game (fn (board player) ( + (if (= " " (get-winner board)) ( + (print-board board) + (def b (do-move board player)) + (game b (next-player player)) + ) ( + (print-board board) + (prnl "") + (prnl "Game over! " (next-player player) " wins!") + )) +))) + +(game empty-board "X") diff --git a/src/main.c b/src/main.c index 5b59416..edb2310 100644 --- a/src/main.c +++ b/src/main.c @@ -102,7 +102,7 @@ void repl(struct Environment* env) } add_history(buf); - int isCd = strncmp("cd ", buf, 3); + int isCd = strncmp("cd ", buf, 3) == 0; int isHelp = buf[0] == '?' && (buf[1] == ' ' || buf[1] == '\0'); if (isCd || isHelp) { char* oldBuf = buf; diff --git a/src/object.h b/src/object.h index 2c344ba..836a6e4 100644 --- a/src/object.h +++ b/src/object.h @@ -183,7 +183,7 @@ struct StructDef { struct StructObject { int definition; - struct Object* fields; // Order should match that in the definition. + Object* fields; // Order should match that in the definition. }; #define lambdaDocs(LAMBDA_OBJECT) (LAMBDA_OBJECT)->lambda->params.docStrings diff --git a/src/pebblisp.c b/src/pebblisp.c index 017afaf..6f36eaa 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -147,7 +147,13 @@ Object mapO(Object* params, int length, struct Environment* env) struct Environment newEnv = envForLambda(lambdaParams, &tempInput, listLength(lambdaParams), env); // Add the lambda evaluation to the list - addToList(outputList, eval(&lambda.lambda->body, &newEnv)); + Object ret = eval(&lambda.lambda->body, &newEnv); + if (isListy(ret)) { + Object o = cloneObject(*tail(&ret)); + cleanObject(&ret); + ret = o; + } + addToList(outputList, ret); deleteEnv(&newEnv); cleanObject(&tempInput); }