#include "ink.h" #include #include #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; int i; for(nit = ctx->native_words; nit != ctx->native_words + ctx->native_words_top; ++nit) { const struct ink_array* name = ink_get_value(ctx, nit->name); for (i = 0; i < name->top; ++i) { const struct elem a = name->elements[i]; if(a.value <= 0x7F) { ctx->putchar(ctx, a.value); } else if(a.value <= 0x7FF) { ctx->putchar(ctx, ((a.value & 0xFC0) >> 6) | 192); ctx->putchar(ctx, (a.value & 0x3F) | 128); } else if(a.value <= 0xFFFF) { ctx->putchar(ctx, ((a.value & 0x3F000) >> 12) | 224); ctx->putchar(ctx, ((a.value & 0xFC0) >> 6) | 128); ctx->putchar(ctx, (a.value & 0x3F) | 128); } else if(a.value <= 0x10FFFF) { ctx->putchar(ctx, ((a.value & 0x3C0000) >> 18) | 240); ctx->putchar(ctx, ((a.value & 0x3F000) >> 12) | 128); ctx->putchar(ctx, ((a.value & 0xFC0) >> 6) | 128); ctx->putchar(ctx, (a.value & 0x3F) | 128); } else { ctx->panic = -9472; return; } } ctx->putchar(ctx, '\n'); } for(dit = ctx->words; dit != ctx->words + ctx->words_top; ++dit) { const struct ink_array* name = ink_get_value(ctx, dit->name); for (i = 0; i < name->top; ++i) { const struct elem a = name->elements[i]; if(a.value <= 0x7F) { ctx->putchar(ctx, a.value); } else if(a.value <= 0x7FF) { ctx->putchar(ctx, ((a.value & 0xFC0) >> 6) | 192); ctx->putchar(ctx, (a.value & 0x3F) | 128); } else if(a.value <= 0xFFFF) { ctx->putchar(ctx, ((a.value & 0x3F000) >> 12) | 224); ctx->putchar(ctx, ((a.value & 0xFC0) >> 6) | 128); ctx->putchar(ctx, (a.value & 0x3F) | 128); } else if(a.value <= 0x10FFFF) { ctx->putchar(ctx, ((a.value & 0x3C0000) >> 18) | 240); ctx->putchar(ctx, ((a.value & 0x3F000) >> 12) | 128); ctx->putchar(ctx, ((a.value & 0xFC0) >> 6) | 128); ctx->putchar(ctx, (a.value & 0x3F) | 128); } else { ctx->panic = -9472; return; } } ctx->putchar(ctx, '\n'); } } static void resolve_word(struct context* ctx) { struct native_fn* nit; struct fn* dit; int i; struct ink_routine *currentRoutine; struct elem a; struct ink_array *ary; unsigned char* name; int it; int found = 0; #ifndef NOEXTRACHECKS int tid; tid = get_type_by_name(ctx, "array"); #endif currentRoutine = ctx->routines + ctx->routine_current; #ifndef NOEXTRACHECKS if (currentRoutine->top < 1 || currentRoutine->stack[currentRoutine->top - 1].type != tid) { currentRoutine->panic = -1; return; } #endif a = currentRoutine->stack[currentRoutine->top - 1]; ary = ink_get_value(ctx, a); #ifndef NOEXTRACHECKS for(i = 0; i < ary->top; ++i) { if(ary->elements[i].type != INK_INTEGER) { currentRoutine->panic = -1; return; } } #endif ink_pop(ctx); for(nit = ctx->native_words; (!found) && nit != ctx->native_words + ctx->native_words_top; ++nit) { struct ink_array* inner_name = ink_get_value(ctx, nit->name); if(ary->top == inner_name->top && memcmp(ary->elements, inner_name->elements, sizeof(struct elem)*ary->top) == 0) { struct elem fn; fn.type = INK_NATIVE_FUNCTION; fn.value = nit - ctx->native_words; ink_push(ctx, fn); found = 1; } } for(dit = ctx->words; (!found) && dit != ctx->words + ctx->words_top; ++dit) { struct ink_array* inner_name = ink_get_value(ctx, dit->name); if(ary->top == inner_name->top && memcmp(ary->elements, inner_name->elements, sizeof(struct elem)*ary->top) == 0) { struct elem fn; fn.type = INK_FUNCTION; fn.value = dit - ctx->words; ink_push(ctx, fn); found = 1; } } } static void call_word(struct context* ctx) { struct ink_routine *currentRoutine; unsigned char* name; int it; int found = 0; struct stack_frame frame; currentRoutine = ctx->routines + ctx->routine_current; #ifndef NOEXTRACHECKS if (currentRoutine->top < 1 || (currentRoutine->stack[currentRoutine->top - 1].type != INK_FUNCTION && currentRoutine->stack[currentRoutine->top - 1].type != INK_NATIVE_FUNCTION)) { currentRoutine->panic = -1; return; } #endif frame.executing = currentRoutine->stack[currentRoutine->top - 1]; frame.index = 0; ink_pop(ctx); ink_push_fn(ctx, frame); } 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); ink_add_native(ctx, "words!", resolve_word); ink_add_native(ctx, "words.call", call_word); 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; no_exit = 0; } 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 ctx !! -> %d\n", ctx->panic); } if (ctx->routines[routine].panic) { fprintf(stderr, "Panicked routine !! -> %d\n", ctx->routines[routine].panic); } if (ctx->routines[routine].runtime_error.is_set) { fprintf(stderr, "Panicked !! -> %s\n", ctx->routines[routine].runtime_error.error_message); } 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* ary_it; int print_as_string = 1; struct ink_array* ary = ink_get_value(ctx, rt->stack[rt->top - 1]); for(ary_it = ary->elements; ary_it != ary->elements + ary->top; ++ary_it) { print_as_string = print_as_string && (isprint(ary_it->value) || isspace(ary_it->value)) && (ary_it->type == INK_INTEGER); } if(print_as_string) { for (ary_it = ary->elements; ary_it != ary->elements + ary->top; ++ary_it) { fputc(ary_it->value, stdout); } fputc('\n', stdout); } else { fputc('[', stdout); for (ary_it = ary->elements; ary_it != ary->elements + ary->top; ++ary_it) { fprintf(stdout, "%u", ary_it->value); if (ary_it + 1 != ary->elements + ary->top) fputc(',', stdout); } fputc(']', stdout); fputc('\n', stdout); } } } } } while(no_exit); fputc('\n', stdout); return ink_destroy(ctx); }