|
|
@ -307,6 +307,47 @@ void ink_pop(struct context* ctx) { |
|
|
|
ctx->routines[ctx->routine_current].top--; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int ink_destroy(struct context* ctx) { |
|
|
|
int panic = ctx->panic; |
|
|
|
int i, j; |
|
|
|
for (i = 0; i < ctx->types_top; ++i) { |
|
|
|
struct ink_type* t = ctx->types + i; |
|
|
|
if (t->element_size > 0 && t->elements_top > 0) { |
|
|
|
for (j = 0; i < t->element_size; ++i) { |
|
|
|
if (t->elements[j].in_use) { |
|
|
|
t->collect(ctx, t->elements[j].data); |
|
|
|
ctx->free(ctx, t->elements[j].data); |
|
|
|
} |
|
|
|
} |
|
|
|
ctx->free(ctx, t->elements); |
|
|
|
} |
|
|
|
/* Type names are not freed, for they are not copied */ |
|
|
|
/* ctx->inner_free(ctx, t->name); */ |
|
|
|
} |
|
|
|
for (i = 0; i < ctx->words_top; ++i) { |
|
|
|
ctx->inner_free(ctx, ctx->words[i].name); |
|
|
|
ctx->free(ctx, ctx->words[i].things); |
|
|
|
} |
|
|
|
for (i = 0; i < ctx->native_words_top; ++i) { |
|
|
|
ctx->inner_free(ctx, ctx->native_words[i].name); |
|
|
|
} |
|
|
|
for (i = 0; i < ctx->routines_top; ++i) { |
|
|
|
ctx->free(ctx, ctx->routines[i].function_stack); |
|
|
|
ctx->free(ctx, ctx->routines[i].stack); |
|
|
|
} |
|
|
|
for (i = 0; i < ctx->lex_reserved_words_top; ++i) { |
|
|
|
ctx->free(ctx, ctx->lex_reserved_words[i]); |
|
|
|
} |
|
|
|
ctx->inner_free(ctx, ctx->lex_reserved_words); |
|
|
|
ctx->inner_free(ctx, ctx->native_words); |
|
|
|
ctx->inner_free(ctx, ctx->routines); |
|
|
|
ctx->free(ctx, ctx->words); |
|
|
|
ctx->inner_free(ctx, ctx->types); |
|
|
|
ctx->inner_free(ctx, ctx); |
|
|
|
return panic; |
|
|
|
} |
|
|
|
|
|
|
|
struct context* ink_make_context(void*(*malloc)(struct context*, size_t), void*(*realloc)(struct context*, void*, size_t), void(*free)(struct context*, void*), int(*putchar)(struct context*, int)) { |
|
|
|
struct context* ctx; |
|
|
|
ctx = (struct context*)malloc(NULL, sizeof(struct context)); |
|
|
|