replace pxl8.sh with Makefile, port client and server to Windows

This commit is contained in:
asrael 2026-04-12 14:32:14 -05:00
parent 8d491612ab
commit 8f9317f751
9 changed files with 725 additions and 878 deletions

View file

@ -1,13 +1,16 @@
#include "pxl8_repl.h"
#include <linenoise.h>
#include <poll.h>
#include <SDL3/SDL.h>
#include <stdatomic.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef _WIN32
#include <poll.h>
#include <unistd.h>
#endif
#include "pxl8_log.h"
#include "pxl8_mem.h"
@ -37,38 +40,71 @@ struct pxl8_repl {
static pxl8_repl* g_repl = NULL;
static void pxl8_repl_completion(const char* buf, linenoiseCompletions* lc) {
const char* fennel_keywords[] = {
"fn", "let", "var", "set", "global", "local",
"if", "when", "do", "while", "for", "each",
"lambda", "λ", "partial", "macro", "macros",
"require", "include", "import-macros",
"values", "select", "table", "length",
".", "..", ":", "->", "->>", "-?>", "-?>>",
"doto", "match", "case", "pick-values",
"collect", "icollect", "accumulate"
};
static const char* fennel_keywords[] = {
"fn", "let", "var", "set", "global", "local",
"if", "when", "do", "while", "for", "each",
"lambda", "λ", "partial", "macro", "macros",
"require", "include", "import-macros",
"values", "select", "table", "length",
".", "..", ":", "->", "->>", "-?>", "-?>>",
"doto", "match", "case", "pick-values",
"collect", "icollect", "accumulate"
};
const char* pxl8_functions[] = {
"pxl8.clr", "pxl8.pixel", "pxl8.get_pixel",
"pxl8.line", "pxl8.rect", "pxl8.rect_fill",
"pxl8.circle", "pxl8.circle_fill", "pxl8.text",
"pxl8.get_screen", "pxl8.info", "pxl8.warn",
"pxl8.error", "pxl8.debug", "pxl8.trace"
};
static const char* pxl8_functions[] = {
"pxl8.clr", "pxl8.pixel", "pxl8.get_pixel",
"pxl8.line", "pxl8.rect", "pxl8.rect_fill",
"pxl8.circle", "pxl8.circle_fill", "pxl8.text",
"pxl8.get_screen", "pxl8.info", "pxl8.warn",
"pxl8.error", "pxl8.debug", "pxl8.trace"
};
#ifdef PXL8_WIN32_LINENOISE
static void pxl8_repl_completion(const char* buf, linenoiseCompletions* lc, void* userdata) {
(void)userdata;
usize buf_len = strlen(buf);
for (usize i = 0; i < sizeof(fennel_keywords) / sizeof(fennel_keywords[0]); i++) {
if (strncmp(buf, fennel_keywords[i], buf_len) == 0) {
if (strncmp(buf, fennel_keywords[i], buf_len) == 0)
linenoiseAddCompletion(lc, fennel_keywords[i]);
}
}
for (usize i = 0; i < sizeof(pxl8_functions) / sizeof(pxl8_functions[0]); i++) {
if (strncmp(buf, pxl8_functions[i], buf_len) == 0) {
if (strncmp(buf, pxl8_functions[i], buf_len) == 0)
linenoiseAddCompletion(lc, pxl8_functions[i]);
}
}
static char* pxl8_repl_hints(const char* buf, int* color, int* bold, void* userdata) {
(void)userdata;
if (strncmp(buf, "pxl8.", 5) == 0 && strlen(buf) == 5) {
*color = 35;
*bold = 0;
return "clr|pixel|line|rect|circle|text|get_screen";
}
if (strcmp(buf, "(fn") == 0) {
*color = 36;
*bold = 0;
return " [args] body)";
}
if (strcmp(buf, "(let") == 0) {
*color = 36;
*bold = 0;
return " [bindings] body)";
}
return NULL;
}
#else
static void pxl8_repl_completion(const char* buf, linenoiseCompletions* lc) {
usize buf_len = strlen(buf);
for (usize i = 0; i < sizeof(fennel_keywords) / sizeof(fennel_keywords[0]); i++) {
if (strncmp(buf, fennel_keywords[i], buf_len) == 0)
linenoiseAddCompletion(lc, fennel_keywords[i]);
}
for (usize i = 0; i < sizeof(pxl8_functions) / sizeof(pxl8_functions[0]); i++) {
if (strncmp(buf, pxl8_functions[i], buf_len) == 0)
linenoiseAddCompletion(lc, pxl8_functions[i]);
}
}
}
@ -78,22 +114,21 @@ static char* pxl8_repl_hints(const char* buf, int* color, int* bold) {
*bold = 0;
return "clr|pixel|line|rect|circle|text|get_screen";
}
if (strcmp(buf, "(fn") == 0) {
*color = 36;
*bold = 0;
return " [args] body)";
}
if (strcmp(buf, "(let") == 0) {
*color = 36;
*bold = 0;
return " [bindings] body)";
}
return NULL;
}
#endif
static void pxl8_repl_flush_logs(pxl8_repl* repl) {
u32 log_read_idx = atomic_load(&repl->log_read_idx);
u32 log_write_idx = atomic_load(&repl->log_write_idx);
@ -106,6 +141,68 @@ static void pxl8_repl_flush_logs(pxl8_repl* repl) {
fflush(stdout);
}
#ifdef _WIN32
static int pxl8_repl_thread(void* arg) {
pxl8_repl* repl = (pxl8_repl*)arg;
printf("[pxl8 REPL] Fennel 1.6.0 - Tab for completion, Ctrl-Z to exit\n");
fflush(stdout);
while (!atomic_load(&repl->should_quit)) {
pxl8_repl_flush_logs(repl);
const char* prompt = (repl->accumulator[0] != '\0') ? ".. " : ">> ";
char* line = linenoise(prompt);
if (line == NULL) {
atomic_store(&repl->should_quit, true);
break;
}
bool in_multiline = (repl->accumulator[0] != '\0');
if (strlen(line) > 0 || in_multiline) {
if (!in_multiline) {
linenoiseHistoryAdd(line);
linenoiseHistorySave(".pxl8_history");
}
if (repl->accumulator[0] != '\0') {
strncat(repl->accumulator, "\n",
PXL8_MAX_REPL_COMMAND_SIZE - strlen(repl->accumulator) - 1);
}
strncat(repl->accumulator, line,
PXL8_MAX_REPL_COMMAND_SIZE - strlen(repl->accumulator) - 1);
u32 write_idx = atomic_load(&repl->cmd_write_idx);
u32 read_idx = atomic_load(&repl->cmd_read_idx);
u32 next_write = (write_idx + 1) % PXL8_REPL_QUEUE_SIZE;
if (next_write != read_idx) {
strncpy(repl->commands[write_idx], repl->accumulator, PXL8_MAX_REPL_COMMAND_SIZE - 1);
repl->commands[write_idx][PXL8_MAX_REPL_COMMAND_SIZE - 1] = '\0';
atomic_store(&repl->cmd_write_idx, next_write);
}
}
free(line);
while (!atomic_load(&repl->should_quit) &&
(atomic_load(&repl->cmd_write_idx) != atomic_load(&repl->cmd_read_idx) ||
!atomic_load(&repl->cmd_complete))) {
pxl8_repl_flush_logs(repl);
SDL_Delay(1);
}
atomic_store(&repl->cmd_complete, false);
}
pxl8_repl_flush_logs(repl);
return 0;
}
#else
static int pxl8_repl_thread(void* arg) {
pxl8_repl* repl = (pxl8_repl*)arg;
@ -217,6 +314,8 @@ static int pxl8_repl_thread(void* arg) {
return 0;
}
#endif
pxl8_repl* pxl8_repl_create(void) {
pxl8_repl* repl = (pxl8_repl*)pxl8_calloc(1, sizeof(pxl8_repl));
if (!repl) return NULL;
@ -231,8 +330,13 @@ pxl8_repl* pxl8_repl_create(void) {
linenoiseHistorySetMaxLen(100);
linenoiseSetMultiLine(1);
#ifdef PXL8_WIN32_LINENOISE
linenoiseSetCompletionCallback(pxl8_repl_completion, NULL);
linenoiseSetHintsCallback(pxl8_repl_hints, NULL);
#else
linenoiseSetCompletionCallback(pxl8_repl_completion);
linenoiseSetHintsCallback(pxl8_repl_hints);
#endif
linenoiseHistoryLoad(".pxl8_history");
g_repl = repl;
@ -264,7 +368,9 @@ void pxl8_repl_destroy(pxl8_repl* repl) {
g_repl = NULL;
pxl8_log_set_handler(NULL);
#ifndef _WIN32
system("stty sane 2>/dev/null");
#endif
pxl8_free(repl);
}

View file

@ -4,6 +4,10 @@
#include <stdlib.h>
#include <string.h>
#ifndef PATH_MAX
#define PATH_MAX 260
#endif
#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>