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 ))
90 const char* strpool,
size_t token_strpool_idx,
size_t token_strpool_sz );
94 const char* token,
size_t token_sz );
98 const char* token,
size_t token_sz, uint8_t env_type,
const void* data,
99 void* cb_data, uint8_t flags );
104#define _MLISP_TYPE_TABLE_PUSH_PROTO( idx, ctype, name, const_name, fmt ) \
105 MERROR_RETVAL _mlisp_stack_push_ ## ctype( \
106 struct MLISP_EXEC_STATE* exec, ctype i );
112#define mlisp_ast_has_ready_children( exec_child_idx, n ) \
113 ((exec_child_idx) < (n)->ast_idx_children_sz)
137 char* strpool = NULL;
140# define _MLISP_TYPE_TABLE_DUMPS( idx, ctype, name, const_name, fmt ) \
141 } else if( MLISP_TYPE_ ## const_name == n_stack->type ) { \
142 debug_printf( MLISP_EXEC_TRACE_LVL, \
143 MLISP_TRACE_SIGIL " stack " SIZE_T_FMT " (" #const_name "): " fmt, \
144 i, n_stack->value.name );
146 mdata_vector_lock( &(exec->
stack) );
147 mdata_strpool_lock( &(parser->strpool), strpool ); \
148 while( i < mdata_vector_ct( &(exec->
stack) ) ) {
152 if( MLISP_TYPE_STR == n_stack->type ) {
153 debug_printf( MLISP_EXEC_TRACE_LVL,
154 MLISP_TRACE_SIGIL
" stack " SIZE_T_FMT
" (STR): %s",
155 i, &(strpool[n_stack->value.strpool_idx]) );
157 }
else if( MLISP_TYPE_CB == n_stack->type ) {
158 debug_printf( MLISP_EXEC_TRACE_LVL,
159 MLISP_TRACE_SIGIL
" stack " SIZE_T_FMT
" (CB): %p",
160 i, n_stack->value.cb );
162 }
else if( MLISP_TYPE_LAMBDA == n_stack->type ) {
163 debug_printf( MLISP_EXEC_TRACE_LVL,
164 MLISP_TRACE_SIGIL
" stack " SIZE_T_FMT
" (LAMBDA): " SIZE_T_FMT,
165 i, n_stack->value.lambda );
167 }
else if( MLISP_TYPE_ARGS_S == n_stack->type ) {
168 debug_printf( MLISP_EXEC_TRACE_LVL,
169 MLISP_TRACE_SIGIL
" stack " SIZE_T_FMT
" (ARGS_S): " SIZE_T_FMT,
170 i, n_stack->value.args_start );
172 }
else if( MLISP_TYPE_ARGS_E == n_stack->type ) {
173 debug_printf( MLISP_EXEC_TRACE_LVL,
174 MLISP_TRACE_SIGIL
" stack " SIZE_T_FMT
" (ARGS_E): " SIZE_T_FMT,
175 i, n_stack->value.args_end );
177 }
else if( MLISP_TYPE_BEGIN == n_stack->type ) {
178 debug_printf( MLISP_EXEC_TRACE_LVL,
179 MLISP_TRACE_SIGIL
" stack " SIZE_T_FMT
" (BEGIN): " SIZE_T_FMT,
180 i, n_stack->value.begin );
185 error_printf(
"invalid stack type: %u", n_stack->type );
189 mdata_strpool_unlock( &(parser->strpool), strpool );
190 mdata_vector_unlock( &(exec->
stack) );
199#define _MLISP_TYPE_TABLE_PUSH( idx, ctype, name, const_name, fmt ) \
200 MERROR_RETVAL _mlisp_stack_push_ ## ctype( \
201 struct MLISP_EXEC_STATE* exec, ctype i \
203 struct MLISP_STACK_NODE n_stack; \
204 MERROR_RETVAL retval = MERROR_OK; \
205 debug_printf( MLISP_EXEC_TRACE_LVL, \
206 "pushing " #const_name " onto stack: " fmt, i ); \
207 n_stack.type = MLISP_TYPE_ ## const_name; \
208 n_stack.value.name = i; \
209 retval = mdata_vector_append( \
210 &(exec->stack), &n_stack, sizeof( struct MLISP_STACK_NODE ) ); \
212 retval = mdata_retval( retval ); \
231 if( mdata_vector_ct( &(exec->
stack) ) == 0 ) {
232 error_printf(
"stack underflow!" );
233 retval = MERROR_OVERFLOW;
237 n_idx = mdata_vector_ct( &(exec->
stack) ) - 1;
240 mdata_vector_lock( &(exec->
stack) );
241 n_stack = mdata_vector_get(
243 assert( NULL != n_stack );
246 mdata_vector_unlock( &(exec->
stack) );
248# define _MLISP_TYPE_TABLE_POPD( idx, ctype, name, const_name, fmt ) \
249 } else if( MLISP_TYPE_ ## const_name == o->type ) { \
250 debug_printf( MLISP_EXEC_TRACE_LVL, \
251 "popping: " SSIZE_T_FMT ": " fmt, n_idx, o->value.name );
257 retval = mdata_vector_remove( &(exec->
stack), n_idx );
275 char* strpool = NULL;
278# define _MLISP_TYPE_TABLE_DUMPE( idx, ctype, name, const_name, fmt ) \
279 } else if( MLISP_TYPE_ ## const_name == e->type ) { \
280 debug_printf( MLISP_EXEC_TRACE_LVL, \
281 MLISP_TRACE_SIGIL " env " SIZE_T_FMT \
282 " \"%s\" (" #const_name "): " fmt, \
283 i, &(strpool[e->name_strpool_idx]), e->value.name ); \
285 mdata_strpool_lock( &(parser->strpool), strpool );
286 mdata_vector_lock( &(exec->
env) );
287 while( i < mdata_vector_ct( &(exec->
env) ) ) {
288 assert( mdata_vector_is_locked( &(exec->
env) ) );
291 if( MLISP_ENV_FLAG_BUILTIN == (MLISP_ENV_FLAG_BUILTIN & e->flags) ) {
300 }
else if( MLISP_TYPE_STR == e->type ) {
301 debug_printf( MLISP_EXEC_TRACE_LVL,
302 MLISP_TRACE_SIGIL
" env " SIZE_T_FMT
" \"%s\" (STR): %s",
303 i, &(strpool[e->name_strpool_idx]),
304 &(strpool[e->value.strpool_idx]) );
306 }
else if( MLISP_TYPE_CB == e->type ) {
307 debug_printf( MLISP_EXEC_TRACE_LVL,
308 MLISP_TRACE_SIGIL
" env " SIZE_T_FMT
" \"%s\" (CB): %p",
309 i, &(strpool[e->name_strpool_idx]), e->value.cb );
311 }
else if( MLISP_TYPE_LAMBDA == e->type ) {
312 debug_printf( MLISP_EXEC_TRACE_LVL,
313 MLISP_TRACE_SIGIL
" env " SIZE_T_FMT
314 " \"%s\" (LAMBDA): " SIZE_T_FMT,
315 i, &(strpool[e->name_strpool_idx]), e->value.lambda );
317 }
else if( MLISP_TYPE_ARGS_S == e->type ) {
318 debug_printf( MLISP_EXEC_TRACE_LVL,
319 MLISP_TRACE_SIGIL
" env " SIZE_T_FMT
320 " \"%s\" (ARGS_S): " SIZE_T_FMT,
321 i, &(strpool[e->name_strpool_idx]), e->value.args_start );
323 }
else if( MLISP_TYPE_ARGS_E == e->type ) {
324 debug_printf( MLISP_EXEC_TRACE_LVL,
325 MLISP_TRACE_SIGIL
" env " SIZE_T_FMT
326 " \"%s\" (ARGS_E): " SIZE_T_FMT,
327 i, &(strpool[e->name_strpool_idx]), e->value.args_end );
330 error_printf( MLISP_TRACE_SIGIL
" invalid env type: %u", e->type );
334 mdata_vector_unlock( &(exec->
env) );
335 mdata_strpool_unlock( &(parser->strpool), strpool );
346 const char* strpool,
size_t token_strpool_idx,
size_t token_strpool_sz
350 ssize_t i = mdata_vector_ct( &(exec->
env) ) - 1;
355 assert( mdata_vector_is_locked( &(exec->
env) ) );
358 &(strpool[node_test->name_strpool_idx]),
359 &(strpool[token_strpool_idx]),
362 node_out = node_test;
375 const char* token,
size_t token_sz
380 char* strpool = NULL;
382 assert( !mdata_vector_is_locked( &(exec->
env) ) );
383 mdata_vector_lock( &(exec->
env) );
385 mdata_strpool_lock( &(parser->strpool), strpool );
388 for( i = mdata_vector_ct( &(exec->
env) ) - 1 ; 0 <= i ; i-- ) {
389 assert( mdata_vector_is_locked( &(exec->
env) ) );
392 if( MLISP_TYPE_ARGS_E == e->type ) {
393 debug_printf( MLISP_EXEC_TRACE_LVL,
394 "reached end of env stack frame: " SSIZE_T_FMT, i );
399 token, &(strpool[e->name_strpool_idx]), token_sz + 1 )
405 debug_printf( MLISP_EXEC_TRACE_LVL,
406 "found token %s: %s (" SSIZE_T_FMT
"), removing...",
407 token, &(strpool[e->name_strpool_idx]), i );
408 mdata_vector_unlock( &(exec->
env) );
410 retval = mdata_vector_remove( &(exec->
env), i );
411 mdata_vector_lock( &(exec->
env) );
417 assert( mdata_vector_is_locked( &(exec->
env) ) );
418 mdata_vector_unlock( &(exec->
env) );
420 mdata_strpool_unlock( &(parser->strpool), strpool );
429 const char* token,
size_t token_sz, uint8_t env_type,
const void* data,
430 void* cb_data, uint8_t flags
434 ssize_t new_idx_out = -1;
436 if( 0 == token_sz ) {
437 token_sz = maug_strlen( token );
439 assert( 0 < token_sz );
443 retval = mlisp_env_unset( parser, exec, token, token_sz );
444 maug_cleanup_if_not_ok();
446# define _MLISP_TYPE_TABLE_ASGN( idx, ctype, name, const_name, fmt ) \
448 debug_printf( MLISP_EXEC_TRACE_LVL, \
449 "setting env: \"%s\": #" fmt, \
450 token, (ctype)*((ctype*)data) ); \
451 e.value.name = *((ctype*)data); \
458 mdata_strpool_append( &(parser->strpool), token, token_sz );
459 if( 0 > e.name_strpool_idx ) {
460 retval = mdata_retval( e.name_strpool_idx );
462 maug_cleanup_if_not_ok();
471 debug_printf( MLISP_EXEC_TRACE_LVL,
472 "setting env: \"%s\": strpool(" SSIZE_T_FMT
")",
473 token, *((ssize_t*)data) );
474 e.value.strpool_idx = *((mdata_strpool_idx_t*)data);
478 debug_printf( MLISP_EXEC_TRACE_LVL,
479 "setting env: \"%s\": 0x%p", token, (mlisp_env_cb_t)data );
480 e.value.cb = (mlisp_env_cb_t)data;
484 debug_printf( MLISP_EXEC_TRACE_LVL,
485 "setting env: \"%s\": node #" SSIZE_T_FMT,
486 token, *((mlisp_lambda_t*)data) );
487 e.value.lambda = *((mlisp_lambda_t*)data);
491 debug_printf( MLISP_EXEC_TRACE_LVL,
492 "setting env: \"%s\": node #" SSIZE_T_FMT,
493 token, *((mlisp_args_t*)data) );
494 e.value.args_start = *((mlisp_args_t*)data);
498 debug_printf( MLISP_EXEC_TRACE_LVL,
499 "setting env: \"%s\": node #" SSIZE_T_FMT,
500 token, *((mlisp_arge_t*)data) );
501 e.value.args_end = *((mlisp_arge_t*)data);
505 error_printf(
"attempted to define invalid type: %d", env_type );
506 retval = MERROR_EXEC;
511 new_idx_out = mdata_vector_append(
513 if( 0 > new_idx_out ) {
514 retval = mdata_retval( new_idx_out );
516 maug_cleanup_if_not_ok();
518 debug_printf( MLISP_EXEC_TRACE_LVL,
"setup env node " SSIZE_T_FMT
": %s",
519 new_idx_out, token );
528static ssize_t _mlisp_env_get_env_frame(
535 uint8_t autolock = 0;
537 if( !mdata_vector_is_locked( &(exec->
env) ) ) {
538 mdata_vector_lock( &(exec->
env) );
542 for( i = mdata_vector_ct( &(exec->
env) ) - 1; 0 <= i ; i-- ) {
545 assert( mdata_vector_is_locked( &(exec->
env) ) );
549 if( MLISP_TYPE_ARGS_S != e->type ) {
554 debug_printf( MLISP_EXEC_TRACE_LVL,
555 "found initial env arg separator " SSIZE_T_FMT
" with ret: "
557 i, e->value.args_start );
560 if( NULL != e_out ) {
569 mdata_vector_unlock( &(exec->
env) );
572 if( MERROR_OK != retval ) {
573 ret_idx = retval * -1;
589 assert( !mdata_vector_is_locked( &(exec->
env) ) );
591 assert( 0 < mdata_vector_ct( &(exec->
env) ) );
593 mdata_vector_lock( &(exec->
env) );
596 i = _mlisp_env_get_env_frame( exec, NULL );
597 debug_printf( MLISP_EXEC_TRACE_LVL,
598 "pruning env args starting from env frame " SSIZE_T_FMT
"...", i );
602 while( MLISP_TYPE_ARGS_E != e->type ) {
603 mdata_vector_unlock( &(exec->
env) );
604 retval = mdata_vector_remove( &(exec->
env), i );
605 maug_cleanup_if_not_ok();
606 mdata_vector_lock( &(exec->
env) );
609 assert( mdata_vector_is_locked( &(exec->
env) ) );
617 mdata_vector_unlock( &(exec->
env) );
618 retval = mdata_vector_remove( &(exec->
env), i );
619 maug_cleanup_if_not_ok();
620 mdata_vector_lock( &(exec->
env) );
622 debug_printf( MLISP_EXEC_TRACE_LVL,
623 "removed " SIZE_T_FMT
" args!", removed );
627 mdata_vector_unlock( &(exec->
env) );
629 if( MERROR_OK != retval ) {
630 ret_idx = retval * -1;
640 size_t args_c,
void* cb_data, uint8_t flags
644 char* strpool = NULL;
650# define _MLISP_TYPE_TABLE_CMP( idx, ctype, name, const_name, fmt ) \
651 } else if( MLISP_TYPE_ ## const_name == tmp.type ) { \
652 *cur_int = (int)tmp.value.name; \
653 debug_printf( MLISP_EXEC_TRACE_LVL, \
654 "cmp: pop " fmt " (%d)", tmp.value.name, *cur_int );
657 maug_cleanup_if_not_ok();
662 error_printf(
"cmp: invalid type!" );
663 retval = MERROR_EXEC;
668 maug_cleanup_if_not_ok();
673 error_printf(
"cmp: invalid type!" );
674 retval = MERROR_EXEC;
681 debug_printf( MLISP_EXEC_TRACE_LVL,
"cmp %d > %d", a_int, b_int );
682 truth = a_int > b_int;
684 debug_printf( MLISP_EXEC_TRACE_LVL,
"cmp %d < %d", a_int, b_int );
685 truth = a_int < b_int;
687 debug_printf( MLISP_EXEC_TRACE_LVL,
"cmp %d == %d", a_int, b_int );
688 truth = a_int == b_int;
690 error_printf(
"invalid parameter provided to _mlisp_env_cb_cmp()!" );
691 retval = MERROR_EXEC;
699 mdata_strpool_unlock( &(parser->strpool), strpool );
709 size_t args_c,
void* cb_data, uint8_t flags
713 char* strpool = NULL;
718# define _MLISP_TYPE_TABLE_ARI1( idx, ctype, name, const_name, fmt ) \
719 } else if( MLISP_TYPE_ ## const_name == num.type ) { \
720 num_out = num.value.name;
723 maug_cleanup_if_not_ok();
728 error_printf(
"arithmetic: invalid type!" );
729 retval = MERROR_EXEC;
733# define _MLISP_TYPE_TABLE_ARI2( idx, ctype, name, const_name, fmt ) \
735 MLISP_TYPE_ ## const_name == num.type && \
736 MLISP_ENV_FLAG_ARI_ADD == (MLISP_ENV_FLAG_ARI_ADD & flags) \
738 debug_printf( MLISP_EXEC_TRACE_LVL, \
739 "arithmetic: %d + " fmt, num_out, num.value.name ); \
740 num_out += num.value.name; \
742 MLISP_TYPE_ ## const_name == num.type && \
743 MLISP_ENV_FLAG_ARI_MUL == (MLISP_ENV_FLAG_ARI_MUL & flags) \
745 debug_printf( MLISP_EXEC_TRACE_LVL, \
746 "arithmetic: %d * " fmt, num_out, num.value.name ); \
747 num_out *= num.value.name; \
749 MLISP_TYPE_ ## const_name == num.type && \
750 MLISP_ENV_FLAG_ARI_DIV == (MLISP_ENV_FLAG_ARI_DIV & flags) \
752 debug_printf( MLISP_EXEC_TRACE_LVL, \
753 "arithmetic: %d / " fmt, num_out, num.value.name ); \
754 num_out /= num.value.name; \
756 for( i = 0 ; args_c - 1 > i ; i++ ) {
758 maug_cleanup_if_not_ok();
764 MLISP_TYPE_INT == num.type &&
765 MLISP_ENV_FLAG_ARI_MOD == (MLISP_ENV_FLAG_ARI_MOD & flags)
768 debug_printf( MLISP_EXEC_TRACE_LVL,
769 "arithmetic: %d %% %d", num_out, num.value.integer );
770 num_out %= num.value.integer;
772 error_printf(
"arithmetic: invalid type!" );
773 retval = MERROR_EXEC;
778 debug_printf( MLISP_EXEC_TRACE_LVL,
"arithmetic result: %d", num_out );
784 mdata_strpool_unlock( &(parser->strpool), strpool );
793 size_t args_c,
void* cb_data, uint8_t flags
798 MAUG_MHANDLE key_tmp_h = NULL;
799 char* key_tmp = NULL;
802 maug_cleanup_if_not_ok();
805 maug_cleanup_if_not_ok();
807 if( MLISP_TYPE_STR != key.type ) {
810 error_printf(
"define: invalid key type: %d", key.type );
811 retval = MERROR_EXEC;
815 key_tmp_h = mdata_strpool_extract(
816 &(parser->strpool), key.value.strpool_idx );
818 assert( NULL != key_tmp_h );
820 maug_mlock( key_tmp_h, key_tmp );
821 maug_cleanup_if_null_lock(
char*, key_tmp );
823 debug_printf( MLISP_EXEC_TRACE_LVL,
824 "define \"%s\" (strpool(" SIZE_T_FMT
"))...",
825 key_tmp, key.value.strpool_idx );
827 retval = mlisp_env_set(
828 parser, exec, key_tmp, 0, val.type, &(val.value), NULL, 0 );
832 if( NULL != key_tmp ) {
833 maug_munlock( key_tmp_h, key_tmp );
836 if( NULL != key_tmp_h ) {
837 maug_mfree( key_tmp_h );
847 size_t args_c,
void* cb_data, uint8_t flags
850 size_t* p_if_child_idx = NULL;
854 debug_printf( MLISP_EXEC_TRACE_LVL,
"qrqrqrqrqr STEP IF qrqrqrqrqr" );
857 assert( mdata_vector_is_locked( &(exec->per_node_child_idx) ) );
858 p_if_child_idx = mdata_vector_get(
859 &(exec->per_node_child_idx), n_idx,
size_t );
860 assert( NULL != p_if_child_idx );
861 debug_printf( MLISP_EXEC_TRACE_LVL,
862 "child idx for if AST node " SIZE_T_FMT
": " SIZE_T_FMT,
863 n_idx, *p_if_child_idx );
865 n = mdata_vector_get( &(parser->ast), n_idx,
struct MLISP_AST_NODE );
867 if( 0 == *p_if_child_idx ) {
869 debug_printf( MLISP_EXEC_TRACE_LVL,
"stepping into condition..." );
870 retval = _mlisp_step_iter(
871 parser, n->ast_idx_children[*p_if_child_idx], exec );
872 debug_printf( MLISP_EXEC_TRACE_LVL,
"...stepped out of condition" );
875 if( MERROR_OK == retval ) {
880 maug_cleanup_if_not_ok();
881 if( MLISP_TYPE_BOOLEAN != s.type ) {
882 error_printf(
"(if) can only evaluate boolean type!" );
883 retval = MERROR_EXEC;
888 retval = _mlisp_preempt(
889 "if", parser, n_idx, exec, p_if_child_idx,
891 (1 - s.value.boolean) + 1 );
894 }
else if( args_c > *p_if_child_idx ) {
897 debug_printf( MLISP_EXEC_TRACE_LVL,
898 "descending into IF path: " SIZE_T_FMT, *p_if_child_idx );
903 retval = _mlisp_step_iter(
904 parser, n->ast_idx_children[*p_if_child_idx], exec );
905 if( MERROR_OK == retval ) {
906 retval = _mlisp_preempt(
907 "if", parser, n_idx, exec, p_if_child_idx, 3 );
913 debug_printf( MLISP_EXEC_TRACE_LVL,
"qrqrqrqrqr END STEP IF qrqrqrqrqr" );
922 size_t args_c,
void* cb_data, uint8_t flags
926 int16_t random_int = 0;
929 maug_cleanup_if_not_ok();
931 if( MLISP_TYPE_INT != mod.type ) {
933 error_printf(
"random: invalid modulus type: %d", mod.type );
934 retval = MERROR_EXEC;
938 random_int = retroflat_get_rand() % mod.value.integer;
940 debug_printf( MLISP_EXEC_TRACE_LVL,
"random: %d", random_int );
953 size_t args_c,
void* cb_data, uint8_t flags
957 mlisp_bool_t val_out =
958 MLISP_ENV_FLAG_ANO_OR == (MLISP_ENV_FLAG_ANO_OR & flags) ?
966 for( i = 0 ; args_c > i ; i++ ) {
968 maug_cleanup_if_not_ok();
970 if( MLISP_TYPE_BOOLEAN != val.type ) {
971 error_printf(
"or: invalid boolean type: %d", val.type );
974 if( val.value.boolean ) {
975 debug_printf( MLISP_EXEC_TRACE_LVL,
"found TRUE in %s!",
976 MLISP_ENV_FLAG_ANO_OR == (MLISP_ENV_FLAG_ANO_OR & flags) ?
979 MLISP_ENV_FLAG_ANO_OR == (MLISP_ENV_FLAG_ANO_OR & flags) ? 1 : 0;
983 _mlisp_stack_push_mlisp_bool_t( exec, val_out );
1003 char* strpool = NULL;
1006 n = mdata_vector_get( &(parser->ast), n_idx,
struct MLISP_AST_NODE );
1008 mdata_strpool_lock( &(parser->strpool), strpool );
1009 assert( 0 < maug_strlen( &(strpool[n->token_idx]) ) );
1010 debug_printf( MLISP_EXEC_TRACE_LVL,
1011 "eval step " SSIZE_T_FMT
" under (%s) %s...",
1012 *p_child_idx, caller, &(strpool[n->token_idx]) );
1013 mdata_strpool_unlock( &(parser->strpool), strpool );
1016 (*p_child_idx) = new_idx;
1017 debug_printf( MLISP_EXEC_TRACE_LVL,
1018 "incremented " SIZE_T_FMT
" child idx to: " SIZE_T_FMT,
1019 n_idx, *p_child_idx );
1032 size_t* p_child_idx = NULL;
1036 assert( mdata_vector_is_locked( &(exec->per_node_child_idx) ) );
1037 p_child_idx = mdata_vector_get(
1038 &(exec->per_node_child_idx), n_idx,
size_t );
1039 assert( NULL != p_child_idx );
1040 debug_printf( MLISP_EXEC_TRACE_LVL,
1041 "child idx for AST node " SIZE_T_FMT
": " SIZE_T_FMT,
1042 n_idx, *p_child_idx );
1044 n = mdata_vector_get( &(parser->ast), n_idx,
struct MLISP_AST_NODE );
1048 MLISP_AST_FLAG_LAMBDA == (MLISP_AST_FLAG_LAMBDA & n->flags) &&
1051 MLISP_AST_FLAG_IF == (MLISP_AST_FLAG_IF & n->flags)
1060 debug_printf( MLISP_EXEC_TRACE_LVL,
"skipping lambda children..." );
1064 if( mlisp_ast_has_ready_children( *p_child_idx, n ) ) {
1068 MLISP_AST_FLAG_DEFINE == (MLISP_AST_FLAG_DEFINE & n->flags) &&
1072 debug_printf( MLISP_EXEC_TRACE_LVL,
1073 "setting MLISP_EXEC_FLAG_DEF_TERM!" );
1076 exec->flags &= ~MLISP_EXEC_FLAG_DEF_TERM;
1080 retval = _mlisp_step_iter(
1081 parser, n->ast_idx_children[*p_child_idx], exec );
1082 if( MERROR_OK == retval ) {
1083 retval = _mlisp_preempt(
1084 "node", parser, n_idx, exec, p_child_idx, (*p_child_idx) + 1 );
1093 debug_printf( MDATA_TRACE_LVL,
1094 "resetting node " SIZE_T_FMT
" child pointer to 0...",
1111 ssize_t arg_idx = 0;
1114 MAUG_MHANDLE key_tmp_h = NULL;
1115 char* key_tmp = NULL;
1124 n = mdata_vector_get( &(parser->ast), n_idx,
struct MLISP_AST_NODE );
1127 while( 0 <= arg_idx ) {
1130 maug_cleanup_if_not_ok();
1132 ast_n_arg = mdata_vector_get(
1133 &(parser->ast), n->ast_idx_children[arg_idx],
1137 key_tmp_h = mdata_strpool_extract(
1138 &(parser->strpool), ast_n_arg->token_idx );
1140 assert( NULL != key_tmp_h );
1142 maug_mlock( key_tmp_h, key_tmp );
1143 maug_cleanup_if_null_lock(
char*, key_tmp );
1145 retval = mlisp_env_set(
1146 parser, exec, key_tmp, 0, stack_n_arg.type, &(stack_n_arg.value),
1148 maug_cleanup_if_not_ok();
1150 maug_munlock( key_tmp_h, key_tmp );
1151 maug_mfree( key_tmp_h );
1158 if( NULL != key_tmp ) {
1159 maug_munlock( key_tmp_h, key_tmp );
1162 if( NULL != key_tmp_h ) {
1163 maug_mfree( key_tmp_h );
1176 size_t* p_child_idx = NULL;
1177 size_t* p_visit_ct = NULL;
1181 assert( mdata_vector_is_locked( &(exec->per_node_child_idx) ) );
1182 assert( mdata_vector_is_locked( &(parser->ast) ) );
1185 debug_printf( MLISP_TRACE_LVL,
"resetting PC on node: " SIZE_T_FMT, n_idx );
1186 p_child_idx = mdata_vector_get( &(exec->per_node_child_idx), n_idx,
size_t );
1187 assert( NULL != p_child_idx );
1190 debug_printf( MLISP_TRACE_LVL,
1191 "resetting visit count on node: " SIZE_T_FMT, n_idx );
1193 assert( NULL != p_visit_ct );
1196 n = mdata_vector_get( &(parser->ast), n_idx,
struct MLISP_AST_NODE );
1200 retval = _mlisp_reset_child_pcs( parser, n->ast_idx_children[i], exec );
1201 maug_cleanup_if_not_ok();
1216 ssize_t ret_idx = 0;
1218 debug_printf( MLISP_EXEC_TRACE_LVL,
1219 "resetting lambda " SIZE_T_FMT
"...", n_idx );
1221 assert( mdata_vector_is_locked( &(exec->per_node_child_idx) ) );
1222 assert( !mdata_vector_is_locked( &(exec->
env) ) );
1225 ret_idx = _mlisp_env_prune_args( exec );
1227 retval = ret_idx * -1;
1229 maug_cleanup_if_not_ok();
1232 retval = _mlisp_reset_child_pcs( parser, n_idx, exec );
1246 size_t* p_lambda_child_idx = NULL;
1247 size_t* p_args_child_idx = NULL;
1249 size_t* p_n_last_lambda = NULL;
1250 ssize_t append_retval = 0;
1252#ifdef MLISP_DEBUG_TRACE
1253 exec->trace[exec->trace_depth++] = n_idx;
1254 assert( exec->trace_depth <= MLISP_DEBUG_TRACE );
1259 p_n_last_lambda = mdata_vector_get_last( &(exec->
lambda_trace),
size_t );
1261 if( NULL != p_n_last_lambda && n_idx == *p_n_last_lambda ) {
1265 debug_printf( MLISP_EXEC_TRACE_LVL,
"TRACE TAIL TIME!" );
1266 _mlisp_reset_lambda( parser, n_idx, exec );
1267 retval = mdata_vector_remove_last( &(exec->
lambda_trace) );
1268 maug_cleanup_if_not_ok();
1271 debug_printf( MLISP_EXEC_TRACE_LVL,
1272 "xvxvxvxvxvxvx STEP LAMBDA " SIZE_T_FMT
" xvxvxvxvxvx", n_idx );
1275 append_retval = mdata_vector_append(
1277 retval = mdata_retval( append_retval );
1278 maug_cleanup_if_not_ok();
1281 assert( mdata_vector_is_locked( &(exec->per_node_child_idx) ) );
1282 p_lambda_child_idx = mdata_vector_get(
1283 &(exec->per_node_child_idx), n_idx,
size_t );
1284 assert( NULL != p_lambda_child_idx );
1285 debug_printf( MLISP_EXEC_TRACE_LVL,
1286 "child idx for lambda AST node " SIZE_T_FMT
": " SIZE_T_FMT,
1287 n_idx, *p_lambda_child_idx );
1289 n = mdata_vector_get( &(parser->ast), n_idx,
struct MLISP_AST_NODE );
1295 if( 0 == *p_lambda_child_idx ) {
1299 assert( mdata_vector_is_locked( &(exec->per_node_child_idx) ) );
1300 p_args_child_idx = mdata_vector_get(
1301 &(exec->per_node_child_idx),
1302 n->ast_idx_children[*p_lambda_child_idx],
size_t );
1303 assert( NULL != p_args_child_idx );
1304 debug_printf( MLISP_EXEC_TRACE_LVL,
1305 "child idx for args AST node " SIZE_T_FMT
": " SIZE_T_FMT,
1306 *p_lambda_child_idx, *p_args_child_idx );
1308 if( 0 == *p_args_child_idx ) {
1311 retval = mlisp_env_set(
1312 parser, exec,
"$ARGS_S$", 0, MLISP_TYPE_ARGS_S, &n_idx, NULL, 0 );
1313 maug_cleanup_if_not_ok();
1317 retval = _mlisp_step_lambda_args(
1318 parser, n->ast_idx_children[*p_lambda_child_idx], exec );
1320 if( MERROR_OK == retval ) {
1322 retval = mlisp_env_set(
1323 parser, exec,
"$ARGS_E$", 0, MLISP_TYPE_ARGS_E, &n_idx, NULL, 0 );
1324 maug_cleanup_if_not_ok();
1327 (*p_lambda_child_idx)++;
1328 debug_printf( MLISP_EXEC_TRACE_LVL,
1329 "incremented " SIZE_T_FMT
" child idx to: " SIZE_T_FMT,
1330 n_idx, *p_lambda_child_idx );
1336 retval = MERROR_PREEMPT;
1338 }
else if( mlisp_ast_has_ready_children( *p_lambda_child_idx, n ) ) {
1341 retval = _mlisp_step_iter(
1342 parser, n->ast_idx_children[*p_lambda_child_idx], exec );
1344 if( MERROR_OK == retval ) {
1345 retval = _mlisp_preempt(
1346 "lambda", parser, n_idx, exec, p_lambda_child_idx,
1347 (*p_lambda_child_idx) + 1 );
1352 _mlisp_reset_lambda( parser, n_idx, exec );
1359 debug_printf( MLISP_EXEC_TRACE_LVL,
1360 "xvxvxvxvxvxvx END STEP LAMBDA " SIZE_T_FMT
" xvxvxvxvxvx", n_idx );
1380 i = mdata_vector_ct( &(exec->
stack) ) - 1;
1384 maug_cleanup_if_not_ok();
1386 if( MLISP_TYPE_BEGIN == o.type && n_idx == o.value.begin ) {
1404 uint8_t autolock = 0;
1405 char* strpool = NULL;
1409 if( !mdata_vector_is_locked( &(exec->
env) ) ) {
1410 mdata_vector_lock( &(exec->
env) );
1414 mdata_strpool_lock( &(parser->strpool), strpool );
1416 assert( 0 < maug_strlen( &(strpool[token_idx]) ) );
1418 debug_printf( MLISP_EXEC_TRACE_LVL,
1419 "eval token: \"%s\" (maug_strlen: " SIZE_T_FMT
")",
1420 &(strpool[token_idx]), maug_strlen( &(strpool[token_idx]) ) );
1421 if( 0 == strncmp( &(strpool[token_idx]),
"begin", token_sz ) ) {
1423 e_out->type = MLISP_TYPE_BEGIN;
1426 parser, exec, strpool, token_idx, token_sz
1429 debug_printf( MLISP_EXEC_TRACE_LVL,
"found %s in env!",
1430 &(strpool[p_e->name_strpool_idx]) );
1437 }
else if( maug_is_num( &(strpool[token_idx]), token_sz, 10, 1 ) ) {
1439 e_out->value.integer =
1440 maug_atos32( &(strpool[token_idx]), token_sz );
1441 e_out->type = MLISP_TYPE_INT;
1443 }
else if( maug_is_float( &(strpool[token_idx]), token_sz ) ) {
1445 e_out->value.floating = maug_atof( &(strpool[token_idx]), token_sz );
1446 e_out->type = MLISP_TYPE_FLOAT;
1453 mdata_vector_unlock( &(exec->
env) );
1456 mdata_strpool_unlock( &(parser->strpool), strpool );
1468 size_t* p_visit_ct = NULL;
1470#ifdef MLISP_DEBUG_TRACE
1471 exec->trace[exec->trace_depth++] = n_idx;
1472 assert( exec->trace_depth <= MLISP_DEBUG_TRACE );
1475 n = mdata_vector_get( &(parser->ast), n_idx,
struct MLISP_AST_NODE );
1478 p_visit_ct = mdata_vector_get(
1480 assert( NULL != p_visit_ct );
1482 debug_printf( MLISP_EXEC_TRACE_LVL,
1483 "visit count for AST node " SIZE_T_FMT
": " SIZE_T_FMT,
1484 n_idx, *p_visit_ct );
1488 MLISP_AST_FLAG_BEGIN == (MLISP_AST_FLAG_BEGIN & n->flags) &&
1492 _mlisp_stack_push_mlisp_begin_t( exec, n_idx );
1497 (retval = _mlisp_step_iter_children( parser, n_idx, exec ))
1503 if( MLISP_AST_FLAG_LAMBDA == (MLISP_AST_FLAG_LAMBDA & n->flags) ) {
1518 retval = _mlisp_eval_token_strpool(
1519 parser, exec, n->token_idx, n->token_sz, &e );
1520 maug_cleanup_if_not_ok();
1525# define _MLISP_TYPE_TABLE_ENVE( idx, ctype, name, const_name, fmt ) \
1526 } else if( MLISP_TYPE_ ## const_name == e.type ) { \
1527 _mlisp_stack_push_ ## ctype( exec, e.value.name );
1533 debug_printf( MLISP_EXEC_TRACE_LVL,
1534 "special case! pushing literal to define: " SSIZE_T_FMT,
1536 _mlisp_stack_push_mdata_strpool_idx_t( exec, n->token_idx );
1537 }
else if( MLISP_TYPE_BEGIN == e.type ) {
1541 retval = _mlisp_stack_cleanup( parser, n_idx, exec );
1543 }
else if( MLISP_TYPE_CB == e.type ) {
1548 retval = e.value.cb(
1551 }
else if( MLISP_TYPE_LAMBDA == e.type ) {
1557 retval = _mlisp_step_lambda( parser, e.value.lambda, exec );
1561 _mlisp_stack_push_mdata_strpool_idx_t( exec, n->token_idx );
1575#ifdef MLISP_DEBUG_TRACE
1577 char trace_str[MLISP_DEBUG_TRACE * 5];
1578 maug_ms_t ms_start = 0;
1579 maug_ms_t ms_end = 0;
1581 ms_start = retroflat_get_ms();
1584 debug_printf( MLISP_EXEC_TRACE_LVL,
"heartbeat start" );
1589 assert( !mdata_vector_is_locked( &(exec->per_node_child_idx) ) );
1591 assert( !mdata_vector_is_locked( &(parser->ast) ) );
1592 mdata_vector_lock( &(exec->per_node_child_idx) );
1594 mdata_vector_lock( &(parser->ast) );
1596 if( 0 == mdata_vector_ct( &(parser->ast) ) ) {
1597 error_printf(
"no valid AST present; could not exec!" );
1598 retval = MERROR_EXEC;
1603 assert( 0 == mdata_vector_ct( &(exec->
lambda_trace) ) );
1605#ifdef MLISP_DEBUG_TRACE
1606 exec->trace_depth = 0;
1610 retval = _mlisp_step_iter( parser, 0, exec );
1611 if( MERROR_PREEMPT == retval ) {
1614 }
else if( MERROR_OK == retval ) {
1616 debug_printf( MLISP_EXEC_TRACE_LVL,
"execution terminated successfully" );
1617 retval = MERROR_EXEC;
1619 debug_printf( MLISP_EXEC_TRACE_LVL,
1620 "execution terminated with retval: %d", retval );
1623#ifdef MLISP_DEBUG_TRACE
1624 ms_end = retroflat_get_ms();
1626 maug_mzero( trace_str, MLISP_DEBUG_TRACE * 5 );
1627 for( i = 0 ; exec->trace_depth > i ; i++ ) {
1629 &(trace_str[maug_strlen( trace_str )]),
1630 (MLISP_DEBUG_TRACE * 5) - maug_strlen( trace_str ),
1631 SIZE_T_FMT
", ", exec->trace[i] );
1633 debug_printf( MLISP_EXEC_TRACE_LVL,
1634 MLISP_TRACE_SIGIL
" HBEXEC (%u): %s",
1635 ms_end - ms_start, trace_str );
1640 debug_printf( MLISP_EXEC_TRACE_LVL,
"heartbeat end: %x", retval );
1642 assert( mdata_vector_is_locked( &(parser->ast) ) );
1643 mdata_vector_unlock( &(parser->ast) );
1645 mdata_vector_unlock( &(exec->per_node_child_idx) );
1656 ssize_t append_retval = 0;
1662 retval = mdata_vector_append(
1664 if( 0 > append_retval ) {
1665 retval = mdata_retval( append_retval );
1667 maug_cleanup_if_not_ok();
1670 append_retval = mdata_vector_alloc(
1672 if( 0 > append_retval ) {
1673 retval = mdata_retval( append_retval );
1675 maug_cleanup_if_not_ok();
1678 retval = mdata_vector_append(
1679 &(exec->per_node_child_idx), &zero,
sizeof(
size_t ) );
1680 maug_cleanup_if_not_ok();
1684 mdata_vector_ct( &(exec->per_node_child_idx) ) <=
1685 mdata_vector_ct( &(parser->ast) )
1687 retval = mdata_vector_append( &(exec->per_node_child_idx), &zero,
1692 retval = mdata_vector_append(
1694 maug_cleanup_if_not_ok();
1699 mdata_vector_ct( &(parser->ast) )
1707 retval = mlisp_env_set(
1708 parser, exec,
"and", 2, MLISP_TYPE_CB, _mlisp_env_cb_ano,
1709 NULL, MLISP_ENV_FLAG_BUILTIN | MLISP_ENV_FLAG_ANO_AND );
1710 maug_cleanup_if_not_ok();
1711 retval = mlisp_env_set(
1712 parser, exec,
"or", 2, MLISP_TYPE_CB, _mlisp_env_cb_ano,
1713 NULL, MLISP_ENV_FLAG_BUILTIN | MLISP_ENV_FLAG_ANO_OR );
1714 maug_cleanup_if_not_ok();
1715 retval = mlisp_env_set(
1716 parser, exec,
"random", 6, MLISP_TYPE_CB, _mlisp_env_cb_random,
1717 NULL, MLISP_ENV_FLAG_BUILTIN );
1718 maug_cleanup_if_not_ok();
1719 retval = mlisp_env_set(
1720 parser, exec,
"if", 2, MLISP_TYPE_CB, _mlisp_env_cb_if,
1721 NULL, MLISP_ENV_FLAG_BUILTIN );
1722 maug_cleanup_if_not_ok();
1723 retval = mlisp_env_set(
1724 parser, exec,
"define", 6, MLISP_TYPE_CB, _mlisp_env_cb_define,
1725 NULL, MLISP_ENV_FLAG_BUILTIN );
1726 maug_cleanup_if_not_ok();
1727 retval = mlisp_env_set(
1728 parser, exec,
"*", 1, MLISP_TYPE_CB, _mlisp_env_cb_arithmetic,
1730 maug_cleanup_if_not_ok();
1731 retval = mlisp_env_set(
1732 parser, exec,
"+", 1, MLISP_TYPE_CB, _mlisp_env_cb_arithmetic,
1734 maug_cleanup_if_not_ok();
1735 retval = mlisp_env_set(
1736 parser, exec,
"/", 1, MLISP_TYPE_CB, _mlisp_env_cb_arithmetic,
1737 NULL, MLISP_ENV_FLAG_BUILTIN | MLISP_ENV_FLAG_ARI_DIV );
1738 maug_cleanup_if_not_ok();
1739 retval = mlisp_env_set(
1740 parser, exec,
"%", 1, MLISP_TYPE_CB, _mlisp_env_cb_arithmetic,
1741 NULL, MLISP_ENV_FLAG_BUILTIN | MLISP_ENV_FLAG_ARI_MOD );
1742 maug_cleanup_if_not_ok();
1743 retval = mlisp_env_set(
1744 parser, exec,
"<", 1, MLISP_TYPE_CB, _mlisp_env_cb_cmp,
1746 maug_cleanup_if_not_ok();
1747 retval = mlisp_env_set(
1748 parser, exec,
">", 1, MLISP_TYPE_CB, _mlisp_env_cb_cmp,
1750 maug_cleanup_if_not_ok();
1751 retval = mlisp_env_set(
1752 parser, exec,
"=", 1, MLISP_TYPE_CB, _mlisp_env_cb_cmp,
1754 maug_cleanup_if_not_ok();
1758 if( MERROR_OK != retval ) {
1759 error_printf(
"mlisp exec initialization failed: %d", retval );
1768 mdata_vector_free( &(exec->per_node_child_idx) );
1770 mdata_vector_free( &(exec->
stack) );
1771 mdata_vector_free( &(exec->
env) );
1777# define MLISP_PSTATE_TABLE_CONST( name, idx ) \
1778 extern MAUG_CONST uint8_t SEG_MCONST name;
1780MLISP_PARSER_PSTATE_TABLE( MLISP_PSTATE_TABLE_CONST )
1782#ifdef MPARSER_TRACE_NAMES
1783extern 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
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:60
#define MLISP_NUM_TYPE_TABLE(f)
Table of numeric types.
Definition mlisps.h:50
#define MLISP_EXEC_FLAG_DEF_TERM
Flag for MLISP_EXEC_STATE::flags indicating next token is a term to be defined.
Definition mlisps.h:29
#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
#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
#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.
size_t ast_idx_children_sz
Number of children in MLISP_AST_NODE::ast_idx_children.
Definition mlisps.h:106
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:127
struct MDATA_VECTOR per_node_visit_ct
The number of times each node has been visited ever.
Definition mlisps.h:112
struct MDATA_VECTOR stack
A stack of data values resulting from evaluating statements.
Definition mlisps.h:115
struct MDATA_VECTOR env
Environment in which statements are defined.
Definition mlisps.h:122