|
|
@ -15,8 +15,10 @@ |
|
|
|
#define INK_END_KW (-4) |
|
|
|
#define INK_LABEL (-5) |
|
|
|
#define INK_RETURN (-6) |
|
|
|
#define INK_MACRO_KW (-7) |
|
|
|
|
|
|
|
#define _KEYWORD_INK_FUNCTION "fn" |
|
|
|
#define _KEYWORD_INK_MACRO "macro" |
|
|
|
#define _KEYWORD_INK_DO "do" |
|
|
|
#define _KEYWORD_INK_END "end" |
|
|
|
#define _KEYWORD_INK_RETURN "return" |
|
|
@ -462,6 +464,11 @@ static int ink_consume_one(int* end, struct context* pContext, char* r, int is_s |
|
|
|
value.type = INK_FUNCTION_KW; |
|
|
|
done = 1; |
|
|
|
} |
|
|
|
if (strcmp(r, _KEYWORD_INK_MACRO) == 0) { |
|
|
|
value.value = 0; |
|
|
|
value.type = INK_MACRO_KW; |
|
|
|
done = 1; |
|
|
|
} |
|
|
|
if (!done && strcmp(r, _KEYWORD_INK_DO) == 0) { |
|
|
|
value.value = 0; |
|
|
|
value.type = INK_DO_KW; |
|
|
@ -603,6 +610,7 @@ static int ink_lex(struct context *pContext, const char* buffer) { |
|
|
|
goto restart_after_comment; |
|
|
|
} |
|
|
|
err = ink_consume_one(&end, pContext, r, 0); |
|
|
|
/* Send the token off to the wizard (ink_parse) */ |
|
|
|
#ifndef NOEXTRACHECKS |
|
|
|
if(err < 0) { |
|
|
|
pContext->panic = 1; |
|
|
@ -741,6 +749,7 @@ 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 func_is_macro = 0; |
|
|
|
#pragma GCC diagnostic push |
|
|
|
#pragma GCC diagnostic ignored "-Wunused-parameter" |
|
|
|
#pragma GCC diagnostic ignored "-Wunused-but-set-variable" |
|
|
@ -770,6 +779,12 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i |
|
|
|
case INK_FUNCTION_KW: |
|
|
|
mode = MODE_FUNCTION; |
|
|
|
function_name = -1; |
|
|
|
func_is_macro = 0; |
|
|
|
goto next_token; |
|
|
|
case INK_MACRO_KW: |
|
|
|
mode = MODE_FUNCTION; |
|
|
|
func_is_macro = 1; |
|
|
|
function_name = -1; |
|
|
|
goto next_token; |
|
|
|
#ifndef NOEXTRACHECKS |
|
|
|
case INK_DO_KW: |
|
|
@ -877,6 +892,47 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i |
|
|
|
return -33; |
|
|
|
} |
|
|
|
#endif |
|
|
|
/* Handle the case where what we just pushed should be transformed into a macro instead */ |
|
|
|
if(func_is_macro) { |
|
|
|
struct stack_frame macro_frame; |
|
|
|
struct elem macro_id; |
|
|
|
struct ink_routine* macro_cooking_routine; |
|
|
|
int step_value; |
|
|
|
int parser_routine_index = pContext->routine_current; |
|
|
|
int macro_cooking_routine_ref = ink_make_routine(pContext); |
|
|
|
#ifndef NOEXTRACHECKS |
|
|
|
if(macro_cooking_routine_ref < 0) { |
|
|
|
pContext->panic = 1; |
|
|
|
return macro_cooking_routine_ref; |
|
|
|
} |
|
|
|
#endif |
|
|
|
pContext->routine_current = macro_cooking_routine_ref; |
|
|
|
macro_cooking_routine = pContext->routines + macro_cooking_routine_ref; |
|
|
|
macro_id.type = INK_FUNCTION; |
|
|
|
macro_id.value = err; |
|
|
|
macro_frame.executing = macro_id; |
|
|
|
macro_frame.index = 0; |
|
|
|
ink_push_fn(pContext, macro_frame); |
|
|
|
step_value = 1; |
|
|
|
while(step_value > 0 && macro_cooking_routine->panic == 0 && pContext->panic == 0) { |
|
|
|
step_value = ink_step(pContext); |
|
|
|
} |
|
|
|
#ifndef NOEXTRACHECKS |
|
|
|
if(macro_cooking_routine->panic != 0 || pContext->panic != 0 || step_value < 0) { |
|
|
|
pContext->panic = 1; |
|
|
|
return -138445; |
|
|
|
} |
|
|
|
#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); |
|
|
|
macro_cooking_routine->panic = INK_ROUTINE_SUCCESS; |
|
|
|
#ifndef NOEXTRACHECKS |
|
|
|
if(err < 0) { |
|
|
|
pContext->panic = 1; |
|
|
|
return -542151; |
|
|
|
} |
|
|
|
#endif |
|
|
|
} |
|
|
|
function_buffer_top = 0; |
|
|
|
mode = MODE_EXECUTABLE; |
|
|
|
goto next_token; |
|
|
@ -1334,7 +1390,7 @@ void ink_gc(struct context* ctx) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
for(i = 0; i < ctx->native_words_top; ++i) { |
|
|
|
for(i = 0; i < ctx->words_top; ++i) { |
|
|
|
struct fn* function = ctx->words + i; |
|
|
|
for(j = 0; j < function->size; ++j) { |
|
|
|
thing = function->things + j; |
|
|
|