apfl/webpage/playground/playground.c

104 lines
2.5 KiB
C
Raw Normal View History

#include <emscripten.h>
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
2022-10-28 19:32:33 +00:00
#include "../../src/apfl.h"
#include "../../src/format.h"
struct playground_source_reader_data {
char *str;
size_t len;
size_t off;
bool eof;
};
EM_ASYNC_JS(char *, get_input, (int need), {
var s = await window.playground_get_input(!!need);
var lengthBytes = lengthBytesUTF8(s)+1;
var stringOnWasmHeap = _malloc(lengthBytes);
stringToUTF8(s, stringOnWasmHeap, lengthBytes);
return stringOnWasmHeap;
});
EM_JS(void, web_writer, (int error, const char* str, int size), {
window.playground_write(!!error, UTF8ToString(str, size));
});
static bool
web_fmt_write(void *opaque, const char *buf, size_t len)
{
int error = (int)opaque;
web_writer(error, buf, (int)len);
return true;
}
static bool
playground_source_reader_cb(void *context, char *buf, size_t *len, bool need)
{
struct playground_source_reader_data *r = context;
size_t remain = r->len - r->off;
if (remain == 0) {
free(r->str);
r->str = get_input(need ? 1 : 0);
assert(r->str != NULL);
r->len = strlen(r->str);
r->off = 0;
}
remain = r->len - r->off;
assert(remain > 0);
if (remain < *len) {
*len = remain;
}
memcpy(buf, r->str+r->off, *len);
r->off += *len;
return true;
}
int
main(void)
{
struct apfl_format_writer w_ok = {.write = web_fmt_write, .opaque = (void *)0};
struct apfl_format_writer w_err = {.write = web_fmt_write, .opaque = (void *)1};
apfl_ctx ctx = apfl_ctx_new((struct apfl_config) {
.allocator = apfl_allocator_default(),
.output_writer = w_ok,
});
if (ctx == NULL) {
assert(apfl_format_put_string(w_err, "Failed to init the context\n"));
return 1;
}
struct playground_source_reader_data source_reader_data = {
.str = NULL,
.len = 0,
.off = 0,
.eof = false,
};
apfl_iterative_runner runner = apfl_iterative_runner_new(ctx, (struct apfl_source_reader) {
.callback = playground_source_reader_cb,
.opaque = &source_reader_data,
});
if (runner == NULL) {
apfl_ctx_destroy(ctx);
assert(apfl_format_put_string(w_err, "Failed to init runner\n"));
return 1;
}
2023-01-28 20:41:48 +00:00
int rv = apfl_iterative_runner_run_repl(runner, w_ok, w_err) ? 0 : 1;
free(source_reader_data.str);
apfl_iterative_runner_destroy(runner);
apfl_ctx_destroy(ctx);
return rv;
}