瀏覽代碼

Make it possible to redefine functions

main
Ludovic 'Archivist' Lagouardette 19 小時之前
父節點
當前提交
95875703a6
共有 1 個文件被更改,包括 117 次插入60 次删除
  1. +117
    -60
      lib.c

+ 117
- 60
lib.c 查看文件

@ -241,54 +241,89 @@ int ink_add_native(struct context* ctx, const char* name, void(*value)(struct co
}
static int ink_add_indigenous(struct context* ctx, char* name, struct elem* m, size_t count) {
int tid;
struct elem e;
int i;
struct ink_array ary;
const char* name_it;
struct elem character;
tid = get_type_by_name(ctx, "array");
ary.elements = NULL;
ary.top = 0;
ary.capacity = 0;
ary.flags = 0;
if(ctx->words == NULL) {
ctx->words = ctx->malloc(ctx, sizeof(struct fn) * 8);
ctx->words_top = 0;
ctx->words_capacity = 8;
} else if(ctx->words_top == ctx->words_capacity) {
int new_count;
void* renewed;
new_count = (ctx->words_capacity + ctx->words_capacity/2);
renewed = ctx->realloc(ctx, ctx->words, sizeof(struct fn) * new_count);
if(renewed == NULL) {
return -1;
} else {
ctx->words = renewed;
ctx->words_capacity = new_count;
}
}
name_it = name;
while (utf8_consume(&name_it, &character)) {
array_push_s(ctx, &ary, character);
}
e = ink_make_native(ctx, tid, &ary);
for(i = 0; i < ctx->words_top; ++i) {
struct ink_array* inner_name = ink_get_value(ctx, ctx->words[i].name);
if(ary.top == inner_name->top && memcmp(ary.elements, inner_name->elements, sizeof(struct elem)*ary.top) == 0) {
if(ctx->words[i].things != NULL) ctx->free(ctx, ctx->words[i].things);
ctx->words[i].things = ctx->malloc(ctx, sizeof(struct elem) * count);
memcpy(ctx->words[i].things, m, sizeof(struct elem) * count);
ctx->words[i].size = count;
return i;
}
}
ctx->words[ctx->words_top].things = ctx->malloc(ctx, sizeof(struct elem) * count);
memcpy(ctx->words[ctx->words_top].things, m, sizeof(struct elem) * count);
ctx->words[ctx->words_top].size = count;
ctx->words[ctx->words_top].name = e;
return ctx->words_top++;
int tid;
struct elem e;
int i;
struct ink_array ary;
const char* name_it;
struct elem character;
tid = get_type_by_name(ctx, "array");
ary.elements = NULL;
ary.top = 0;
ary.capacity = 0;
ary.flags = 0;
if(ctx->words == NULL) {
ctx->words = ctx->malloc(ctx, sizeof(struct fn) * 8);
ctx->words_top = 0;
ctx->words_capacity = 8;
} else if(ctx->words_top == ctx->words_capacity) {
int new_count;
void* renewed;
new_count = (ctx->words_capacity + ctx->words_capacity/2);
renewed = ctx->realloc(ctx, ctx->words, sizeof(struct fn) * new_count);
if(renewed == NULL) {
return -1;
} else {
ctx->words = renewed;
ctx->words_capacity = new_count;
}
}
name_it = name;
while (utf8_consume(&name_it, &character)) {
array_push_s(ctx, &ary, character);
}
e = ink_make_native(ctx, tid, &ary);
for(i = 0; i < ctx->words_top; ++i) {
struct ink_array* inner_name = ink_get_value(ctx, ctx->words[i].name);
if(ary.top == inner_name->top && memcmp(ary.elements, inner_name->elements, sizeof(struct elem)*ary.top) == 0) {
if(ctx->words[i].things != NULL) ctx->free(ctx, ctx->words[i].things);
ctx->words[i].things = ctx->malloc(ctx, sizeof(struct elem) * count);
memcpy(ctx->words[i].things, m, sizeof(struct elem) * count);
ctx->words[i].size = count;
return i;
}
}
ctx->words[ctx->words_top].things = ctx->malloc(ctx, sizeof(struct elem) * count);
memcpy(ctx->words[ctx->words_top].things, m, sizeof(struct elem) * count);
ctx->words[ctx->words_top].size = count;
ctx->words[ctx->words_top].name = e;
return ctx->words_top++;
}
static int ink_add_indigenous_already_array(struct context* ctx, struct elem e, struct elem* m, size_t count) {
int i;
if(ctx->words == NULL) {
ctx->words = ctx->malloc(ctx, sizeof(struct fn) * 8);
ctx->words_top = 0;
ctx->words_capacity = 8;
} else if(ctx->words_top == ctx->words_capacity) {
int new_count;
void* renewed;
new_count = (ctx->words_capacity + ctx->words_capacity/2);
renewed = ctx->realloc(ctx, ctx->words, sizeof(struct fn) * new_count);
if(renewed == NULL) {
return -1;
} else {
ctx->words = renewed;
ctx->words_capacity = new_count;
}
}
for(i = 0; i < ctx->words_top; ++i) {
if(e.value == ctx->words[i].name.value) {
if(ctx->words[i].things != NULL) ctx->free(ctx, ctx->words[i].things);
ctx->words[i].things = ctx->malloc(ctx, sizeof(struct elem) * count);
memcpy(ctx->words[i].things, m, sizeof(struct elem) * count);
ctx->words[i].size = count;
return i;
}
}
ctx->words[ctx->words_top].things = ctx->malloc(ctx, sizeof(struct elem) * count);
memcpy(ctx->words[ctx->words_top].things, m, sizeof(struct elem) * count);
ctx->words[ctx->words_top].size = count;
ctx->words[ctx->words_top].name = e;
return ctx->words_top++;
}
/**
@ -578,11 +613,13 @@ static int ink_consume_one(int* end, struct context* pContext, char* r, int is_s
}
#endif
for(;it != *end;++it) {
struct elem character;
const char* iterator;
character.type = INK_INTEGER;
/* TODO: codepoint conversion and coalescence is required here */
character.value = r[it];
iterator = r + it;
utf8_consume(&iterator, &character);
array_push(pContext, routine, ary, character);
it += (iterator - (r + it)) - 1;
}
*end = 0;
return 0;
@ -888,7 +925,8 @@ int ink_kill_routine(struct context* ctx, int routine){
*/
static int ink_parse(struct context* pContext, struct elem* executable_buffer, int* executable_buffer_top) {
struct ink_routine* currentRoutine;
int i, function_buffer_top, function_name, mode;
int i, function_buffer_top, mode;
struct elem function_name;
int func_is_macro = 0;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
@ -902,7 +940,8 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i
/* TODO: add checks for overflows in these arrays */
currentRoutine = pContext->routines + pContext->routine_current;
function_buffer_top = 0;
function_name = -1;
function_name.type = INK_RESERVED;
function_name.value = -1;
#define MODE_EXECUTABLE 0
#define MODE_FUNCTION 1
#define MODE_DO 2
@ -918,13 +957,13 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i
switch(current.type) {
case INK_FUNCTION_KW:
mode = MODE_FUNCTION;
function_name = -1;
function_name.value = -1;
func_is_macro = 0;
goto next_token;
case INK_MACRO_KW:
mode = MODE_FUNCTION;
func_is_macro = 1;
function_name = -1;
function_name.value = -1;
goto next_token;
#ifndef NOEXTRACHECKS
case INK_DO_KW:
@ -946,7 +985,7 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i
case MODE_FUNCTION:
if(current.type == INK_DO_KW) {
#ifndef NOEXTRACHECKS
if(function_name == -1) {
if(function_name.value == -1) {
currentRoutine->parse_error.is_set = 1;
currentRoutine->parse_error.error_message = "Found start of function body before the name of the function was provided";
currentRoutine->parse_error.offset= i;
@ -958,20 +997,20 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i
goto next_token;
}
#ifndef NOEXTRACHECKS
if(function_name != -1) {
if(function_name.value != -1) {
currentRoutine->parse_error.is_set = 1;
currentRoutine->parse_error.error_message = "Function name was not found";
currentRoutine->parse_error.offset= i;
return -28;
}
if(current.type != INK_RESERVED) {
if(current.type != INK_RESERVED && current.type != INK_FUNCTION && current.type != INK_NATIVE_FUNCTION) {
currentRoutine->parse_error.is_set = 1;
currentRoutine->parse_error.error_message = "Expected special token";
currentRoutine->parse_error.offset= i;
return -29;
}
#endif
function_name = current.value;
function_name = current;
break;
case MODE_DO:
if(current.type == INK_END_KW) {
@ -1025,7 +1064,15 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i
}
}
}
err = ink_add_indigenous(pContext, pContext->lex_reserved_words[function_name], function_buffer, function_buffer_top);
if(function_name.type == INK_RESERVED) {
err = ink_add_indigenous(pContext, pContext->lex_reserved_words[function_name.value], function_buffer, function_buffer_top);
} else {
if(function_name.type == INK_NATIVE_FUNCTION) {
err = ink_add_indigenous_already_array(pContext, pContext->native_words[function_name.value].name,function_buffer, function_buffer_top);
} else if(function_name.type == INK_FUNCTION) {
err = ink_add_indigenous_already_array(pContext, pContext->words[function_name.value].name,function_buffer, function_buffer_top);
}
}
#ifndef NOEXTRACHECKS
if(err < 0) {
pContext->panic = 1;
@ -1064,7 +1111,17 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i
}
#endif
pContext->routine_current = parser_routine_index;
err = ink_add_indigenous(pContext, pContext->lex_reserved_words[function_name], macro_cooking_routine->stack, macro_cooking_routine->top);
if(function_name.type == INK_RESERVED) {
err = ink_add_indigenous(pContext, pContext->lex_reserved_words[function_name.value], function_buffer, function_buffer_top);
} else {
if(function_name.type == INK_NATIVE_FUNCTION) {
err = ink_add_indigenous_already_array(pContext, pContext->native_words[function_name.value].name,function_buffer, function_buffer_top);
} else if(function_name.type == INK_FUNCTION) {
err = ink_add_indigenous_already_array(pContext, pContext->words[function_name.value].name,function_buffer, function_buffer_top);
}
}
macro_cooking_routine->panic = INK_ROUTINE_SUCCESS;
#ifndef NOEXTRACHECKS
if(err < 0) {

Loading…
取消
儲存