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) ))
80 struct MLISP_PARSER* parser,
size_t ast_node_idx,
size_t depth,
char ab );
97#define _MLISP_TYPE_TABLE_CONSTS( idx, ctype, name, const_name, fmt ) \
98 MAUG_CONST uint8_t SEG_MCONST MLISP_TYPE_ ## const_name = idx;
102MLISP_PARSER_PSTATE_TABLE( MPARSER_PSTATE_TABLE_CONST )
104MPARSER_PSTATE_NAMES( MLISP_PARSER_PSTATE_TABLE, mlisp )
113_mlisp_ast_add_child(
struct MLISP_PARSER* parser, uint8_t flags ) {
117 ssize_t parent_child_idx = -1;
118 ssize_t new_idx_out = 0;
123 ast_node.ast_idx_parent = parser->ast_node_iter;
124 for( i = 0 ; MLISP_AST_IDX_CHILDREN_MAX > i ; i++ ) {
125 ast_node.ast_idx_children[i] = -1;
127 ast_node.token_idx = -1;
128 ast_node.ast_idx_children_sz = 0;
129 ast_node.flags = flags;
131 debug_printf( MLISP_PARSE_TRACE_LVL,
"adding node under " SSIZE_T_FMT
"...",
132 ast_node.ast_idx_parent );
135 new_idx_out = mdata_vector_append(
137 if( 0 > new_idx_out ) {
138 retval = mdata_retval( new_idx_out );
142 if( 0 <= ast_node.ast_idx_parent ) {
143 mdata_vector_lock( &(parser->ast) );
145 n_parent = mdata_vector_get(
149 parent_child_idx = 0;
150 while( -1 != n_parent->ast_idx_children[parent_child_idx] ) {
154 n_parent->ast_idx_children[parent_child_idx] = new_idx_out;
158 mdata_vector_unlock( &(parser->ast) );
171 parser->ast_node_iter = new_idx_out;
173 debug_printf( MLISP_PARSE_TRACE_LVL,
"added node " SSIZE_T_FMT
174 " under parent: " SSIZE_T_FMT
" as child " SSIZE_T_FMT,
175 new_idx_out, ast_node.ast_idx_parent, parent_child_idx );
185 struct MLISP_PARSER* parser, mdata_strpool_idx_t token_idx,
size_t token_sz
188 char* strpool = NULL;
191 mdata_vector_lock( &(parser->ast) );
193 n = mdata_vector_get(
197 mdata_strpool_lock( &(parser->strpool), strpool );
198 if( 0 == token_sz ) {
199 token_sz = maug_strlen( &(strpool[token_idx]) );
201 assert( 0 < token_sz );
204 if( 0 == strncmp( &(strpool[token_idx]),
"lambda", token_sz + 1 ) ) {
206 debug_printf( MLISP_PARSE_TRACE_LVL,
207 "setting node \"%s\" (" SIZE_T_FMT
") flag: LAMBDA",
208 &(strpool[token_idx]), token_sz );
209 n->flags |= MLISP_AST_FLAG_LAMBDA;
211 }
else if( 0 == strncmp( &(strpool[token_idx]),
"if", token_sz + 1 ) ) {
213 debug_printf( MLISP_PARSE_TRACE_LVL,
214 "setting node \"%s\" (" SIZE_T_FMT
") flag: IF",
215 &(strpool[token_idx]), token_sz );
216 n->flags |= MLISP_AST_FLAG_IF;
218 }
else if( 0 == strncmp( &(strpool[token_idx]),
"begin", token_sz + 1 ) ) {
220 debug_printf( MLISP_PARSE_TRACE_LVL,
221 "setting node \"%s\" (" SIZE_T_FMT
") flag: BEGIN",
222 &(strpool[token_idx]), token_sz );
223 n->flags |= MLISP_AST_FLAG_BEGIN;
225 }
else if( 0 == strncmp( &(strpool[token_idx]),
"define", token_sz + 1 ) ) {
227 debug_printf( MLISP_PARSE_TRACE_LVL,
228 "setting node \"%s\" (" SIZE_T_FMT
") flag: DEFINE",
229 &(strpool[token_idx]), token_sz );
230 n->flags |= MLISP_AST_FLAG_DEFINE;
234 debug_printf( MLISP_PARSE_TRACE_LVL,
"setting node " SSIZE_T_FMT
235 " token: \"%s\" (" SIZE_T_FMT
")",
236 parser->ast_node_iter, &(strpool[token_idx]), token_sz );
237 mdata_strpool_unlock( &(parser->strpool), strpool );
240 n->token_idx = token_idx;
241 n->token_sz = token_sz;
245 if( NULL != strpool ) {
246 mdata_strpool_unlock( &(parser->strpool), strpool );
249 mdata_vector_unlock( &(parser->ast) );
261 mdata_vector_lock( &(parser->ast) );
263 assert( 0 <= parser->ast_node_iter );
265 n = mdata_vector_get(
268 parser->ast_node_iter = n->ast_idx_parent;
270 debug_printf( MLISP_PARSE_TRACE_LVL,
"moved up to node: " SSIZE_T_FMT,
271 parser->ast_node_iter );
275 mdata_vector_unlock( &(parser->ast) );
285 mdata_strpool_idx_t str_idx = -1;
287 str_idx = mdata_strpool_append( &(parser->strpool),
288 parser->base.token, parser->base.token_sz );
290 error_printf(
"invalid str_idx: " SSIZE_T_FMT, str_idx );
291 retval = MERROR_ALLOC;
295 _mlisp_ast_add_child( parser, 0 );
296 _mlisp_ast_set_child_token( parser, str_idx, parser->base.token_sz );
297 mlisp_parser_reset_token( parser );
298 retval = _mlisp_ast_traverse_parent( parser );
307 struct MLISP_PARSER* parser,
size_t ast_node_idx,
size_t depth,
char ab
310 uint8_t autolock = 0;
314 char* strpool = NULL;
318 mdata_vector_lock( &(parser->ast) );
319 debug_printf( MLISP_TRACE_LVL,
320 MLISP_TRACE_SIGIL
" --- BEGIN AST DUMP ---" );
325 assert( depth < 100 );
326 for( i = 0 ; depth > i ; i++ ) {
335 n = mdata_vector_get( &(parser->ast), ast_node_idx,
struct MLISP_AST_NODE );
336 mdata_strpool_lock( &(parser->strpool), strpool );
337 debug_printf( MLISP_TRACE_LVL,
338 MLISP_TRACE_SIGIL
" %s%c: \"%s\" (i: " SIZE_T_FMT
", t: " SSIZE_T_FMT
339 ", c: " SSIZE_T_FMT
", f: 0x%02x)",
340 indent, ab, 0 <= n->token_idx ? &(strpool[n->token_idx]) :
"",
342 mdata_strpool_unlock( &(parser->strpool), strpool );
343 for( i = 0 ; MLISP_AST_IDX_CHILDREN_MAX > i ; i++ ) {
344 if( -1 == n->ast_idx_children[i] ) {
348 mlisp_ast_dump( parser, n->ast_idx_children[i], depth + 1,
'0' + i );
353 if( NULL != parser->ast.
data_bytes && autolock ) {
354 mdata_vector_unlock( &(parser->ast) );
355 debug_printf( MLISP_TRACE_LVL,
356 MLISP_TRACE_SIGIL
" --- END AST DUMP ---" );
370 mdata_strpool_idx_t str_idx = -1;
372 size_t n_children = 0;
375#ifdef MPARSER_TRACE_NAMES
376 debug_printf( MLISP_PARSE_TRACE_LVL,
377 SIZE_T_FMT
": \"%c\" (last: \"%c\") (%s (%d)) (sz: " SIZE_T_FMT
")",
378 parser->base.i, c, parser->base.last_c,
379 gc_mlisp_pstate_names[mlisp_parser_pstate( parser )],
380 mlisp_parser_pstate( parser ),
381 parser->base.pstate_sz );
384 mdata_vector_lock( &(parser->ast) );
385 n = mdata_vector_get(
391 mdata_vector_unlock( &(parser->ast) );
396 if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
398 mlisp_parser_pstate_pop( parser );
405 MLISP_PSTATE_SYMBOL_OP == mlisp_parser_pstate( parser )
409 &&
'\r' != parser->base.last_c
410 &&
'\n' != parser->base.last_c
411 &&
'\t' != parser->base.last_c
412 &&
' ' != parser->base.last_c
413 &&
')' != parser->base.last_c
414 &&
'(' != parser->base.last_c
416 assert( 0 < parser->base.token_sz );
417 debug_printf( MLISP_PARSE_TRACE_LVL,
418 "found symbol: %s (" SIZE_T_FMT
")",
419 parser->base.token, parser->base.token_sz );
424 str_idx = mdata_strpool_append( &(parser->strpool),
425 parser->base.token, parser->base.token_sz );
426 mlisp_parser_reset_token( parser );
427 _mlisp_ast_set_child_token( parser, str_idx, parser->base.token_sz );
430 mlisp_parser_pstate_pop( parser );
431 retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL );
432 maug_cleanup_if_not_ok();
438 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser ) ||
439 MLISP_PSTATE_LAMBDA_ARGS == mlisp_parser_pstate( parser )
444 &&
'\r' != parser->base.last_c
445 &&
'\n' != parser->base.last_c
446 &&
'\t' != parser->base.last_c
447 &&
' ' != parser->base.last_c
448 &&
')' != parser->base.last_c
449 &&
'(' != parser->base.last_c
451 assert( 0 < parser->base.token_sz );
452 debug_printf( MLISP_PARSE_TRACE_LVL,
453 "found symbol: %s (" SIZE_T_FMT
")",
454 parser->base.token, parser->base.token_sz );
459 _mlisp_ast_add_raw_token( parser );
461 }
else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
462 retval = mlisp_parser_append_token( parser, c );
463 maug_cleanup_if_not_ok();
470 if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
471 mlisp_parser_pstate_pop( parser );
473 mlisp_parser_pstate_push( parser, MLISP_PSTATE_STRING );
479 MLISP_PSTATE_NONE == mlisp_parser_pstate( parser ) ||
480 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser )
483 MLISP_AST_FLAG_LAMBDA == (MLISP_AST_FLAG_LAMBDA & n_flags) &&
488 mlisp_parser_pstate_push( parser, MLISP_PSTATE_LAMBDA_ARGS );
491 retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL_OP );
493 maug_cleanup_if_not_ok();
494 mlisp_parser_reset_token( parser );
497 _mlisp_ast_add_child( parser, 0 );
499 }
else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
500 retval = mlisp_parser_append_token( parser, c );
501 maug_cleanup_if_not_ok();
504 mlisp_parser_invalid_c( parser, c, retval );
510 MLISP_PSTATE_SYMBOL_OP == mlisp_parser_pstate( parser ) ||
511 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser ) ||
512 MLISP_PSTATE_LAMBDA_ARGS == mlisp_parser_pstate( parser )
514 if( 0 < parser->base.token_sz ) {
518 _mlisp_ast_add_raw_token( parser );
522 mlisp_parser_pstate_pop( parser );
523 _mlisp_ast_traverse_parent( parser );
527 }
else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
528 retval = mlisp_parser_append_token( parser, c );
529 maug_cleanup_if_not_ok();
532 mlisp_parser_invalid_c( parser, c, retval );
537 if( MLISP_PSTATE_COMMENT != mlisp_parser_pstate( parser ) ) {
538 mlisp_parser_pstate_push( parser, MLISP_PSTATE_COMMENT );
543 if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
546 retval = mlisp_parser_append_token( parser, c );
547 maug_cleanup_if_not_ok();
551 mparser_wait( &(parser->base) );
557 parser->base.last_c = c;
572 debug_printf( MLISP_TRACE_LVL,
"loading mlisp AST..." );
575 maug_cleanup_if_not_ok();
577 retval = mlisp_parser_init( parser );
578 maug_cleanup_if_not_ok();
580 for( i = 0 ; mfile_get_sz( &ai_file ) > i ; i++ ) {
581 retval = ai_file.read_int( &ai_file, (uint8_t*)&c, 1, 0 );
582 maug_cleanup_if_not_ok();
583 retval = mlisp_parse_c( parser, c );
584 maug_cleanup_if_not_ok();
586 mlisp_ast_dump( parser, 0, 0, 0 );
587 if( 0 < parser->base.pstate_sz ) {
588 error_printf(
"invalid parser state!" );
589 retval = MERROR_EXEC;
602 ssize_t append_retval = 0;
606 debug_printf( MLISP_TRACE_LVL,
607 "initializing mlisp parser (" SIZE_T_FMT
" bytes)...",
612 parser->ast_node_iter = -1;
622 &(parser->ast),
sizeof(
struct MLISP_AST_NODE ), MDATA_VECTOR_INIT_SZ );
623 if( 0 > append_retval ) {
624 retval = mdata_retval( append_retval );
626 maug_cleanup_if_not_ok();
630 if( MERROR_OK != retval ) {
631 error_printf(
"mlisp parser initialization failed: %d", retval );
640 debug_printf( MLISP_TRACE_LVL,
641 "destroying parser (ast: " SIZE_T_FMT
", env: " SIZE_T_FMT
")...",
642 mdata_vector_ct( &(parser->ast) ), mdata_vector_ct( &(parser->
env) ) );
643 mdata_strpool_free( &(parser->strpool) );
644 mdata_vector_free( &(parser->ast) );
645 mdata_vector_free( &(parser->
env) );
646 debug_printf( MLISP_PARSE_TRACE_LVL,
"parser destroyed!" );
651# define _MLISP_TYPE_TABLE_CONSTS( idx, ctype, name, const_name, fmt ) \
652 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
#define maug_mzero(ptr, sz)
Zero the block of memory pointed to by ptr.
Definition mmem.h:62
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[RETROFLAT_PATH_MAX]
Path/name used to load an asset from disk.
Definition retroflt.h:771
MERROR_RETVAL mdata_vector_alloc(struct MDATA_VECTOR *v, size_t item_sz, size_t item_ct_init)
#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:92
uint8_t * data_bytes
Handle for allocated items (locked).
Definition mdata.h:94
size_t ast_idx_children_sz
Number of children in MLISP_AST_NODE::ast_idx_children.
Definition mlisps.h:126
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