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 )
77#define mlisp_check_ast( parser ) (0 < mdata_vector_ct( &((parser)->ast) ))
79#if defined( MLISP_DUMP_ENABLED ) || defined( DOCUMENTATION )
87 struct MLISP_PARSER* parser,
size_t ast_node_idx,
size_t depth,
char ab );
106#define _MLISP_TYPE_TABLE_CONSTS( idx, ctype, name, const_name, fmt ) \
107 MAUG_CONST uint8_t SEG_MCONST MLISP_TYPE_ ## const_name = idx;
111MLISP_PARSER_PSTATE_TABLE( MPARSER_PSTATE_TABLE_CONST )
113MPARSER_PSTATE_NAMES( MLISP_PARSER_PSTATE_TABLE, mlisp )
122_mlisp_ast_add_child(
struct MLISP_PARSER* parser, uint8_t flags ) {
126 ssize_t parent_child_idx = -1;
127 ssize_t new_idx_out = 0;
133 for( i = 0 ; MLISP_AST_IDX_CHILDREN_MAX > i ; i++ ) {
134 ast_node.ast_idx_children[i] = -1;
136 ast_node.token_idx = -1;
137 ast_node.ast_idx_children_sz = 0;
138 ast_node.flags = flags;
140 debug_printf( MLISP_PARSE_TRACE_LVL,
"adding node under " SSIZE_T_FMT
"...",
141 ast_node.ast_idx_parent );
144 new_idx_out = mdata_vector_append(
146 if( 0 > new_idx_out ) {
147 retval = mdata_retval( new_idx_out );
151 if( 0 <= ast_node.ast_idx_parent ) {
152 mdata_vector_lock( &(parser->ast) );
154 n_parent = mdata_vector_get(
158 parent_child_idx = 0;
159 while( -1 != n_parent->ast_idx_children[parent_child_idx] ) {
163 n_parent->ast_idx_children[parent_child_idx] = new_idx_out;
167 mdata_vector_unlock( &(parser->ast) );
182 debug_printf( MLISP_PARSE_TRACE_LVL,
"added node " SSIZE_T_FMT
183 " under parent: " SSIZE_T_FMT
" as child " SSIZE_T_FMT,
184 new_idx_out, ast_node.ast_idx_parent, parent_child_idx );
194 struct MLISP_PARSER* parser, mdata_strpool_idx_t token_idx,
size_t token_sz
198 char* strpool_token = NULL;
200 mdata_vector_lock( &(parser->ast) );
202 n = mdata_vector_get(
206 mdata_strpool_lock( &(parser->strpool) );
208 strpool_token = mdata_strpool_get( &(parser->strpool), token_idx );
209 assert( NULL != strpool_token );
211 if( 0 == token_sz ) {
212 token_sz = maug_strlen( strpool_token );
214 assert( 0 < token_sz );
217 if( 0 == strncmp( strpool_token,
"lambda", token_sz + 1 ) ) {
219 debug_printf( MLISP_PARSE_TRACE_LVL,
220 "setting node \"%s\" (" SIZE_T_FMT
") flag: LAMBDA",
221 strpool_token, token_sz );
222 n->flags |= MLISP_AST_FLAG_LAMBDA;
224 }
else if( 0 == strncmp( strpool_token,
"if", token_sz + 1 ) ) {
226 debug_printf( MLISP_PARSE_TRACE_LVL,
227 "setting node \"%s\" (" SIZE_T_FMT
") flag: IF",
228 strpool_token, token_sz );
229 n->flags |= MLISP_AST_FLAG_IF;
231 }
else if( 0 == strncmp( strpool_token,
"begin", token_sz + 1 ) ) {
233 debug_printf( MLISP_PARSE_TRACE_LVL,
234 "setting node \"%s\" (" SIZE_T_FMT
") flag: BEGIN",
235 strpool_token, token_sz );
236 n->flags |= MLISP_AST_FLAG_BEGIN;
238 }
else if( 0 == strncmp( strpool_token,
"define", token_sz + 1 ) ) {
240 debug_printf( MLISP_PARSE_TRACE_LVL,
241 "setting node \"%s\" (" SIZE_T_FMT
") flag: DEFINE",
242 strpool_token, token_sz );
243 n->flags |= MLISP_AST_FLAG_DEFINE;
247 debug_printf( MLISP_PARSE_TRACE_LVL,
248 "setting node " SSIZE_T_FMT
" token: \"%s\" (" SIZE_T_FMT
")",
253 n->token_idx = token_idx;
254 n->token_sz = token_sz;
258 if( mdata_strpool_is_locked( &(parser->strpool) ) ) {
259 mdata_strpool_unlock( &(parser->strpool) );
262 mdata_vector_unlock( &(parser->ast) );
274 mdata_vector_lock( &(parser->ast) );
278 n = mdata_vector_get(
283 debug_printf( MLISP_PARSE_TRACE_LVL,
"moved up to node: " SSIZE_T_FMT,
288 mdata_vector_unlock( &(parser->ast) );
298 mdata_strpool_idx_t str_idx = -1;
300 str_idx = mdata_strpool_append( &(parser->strpool),
301 parser->base.token, parser->base.token_sz, MDATA_STRPOOL_FLAG_DEDUPE );
303 error_printf(
"invalid str_idx: " SSIZE_T_FMT, str_idx );
304 retval = MERROR_ALLOC;
308 _mlisp_ast_add_child( parser, 0 );
309 _mlisp_ast_set_child_token( parser, str_idx, parser->base.token_sz );
310 mlisp_parser_reset_token( parser );
311 retval = _mlisp_ast_traverse_parent( parser );
319#if defined( MLISP_DUMP_ENABLED ) || defined( DOCUMENTATION )
322 struct MLISP_PARSER* parser,
size_t ast_node_idx,
size_t depth,
char ab
325 uint8_t autolock = 0;
332 mdata_vector_lock( &(parser->ast) );
334 MLISP_TRACE_SIGIL
" --- BEGIN AST DUMP ---" );
338 maug_mzero( indent, 101 );
339 assert( depth < 100 );
340 for( i = 0 ; depth > i ; i++ ) {
349 n = mdata_vector_get( &(parser->ast), ast_node_idx,
struct MLISP_AST_NODE );
350 mdata_strpool_lock( &(parser->strpool) );
352 MLISP_TRACE_SIGIL
" %s%c: \"%s\" (i: " SIZE_T_FMT
", t: " SSIZE_T_FMT
353 ", c: " SSIZE_T_FMT
", f: 0x%02x)",
354 indent, ab, 0 <= n->token_idx ?
355 mdata_strpool_get( &(parser->strpool), n->token_idx ) :
"",
357 mdata_strpool_unlock( &(parser->strpool) );
358 for( i = 0 ; MLISP_AST_IDX_CHILDREN_MAX > i ; i++ ) {
359 if( -1 == n->ast_idx_children[i] ) {
363 mlisp_ast_dump( parser, n->ast_idx_children[i], depth + 1,
'0' + i );
368 if( NULL != parser->ast.
data_bytes && autolock ) {
369 mdata_vector_unlock( &(parser->ast) );
371 MLISP_TRACE_SIGIL
" --- END AST DUMP ---" );
387 mdata_strpool_idx_t str_idx = -1;
389 size_t n_children = 0;
392#ifdef MPARSER_TRACE_NAMES
393 debug_printf( MLISP_PARSE_TRACE_LVL,
394 SIZE_T_FMT
": \"%c\" (last: \"%c\") (%s (%d)) (sz: " SIZE_T_FMT
")",
395 parser->base.i, c, parser->base.last_c,
396 gc_mlisp_pstate_names[mlisp_parser_pstate( parser )],
397 mlisp_parser_pstate( parser ),
398 parser->base.pstate_sz );
401 mdata_vector_lock( &(parser->ast) );
402 n = mdata_vector_get(
408 mdata_vector_unlock( &(parser->ast) );
413 if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
415 mlisp_parser_pstate_pop( parser );
422 MLISP_PSTATE_SYMBOL_OP == mlisp_parser_pstate( parser )
426 &&
'\r' != parser->base.last_c
427 &&
'\n' != parser->base.last_c
428 &&
'\t' != parser->base.last_c
429 &&
' ' != parser->base.last_c
430 &&
')' != parser->base.last_c
431 &&
'(' != parser->base.last_c
433 assert( 0 < parser->base.token_sz );
434 debug_printf( MLISP_PARSE_TRACE_LVL,
435 "found symbol: %s (" SIZE_T_FMT
")",
436 parser->base.token, parser->base.token_sz );
441 str_idx = mdata_strpool_append( &(parser->strpool),
442 parser->base.token, parser->base.token_sz,
443 MDATA_STRPOOL_FLAG_DEDUPE );
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 assert( 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 );
479 }
else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
480 retval = mlisp_parser_append_token( parser, c );
481 maug_cleanup_if_not_ok();
488 if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
489 mlisp_parser_pstate_pop( parser );
491 mlisp_parser_pstate_push( parser, MLISP_PSTATE_STRING );
497 MLISP_PSTATE_NONE == mlisp_parser_pstate( parser ) ||
498 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser )
501 MLISP_AST_FLAG_LAMBDA == (MLISP_AST_FLAG_LAMBDA & n_flags) &&
506 mlisp_parser_pstate_push( parser, MLISP_PSTATE_LAMBDA_ARGS );
509 retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL_OP );
511 maug_cleanup_if_not_ok();
512 mlisp_parser_reset_token( parser );
515 _mlisp_ast_add_child( parser, 0 );
517 }
else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
518 retval = mlisp_parser_append_token( parser, c );
519 maug_cleanup_if_not_ok();
522 mlisp_parser_invalid_c( parser, c, retval );
528 MLISP_PSTATE_SYMBOL_OP == mlisp_parser_pstate( parser ) ||
529 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser ) ||
530 MLISP_PSTATE_LAMBDA_ARGS == mlisp_parser_pstate( parser )
532 if( 0 < parser->base.token_sz ) {
536 _mlisp_ast_add_raw_token( parser );
540 mlisp_parser_pstate_pop( parser );
541 _mlisp_ast_traverse_parent( parser );
545 }
else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
546 retval = mlisp_parser_append_token( parser, c );
547 maug_cleanup_if_not_ok();
550 mlisp_parser_invalid_c( parser, c, retval );
555 if( MLISP_PSTATE_COMMENT != mlisp_parser_pstate( parser ) ) {
556 mlisp_parser_pstate_push( parser, MLISP_PSTATE_COMMENT );
561 if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
564 retval = mlisp_parser_append_token( parser, c );
565 maug_cleanup_if_not_ok();
569 mparser_wait( &(parser->base) );
575 parser->base.last_c = c;
590 debug_printf( MLISP_TRACE_LVL,
"loading mlisp AST..." );
593 maug_cleanup_if_not_ok();
595 retval = mlisp_parser_init( parser );
596 maug_cleanup_if_not_ok();
598 for( i = 0 ; mfile_get_sz( &ai_file ) > i ; i++ ) {
599 retval = ai_file.read_int( &ai_file, (uint8_t*)&c, 1, 0 );
600 maug_cleanup_if_not_ok();
601 retval = mlisp_parse_c( parser, c );
602 maug_cleanup_if_not_ok();
604#if defined( MLISP_DUMP_ENABLED )
607 if( 0 < parser->base.pstate_sz ) {
608 error_printf(
"invalid parser state!" );
609 retval = MERROR_EXEC;
622 ssize_t append_retval = 0;
624 debug_printf( MLISP_TRACE_LVL,
625 "initializing mlisp parser (" SIZE_T_FMT
" bytes)...",
641 if( 0 > append_retval ) {
642 retval = mdata_retval( append_retval );
644 maug_cleanup_if_not_ok();
648 if( MERROR_OK != retval ) {
649 error_printf(
"mlisp parser initialization failed: %d", retval );
658 debug_printf( MLISP_TRACE_LVL,
659 "destroying parser (ast: " SIZE_T_FMT
")...",
660 mdata_vector_ct( &(parser->ast) ) );
661 mdata_strpool_free( &(parser->strpool) );
662 mdata_vector_free( &(parser->ast) );
663 debug_printf( MLISP_PARSE_TRACE_LVL,
"parser destroyed!" );
668# define _MLISP_TYPE_TABLE_CONSTS( idx, ctype, name, const_name, fmt ) \
669 extern MAUG_CONST uint8_t SEG_MCONST MLISP_TYPE_ ## const_name;
int MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition merror.h:19
MERROR_RETVAL mfile_open_read(const char *filename, mfile_t *p_file)
Open a file and read it into memory or memory-map it.
char retroflat_asset_path[MAUG_PATH_SZ_MAX+1]
Path/name used to load an asset from disk.
Definition mfile.h:111
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.
uint8_t * data_bytes
Handle for allocated items (locked).
Definition mdata.h:100
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::fla...
Definition mlisps.h:202