15#ifndef MLISP_TOKEN_SZ_MAX
16# define MLISP_TOKEN_SZ_MAX 4096
19#ifndef MLISP_EXEC_TRACE_LVL
20# define MLISP_EXEC_TRACE_LVL 0
23#define MLISP_ENV_FLAG_BUILTIN 0x02
26#define MLISP_ENV_FLAG_CMP_GT 0x10
29#define MLISP_ENV_FLAG_CMP_LT 0x20
32#define MLISP_ENV_FLAG_CMP_EQ 0x40
35#define MLISP_ENV_FLAG_ARI_ADD 0x10
38#define MLISP_ENV_FLAG_ARI_MUL 0x20
40#define MLISP_ENV_FLAG_ARI_DIV 0x40
42#define MLISP_ENV_FLAG_ARI_MOD 0x80
44#define MLISP_ENV_FLAG_ANO_OR 0x10
46#define MLISP_ENV_FLAG_ANO_AND 0x20
61#define mlisp_stack_push( exec, i, ctype ) \
62 (_mlisp_stack_push_ ## ctype( exec, (ctype)i ))
93 const char* strpool,
size_t token_strpool_idx,
size_t token_strpool_sz );
97 const char* token,
size_t token_sz );
101 const char* token,
size_t token_sz, uint8_t env_type,
const void* data,
102 void* cb_data, uint8_t flags );
128 const char* lambda );
135#define _MLISP_TYPE_TABLE_PUSH_PROTO( idx, ctype, name, const_name, fmt ) \
136 MERROR_RETVAL _mlisp_stack_push_ ## ctype( \
137 struct MLISP_EXEC_STATE* exec, ctype i );
143#define mlisp_ast_has_ready_children( exec_child_idx, n ) \
144 ((exec_child_idx) < (n)->ast_idx_children_sz)
168 char* strpool = NULL;
171# define _MLISP_TYPE_TABLE_DUMPS( idx, ctype, name, const_name, fmt ) \
172 } else if( MLISP_TYPE_ ## const_name == n_stack->type ) { \
173 debug_printf( MLISP_EXEC_TRACE_LVL, \
174 MLISP_TRACE_SIGIL " stack " SIZE_T_FMT " (" #const_name "): " fmt, \
175 i, n_stack->value.name );
177 mdata_vector_lock( &(exec->
stack) );
178 mdata_strpool_lock( &(parser->strpool), strpool ); \
179 while( i < mdata_vector_ct( &(exec->
stack) ) ) {
183 if( MLISP_TYPE_STR == n_stack->type ) {
184 debug_printf( MLISP_EXEC_TRACE_LVL,
185 MLISP_TRACE_SIGIL
" stack " SIZE_T_FMT
" (STR): %s",
186 i, &(strpool[n_stack->value.strpool_idx]) );
188 }
else if( MLISP_TYPE_CB == n_stack->type ) {
189 debug_printf( MLISP_EXEC_TRACE_LVL,
190 MLISP_TRACE_SIGIL
" stack " SIZE_T_FMT
" (CB): %p",
191 i, n_stack->value.cb );
193 }
else if( MLISP_TYPE_LAMBDA == n_stack->type ) {
194 debug_printf( MLISP_EXEC_TRACE_LVL,
195 MLISP_TRACE_SIGIL
" stack " SIZE_T_FMT
" (LAMBDA): " SIZE_T_FMT,
196 i, n_stack->value.lambda );
198 }
else if( MLISP_TYPE_ARGS_S == n_stack->type ) {
199 debug_printf( MLISP_EXEC_TRACE_LVL,
200 MLISP_TRACE_SIGIL
" stack " SIZE_T_FMT
" (ARGS_S): " SIZE_T_FMT,
201 i, n_stack->value.args_start );
203 }
else if( MLISP_TYPE_ARGS_E == n_stack->type ) {
204 debug_printf( MLISP_EXEC_TRACE_LVL,
205 MLISP_TRACE_SIGIL
" stack " SIZE_T_FMT
" (ARGS_E): " SIZE_T_FMT,
206 i, n_stack->value.args_end );
208 }
else if( MLISP_TYPE_BEGIN == n_stack->type ) {
209 debug_printf( MLISP_EXEC_TRACE_LVL,
210 MLISP_TRACE_SIGIL
" stack " SIZE_T_FMT
" (BEGIN): " SIZE_T_FMT,
211 i, n_stack->value.begin );
216 error_printf(
"invalid stack type: %u", n_stack->type );
220 mdata_strpool_unlock( &(parser->strpool), strpool );
221 mdata_vector_unlock( &(exec->
stack) );
225 assert( NULL == strpool );
232#define _MLISP_TYPE_TABLE_PUSH( idx, ctype, name, const_name, fmt ) \
233 MERROR_RETVAL _mlisp_stack_push_ ## ctype( \
234 struct MLISP_EXEC_STATE* exec, ctype i \
236 struct MLISP_STACK_NODE n_stack; \
237 MERROR_RETVAL retval = MERROR_OK; \
238 debug_printf( MLISP_EXEC_TRACE_LVL, \
239 "pushing " #const_name " onto stack: " fmt, i ); \
240 n_stack.type = MLISP_TYPE_ ## const_name; \
241 n_stack.value.name = i; \
242 retval = mdata_vector_append( \
243 &(exec->stack), &n_stack, sizeof( struct MLISP_STACK_NODE ) ); \
245 retval = mdata_retval( retval ); \
264 if( mdata_vector_ct( &(exec->
stack) ) == 0 ) {
265 error_printf(
"stack underflow!" );
266 retval = MERROR_OVERFLOW;
270 n_idx = mdata_vector_ct( &(exec->
stack) ) - 1;
273 mdata_vector_lock( &(exec->
stack) );
274 n_stack = mdata_vector_get(
276 assert( NULL != n_stack );
279 mdata_vector_unlock( &(exec->
stack) );
281# define _MLISP_TYPE_TABLE_POPD( idx, ctype, name, const_name, fmt ) \
282 } else if( MLISP_TYPE_ ## const_name == o->type ) { \
283 debug_printf( MLISP_EXEC_TRACE_LVL, \
284 "popping: " SSIZE_T_FMT ": " fmt, n_idx, o->value.name );
290 retval = mdata_vector_remove( &(exec->
stack), n_idx );
308 char* strpool = NULL;
312# define _MLISP_TYPE_TABLE_DUMPE( idx, ctype, name, const_name, fmt ) \
313 } else if( MLISP_TYPE_ ## const_name == e->type ) { \
314 debug_printf( MLISP_EXEC_TRACE_LVL, \
315 MLISP_TRACE_SIGIL " env " SIZE_T_FMT \
316 " \"%s\" (" #const_name "): " fmt, \
317 i, &(strpool[e->name_strpool_idx]), e->value.name ); \
320 MLISP_EXEC_FLAG_SHARED_ENV == (MLISP_EXEC_FLAG_SHARED_ENV & exec->
flags)
322 env = &(parser->
env);
326 assert( NULL != env->
data_h );
327 assert( NULL != parser->strpool.str_h );
328 mdata_strpool_lock( &(parser->strpool), strpool );
329 assert( NULL != strpool );
332 assert( mdata_vector_is_locked( env ) );
336 if( MLISP_ENV_FLAG_BUILTIN == (MLISP_ENV_FLAG_BUILTIN & e->flags) ) {
345 }
else if( MLISP_TYPE_STR == e->type ) {
346 debug_printf( MLISP_EXEC_TRACE_LVL,
347 MLISP_TRACE_SIGIL
" env " SIZE_T_FMT
" \"%s\" (STR): %s",
348 i, &(strpool[e->name_strpool_idx]),
349 &(strpool[e->value.strpool_idx]) );
351 }
else if( MLISP_TYPE_CB == e->type ) {
352 debug_printf( MLISP_EXEC_TRACE_LVL,
353 MLISP_TRACE_SIGIL
" env " SIZE_T_FMT
" \"%s\" (CB): %p",
354 i, &(strpool[e->name_strpool_idx]), e->value.cb );
356 }
else if( MLISP_TYPE_LAMBDA == e->type ) {
357 debug_printf( MLISP_EXEC_TRACE_LVL,
358 MLISP_TRACE_SIGIL
" env " SIZE_T_FMT
359 " \"%s\" (LAMBDA): " SIZE_T_FMT,
360 i, &(strpool[e->name_strpool_idx]), e->value.lambda );
362 }
else if( MLISP_TYPE_ARGS_S == e->type ) {
363 debug_printf( MLISP_EXEC_TRACE_LVL,
364 MLISP_TRACE_SIGIL
" env " SIZE_T_FMT
365 " \"%s\" (ARGS_S): " SIZE_T_FMT,
366 i, &(strpool[e->name_strpool_idx]), e->value.args_start );
368 }
else if( MLISP_TYPE_ARGS_E == e->type ) {
369 debug_printf( MLISP_EXEC_TRACE_LVL,
370 MLISP_TRACE_SIGIL
" env " SIZE_T_FMT
371 " \"%s\" (ARGS_E): " SIZE_T_FMT,
372 i, &(strpool[e->name_strpool_idx]), e->value.args_end );
375 error_printf( MLISP_TRACE_SIGIL
" invalid env type: %u", e->type );
380 mdata_strpool_unlock( &(parser->strpool), strpool );
400 MLISP_EXEC_FLAG_SHARED_ENV == (MLISP_EXEC_FLAG_SHARED_ENV & exec->
flags)
402 env = &(parser->
env);
409 assert( mdata_vector_is_locked( env ) );
411 mdata_strpool_lock( &(parser->strpool), strpool );
414 assert( mdata_vector_is_locked( env ) );
417 &(strpool[node_test->name_strpool_idx]), key, strlen( key )
419 node_out = node_test;
427 if( MERROR_OK != retval ) {
431 if( NULL != strpool ) {
432 mdata_strpool_unlock( &(parser->strpool), strpool );
442 const char* strpool,
size_t token_strpool_idx,
size_t token_strpool_sz
450 MLISP_EXEC_FLAG_SHARED_ENV == (MLISP_EXEC_FLAG_SHARED_ENV & exec->
flags)
452 env = &(parser->
env);
459 assert( mdata_vector_is_locked( env ) );
462 assert( mdata_vector_is_locked( env ) );
465 &(strpool[node_test->name_strpool_idx]),
466 &(strpool[token_strpool_idx]),
469 node_out = node_test;
482 const char* token,
size_t token_sz
487 char* strpool = NULL;
491 MLISP_EXEC_FLAG_SHARED_ENV == (MLISP_EXEC_FLAG_SHARED_ENV & exec->
flags)
493 env = &(parser->
env);
498 assert( !mdata_vector_is_locked( env ) );
501 mdata_strpool_lock( &(parser->strpool), strpool );
503 debug_printf( MLISP_TRACE_LVL,
"attempting to undefine %s...", token );
507 assert( mdata_vector_is_locked( env ) );
513 if( MLISP_TYPE_ARGS_E == e->type ) {
514 debug_printf( MLISP_EXEC_TRACE_LVL,
515 "reached end of env stack frame: " SSIZE_T_FMT, i );
520 token, &(strpool[e->name_strpool_idx]), token_sz + 1 )
526 debug_printf( MLISP_EXEC_TRACE_LVL,
527 "found token %s: %s (" SSIZE_T_FMT
"), removing...",
528 token, &(strpool[e->name_strpool_idx]), i );
538 assert( mdata_vector_is_locked( env ) );
541 mdata_strpool_unlock( &(parser->strpool), strpool );
550 const char* token,
size_t token_sz, uint8_t env_type,
const void* data,
551 void* cb_data, uint8_t flags
555 ssize_t new_idx_out = -1;
559 MLISP_EXEC_FLAG_SHARED_ENV == (MLISP_EXEC_FLAG_SHARED_ENV & exec->
flags)
561 debug_printf( MLISP_EXEC_TRACE_LVL,
"using parser env..." );
562 env = &(parser->
env);
564 debug_printf( MLISP_EXEC_TRACE_LVL,
"using exec env..." );
568 assert( NULL != env );
570 if( 0 == token_sz ) {
571 token_sz = maug_strlen( token );
573 assert( 0 < token_sz );
577 retval = mlisp_env_unset( parser, exec, token, token_sz );
578 assert( 0 == retval );
579 maug_cleanup_if_not_ok();
581# define _MLISP_TYPE_TABLE_ASGN( idx, ctype, name, const_name, fmt ) \
583 debug_printf( MLISP_EXEC_TRACE_LVL, \
584 "setting env: \"%s\": #" fmt, \
585 token, (ctype)*((ctype*)data) ); \
586 e.value.name = *((ctype*)data); \
593 mdata_strpool_append( &(parser->strpool), token, token_sz );
594 if( 0 > e.name_strpool_idx ) {
595 retval = mdata_retval( e.name_strpool_idx );
597 maug_cleanup_if_not_ok();
606 debug_printf( MLISP_EXEC_TRACE_LVL,
607 "setting env: \"%s\": strpool(" SSIZE_T_FMT
")",
608 token, *((ssize_t*)data) );
609 e.value.strpool_idx = *((mdata_strpool_idx_t*)data);
613 debug_printf( MLISP_EXEC_TRACE_LVL,
614 "setting env: \"%s\": 0x%p", token, (mlisp_env_cb_t)data );
615 e.value.cb = (mlisp_env_cb_t)data;
619 debug_printf( MLISP_EXEC_TRACE_LVL,
620 "setting env: \"%s\": node #" SSIZE_T_FMT,
621 token, *((mlisp_lambda_t*)data) );
622 e.value.lambda = *((mlisp_lambda_t*)data);
626 debug_printf( MLISP_EXEC_TRACE_LVL,
627 "setting env: \"%s\": node #" SSIZE_T_FMT,
628 token, *((mlisp_args_t*)data) );
629 e.value.args_start = *((mlisp_args_t*)data);
633 debug_printf( MLISP_EXEC_TRACE_LVL,
634 "setting env: \"%s\": node #" SSIZE_T_FMT,
635 token, *((mlisp_arge_t*)data) );
636 e.value.args_end = *((mlisp_arge_t*)data);
640 error_printf(
"attempted to define invalid type: %d", env_type );
641 retval = MERROR_EXEC;
649 debug_printf( MLISP_EXEC_TRACE_LVL,
"env %p has " SIZE_T_FMT
" nodes",
651 if( 0 > new_idx_out ) {
652 retval = mdata_retval( new_idx_out );
654 maug_cleanup_if_not_ok();
656 debug_printf( MLISP_EXEC_TRACE_LVL,
"setup env node " SSIZE_T_FMT
": %s",
657 new_idx_out, token );
666static ssize_t _mlisp_env_get_env_frame(
674 uint8_t autolock = 0;
678 MLISP_EXEC_FLAG_SHARED_ENV == (MLISP_EXEC_FLAG_SHARED_ENV & exec->
flags)
680 env = &(parser->
env);
685 if( !mdata_vector_is_locked( env ) ) {
693 assert( mdata_vector_is_locked( env ) );
697 if( MLISP_TYPE_ARGS_S != e->type ) {
702 debug_printf( MLISP_EXEC_TRACE_LVL,
703 "found initial env arg separator " SSIZE_T_FMT
" with ret: "
705 i, e->value.args_start );
708 if( NULL != e_out ) {
720 if( MERROR_OK != retval ) {
721 ret_idx = retval * -1;
729static ssize_t _mlisp_env_prune_args(
740 MLISP_EXEC_FLAG_SHARED_ENV == (MLISP_EXEC_FLAG_SHARED_ENV & exec->
flags)
742 env = &(parser->
env);
748 assert( !mdata_vector_is_locked( env ) );
755 i = _mlisp_env_get_env_frame( exec, parser, NULL );
756 debug_printf( MLISP_EXEC_TRACE_LVL,
757 "pruning env args starting from env frame " SSIZE_T_FMT
"...", i );
761 while( MLISP_TYPE_ARGS_E != e->type ) {
764 maug_cleanup_if_not_ok();
768 assert( mdata_vector_is_locked( env ) );
778 maug_cleanup_if_not_ok();
781 debug_printf( MLISP_EXEC_TRACE_LVL,
782 "removed " SIZE_T_FMT
" args!", removed );
788 if( MERROR_OK != retval ) {
789 ret_idx = retval * -1;
799 size_t args_c,
void* cb_data, uint8_t flags
803 char* strpool = NULL;
811# define _MLISP_TYPE_TABLE_CMP( idx, ctype, name, const_name, fmt ) \
812 } else if( MLISP_TYPE_ ## const_name == tmp.type ) { \
813 *cur_int = (int)tmp.value.name; \
814 debug_printf( MLISP_EXEC_TRACE_LVL, \
815 "cmp: pop " fmt " (%d)", tmp.value.name, *cur_int );
818 maug_cleanup_if_not_ok();
823 error_printf(
"cmp: invalid type!" );
824 retval = MERROR_EXEC;
829 maug_cleanup_if_not_ok();
834 error_printf(
"cmp: invalid type!" );
835 retval = MERROR_EXEC;
842 debug_printf( MLISP_EXEC_TRACE_LVL,
"cmp %d > %d", a_int, b_int );
843 truth = a_int > b_int;
845 debug_printf( MLISP_EXEC_TRACE_LVL,
"cmp %d < %d", a_int, b_int );
846 truth = a_int < b_int;
848 debug_printf( MLISP_EXEC_TRACE_LVL,
"cmp %d == %d", a_int, b_int );
849 truth = a_int == b_int;
851 error_printf(
"invalid parameter provided to _mlisp_env_cb_cmp()!" );
852 retval = MERROR_EXEC;
860 mdata_strpool_unlock( &(parser->strpool), strpool );
870 size_t args_c,
void* cb_data, uint8_t flags
874 char* strpool = NULL;
879# define _MLISP_TYPE_TABLE_ARI1( idx, ctype, name, const_name, fmt ) \
880 } else if( MLISP_TYPE_ ## const_name == num.type ) { \
881 num_out = num.value.name;
884 maug_cleanup_if_not_ok();
889 error_printf(
"arithmetic: invalid type!" );
890 retval = MERROR_EXEC;
894# define _MLISP_TYPE_TABLE_ARI2( idx, ctype, name, const_name, fmt ) \
896 MLISP_TYPE_ ## const_name == num.type && \
897 MLISP_ENV_FLAG_ARI_ADD == (MLISP_ENV_FLAG_ARI_ADD & flags) \
899 debug_printf( MLISP_EXEC_TRACE_LVL, \
900 "arithmetic: %d + " fmt, num_out, num.value.name ); \
901 num_out += num.value.name; \
903 MLISP_TYPE_ ## const_name == num.type && \
904 MLISP_ENV_FLAG_ARI_MUL == (MLISP_ENV_FLAG_ARI_MUL & flags) \
906 debug_printf( MLISP_EXEC_TRACE_LVL, \
907 "arithmetic: %d * " fmt, num_out, num.value.name ); \
908 num_out *= num.value.name; \
910 MLISP_TYPE_ ## const_name == num.type && \
911 MLISP_ENV_FLAG_ARI_DIV == (MLISP_ENV_FLAG_ARI_DIV & flags) \
913 debug_printf( MLISP_EXEC_TRACE_LVL, \
914 "arithmetic: %d / " fmt, num_out, num.value.name ); \
915 num_out /= num.value.name; \
917 for( i = 0 ; args_c - 1 > i ; i++ ) {
919 maug_cleanup_if_not_ok();
925 MLISP_TYPE_INT == num.type &&
926 MLISP_ENV_FLAG_ARI_MOD == (MLISP_ENV_FLAG_ARI_MOD & flags)
929 debug_printf( MLISP_EXEC_TRACE_LVL,
930 "arithmetic: %d %% %d", num_out, num.value.integer );
931 num_out %= num.value.integer;
933 error_printf(
"arithmetic: invalid type!" );
934 retval = MERROR_EXEC;
939 debug_printf( MLISP_EXEC_TRACE_LVL,
"arithmetic result: %d", num_out );
945 mdata_strpool_unlock( &(parser->strpool), strpool );
954 size_t args_c,
void* cb_data, uint8_t flags
959 MAUG_MHANDLE key_tmp_h = NULL;
960 char* key_tmp = NULL;
963 maug_cleanup_if_not_ok();
966 maug_cleanup_if_not_ok();
968 if( MLISP_TYPE_STR != key.type ) {
971 error_printf(
"define: invalid key type: %d", key.type );
972 retval = MERROR_EXEC;
976 key_tmp_h = mdata_strpool_extract(
977 &(parser->strpool), key.value.strpool_idx );
979 assert( NULL != key_tmp_h );
981 maug_mlock( key_tmp_h, key_tmp );
982 maug_cleanup_if_null_lock(
char*, key_tmp );
984 debug_printf( MLISP_EXEC_TRACE_LVL,
985 "define \"%s\" (strpool(" SIZE_T_FMT
"))...",
986 key_tmp, key.value.strpool_idx );
988 retval = mlisp_env_set(
989 parser, exec, key_tmp, 0, val.type, &(val.value), NULL, 0 );
993 if( NULL != key_tmp ) {
994 maug_munlock( key_tmp_h, key_tmp );
997 if( NULL != key_tmp_h ) {
998 maug_mfree( key_tmp_h );
1008 size_t args_c,
void* cb_data, uint8_t flags
1011 size_t* p_if_child_idx = NULL;
1015 debug_printf( MLISP_EXEC_TRACE_LVL,
"qrqrqrqrqr STEP IF qrqrqrqrqr" );
1019 p_if_child_idx = mdata_vector_get(
1021 assert( NULL != p_if_child_idx );
1022 debug_printf( MLISP_EXEC_TRACE_LVL,
1023 "child idx for if AST node " SIZE_T_FMT
": " SIZE_T_FMT,
1024 n_idx, *p_if_child_idx );
1026 n = mdata_vector_get( &(parser->ast), n_idx,
struct MLISP_AST_NODE );
1028 if( 0 == *p_if_child_idx ) {
1030 debug_printf( MLISP_EXEC_TRACE_LVL,
"stepping into condition..." );
1031 retval = _mlisp_step_iter(
1032 parser, n->ast_idx_children[*p_if_child_idx], exec );
1033 debug_printf( MLISP_EXEC_TRACE_LVL,
"...stepped out of condition" );
1036 if( MERROR_OK == retval ) {
1041 maug_cleanup_if_not_ok();
1042 if( MLISP_TYPE_BOOLEAN != s.type ) {
1043 error_printf(
"(if) can only evaluate boolean type!" );
1044 retval = MERROR_EXEC;
1049 retval = _mlisp_preempt(
1050 "if", parser, n_idx, exec, p_if_child_idx,
1052 (1 - s.value.boolean) + 1 );
1055 }
else if( args_c > *p_if_child_idx ) {
1058 debug_printf( MLISP_EXEC_TRACE_LVL,
1059 "descending into IF path: " SIZE_T_FMT, *p_if_child_idx );
1064 retval = _mlisp_step_iter(
1065 parser, n->ast_idx_children[*p_if_child_idx], exec );
1066 if( MERROR_OK == retval ) {
1067 retval = _mlisp_preempt(
1068 "if", parser, n_idx, exec, p_if_child_idx, 3 );
1074 debug_printf( MLISP_EXEC_TRACE_LVL,
"qrqrqrqrqr END STEP IF qrqrqrqrqr" );
1083 size_t args_c,
void* cb_data, uint8_t flags
1087 int16_t random_int = 0;
1090 maug_cleanup_if_not_ok();
1092 if( MLISP_TYPE_INT != mod.type ) {
1094 error_printf(
"random: invalid modulus type: %d", mod.type );
1095 retval = MERROR_EXEC;
1099 random_int = retroflat_get_rand() % mod.value.integer;
1101 debug_printf( MLISP_EXEC_TRACE_LVL,
"random: %d", random_int );
1114 size_t args_c,
void* cb_data, uint8_t flags
1118 mlisp_bool_t val_out =
1119 MLISP_ENV_FLAG_ANO_OR == (MLISP_ENV_FLAG_ANO_OR & flags) ?
1127 for( i = 0 ; args_c > i ; i++ ) {
1129 maug_cleanup_if_not_ok();
1131 if( MLISP_TYPE_BOOLEAN != val.type ) {
1132 error_printf(
"or: invalid boolean type: %d", val.type );
1135 if( val.value.boolean ) {
1136 debug_printf( MLISP_EXEC_TRACE_LVL,
"found TRUE in %s!",
1137 MLISP_ENV_FLAG_ANO_OR == (MLISP_ENV_FLAG_ANO_OR & flags) ?
1140 MLISP_ENV_FLAG_ANO_OR == (MLISP_ENV_FLAG_ANO_OR & flags) ? 1 : 0;
1144 retval = _mlisp_stack_push_mlisp_bool_t( exec, val_out );
1164 char* strpool = NULL;
1167 n = mdata_vector_get( &(parser->ast), n_idx,
struct MLISP_AST_NODE );
1169 mdata_strpool_lock( &(parser->strpool), strpool );
1170 assert( 0 < maug_strlen( &(strpool[n->token_idx]) ) );
1171 debug_printf( MLISP_EXEC_TRACE_LVL,
1172 "eval step " SSIZE_T_FMT
" under (%s) %s...",
1173 *p_child_idx, caller, &(strpool[n->token_idx]) );
1174 mdata_strpool_unlock( &(parser->strpool), strpool );
1177 (*p_child_idx) = new_idx;
1178 debug_printf( MLISP_EXEC_TRACE_LVL,
1179 "incremented " SIZE_T_FMT
" child idx to: " SIZE_T_FMT,
1180 n_idx, *p_child_idx );
1184 assert( NULL == strpool );
1195 size_t* p_child_idx = NULL;
1200 p_child_idx = mdata_vector_get(
1202 assert( NULL != p_child_idx );
1203 debug_printf( MLISP_EXEC_TRACE_LVL,
1204 "child idx for AST node " SIZE_T_FMT
": " SIZE_T_FMT,
1205 n_idx, *p_child_idx );
1207 n = mdata_vector_get( &(parser->ast), n_idx,
struct MLISP_AST_NODE );
1211 MLISP_AST_FLAG_LAMBDA == (MLISP_AST_FLAG_LAMBDA & n->flags) &&
1214 MLISP_AST_FLAG_IF == (MLISP_AST_FLAG_IF & n->flags)
1223 debug_printf( MLISP_EXEC_TRACE_LVL,
"skipping lambda children..." );
1227 if( mlisp_ast_has_ready_children( *p_child_idx, n ) ) {
1231 MLISP_AST_FLAG_DEFINE == (MLISP_AST_FLAG_DEFINE & n->flags) &&
1235 debug_printf( MLISP_EXEC_TRACE_LVL,
1236 "setting MLISP_EXEC_FLAG_DEF_TERM!" );
1237 exec->
flags |= MLISP_EXEC_FLAG_DEF_TERM;
1239 exec->
flags &= ~MLISP_EXEC_FLAG_DEF_TERM;
1243 retval = _mlisp_step_iter(
1244 parser, n->ast_idx_children[*p_child_idx], exec );
1245 if( MERROR_OK == retval ) {
1246 retval = _mlisp_preempt(
1247 "node", parser, n_idx, exec, p_child_idx, (*p_child_idx) + 1 );
1256 debug_printf( MDATA_TRACE_LVL,
1257 "resetting node " SIZE_T_FMT
" child pointer to 0...",
1274 ssize_t arg_idx = 0;
1277 MAUG_MHANDLE key_tmp_h = NULL;
1278 char* key_tmp = NULL;
1287 n = mdata_vector_get( &(parser->ast), n_idx,
struct MLISP_AST_NODE );
1290 while( 0 <= arg_idx ) {
1293 maug_cleanup_if_not_ok();
1295 ast_n_arg = mdata_vector_get(
1296 &(parser->ast), n->ast_idx_children[arg_idx],
1300 key_tmp_h = mdata_strpool_extract(
1301 &(parser->strpool), ast_n_arg->token_idx );
1303 assert( NULL != key_tmp_h );
1305 maug_mlock( key_tmp_h, key_tmp );
1306 maug_cleanup_if_null_lock(
char*, key_tmp );
1308 retval = mlisp_env_set(
1309 parser, exec, key_tmp, 0, stack_n_arg.type, &(stack_n_arg.value),
1311 maug_cleanup_if_not_ok();
1313 maug_munlock( key_tmp_h, key_tmp );
1314 maug_mfree( key_tmp_h );
1321 if( NULL != key_tmp ) {
1322 maug_munlock( key_tmp_h, key_tmp );
1325 if( NULL != key_tmp_h ) {
1326 maug_mfree( key_tmp_h );
1339 size_t* p_child_idx = NULL;
1340 size_t* p_visit_ct = NULL;
1345 assert( mdata_vector_is_locked( &(parser->ast) ) );
1348 debug_printf( MLISP_TRACE_LVL,
"resetting PC on node: " SIZE_T_FMT, n_idx );
1350 assert( NULL != p_child_idx );
1353 debug_printf( MLISP_TRACE_LVL,
1354 "resetting visit count on node: " SIZE_T_FMT, n_idx );
1356 assert( NULL != p_visit_ct );
1359 n = mdata_vector_get( &(parser->ast), n_idx,
struct MLISP_AST_NODE );
1363 retval = _mlisp_reset_child_pcs( parser, n->ast_idx_children[i], exec );
1364 maug_cleanup_if_not_ok();
1379 ssize_t ret_idx = 0;
1383 MLISP_EXEC_FLAG_SHARED_ENV == (MLISP_EXEC_FLAG_SHARED_ENV & exec->
flags)
1385 env = &(parser->
env);
1390 debug_printf( MLISP_EXEC_TRACE_LVL,
1391 "resetting lambda " SIZE_T_FMT
"...", n_idx );
1394 assert( !mdata_vector_is_locked( env ) );
1397 ret_idx = _mlisp_env_prune_args( exec, parser );
1399 retval = ret_idx * -1;
1401 maug_cleanup_if_not_ok();
1404 retval = _mlisp_reset_child_pcs( parser, n_idx, exec );
1419 size_t* p_lambda_child_idx = NULL;
1420 size_t* p_args_child_idx = NULL;
1422 size_t* p_n_last_lambda = NULL;
1423 ssize_t append_retval = 0;
1425#ifdef MLISP_DEBUG_TRACE
1426 exec->trace[exec->trace_depth++] = n_idx;
1427 assert( exec->trace_depth <= MLISP_DEBUG_TRACE );
1432 p_n_last_lambda = mdata_vector_get_last( &(exec->
lambda_trace),
size_t );
1434 if( NULL != p_n_last_lambda && n_idx == *p_n_last_lambda ) {
1438 debug_printf( MLISP_EXEC_TRACE_LVL,
"TRACE TAIL TIME!" );
1439 _mlisp_reset_lambda( parser, n_idx, exec );
1440 retval = mdata_vector_remove_last( &(exec->
lambda_trace) );
1441 maug_cleanup_if_not_ok();
1444 debug_printf( MLISP_EXEC_TRACE_LVL,
1445 "xvxvxvxvxvxvx STEP LAMBDA " SIZE_T_FMT
" xvxvxvxvxvx", n_idx );
1448 append_retval = mdata_vector_append(
1450 retval = mdata_retval( append_retval );
1451 maug_cleanup_if_not_ok();
1455 p_lambda_child_idx = mdata_vector_get(
1457 assert( NULL != p_lambda_child_idx );
1458 debug_printf( MLISP_EXEC_TRACE_LVL,
1459 "child idx for lambda AST node " SIZE_T_FMT
": " SIZE_T_FMT,
1460 n_idx, *p_lambda_child_idx );
1462 n = mdata_vector_get( &(parser->ast), n_idx,
struct MLISP_AST_NODE );
1468 if( 0 == *p_lambda_child_idx ) {
1473 p_args_child_idx = mdata_vector_get(
1475 n->ast_idx_children[*p_lambda_child_idx],
size_t );
1476 assert( NULL != p_args_child_idx );
1477 debug_printf( MLISP_EXEC_TRACE_LVL,
1478 "child idx for args AST node " SIZE_T_FMT
": " SIZE_T_FMT,
1479 *p_lambda_child_idx, *p_args_child_idx );
1481 if( 0 == *p_args_child_idx ) {
1484 retval = mlisp_env_set(
1485 parser, exec,
"$ARGS_S$", 0, MLISP_TYPE_ARGS_S, &n_idx, NULL, 0 );
1486 maug_cleanup_if_not_ok();
1490 retval = _mlisp_step_lambda_args(
1491 parser, n->ast_idx_children[*p_lambda_child_idx], exec );
1492 if( MERROR_OK != retval && MERROR_PREEMPT != retval ) {
1497 if( MERROR_OK == retval ) {
1499 retval = mlisp_env_set(
1500 parser, exec,
"$ARGS_E$", 0, MLISP_TYPE_ARGS_E, &n_idx, NULL, 0 );
1501 maug_cleanup_if_not_ok();
1504 (*p_lambda_child_idx)++;
1505 debug_printf( MLISP_EXEC_TRACE_LVL,
1506 "incremented " SIZE_T_FMT
" child idx to: " SIZE_T_FMT,
1507 n_idx, *p_lambda_child_idx );
1513 retval = MERROR_PREEMPT;
1515 }
else if( mlisp_ast_has_ready_children( *p_lambda_child_idx, n ) ) {
1518 retval = _mlisp_step_iter(
1519 parser, n->ast_idx_children[*p_lambda_child_idx], exec );
1521 if( MERROR_OK == retval ) {
1522 retval = _mlisp_preempt(
1523 "lambda", parser, n_idx, exec, p_lambda_child_idx,
1524 (*p_lambda_child_idx) + 1 );
1529 _mlisp_reset_lambda( parser, n_idx, exec );
1536 debug_printf( MLISP_EXEC_TRACE_LVL,
1537 "xvxvxvxvxvxvx END STEP LAMBDA " SIZE_T_FMT
" xvxvxvxvxvx", n_idx );
1557 i = mdata_vector_ct( &(exec->
stack) ) - 1;
1561 maug_cleanup_if_not_ok();
1563 if( MLISP_TYPE_BEGIN == o.type && n_idx == o.value.begin ) {
1581 uint8_t autolock = 0;
1582 char* strpool = NULL;
1588 MLISP_EXEC_FLAG_SHARED_ENV == (MLISP_EXEC_FLAG_SHARED_ENV & exec->
flags)
1590 env = &(parser->
env);
1595 if( !mdata_vector_is_locked( env ) ) {
1596 assert( env->
data_h != NULL );
1601 mdata_strpool_lock( &(parser->strpool), strpool );
1603 assert( 0 < maug_strlen( &(strpool[token_idx]) ) );
1605 debug_printf( MLISP_EXEC_TRACE_LVL,
1606 "eval token: \"%s\" (maug_strlen: " SIZE_T_FMT
")",
1607 &(strpool[token_idx]), maug_strlen( &(strpool[token_idx]) ) );
1608 if( 0 == strncmp( &(strpool[token_idx]),
"begin", token_sz ) ) {
1610 e_out->type = MLISP_TYPE_BEGIN;
1613 parser, exec, strpool, token_idx, token_sz
1616 debug_printf( MLISP_EXEC_TRACE_LVL,
"found %s in env!",
1617 &(strpool[p_e->name_strpool_idx]) );
1624 }
else if( maug_is_num( &(strpool[token_idx]), token_sz, 10, 1 ) ) {
1626 e_out->value.integer =
1628 e_out->type = MLISP_TYPE_INT;
1630 }
else if( maug_is_float( &(strpool[token_idx]), token_sz ) ) {
1632 e_out->value.floating = maug_atof( &(strpool[token_idx]), token_sz );
1633 e_out->type = MLISP_TYPE_FLOAT;
1643 mdata_strpool_unlock( &(parser->strpool), strpool );
1655 size_t* p_visit_ct = NULL;
1657#ifdef MLISP_DEBUG_TRACE
1658 exec->trace[exec->trace_depth++] = n_idx;
1659 assert( exec->trace_depth <= MLISP_DEBUG_TRACE );
1662 n = mdata_vector_get( &(parser->ast), n_idx,
struct MLISP_AST_NODE );
1665 p_visit_ct = mdata_vector_get(
1667 assert( NULL != p_visit_ct );
1669 debug_printf( MLISP_EXEC_TRACE_LVL,
1670 "visit count for AST node " SIZE_T_FMT
": " SIZE_T_FMT,
1671 n_idx, *p_visit_ct );
1675 MLISP_AST_FLAG_BEGIN == (MLISP_AST_FLAG_BEGIN & n->flags) &&
1679 retval = _mlisp_stack_push_mlisp_begin_t( exec, n_idx );
1680 maug_cleanup_if_not_ok();
1685 (retval = _mlisp_step_iter_children( parser, n_idx, exec ))
1691 if( MLISP_AST_FLAG_LAMBDA == (MLISP_AST_FLAG_LAMBDA & n->flags) ) {
1706 retval = _mlisp_eval_token_strpool(
1707 parser, exec, n->token_idx, n->token_sz, &e );
1708 maug_cleanup_if_not_ok();
1713# define _MLISP_TYPE_TABLE_ENVE( idx, ctype, name, const_name, fmt ) \
1714 } else if( MLISP_TYPE_ ## const_name == e.type ) { \
1715 retval = _mlisp_stack_push_ ## ctype( exec, e.value.name ); \
1716 maug_cleanup_if_not_ok();
1718 if( MLISP_EXEC_FLAG_DEF_TERM == (MLISP_EXEC_FLAG_DEF_TERM & exec->
flags) ) {
1722 debug_printf( MLISP_EXEC_TRACE_LVL,
1723 "special case! pushing literal to define: " SSIZE_T_FMT,
1725 retval = _mlisp_stack_push_mdata_strpool_idx_t( exec, n->token_idx );
1726 maug_cleanup_if_not_ok();
1727 }
else if( MLISP_TYPE_BEGIN == e.type ) {
1731 retval = _mlisp_stack_cleanup( parser, n_idx, exec );
1733 }
else if( MLISP_TYPE_CB == e.type ) {
1738 retval = e.value.cb(
1741 }
else if( MLISP_TYPE_LAMBDA == e.type ) {
1747 retval = _mlisp_step_lambda( parser, e.value.lambda, exec );
1751 retval = _mlisp_stack_push_mdata_strpool_idx_t( exec, n->token_idx );
1752 maug_cleanup_if_not_ok();
1780 error_printf(
"no valid AST present; could not exec!" );
1781 retval = MERROR_EXEC;
1794 MLISP_EXEC_FLAG_INITIALIZED != (exec->
flags & MLISP_EXEC_FLAG_INITIALIZED)
1796 retval = MERROR_EXEC;
1811#ifdef MLISP_DEBUG_TRACE
1813 char trace_str[MLISP_DEBUG_TRACE * 5];
1814 maug_ms_t ms_start = 0;
1815 maug_ms_t ms_end = 0;
1817 ms_start = retroflat_get_ms();
1820 debug_printf( MLISP_EXEC_TRACE_LVL,
"heartbeat start" );
1827 assert( !mdata_vector_is_locked( &(parser->ast) ) );
1830 mdata_vector_lock( &(parser->ast) );
1833 exec->
flags &= MLISP_EXEC_FLAG_TRANSIENT_MASK;
1834 assert( 0 == mdata_vector_ct( &(exec->
lambda_trace) ) );
1836#ifdef MLISP_DEBUG_TRACE
1837 exec->trace_depth = 0;
1841 retval = _mlisp_step_iter( parser, 0, exec );
1842 if( MERROR_PREEMPT == retval ) {
1845 }
else if( MERROR_OK == retval ) {
1847 debug_printf( MLISP_EXEC_TRACE_LVL,
"execution terminated successfully" );
1848 retval = MERROR_EXEC;
1850 debug_printf( MLISP_EXEC_TRACE_LVL,
1851 "execution terminated with retval: %d", retval );
1854#ifdef MLISP_DEBUG_TRACE
1855 ms_end = retroflat_get_ms();
1857 maug_mzero( trace_str, MLISP_DEBUG_TRACE * 5 );
1858 for( i = 0 ; exec->trace_depth > i ; i++ ) {
1860 &(trace_str[maug_strlen( trace_str )]),
1861 (MLISP_DEBUG_TRACE * 5) - maug_strlen( trace_str ),
1862 SIZE_T_FMT
", ", exec->trace[i] );
1864 debug_printf( MLISP_EXEC_TRACE_LVL,
1865 MLISP_TRACE_SIGIL
" HBEXEC (%u): %s",
1866 ms_end - ms_start, trace_str );
1871 debug_printf( MLISP_EXEC_TRACE_LVL,
"heartbeat end: %x", retval );
1873 assert( mdata_vector_is_locked( &(parser->ast) ) );
1874 mdata_vector_unlock( &(parser->ast) );
1889 uint8_t autolock = 0;
1891 mlisp_lambda_t lambda_idx = 0;
1895 MLISP_EXEC_FLAG_SHARED_ENV == (MLISP_EXEC_FLAG_SHARED_ENV & exec->
flags)
1897 env = &(parser->
env);
1902 if( MERROR_OK != mlisp_check_state( parser, exec ) ) {
1903 error_printf(
"mlisp not ready!" );
1904 retval = MERROR_EXEC;
1910 if( !mdata_vector_is_locked( env ) ) {
1911 assert( env->
data_h != NULL );
1923 if( !mdata_vector_is_locked( &(parser->ast) ) ) {
1929 e = mlisp_env_get( parser, exec, lambda );
1931 error_printf(
"lambda \"%s\" not found!", lambda );
1932 retval = MERROR_OVERFLOW;
1935 lambda_idx = e->value.lambda;
1940 if( 0x01 == (0x01 & autolock) ) {
1945 debug_printf( MLISP_EXEC_TRACE_LVL,
"lambda \"%s\" is AST node idx %ld",
1946 lambda, lambda_idx );
1949 retval = _mlisp_step_lambda( parser, lambda_idx, exec );
1954 if( 0x01 == (0x01 & autolock) ) {
1957 if( 0x02 == (0x02 & autolock) ) {
1960 if( 0x04 == (0x04 & autolock) ) {
1963 if( 0x08 == (0x08 & autolock) ) {
1976 ssize_t append_retval = 0;
1979 assert( 0 == exec->
flags );
1983 exec->
flags = flags;
1988 if( 0 > append_retval ) {
1989 retval = mdata_retval( append_retval );
1991 maug_cleanup_if_not_ok();
1999 MLISP_EXEC_FLAG_SHARED_ENV == (MLISP_EXEC_FLAG_SHARED_ENV & exec->
flags)
2009 if( 0 > append_retval ) {
2010 retval = mdata_retval( append_retval );
2012 maug_cleanup_if_not_ok();
2017 if( 0 > append_retval ) {
2018 retval = mdata_retval( append_retval );
2020 maug_cleanup_if_not_ok();
2029 if( 0 > append_retval ) {
2030 retval = mdata_retval( append_retval );
2032 maug_cleanup_if_not_ok();
2038 if( 0 > append_retval ) {
2039 retval = mdata_retval( append_retval );
2041 maug_cleanup_if_not_ok();
2050 if( 0 > append_retval ) {
2051 retval = mdata_retval( append_retval );
2053 maug_cleanup_if_not_ok();
2056 exec->
flags |= MLISP_EXEC_FLAG_INITIALIZED;
2061 MLISP_EXEC_FLAG_SHARED_ENV == (MLISP_EXEC_FLAG_SHARED_ENV & flags) &&
2064 debug_printf( MLISP_EXEC_TRACE_LVL,
"skipping initialized environment!" );
2068 retval = mlisp_env_set(
2069 parser, exec,
"and", 2, MLISP_TYPE_CB, _mlisp_env_cb_ano,
2070 NULL, MLISP_ENV_FLAG_BUILTIN | MLISP_ENV_FLAG_ANO_AND );
2071 maug_cleanup_if_not_ok();
2072 retval = mlisp_env_set(
2073 parser, exec,
"or", 2, MLISP_TYPE_CB, _mlisp_env_cb_ano,
2074 NULL, MLISP_ENV_FLAG_BUILTIN | MLISP_ENV_FLAG_ANO_OR );
2075 maug_cleanup_if_not_ok();
2076 retval = mlisp_env_set(
2077 parser, exec,
"random", 6, MLISP_TYPE_CB, _mlisp_env_cb_random,
2078 NULL, MLISP_ENV_FLAG_BUILTIN );
2079 maug_cleanup_if_not_ok();
2080 retval = mlisp_env_set(
2081 parser, exec,
"if", 2, MLISP_TYPE_CB, _mlisp_env_cb_if,
2082 NULL, MLISP_ENV_FLAG_BUILTIN );
2083 maug_cleanup_if_not_ok();
2084 retval = mlisp_env_set(
2085 parser, exec,
"define", 6, MLISP_TYPE_CB, _mlisp_env_cb_define,
2086 NULL, MLISP_ENV_FLAG_BUILTIN );
2087 maug_cleanup_if_not_ok();
2088 retval = mlisp_env_set(
2089 parser, exec,
"*", 1, MLISP_TYPE_CB, _mlisp_env_cb_arithmetic,
2091 maug_cleanup_if_not_ok();
2092 retval = mlisp_env_set(
2093 parser, exec,
"+", 1, MLISP_TYPE_CB, _mlisp_env_cb_arithmetic,
2095 maug_cleanup_if_not_ok();
2096 retval = mlisp_env_set(
2097 parser, exec,
"/", 1, MLISP_TYPE_CB, _mlisp_env_cb_arithmetic,
2098 NULL, MLISP_ENV_FLAG_BUILTIN | MLISP_ENV_FLAG_ARI_DIV );
2099 maug_cleanup_if_not_ok();
2100 retval = mlisp_env_set(
2101 parser, exec,
"%", 1, MLISP_TYPE_CB, _mlisp_env_cb_arithmetic,
2102 NULL, MLISP_ENV_FLAG_BUILTIN | MLISP_ENV_FLAG_ARI_MOD );
2103 maug_cleanup_if_not_ok();
2104 retval = mlisp_env_set(
2105 parser, exec,
"<", 1, MLISP_TYPE_CB, _mlisp_env_cb_cmp,
2107 maug_cleanup_if_not_ok();
2108 retval = mlisp_env_set(
2109 parser, exec,
">", 1, MLISP_TYPE_CB, _mlisp_env_cb_cmp,
2111 maug_cleanup_if_not_ok();
2112 retval = mlisp_env_set(
2113 parser, exec,
"=", 1, MLISP_TYPE_CB, _mlisp_env_cb_cmp,
2115 maug_cleanup_if_not_ok();
2119 if( MERROR_OK != retval ) {
2120 error_printf(
"mlisp exec initialization failed: %d", retval );
2129 debug_printf( MLISP_EXEC_TRACE_LVL,
2130 "destroying exec (stack: " SIZE_T_FMT
", env: " SIZE_T_FMT
")...",
2134 mdata_vector_free( &(exec->
stack) );
2135 mdata_vector_free( &(exec->
env) );
2138 debug_printf( MLISP_EXEC_TRACE_LVL,
"exec destroyed!" );
2143# define MLISP_PSTATE_TABLE_CONST( name, idx ) \
2144 extern MAUG_CONST uint8_t SEG_MCONST name;
2146MLISP_PARSER_PSTATE_TABLE( MLISP_PSTATE_TABLE_CONST )
2148#ifdef MPARSER_TRACE_NAMES
2149extern MAUG_CONST
char* SEG_MCONST gc_mlisp_pstate_names[];
int MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition merror.h:19
#define maug_mzero(ptr, sz)
Zero the block of memory pointed to by ptr.
Definition mmem.h:62
int32_t maug_atos32(const char *buffer, size_t buffer_sz)
#define mdata_vector_lock(v)
Lock the vector. This should be done when items from the vector are actively being referenced,...
Definition mdata.h:241
#define mdata_vector_unlock(v)
Unlock the vector so items may be added and removed.
Definition mdata.h:261
#define MDATA_VECTOR_INIT_SZ
Default initial value for MDATA_VECTOR::ct_max.
Definition mdata.h:37
ssize_t mdata_vector_append(struct MDATA_VECTOR *v, const void *item, size_t item_sz)
Append an item to the specified vector.
MERROR_RETVAL mdata_vector_remove(struct MDATA_VECTOR *v, size_t idx)
Remove item at the given index, shifting subsequent items up by 1.
#define mdata_vector_ct(v)
Number of items of MDATA_VECTOR::item_sz bytes actively stored in this vector.
Definition mdata.h:295
MERROR_RETVAL mdata_vector_alloc(struct MDATA_VECTOR *v, size_t item_sz, size_t item_ct_init)
#define mlisp_check_ast(parser)
Macro to check if a parser contains a valid AST ready to be executed.
Definition mlispp.h:77
MERROR_RETVAL mlisp_stack_pop(struct MLISP_EXEC_STATE *exec, struct MLISP_STACK_NODE *o)
Pop a value off of (removing from) MLISP_EXEC_STATE::stack and copy it to a provided output.
#define mlisp_stack_push(exec, i, ctype)
Push a value onto MLISP_EXEC_STATE::stack.
Definition mlispe.h:61
#define MLISP_TYPE_TABLE(f)
Table of other types.
Definition mlisps.h:80
#define MLISP_NUM_TYPE_TABLE(f)
Table of numeric types.
Definition mlisps.h:70
#define MLISP_ENV_FLAG_CMP_GT
Flag for _mlisp_env_cb_cmp() specifying TRUE if A > B.
Definition mlispe.h:26
#define MLISP_ENV_FLAG_ARI_MUL
Flag for _mlisp_env_cb_arithmetic() specifying to multiply A * B.
Definition mlispe.h:38
MERROR_RETVAL mlisp_step(struct MLISP_PARSER *parser, struct MLISP_EXEC_STATE *exec)
Iterate the current exec_state() starting from the next MLISP_AST_NODE to be executed according to th...
#define MLISP_ENV_FLAG_ARI_ADD
Flag for _mlisp_env_cb_arithmetic() specifying to add A + B.
Definition mlispe.h:35
#define MLISP_ENV_FLAG_CMP_EQ
Flag for _mlisp_env_cb_cmp() specifying TRUE if A == B.
Definition mlispe.h:32
MERROR_RETVAL mlisp_step_lambda(struct MLISP_PARSER *parser, struct MLISP_EXEC_STATE *exec, const char *lambda)
Iterate the current exec_state() starting from the lambda named.
#define MLISP_ENV_FLAG_CMP_LT
Flag for _mlisp_env_cb_cmp() specifying TRUE if A < B.
Definition mlispe.h:29
struct MLISP_ENV_NODE * mlisp_env_get_strpool(struct MLISP_PARSER *parser, struct MLISP_EXEC_STATE *exec, const char *strpool, size_t token_strpool_idx, size_t token_strpool_sz)
Get a node from the environment denoted by a string in the strpool.
MLISP Interpreter/Parser Structs.
A vector of uniformly-sized objects, stored contiguously.
Definition mdata.h:89
MAUG_MHANDLE data_h
Handle for allocated items (unlocked).
Definition mdata.h:92
size_t ast_idx_children_sz
Number of children in MLISP_AST_NODE::ast_idx_children.
Definition mlisps.h:126
Current execution state to associate with a MLISP_PARSER.
Definition mlisps.h:136
struct MDATA_VECTOR lambda_trace
Path through any lambdas the execution has entered during this heartbeat cycle. Used to detect tail c...
Definition mlisps.h:161
struct MDATA_VECTOR per_node_child_idx
The hild index that will be visited on next visit of each node.
Definition mlisps.h:147
struct MDATA_VECTOR per_node_visit_ct
The number of times each node has been visited ever.
Definition mlisps.h:140
struct MDATA_VECTOR stack
A stack of data values resulting from evaluating statements.
Definition mlisps.h:149
uint8_t flags
Flags which dictate the behavior of this object.
Definition mlisps.h:138
struct MDATA_VECTOR env
Environment in which statements are defined if ::MLISP_.
Definition mlisps.h:156
struct MDATA_VECTOR env
Definitions to use if ::MLISP_EXEC_FLAG_DEF_TERM is defined on the accompanying MLISP_EXEC_STATE::fla...
Definition mlisps.h:177