From bdc1d1dac950d1364819abce776ab41541942ca5 Mon Sep 17 00:00:00 2001 From: Ludovic 'Archivist' Lagouardette Date: Thu, 18 Jul 2024 06:18:06 +0200 Subject: [PATCH] added parsing of string literals --- CMakeLists.txt | 3 ++ include/ink.h | 1 + lib.c | 110 +++++++++++++++++++++++++++++++++++++++++++++---- test/test04.nk | 1 + 4 files changed, 107 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d0fa01..570311c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,9 @@ add_library(ink lib.c include/ink.h) # Uncomment to disable array types # add_definitions(-DNOARRAYLIB) +# Uncomment to disable string literals +# add_definitions(-DNOSTRINGLITERALS) + # Ensures the interpreter doesn't use the standard C library functions # add_definitions(-DNOSTDLIB) diff --git a/include/ink.h b/include/ink.h index cf0711d..351aa16 100644 --- a/include/ink.h +++ b/include/ink.h @@ -99,6 +99,7 @@ struct ink_collection_list { */ struct element_slab { void* data; + int is_protected; int uses; int in_use; }; diff --git a/lib.c b/lib.c index 54238b5..40d3489 100644 --- a/lib.c +++ b/lib.c @@ -355,11 +355,43 @@ struct context* ink_make_default_context(void) { } #endif -static int ink_consume_one(int* end, struct context* pContext, char* r) { +#ifndef NOSTRINGLITERALS +static void new_protected_array(struct context* ctx); +#endif + +static int ink_consume_one(int* end, struct context* pContext, char* r, int is_str) { int i; int done; struct elem value; int err; +#ifndef NOSTRINGLITERALS + if(is_str) { + struct ink_routine* routine = pContext->routines + pContext->routine_current; + struct ink_array* ary; + int it = 0; + new_protected_array(pContext); + if(routine->top < 1) { + pContext->panic = -1; + return -8746; + } + value = routine->stack[routine->top - 1]; + ary = ink_get_value(pContext, value); + if(ary == NULL) { + pContext->panic = -1; + return -8747; + } + for(;it != *end;++it) { + struct elem character; + character.type = INK_INTEGER; + /* TODO: codepoint conversion and coalescence is required here */ + character.value = r[it]; + array_push(pContext, routine, ary, character); + } + *end = 0; + return 0; + } +#endif + is_str = is_str; if(*end == 0) { return 0; } @@ -460,9 +492,46 @@ static int ink_lex(struct context *pContext, const char* buffer) { char r[128]; int end; int err; +#ifndef NOSTRINGLITERALS + int parses_string; +#endif end = 0; restart_after_comment: +#ifndef NOSTRINGLITERALS + parses_string = 0; +#endif while(*buffer != 0) { +#ifndef NOSTRINGLITERALS + if(parses_string) { + switch(*buffer) { + case '"': { + if(*(buffer+1) == 0 || isspace(*(buffer+1))) { + err = ink_consume_one(&end, pContext, r, 1); + if(err < 0) { + pContext->panic = 1; + return -995; + } + parses_string = 0; + } else if(*(buffer+1) == '"') { + r[end] = *buffer; + ++end; + ++buffer; + } else if(*(buffer+1) == '/' && *(buffer+2) == '"') { + r[end] = '\n'; + ++end; + ++buffer; + ++buffer; + } else { + pContext->panic = 1; + return -994; + } + }break; + default: + r[end] = *buffer; + ++end; + } + } else /* ... */ +#endif if(isspace(*buffer)) { if(end == 1 && r[0] == '#') { while(*buffer != '\n' && *buffer != 0) { @@ -471,18 +540,24 @@ restart_after_comment: end = 0; goto restart_after_comment; } - err = ink_consume_one(&end, pContext, r); + err = ink_consume_one(&end, pContext, r, 0); if(err < 0) { pContext->panic = 1; return -8; } - } else { + } else /* ... */ +#ifndef NOSTRINGLITERALS + if(end == 0 && *buffer == '"' && !parses_string) { + parses_string = 1; + } else /* ... */ +#endif + { r[end] = *buffer; ++end; } ++buffer; } - err = ink_consume_one(&end, pContext, r); + err = ink_consume_one(&end, pContext, r, 0); if(err < 0) { pContext->panic = 1; return -9; @@ -930,7 +1005,7 @@ void* ink_get_value(struct context* ctx, struct elem ref) { return s->data; } -struct elem ink_make_native(struct context* ctx, int type, void* ptr) { +struct elem ink_make_native_unsafe(struct context* ctx, int type, void* ptr, int is_protected) { int type_id; struct elem ret; int g, i; @@ -982,7 +1057,8 @@ struct elem ink_make_native(struct context* ctx, int type, void* ptr) { for(i = 0; i < g; ++i) { if(! ctx->types[type_id].elements[i].in_use) { ctx->types[type_id].elements[i].in_use = 1; - ctx->types[type_id].elements[i].uses = 1; + ctx->types[type_id].elements[i].uses = 1; + ctx->types[type_id].elements[i].is_protected = is_protected; if(ctx->types[type_id].element_size < 0) { ctx->types[type_id].elements[i].data = ptr; } else { @@ -1006,6 +1082,10 @@ struct elem ink_make_native(struct context* ctx, int type, void* ptr) { return ret; } +struct elem ink_make_native(struct context* ctx, int type, void* ptr) { + return ink_make_native_unsafe(ctx, type, ptr, 0); +} + void ink_gc(struct context* ctx) { int i, j, k; int marked; @@ -1041,7 +1121,7 @@ void ink_gc(struct context* ctx) { for (i = 0; i < ctx->types_top; ++i) { for (j = 0; j < ctx->types[i].elements_top; ++j) { /* Only mark from things that are active and detected as in use */ - if (ctx->types[i].elements[j].in_use && ctx->types[i].elements[j].uses) { + if (ctx->types[i].elements[j].in_use && ctx->types[i].elements[j].is_protected && ctx->types[i].elements[j].uses) { struct ink_collection_list c; c = ctx->types[i].gc(ctx, ctx->types[i].elements[j].data); for (k = 0; k < c.count; ++k) { @@ -1061,7 +1141,7 @@ void ink_gc(struct context* ctx) { /* Sweep phase: explore any allocated data and sweep the unused away */ for(i = 0; i < ctx->types_top; ++i) { for(j = 0; j < ctx->types[i].elements_top; ++j) { - if(ctx->types[i].elements[j].uses == 0 && ctx->types[i].elements[j].in_use) { + if(ctx->types[i].elements[j].uses == 0 && ctx->types[i].elements[j].in_use && ctx->types[i].elements[j].is_protected == 0) { ctx->collections++; ctx->types[i].collect(ctx, ctx->types[i].elements[j].data); if(ctx->types[i].element_size > 0) { @@ -1598,6 +1678,20 @@ static void new_array(struct context* ctx) { ink_push(ctx, e); } +#ifndef NOSTRINGLITERALS +static void new_protected_array(struct context* ctx) { + int tid; + struct elem e; + struct ink_array ary; + tid = get_type_by_name(ctx, "array"); + ary.elements = NULL; + ary.top = 0; + ary.capacity = 0; + e = ink_make_native_unsafe(ctx, tid, &ary, 1); + ink_push(ctx, e); +} +#endif + static void push_array_stack_delim(struct context* ctx) { int tid; struct elem e; diff --git a/test/test04.nk b/test/test04.nk index e69de29..6937c9a 100644 --- a/test/test04.nk +++ b/test/test04.nk @@ -0,0 +1 @@ +"""Hello world"""/"" array.print_utf8 \ No newline at end of file