@ -194,14 +194,15 @@ static int ink_add_indigenous(struct context* ctx, const char* name, struct elem
*/
static int ink_add_lex_string ( struct context * ctx , const char * name ) {
int i ;
int len ;
if ( ctx - > lex_reserved_words = = NULL ) {
ctx - > lex_reserved_words = ctx - > inner_malloc ( sizeof ( char * ) * 8 ) ;
ctx - > lex_reserved_words_top = 0 ;
ctx - > lex_reserved_words_capacity = 8 ;
} else if ( ctx - > lex_reserved_words_top = = ctx - > lex_reserved_words_capacity ) {
int new_count ;
new_count = ( ctx - > lex_reserved_words_capacity + ctx - > lex_reserved_words_capacity / 2 ) ;
void * renewed ;
new_count = ( ctx - > lex_reserved_words_capacity + ctx - > lex_reserved_words_capacity / 2 ) ;
renewed = ctx - > inner_realloc ( ctx - > lex_reserved_words , sizeof ( struct native_fn ) * new_count ) ;
if ( renewed = = NULL ) {
return - 5 ;
@ -215,7 +216,6 @@ static int ink_add_lex_string(struct context* ctx, const char* name) {
return i ;
}
}
int len ;
len = strlen ( name ) ;
i = ctx - > lex_reserved_words_top ;
ctx - > lex_reserved_words [ i ] = ctx - > malloc ( len + 1 ) ;
@ -332,9 +332,11 @@ struct context* ink_make_context(void*(*malloc)(size_t), void*(*realloc)(void*,
* @ internal this function is slightly cursed
*/
static char * ink_itoa ( struct context * _ , int cpy ) {
char * n = _ - > malloc ( 16 ) ;
char * n ;
char * it ;
n = _ - > malloc ( 16 ) ;
n [ 15 ] = 0 ;
char * it = n + 15 ;
it = n + 15 ;
do {
it - - ;
* it = ( cpy % 10 ) + ' 0 ' ;
@ -345,7 +347,7 @@ static char* ink_itoa(struct context* _, int cpy) {
}
# ifndef NOSTDLIB
struct context * ink_make_default_context ( ) {
struct context * ink_make_default_context ( kt">void ) {
struct context * ctx ;
ctx = ink_make_context ( malloc , realloc , free , putchar ) ;
ink_std_library ( ctx ) ;
@ -357,6 +359,7 @@ static int ink_consume_one(int* end, struct context* pContext, char** buffer, ch
int i ;
int done ;
struct elem value ;
int err ;
if ( * end = = 0 ) {
return 0 ;
}
@ -383,7 +386,6 @@ static int ink_consume_one(int* end, struct context* pContext, char** buffer, ch
done = 1 ;
}
if ( done ) {
int err ;
err = ink_push ( pContext , value ) ;
if ( err < 0 ) {
return - 19 ;
@ -394,7 +396,6 @@ static int ink_consume_one(int* end, struct context* pContext, char** buffer, ch
if ( strcmp ( r , pContext - > words [ i ] . name ) = = 0 ) {
value . value = i ;
value . type = INK_FUNCTION ;
int err ;
err = ink_push ( pContext , value ) ;
if ( err < 0 ) {
return - 20 ;
@ -409,7 +410,6 @@ static int ink_consume_one(int* end, struct context* pContext, char** buffer, ch
if ( strcmp ( r , pContext - > native_words [ i ] . name ) = = 0 ) {
value . value = i ;
value . type = INK_NATIVE_FUNCTION ;
int err ;
err = ink_push ( pContext , value ) ;
if ( err < 0 ) {
return - 21 ;
@ -427,7 +427,6 @@ static int ink_consume_one(int* end, struct context* pContext, char** buffer, ch
}
value . value = atoi ( r ) ;
value . type = INK_INTEGER ;
int err ;
err = ink_push ( pContext , value ) ;
if ( err < 0 ) {
return - 22 ;
@ -447,7 +446,6 @@ static int ink_consume_one(int* end, struct context* pContext, char** buffer, ch
} else {
value . type = INK_RESERVED ;
}
int err ;
err = ink_push ( pContext , value ) ;
if ( err < 0 ) {
return - 23 ;
@ -458,8 +456,7 @@ static int ink_consume_one(int* end, struct context* pContext, char** buffer, ch
}
static int ink_lex ( struct context * pContext , char * buffer ) {
int i ;
/ / Limits the token size to 127 chars
/* Limits the token size to 127 chars */
char r [ 128 ] ;
int end ;
int err ;
@ -501,7 +498,7 @@ int ink_make_routine(struct context* ctx) {
struct ink_routine * it ;
struct ink_routine * end ;
o">/ / Allocate space if needed
cm">/* Allocate space if needed */
if ( ctx - > routines = = NULL ) {
ctx - > routines = ctx - > inner_malloc ( sizeof ( struct ink_routine ) * 8 ) ;
ctx - > routines_top = 0 ;
@ -533,7 +530,7 @@ int ink_make_routine(struct context* ctx) {
it = ctx - > routines ;
end = ctx - > routines + ctx - > routines_capacity ;
o">/ / Looks for a reusable routine space then uses it
cm">/* Looks for a reusable routine space then uses it */
for ( ; it ! = end ; + + it ) {
if ( it - > panic = = INK_ROUTINE_CAN_REUSE ) {
int idx ;
@ -551,6 +548,7 @@ int ink_make_routine(struct context* ctx) {
return idx ;
}
}
return - 758 ;
}
int ink_kill_routine ( struct context * ctx , int routine ) {
@ -584,6 +582,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 err ;
# define LABEL_BUFFER 128
# define FUNCTION_BUFFER 256
struct label labels [ LABEL_BUFFER ] ;
@ -597,7 +596,7 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i
mode = MODE_EXECUTABLE ;
memset ( labels , 0 , sizeof ( struct label ) * LABEL_BUFFER ) ;
o">/ / Loop from hell , good luck , pro - tip : leave the parser alone
cm">/* Loop from hell, good luck, pro-tip: leave the parser alone */
for ( i = 0 ; i < currentRoutine - > top ; + + i ) {
struct elem current ;
current = currentRoutine - > stack [ i ] ;
@ -665,7 +664,6 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i
struct elem pt ;
pt = function_buffer [ j ] ;
if ( pt . type = = INK_RESERVED ) {
const char * str = pContext - > lex_reserved_words [ pt . value ] ;
int k ;
for ( k = 0 ; k < LABEL_BUFFER ; k + + ) {
if ( labels [ k ] . active ) {
@ -682,7 +680,6 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i
}
}
}
int err ;
err = ink_add_indigenous ( pContext , pContext - > lex_reserved_words [ function_name ] , function_buffer , function_buffer_top ) ;
if ( err < 0 ) {
pContext - > panic = 1 ;
@ -774,33 +771,36 @@ int ink_step(struct context *pContext) {
}
void ink_compile ( struct context * pContext , char * buffer ) {
int routine , saved , i , executable_buffer_top;
o">/ / Main function has a size limit of 256 ( need to know that for REPL
int routine , saved , executable_buffer_top ;
cm">/* Main function has a size limit of 256 (need to know that for REPL */
struct elem executable_buffer [ 256 ] ;
struct ink_routine * currentRoutine ;
int err ;
struct stack_frame frame ;
char * integer ;
size_t integer_size ;
char main_fn [ 32 ] = " __-MAIN-__ " ;
routine = ink_make_routine ( pContext ) ;
saved = pContext - > routine_current ;
pContext - > routine_current = routine ;
struct ink_routine * currentRoutine = pContext - > routines + routine ;
currentRoutine = pContext - > routines + routine ;
currentRoutine - > stack = NULL ;
currentRoutine - > top = 0 ;
currentRoutine - > capacity = 0 ;
int err ;
err = ink_lex ( pContext , buffer ) ;
if ( err < 0 ) {
pContext - > panic = 1 ;
return ;
}
i = 0 ;
executable_buffer_top = 0 ;
err = ink_parse ( pContext , executable_buffer , & executable_buffer_top ) ;
if ( err < 0 ) {
pContext - > panic = 1 ;
return ;
}
struct stack_frame frame ;
char main_fn [ 32 ] = " __-MAIN-__ " ;
char * integer = ink_itoa ( pContext , routine ) ;
size_t integer_size = strlen ( integer ) ;
integer = ink_itoa ( pContext , routine ) ;
integer_size = strlen ( integer ) ;
memcpy ( main_fn + 10 , integer , integer_size ) ;
pContext - > free ( integer ) ;
main_fn [ 10 + integer_size ] = 0 ;
@ -835,19 +835,19 @@ int ink_step_everyone(struct context* pContext) {
int out ;
pContext - > routine_current = - 1 ;
for ( ; ; ) {
o">/ / Increment to next runnable routine
cm">/* Increment to next runnable routine */
do {
+ + ( pContext - > routine_current ) ;
} while ( pContext - > routine_current < pContext - > routines_top & & pContext - > routines [ pContext - > routine_current ] . panic ! = 0 ) ;
o">/ / Exit condition
cm">/* Exit condition */
if ( pContext - > routine_current > = pContext - > routines_top ) break ;
o">/ / Kill ?
cm">/* Kill? */
if ( pContext - > routines [ pContext - > routine_current ] . panic = = INK_ROUTINE_SUCCESS ) {
ink_kill_routine ( pContext , pContext - > routine_current ) ;
}
o">/ / Step !
cm">/* Step! */
out = ink_step ( pContext ) ;
if ( out = = 0 ) {
pContext - > routines [ pContext - > routine_current ] . panic = INK_ROUTINE_SUCCESS ;
@ -866,7 +866,7 @@ int ink_new_type(
struct ink_collection_list ( * gc ) ( struct context * , void * )
) {
if ( ctx - > panic ) return - 128 ;
o">/ / Resize for push
cm">/* Resize for push */
if ( ctx - > types = = NULL ) {
ctx - > types = ctx - > inner_malloc ( sizeof ( struct ink_type ) * 8 ) ;
ctx - > types_top = 0 ;
@ -884,7 +884,7 @@ int ink_new_type(
}
}
o">/ / Push
cm">/* Push */
ctx - > types [ ctx - > types_top ] . name = type_name ;
ctx - > types [ ctx - > types_top ] . element_size = size ;
ctx - > types [ ctx - > types_top ] . elements = NULL ;
@ -894,7 +894,7 @@ int ink_new_type(
ctx - > types [ ctx - > types_top ] . gc = gc ;
ctx - > types_top + + ;
o">/ / Satisfying the minimal value requirement
cm">/* Satisfying the minimal value requirement */
return ctx - > types_top - 1 + 16 ;
}
@ -920,13 +920,15 @@ void* ink_get_value(struct context* ctx, struct elem ref) {
struct elem ink_make_native ( struct context * ctx , int type , void * ptr ) {
int type_id ;
struct elem ret ;
int g , i ;
if ( type < 16 ) {
ret . type = 0 ;
ret . value = - 130 ;
return ret ;
}
o">/ / Apply invariant of the user defined types
cm">/* Apply invariant of the user defined types */
type_id = type - 16 ;
if ( type_id > = ctx - > types_top ) {
ret . type = 0 ;
@ -940,7 +942,7 @@ struct elem ink_make_native(struct context* ctx, int type, void* ptr) {
return ret ;
}
o">/ / Resize for push of value in store
cm">/* Resize for push of value in store */
if ( ctx - > types [ type_id ] . elements = = NULL ) {
ctx - > types [ type_id ] . elements = ctx - > inner_malloc ( sizeof ( struct element_slab ) * 8 ) ;
ctx - > types [ type_id ] . elements_top = 0 ;
@ -962,8 +964,7 @@ struct elem ink_make_native(struct context* ctx, int type, void* ptr) {
}
}
/ / Push value in store
int g , i ;
/* Push value in store */
g = ctx - > types [ type_id ] . elements_capacity ;
for ( i = 0 ; i < g ; + + i ) {
if ( ! ctx - > types [ type_id ] . elements [ i ] . in_use ) {
@ -1003,7 +1004,7 @@ void ink_gc(struct context* ctx) {
}
}
o">/ / Start by marking the roots of the routines
cm">/* Start by marking the roots of the routines */
for ( i = 0 ; i < ctx - > routines_top ; + + i ) {
for ( j = 0 ; j < ctx - > routines [ i ] . top ; + + j ) {
v = ink_get_value_link ( ctx , ctx - > routines [ i ] . stack [ j ] ) ;
@ -1011,19 +1012,18 @@ void ink_gc(struct context* ctx) {
}
}
o">/ / Mark the rest of the data
cm">/* Mark the rest of the data */
do {
marked = 0 ;
for ( i = 0 ; i < ctx - > types_top ; + + i ) {
for ( j = 0 ; j < ctx - > types [ i ] . elements_top ; + + j ) {
o">/ / Only mark from things that are active and detected as in use
cm">/* 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 ) {
struct ink_collection_list c ;
c = ctx - > types [ i ] . gc ( ctx , ctx - > types [ i ] . elements [ j ] . data ) ;
for ( k = 0 ; k < c . count ; + + k ) {
struct element_slab * v ;
v = ink_get_value_link ( ctx , c . elements [ k ] ) ;
o">/ / Never mark twice to avoid infinite loops with e . g . arrays that contain themselves
cm">/* Never mark twice to avoid infinite loops with e.g. arrays that contain themselves */
if ( v ! = NULL & & ! v - > uses ) {
+ + v - > uses ;
marked = 1 ;
@ -1035,7 +1035,7 @@ void ink_gc(struct context* ctx) {
}
} while ( marked ) ;
o">/ / Sweep phase : explore any allocated data and sweep the unused away
cm">/* 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 ) {
@ -1201,7 +1201,7 @@ static void dupe_elem(struct context* ctx) {
}
a = currentRoutine - > stack [ currentRoutine - > top - 1 ] ;
err = ink_push ( ctx , a ) ;
if ( err < 0 ) ctx - > panic ;
if ( err < 0 ) ctx - > panic = 1 ;
}
static void drop_elem ( struct context * ctx ) {
@ -1235,7 +1235,7 @@ static void pluck_elem(struct context* ctx) {
}
ink_pop ( ctx ) ;
err = ink_push ( ctx , currentRoutine - > stack [ position ] ) ;
if ( err < 0 ) ctx - > panic ;
if ( err < 0 ) ctx - > panic = 1 ;
}
static void swap_elem ( struct context * ctx ) {
@ -1473,9 +1473,9 @@ static void run_gc(struct context* ctx) {
int ink_std_library ( struct context * ctx ) {
int v , array_t ;
int v ;
v = 0 ;
array_t = ink_new_type( ctx , " array " , sizeof ( struct ink_array ) , collect_array , gc_array ) ;
ink_new_type ( ctx , " array " , sizeof ( struct ink_array ) , collect_array , gc_array ) ;
v + = ink_add_native ( ctx , " array.new " , new_array ) ;
v + = ink_add_native ( ctx , " array.push " , push_array ) ;
v + = ink_add_native ( ctx , " array.index " , index_array ) ;