From a4fb883b62bd5af8af5c49bdf01011dc279e7a9b Mon Sep 17 00:00:00 2001 From: Ludovic 'Archivist' Lagouardette Date: Wed, 1 Oct 2025 02:03:39 +0200 Subject: [PATCH] Added a C89 example shell which defines a couple of functions as an example --- CMakeLists.txt | 3 ++ sh.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 sh.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ba81da..00e1ebe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,9 @@ add_executable(ink_exe main.c) target_link_libraries(ink_exe PUBLIC ink) target_include_directories(ink PUBLIC include) +add_executable(inksh sh.c) +target_link_libraries(inksh PUBLIC ink) + # Functional tests function(add_success_compiled_test cfile success_regex) diff --git a/sh.c b/sh.c new file mode 100644 index 0000000..5b0bcae --- /dev/null +++ b/sh.c @@ -0,0 +1,107 @@ +#include "ink.h" +#include +#include + +#ifndef INK_SH_READ_BUFF +#define INK_SH_READ_BUFF 32768 +#endif // INK_SH_READ_BUFF + +int get_type_by_name(struct context* ctx, const char* name); + +static void list_words(struct context* ctx) { + struct native_fn* nit; + struct fn* dit; + for(nit = ctx->native_words; nit != ctx->native_words + ctx->native_words_top; ++nit) { + fprintf(stdout, "%s\n", nit->name); + } + for(dit = ctx->words; dit != ctx->words + ctx->words_top; ++dit) { + fprintf(stdout, "%s\n", dit->name); + } +} + +int main(int argc, char** argv) { + char read_buffer[INK_SH_READ_BUFF]; + struct context* ctx; + char** end_argv; + ctx = ink_make_default_context(); + ink_add_native(ctx, "words?", list_words); + end_argv = argv + argc; + size_t cnt; + int no_exit = 1; + for(argv+=1; argv != end_argv; argv++) { + FILE* file; + file = fopen(*argv, "r"); + cnt = fread(read_buffer, 1, INK_SH_READ_BUFF - 1, file); + if(cnt == 0) { + fprintf(stderr, "Can't read file !! -> %s\n", *argv); + } + read_buffer[cnt] = 0; + ink_compile(ctx, read_buffer); + + if(ctx->panic) { + fprintf(stderr, "Panicked !! -> %d\n", ctx->panic); + } + + while (ink_can_run(ctx)) { + ink_step_everyone(ctx); + } + + fclose(file); + } + + char* it = read_buffer; + do { + int line_on = 0; + int routine; + struct ink_routine* rt; + // cnt = fread(read_buffer, 1, INK_SH_READ_BUFF - 1, stdin); + fputc('%', stdout); + fputc(' ', stdout); + cnt = 0; + + while(!line_on) { + int c = fgetc(stdin); + if (c == EOF) { + read_buffer[cnt] = 0; + line_on = 1; + } else if(c == '\n'){ + read_buffer[cnt] = 0; + line_on = 1; + } else { + read_buffer[cnt] = c; + ++cnt; + } + } + if(cnt > 0) { + read_buffer[cnt] = 0; + routine = ink_compile(ctx, read_buffer); + + if (ctx->panic) { + fprintf(stderr, "Panicked !! -> %d\n", ctx->panic); + } + + while (ink_can_run(ctx)) { + ink_step_everyone(ctx); + } + rt = ctx->routines + routine; + if(rt->top) { + if(rt->stack[rt->top - 1].type == INK_INTEGER) { + fprintf(stdout, "%u\n", rt->stack[rt->top - 1].value); + } + if(rt->stack[rt->top - 1].type == get_type_by_name(ctx, "array")) { + struct elem* it; + struct ink_array* ary = ink_get_value(ctx, rt->stack[rt->top - 1]); + fputc('[', stdout); + for(it = ary->elements; it != ary->elements + ary->top; ++it) { + fprintf(stdout, "%u", it->value); + if(it + 1 != ary->elements + ary->top) fputc(',', stdout); + } + fputc(']', stdout); + fputc('\n', stdout); + } + } + } + } while(no_exit); + + return ink_destroy(ctx); +} \ No newline at end of file