15#ifndef MLISP_PARSE_TRACE_LVL
16# define MLISP_PARSE_TRACE_LVL 0
19#define MLISP_AST_FLAG_LAMBDA 0x02
21#define MLISP_AST_FLAG_IF 0x04
23#define MLISP_AST_FLAG_DEFINE 0x08
25#define MLISP_AST_FLAG_BEGIN 0x20
27#define MLISP_PARSER_PSTATE_TABLE( f ) \
28 f( MLISP_PSTATE_NONE, 0 ) \
29 f( MLISP_PSTATE_SYMBOL_OP, 1 ) \
30 f( MLISP_PSTATE_SYMBOL, 2 ) \
31 f( MLISP_PSTATE_STRING, 3 ) \
32 f( MLISP_PSTATE_LAMBDA_ARGS, 4 ) \
33 f( MLISP_PSTATE_COMMENT, 5 )
40#define mlisp_parser_pstate( parser ) \
41 ((parser)->base.pstate_sz > 0 ? \
42 (parser)->base.pstate[(parser)->base.pstate_sz - 1] : MLISP_PSTATE_NONE)
44#ifdef MPARSER_TRACE_NAMES
45# define mlisp_parser_pstate_push( parser, new_pstate ) \
46 mparser_pstate_push( \
47 "mlisp", &((parser)->base), new_pstate, gc_mlisp_pstate_names );
49# define mlisp_parser_pstate_pop( parser ) \
51 "mlisp", &((parser)->base), gc_mlisp_pstate_names );
53# define mlisp_parser_pstate_push( parser, new_pstate ) \
54 mparser_pstate_push( "mlisp", &((parser)->base), new_pstate )
56# define mlisp_parser_pstate_pop( parser ) \
57 mparser_pstate_pop( "mlisp", &((parser)->base) )
60#define mlisp_parser_invalid_c( parser, c, retval ) \
61 mparser_invalid_c( mlisp, &((parser)->base), c, retval )
63#define mlisp_parser_reset_token( parser ) \
64 mparser_reset_token( "mlisp", &((parser)->base) )
66#define mlisp_parser_append_token( parser, c ) \
67 mparser_append_token( "mlisp", &((parser)->base), c )
69#define mlisp_parser_parse_token( parser ) \
70 parser->token_parser( \
71 (parser)->token, (parser)->token_sz, (parser)->token_parser_arg )
73#define mlisp_parser_is_loaded( p ) (0 < mdata_vector_sz( &((p)->ast) ))
80#define mlisp_check_ast( parser ) (0 < mdata_vector_ct( &((parser)->ast) ))
82#if defined( MLISP_DUMP_ENABLED ) || defined( DOCUMENTATION )
90 struct MLISP_PARSER* parser,
size_t ast_node_idx,
size_t depth,
char ab );
109#define _MLISP_TYPE_TABLE_CONSTS( idx, ctype, name, const_name, fmt ) \
110 MAUG_CONST uint8_t SEG_MCONST MLISP_TYPE_ ## const_name = idx;
114MLISP_PARSER_PSTATE_TABLE( MPARSER_PSTATE_TABLE_CONST )
116MPARSER_PSTATE_NAMES( MLISP_PARSER_PSTATE_TABLE, mlisp )
125_mlisp_ast_add_child(
struct MLISP_PARSER* parser, uint8_t flags ) {
129 ssize_t parent_child_idx = -1;
130 ssize_t new_idx_out = 0;
136 for( i = 0 ; MLISP_AST_IDX_CHILDREN_MAX > i ; i++ ) {
137 ast_node.ast_idx_children[i] = -1;
139 ast_node.token_idx = -1;
140 ast_node.ast_idx_children_sz = 0;
141 ast_node.flags = flags;
143 debug_printf( MLISP_PARSE_TRACE_LVL,
"adding node under " SSIZE_T_FMT
"...",
144 ast_node.ast_idx_parent );
149 if( 0 > new_idx_out ) {
150 retval = mdata_retval( new_idx_out );
154 if( 0 <= ast_node.ast_idx_parent ) {
157 n_parent = mdata_vector_get(
161 parent_child_idx = 0;
162 while( -1 != n_parent->ast_idx_children[parent_child_idx] ) {
166 n_parent->ast_idx_children[parent_child_idx] = new_idx_out;
185 debug_printf( MLISP_PARSE_TRACE_LVL,
"added node " SSIZE_T_FMT
186 " under parent: " SSIZE_T_FMT
" as child " SSIZE_T_FMT,
187 new_idx_out, ast_node.ast_idx_parent, parent_child_idx );
197 struct MLISP_PARSER* parser, mdata_strpool_idx_t token_idx,
size_t token_sz
201 char* strpool_token = NULL;
205 n = mdata_vector_get(
209 mdata_strpool_lock( &(parser->strpool) );
212 assert( NULL != strpool_token );
214 if( 0 == token_sz ) {
215 token_sz = maug_strlen( strpool_token );
217 assert( 0 < token_sz );
220 if( 0 == maug_strncmp( strpool_token,
"lambda", 7 ) ) {
222 debug_printf( MLISP_PARSE_TRACE_LVL,
223 "setting node \"%s\" (" SIZE_T_FMT
") flag: LAMBDA",
224 strpool_token, token_sz );
225 n->flags |= MLISP_AST_FLAG_LAMBDA;
227 }
else if( 0 == maug_strncmp( strpool_token,
"if", 3 ) ) {
229 debug_printf( MLISP_PARSE_TRACE_LVL,
230 "setting node \"%s\" (" SIZE_T_FMT
") flag: IF",
231 strpool_token, token_sz );
232 n->flags |= MLISP_AST_FLAG_IF;
234 }
else if( 0 == maug_strncmp( strpool_token,
"begin", 6 ) ) {
236 debug_printf( MLISP_PARSE_TRACE_LVL,
237 "setting node \"%s\" (" SIZE_T_FMT
") flag: BEGIN",
238 strpool_token, token_sz );
239 n->flags |= MLISP_AST_FLAG_BEGIN;
241 }
else if( 0 == maug_strncmp( strpool_token,
"define", 7 ) ) {
243 debug_printf( MLISP_PARSE_TRACE_LVL,
244 "setting node \"%s\" (" SIZE_T_FMT
") flag: DEFINE",
245 strpool_token, token_sz );
246 n->flags |= MLISP_AST_FLAG_DEFINE;
250 debug_printf( MLISP_PARSE_TRACE_LVL,
251 "setting node " SSIZE_T_FMT
" token: \"%s\" (" SIZE_T_FMT
")",
256 n->token_idx = token_idx;
257 n->token_sz = token_sz;
261 if( mdata_strpool_is_locked( &(parser->strpool) ) ) {
262 mdata_strpool_unlock( &(parser->strpool) );
281 n = mdata_vector_get(
286 debug_printf( MLISP_PARSE_TRACE_LVL,
"moved up to node: " SSIZE_T_FMT,
301 mdata_strpool_idx_t str_idx = 0;
303 str_idx = mdata_strpool_append( &(parser->strpool),
304 parser->base.token, parser->base.token_sz, MDATA_STRPOOL_FLAG_DEDUPE );
305 maug_cleanup_if_eq( str_idx, 0, SIZE_T_FMT, MERROR_ALLOC );
307 _mlisp_ast_add_child( parser, 0 );
308 _mlisp_ast_set_child_token( parser, str_idx, parser->base.token_sz );
309 mlisp_parser_reset_token( parser );
310 retval = _mlisp_ast_traverse_parent( parser );
318#if defined( MLISP_DUMP_ENABLED ) || defined( DOCUMENTATION )
321 struct MLISP_PARSER* parser,
size_t ast_node_idx,
size_t depth,
char ab
324 uint8_t autolock = 0;
333 MLISP_TRACE_SIGIL
" --- BEGIN AST DUMP ---" );
337 maug_mzero( indent, 101 );
338 assert( depth < 100 );
339 for( i = 0 ; depth > i ; i++ ) {
348 n = mdata_vector_get( &(parser->ast), ast_node_idx,
struct MLISP_AST_NODE );
349 mdata_strpool_lock( &(parser->strpool) );
351 MLISP_TRACE_SIGIL
" %s%c: \"%s\" (i: " SIZE_T_FMT
", t: " SSIZE_T_FMT
352 ", c: " SSIZE_T_FMT
", f: 0x%02x)",
353 indent, ab, 0 <= n->token_idx ?
356 mdata_strpool_unlock( &(parser->strpool) );
357 for( i = 0 ; MLISP_AST_IDX_CHILDREN_MAX > i ; i++ ) {
358 if( -1 == n->ast_idx_children[i] ) {
362 mlisp_ast_dump( parser, n->ast_idx_children[i], depth + 1,
'0' + i );
367 if( NULL != parser->ast.
data_bytes && autolock ) {
370 MLISP_TRACE_SIGIL
" --- END AST DUMP ---" );
386 mdata_strpool_idx_t str_idx = 0;
388 size_t n_children = 0;
391#ifdef MPARSER_TRACE_NAMES
392 debug_printf( MLISP_PARSE_TRACE_LVL,
393 SIZE_T_FMT
": \"%c\" (last: \"%c\") (%s (%d)) (sz: " SIZE_T_FMT
")",
394 parser->base.i, c, parser->base.last_c,
395 gc_mlisp_pstate_names[mlisp_parser_pstate( parser )],
396 mlisp_parser_pstate( parser ),
397 parser->base.pstate_sz );
401 n = mdata_vector_get(
412 if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
414 mlisp_parser_pstate_pop( parser );
421 MLISP_PSTATE_SYMBOL_OP == mlisp_parser_pstate( parser )
425 &&
'\r' != parser->base.last_c
426 &&
'\n' != parser->base.last_c
427 &&
'\t' != parser->base.last_c
428 &&
' ' != parser->base.last_c
429 &&
')' != parser->base.last_c
430 &&
'(' != parser->base.last_c
432 assert( 0 < parser->base.token_sz );
433 debug_printf( MLISP_PARSE_TRACE_LVL,
434 "found symbol: %s (" SIZE_T_FMT
")",
435 parser->base.token, parser->base.token_sz );
440 str_idx = mdata_strpool_append( &(parser->strpool),
441 parser->base.token, parser->base.token_sz,
442 MDATA_STRPOOL_FLAG_DEDUPE );
443 maug_cleanup_if_eq( str_idx, 0, SIZE_T_FMT, MERROR_ALLOC );
444 mlisp_parser_reset_token( parser );
445 _mlisp_ast_set_child_token( parser, str_idx, parser->base.token_sz );
448 mlisp_parser_pstate_pop( parser );
449 retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL );
450 maug_cleanup_if_not_ok();
456 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser ) ||
457 MLISP_PSTATE_LAMBDA_ARGS == mlisp_parser_pstate( parser )
462 &&
'\r' != parser->base.last_c
463 &&
'\n' != parser->base.last_c
464 &&
'\t' != parser->base.last_c
465 &&
' ' != parser->base.last_c
466 &&
')' != parser->base.last_c
467 &&
'(' != parser->base.last_c
469 if( 0 < parser->base.token_sz ) {
470 debug_printf( MLISP_PARSE_TRACE_LVL,
471 "found symbol: %s (" SIZE_T_FMT
")",
472 parser->base.token, parser->base.token_sz );
477 _mlisp_ast_add_raw_token( parser );
480 }
else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
481 retval = mlisp_parser_append_token( parser, c );
482 maug_cleanup_if_not_ok();
489 if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
490 mlisp_parser_pstate_pop( parser );
492 mlisp_parser_pstate_push( parser, MLISP_PSTATE_STRING );
498 MLISP_PSTATE_NONE == mlisp_parser_pstate( parser ) ||
499 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser )
502 MLISP_AST_FLAG_LAMBDA == (MLISP_AST_FLAG_LAMBDA & n_flags) &&
507 mlisp_parser_pstate_push( parser, MLISP_PSTATE_LAMBDA_ARGS );
510 retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL_OP );
512 maug_cleanup_if_not_ok();
513 mlisp_parser_reset_token( parser );
516 _mlisp_ast_add_child( parser, 0 );
518 }
else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
519 retval = mlisp_parser_append_token( parser, c );
520 maug_cleanup_if_not_ok();
523 mlisp_parser_invalid_c( parser, c, retval );
529 MLISP_PSTATE_SYMBOL_OP == mlisp_parser_pstate( parser ) ||
530 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser ) ||
531 MLISP_PSTATE_LAMBDA_ARGS == mlisp_parser_pstate( parser )
533 if( 0 < parser->base.token_sz ) {
537 _mlisp_ast_add_raw_token( parser );
541 mlisp_parser_pstate_pop( parser );
542 _mlisp_ast_traverse_parent( parser );
546 }
else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
547 retval = mlisp_parser_append_token( parser, c );
548 maug_cleanup_if_not_ok();
551 mlisp_parser_invalid_c( parser, c, retval );
556 if( MLISP_PSTATE_COMMENT != mlisp_parser_pstate( parser ) ) {
557 mlisp_parser_pstate_push( parser, MLISP_PSTATE_COMMENT );
562 if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
565 retval = mlisp_parser_append_token( parser, c );
566 maug_cleanup_if_not_ok();
570 mparser_wait( &(parser->base) );
576 parser->base.last_c = c;
591 debug_printf( MLISP_TRACE_LVL,
"loading mlisp AST..." );
594 maug_cleanup_if_not_ok();
596 retval = mlisp_parser_init( parser );
597 maug_cleanup_if_not_ok();
599 for( i = 0 ; mfile_get_sz( &ai_file ) > i ; i++ ) {
600 retval = ai_file.read_int( &ai_file, (uint8_t*)&c, 1, 0 );
601 maug_cleanup_if_not_ok();
602 retval = mlisp_parse_c( parser, c );
603 maug_cleanup_if_not_ok();
605#if defined( MLISP_DUMP_ENABLED )
608 if( 0 < parser->base.pstate_sz ) {
609 error_printf(
"invalid parser state!" );
610 retval = MERROR_EXEC;
623 ssize_t append_retval = 0;
625 debug_printf( MLISP_TRACE_LVL,
626 "initializing mlisp parser (" SIZE_T_FMT
" bytes)...",
642 if( 0 > append_retval ) {
643 retval = mdata_retval( append_retval );
645 maug_cleanup_if_not_ok();
649 if( MERROR_OK != retval ) {
650 error_printf(
"mlisp parser initialization failed: %d", retval );
659 debug_printf( MLISP_TRACE_LVL,
660 "destroying parser (ast: " SIZE_T_FMT
")...",
662 mdata_strpool_free( &(parser->strpool) );
663 mdata_vector_free( &(parser->ast) );
664 debug_printf( MLISP_PARSE_TRACE_LVL,
"parser destroyed!" );
669# define _MLISP_TYPE_TABLE_CONSTS( idx, ctype, name, const_name, fmt ) \
670 extern MAUG_CONST uint8_t SEG_MCONST MLISP_TYPE_ ## const_name;
uint16_t MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition: merror.h:28
MERROR_RETVAL mfile_open_read(const maug_path filename, mfile_t *p_file)
Open a file and read it into memory or memory-map it.
char maug_path[MAUG_PATH_SZ_MAX]
Path/name used to load an asset from disk or access other files.
Definition: mfile.h:141
#define mdata_strpool_get(sp, idx)
Get a string by the index of its first character in the strpool.
Definition: mdata.h:334
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_alloc(struct MDATA_VECTOR *v, size_t item_sz, size_t item_ct_init)
MERROR_RETVAL mlisp_ast_dump(struct MLISP_PARSER *parser, size_t ast_node_idx, size_t depth, char ab)
Dump the given parser AST.
#define MLISP_TYPE_TABLE(f)
Table of other types.
Definition: mlisps.h:74
MLISP Interpreter/Parser Structs.
#define mdata_vector_lock(v)
Lock the vector. This should be done when items from the vector are actively being referenced,...
Definition: mdata.h:372
#define mdata_vector_unlock(v)
Unlock the vector so items may be added and removed.
Definition: mdata.h:405
uint8_t * data_bytes
Handle for allocated items (locked).
Definition: mdata.h:113
#define mdata_vector_ct(v)
Number of items of MDATA_VECTOR::item_sz bytes actively stored in this vector.
Definition: mdata.h:448
size_t ast_idx_children_sz
Number of children in MLISP_AST_NODE::ast_idx_children.
Definition: mlisps.h:126
ssize_t ast_node_iter
Definitions to use if MLISP_EXEC_FLAG_DEF_TERM is defined on the accompanying MLISP_EXEC_STATE::flags...
Definition: mlisps.h:207