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;
132 ast_node.ast_idx_parent = parser->ast_node_iter;
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) );
180 parser->ast_node_iter = new_idx_out;
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
197 char* strpool = NULL;
200 mdata_vector_lock( &(parser->ast) );
202 n = mdata_vector_get(
206 mdata_strpool_lock( &(parser->strpool), strpool );
207 if( 0 == token_sz ) {
208 token_sz = maug_strlen( &(strpool[token_idx]) );
210 assert( 0 < token_sz );
213 if( 0 == strncmp( &(strpool[token_idx]),
"lambda", token_sz + 1 ) ) {
215 debug_printf( MLISP_PARSE_TRACE_LVL,
216 "setting node \"%s\" (" SIZE_T_FMT
") flag: LAMBDA",
217 &(strpool[token_idx]), token_sz );
218 n->flags |= MLISP_AST_FLAG_LAMBDA;
220 }
else if( 0 == strncmp( &(strpool[token_idx]),
"if", token_sz + 1 ) ) {
222 debug_printf( MLISP_PARSE_TRACE_LVL,
223 "setting node \"%s\" (" SIZE_T_FMT
") flag: IF",
224 &(strpool[token_idx]), token_sz );
225 n->flags |= MLISP_AST_FLAG_IF;
227 }
else if( 0 == strncmp( &(strpool[token_idx]),
"begin", token_sz + 1 ) ) {
229 debug_printf( MLISP_PARSE_TRACE_LVL,
230 "setting node \"%s\" (" SIZE_T_FMT
") flag: BEGIN",
231 &(strpool[token_idx]), token_sz );
232 n->flags |= MLISP_AST_FLAG_BEGIN;
234 }
else if( 0 == strncmp( &(strpool[token_idx]),
"define", token_sz + 1 ) ) {
236 debug_printf( MLISP_PARSE_TRACE_LVL,
237 "setting node \"%s\" (" SIZE_T_FMT
") flag: DEFINE",
238 &(strpool[token_idx]), token_sz );
239 n->flags |= MLISP_AST_FLAG_DEFINE;
243 debug_printf( MLISP_PARSE_TRACE_LVL,
"setting node " SSIZE_T_FMT
244 " token: \"%s\" (" SIZE_T_FMT
")",
245 parser->ast_node_iter, &(strpool[token_idx]), token_sz );
246 mdata_strpool_unlock( &(parser->strpool), strpool );
249 n->token_idx = token_idx;
250 n->token_sz = token_sz;
254 if( NULL != strpool ) {
255 mdata_strpool_unlock( &(parser->strpool), strpool );
258 mdata_vector_unlock( &(parser->ast) );
270 mdata_vector_lock( &(parser->ast) );
272 assert( 0 <= parser->ast_node_iter );
274 n = mdata_vector_get(
277 parser->ast_node_iter = n->ast_idx_parent;
279 debug_printf( MLISP_PARSE_TRACE_LVL,
"moved up to node: " SSIZE_T_FMT,
280 parser->ast_node_iter );
284 mdata_vector_unlock( &(parser->ast) );
294 mdata_strpool_idx_t str_idx = -1;
296 str_idx = mdata_strpool_append( &(parser->strpool),
297 parser->base.token, parser->base.token_sz );
299 error_printf(
"invalid str_idx: " SSIZE_T_FMT, str_idx );
300 retval = MERROR_ALLOC;
304 _mlisp_ast_add_child( parser, 0 );
305 _mlisp_ast_set_child_token( parser, str_idx, parser->base.token_sz );
306 mlisp_parser_reset_token( parser );
307 retval = _mlisp_ast_traverse_parent( parser );
315#if defined( MLISP_DUMP_ENABLED ) || defined( DOCUMENTATION )
318 struct MLISP_PARSER* parser,
size_t ast_node_idx,
size_t depth,
char ab
321 uint8_t autolock = 0;
325 char* strpool = NULL;
329 mdata_vector_lock( &(parser->ast) );
331 MLISP_TRACE_SIGIL
" --- BEGIN AST DUMP ---" );
335 maug_mzero( indent, 101 );
336 assert( depth < 100 );
337 for( i = 0 ; depth > i ; i++ ) {
346 n = mdata_vector_get( &(parser->ast), ast_node_idx,
struct MLISP_AST_NODE );
347 mdata_strpool_lock( &(parser->strpool), strpool );
349 MLISP_TRACE_SIGIL
" %s%c: \"%s\" (i: " SIZE_T_FMT
", t: " SSIZE_T_FMT
350 ", c: " SSIZE_T_FMT
", f: 0x%02x)",
351 indent, ab, 0 <= n->token_idx ? &(strpool[n->token_idx]) :
"",
353 mdata_strpool_unlock( &(parser->strpool), strpool );
354 for( i = 0 ; MLISP_AST_IDX_CHILDREN_MAX > i ; i++ ) {
355 if( -1 == n->ast_idx_children[i] ) {
359 mlisp_ast_dump( parser, n->ast_idx_children[i], depth + 1,
'0' + i );
364 if( NULL != parser->ast.
data_bytes && autolock ) {
365 mdata_vector_unlock( &(parser->ast) );
367 MLISP_TRACE_SIGIL
" --- END AST DUMP ---" );
383 mdata_strpool_idx_t str_idx = -1;
385 size_t n_children = 0;
388#ifdef MPARSER_TRACE_NAMES
389 debug_printf( MLISP_PARSE_TRACE_LVL,
390 SIZE_T_FMT
": \"%c\" (last: \"%c\") (%s (%d)) (sz: " SIZE_T_FMT
")",
391 parser->base.i, c, parser->base.last_c,
392 gc_mlisp_pstate_names[mlisp_parser_pstate( parser )],
393 mlisp_parser_pstate( parser ),
394 parser->base.pstate_sz );
397 mdata_vector_lock( &(parser->ast) );
398 n = mdata_vector_get(
404 mdata_vector_unlock( &(parser->ast) );
409 if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
411 mlisp_parser_pstate_pop( parser );
418 MLISP_PSTATE_SYMBOL_OP == mlisp_parser_pstate( parser )
422 &&
'\r' != parser->base.last_c
423 &&
'\n' != parser->base.last_c
424 &&
'\t' != parser->base.last_c
425 &&
' ' != parser->base.last_c
426 &&
')' != parser->base.last_c
427 &&
'(' != parser->base.last_c
429 assert( 0 < parser->base.token_sz );
430 debug_printf( MLISP_PARSE_TRACE_LVL,
431 "found symbol: %s (" SIZE_T_FMT
")",
432 parser->base.token, parser->base.token_sz );
437 str_idx = mdata_strpool_append( &(parser->strpool),
438 parser->base.token, parser->base.token_sz );
439 mlisp_parser_reset_token( parser );
440 _mlisp_ast_set_child_token( parser, str_idx, parser->base.token_sz );
443 mlisp_parser_pstate_pop( parser );
444 retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL );
445 maug_cleanup_if_not_ok();
451 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser ) ||
452 MLISP_PSTATE_LAMBDA_ARGS == mlisp_parser_pstate( parser )
457 &&
'\r' != parser->base.last_c
458 &&
'\n' != parser->base.last_c
459 &&
'\t' != parser->base.last_c
460 &&
' ' != parser->base.last_c
461 &&
')' != parser->base.last_c
462 &&
'(' != parser->base.last_c
464 assert( 0 < parser->base.token_sz );
465 debug_printf( MLISP_PARSE_TRACE_LVL,
466 "found symbol: %s (" SIZE_T_FMT
")",
467 parser->base.token, parser->base.token_sz );
472 _mlisp_ast_add_raw_token( parser );
474 }
else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
475 retval = mlisp_parser_append_token( parser, c );
476 maug_cleanup_if_not_ok();
483 if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
484 mlisp_parser_pstate_pop( parser );
486 mlisp_parser_pstate_push( parser, MLISP_PSTATE_STRING );
492 MLISP_PSTATE_NONE == mlisp_parser_pstate( parser ) ||
493 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser )
496 MLISP_AST_FLAG_LAMBDA == (MLISP_AST_FLAG_LAMBDA & n_flags) &&
501 mlisp_parser_pstate_push( parser, MLISP_PSTATE_LAMBDA_ARGS );
504 retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL_OP );
506 maug_cleanup_if_not_ok();
507 mlisp_parser_reset_token( parser );
510 _mlisp_ast_add_child( parser, 0 );
512 }
else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
513 retval = mlisp_parser_append_token( parser, c );
514 maug_cleanup_if_not_ok();
517 mlisp_parser_invalid_c( parser, c, retval );
523 MLISP_PSTATE_SYMBOL_OP == mlisp_parser_pstate( parser ) ||
524 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser ) ||
525 MLISP_PSTATE_LAMBDA_ARGS == mlisp_parser_pstate( parser )
527 if( 0 < parser->base.token_sz ) {
531 _mlisp_ast_add_raw_token( parser );
535 mlisp_parser_pstate_pop( parser );
536 _mlisp_ast_traverse_parent( parser );
540 }
else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
541 retval = mlisp_parser_append_token( parser, c );
542 maug_cleanup_if_not_ok();
545 mlisp_parser_invalid_c( parser, c, retval );
550 if( MLISP_PSTATE_COMMENT != mlisp_parser_pstate( parser ) ) {
551 mlisp_parser_pstate_push( parser, MLISP_PSTATE_COMMENT );
556 if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
559 retval = mlisp_parser_append_token( parser, c );
560 maug_cleanup_if_not_ok();
564 mparser_wait( &(parser->base) );
570 parser->base.last_c = c;
585 debug_printf( MLISP_TRACE_LVL,
"loading mlisp AST..." );
588 maug_cleanup_if_not_ok();
590 retval = mlisp_parser_init( parser );
591 maug_cleanup_if_not_ok();
593 for( i = 0 ; mfile_get_sz( &ai_file ) > i ; i++ ) {
594 retval = ai_file.read_int( &ai_file, (uint8_t*)&c, 1, 0 );
595 maug_cleanup_if_not_ok();
596 retval = mlisp_parse_c( parser, c );
597 maug_cleanup_if_not_ok();
599#if defined( MLISP_DUMP_ENABLED )
602 if( 0 < parser->base.pstate_sz ) {
603 error_printf(
"invalid parser state!" );
604 retval = MERROR_EXEC;
617 ssize_t append_retval = 0;
619 assert( (MAUG_MHANDLE)NULL == parser->
env.
data_h );
621 debug_printf( MLISP_TRACE_LVL,
622 "initializing mlisp parser (" SIZE_T_FMT
" bytes)...",
627 parser->ast_node_iter = -1;
638 if( 0 > append_retval ) {
639 retval = mdata_retval( append_retval );
641 maug_cleanup_if_not_ok();
645 if( MERROR_OK != retval ) {
646 error_printf(
"mlisp parser initialization failed: %d", retval );
655 debug_printf( MLISP_TRACE_LVL,
656 "destroying parser (ast: " SIZE_T_FMT
", env: " SIZE_T_FMT
")...",
657 mdata_vector_ct( &(parser->ast) ), mdata_vector_ct( &(parser->
env) ) );
658 mdata_strpool_free( &(parser->strpool) );
659 mdata_vector_free( &(parser->ast) );
660 mdata_vector_free( &(parser->
env) );
661 debug_printf( MLISP_PARSE_TRACE_LVL,
"parser destroyed!" );
666# define _MLISP_TYPE_TABLE_CONSTS( idx, ctype, name, const_name, fmt ) \
667 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:103
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:80
MLISP Interpreter/Parser Structs.
MAUG_MHANDLE data_h
Handle for allocated items (unlocked).
Definition mdata.h:90
uint8_t * data_bytes
Handle for allocated items (locked).
Definition mdata.h:92
size_t ast_idx_children_sz
Number of children in MLISP_AST_NODE::ast_idx_children.
Definition mlisps.h:133
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:186