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 )
74 struct MLISP_PARSER* parser,
size_t ast_node_idx,
size_t depth,
char ab );
91#define _MLISP_TYPE_TABLE_CONSTS( idx, ctype, name, const_name, fmt ) \
92 MAUG_CONST uint8_t SEG_MCONST MLISP_TYPE_ ## const_name = idx;
96MLISP_PARSER_PSTATE_TABLE( MPARSER_PSTATE_TABLE_CONST )
98MPARSER_PSTATE_NAMES( MLISP_PARSER_PSTATE_TABLE, mlisp )
107_mlisp_ast_add_child(
struct MLISP_PARSER* parser, uint8_t flags ) {
111 ssize_t parent_child_idx = -1;
112 ssize_t new_idx_out = 0;
117 ast_node.ast_idx_parent = parser->ast_node_iter;
118 for( i = 0 ; MLISP_AST_IDX_CHILDREN_MAX > i ; i++ ) {
119 ast_node.ast_idx_children[i] = -1;
121 ast_node.token_idx = -1;
122 ast_node.ast_idx_children_sz = 0;
123 ast_node.flags = flags;
125 debug_printf( MLISP_PARSE_TRACE_LVL,
"adding node under " SSIZE_T_FMT
"...",
126 ast_node.ast_idx_parent );
129 new_idx_out = mdata_vector_append(
131 if( 0 > new_idx_out ) {
132 retval = mdata_retval( new_idx_out );
136 if( 0 <= ast_node.ast_idx_parent ) {
137 mdata_vector_lock( &(parser->ast) );
139 n_parent = mdata_vector_get(
143 parent_child_idx = 0;
144 while( -1 != n_parent->ast_idx_children[parent_child_idx] ) {
148 n_parent->ast_idx_children[parent_child_idx] = new_idx_out;
152 mdata_vector_unlock( &(parser->ast) );
165 parser->ast_node_iter = new_idx_out;
167 debug_printf( MLISP_PARSE_TRACE_LVL,
"added node " SSIZE_T_FMT
168 " under parent: " SSIZE_T_FMT
" as child " SSIZE_T_FMT,
169 new_idx_out, ast_node.ast_idx_parent, parent_child_idx );
179 struct MLISP_PARSER* parser, mdata_strpool_idx_t token_idx,
size_t token_sz
182 char* strpool = NULL;
185 mdata_vector_lock( &(parser->ast) );
187 n = mdata_vector_get(
191 mdata_strpool_lock( &(parser->strpool), strpool );
192 if( 0 == token_sz ) {
193 token_sz = maug_strlen( &(strpool[token_idx]) );
195 assert( 0 < token_sz );
198 if( 0 == strncmp( &(strpool[token_idx]),
"lambda", token_sz + 1 ) ) {
200 debug_printf( MLISP_PARSE_TRACE_LVL,
201 "setting node \"%s\" (" SIZE_T_FMT
") flag: LAMBDA",
202 &(strpool[token_idx]), token_sz );
203 n->flags |= MLISP_AST_FLAG_LAMBDA;
205 }
else if( 0 == strncmp( &(strpool[token_idx]),
"if", token_sz + 1 ) ) {
207 debug_printf( MLISP_PARSE_TRACE_LVL,
208 "setting node \"%s\" (" SIZE_T_FMT
") flag: IF",
209 &(strpool[token_idx]), token_sz );
210 n->flags |= MLISP_AST_FLAG_IF;
212 }
else if( 0 == strncmp( &(strpool[token_idx]),
"begin", token_sz + 1 ) ) {
214 debug_printf( MLISP_PARSE_TRACE_LVL,
215 "setting node \"%s\" (" SIZE_T_FMT
") flag: BEGIN",
216 &(strpool[token_idx]), token_sz );
217 n->flags |= MLISP_AST_FLAG_BEGIN;
219 }
else if( 0 == strncmp( &(strpool[token_idx]),
"define", token_sz + 1 ) ) {
221 debug_printf( MLISP_PARSE_TRACE_LVL,
222 "setting node \"%s\" (" SIZE_T_FMT
") flag: DEFINE",
223 &(strpool[token_idx]), token_sz );
224 n->flags |= MLISP_AST_FLAG_DEFINE;
228 debug_printf( MLISP_PARSE_TRACE_LVL,
"setting node " SSIZE_T_FMT
229 " token: \"%s\" (" SIZE_T_FMT
")",
230 parser->ast_node_iter, &(strpool[token_idx]), token_sz );
231 mdata_strpool_unlock( &(parser->strpool), strpool );
234 n->token_idx = token_idx;
235 n->token_sz = token_sz;
239 if( NULL != strpool ) {
240 mdata_strpool_unlock( &(parser->strpool), strpool );
243 mdata_vector_unlock( &(parser->ast) );
255 mdata_vector_lock( &(parser->ast) );
257 assert( 0 <= parser->ast_node_iter );
259 n = mdata_vector_get(
262 parser->ast_node_iter = n->ast_idx_parent;
264 debug_printf( MLISP_PARSE_TRACE_LVL,
"moved up to node: " SSIZE_T_FMT,
265 parser->ast_node_iter );
269 mdata_vector_unlock( &(parser->ast) );
279 mdata_strpool_idx_t str_idx = -1;
281 str_idx = mdata_strpool_append( &(parser->strpool),
282 parser->base.token, parser->base.token_sz );
284 error_printf(
"invalid str_idx: " SSIZE_T_FMT, str_idx );
285 retval = MERROR_ALLOC;
289 _mlisp_ast_add_child( parser, 0 );
290 _mlisp_ast_set_child_token( parser, str_idx, parser->base.token_sz );
291 mlisp_parser_reset_token( parser );
292 retval = _mlisp_ast_traverse_parent( parser );
301 struct MLISP_PARSER* parser,
size_t ast_node_idx,
size_t depth,
char ab
304 uint8_t autolock = 0;
308 char* strpool = NULL;
310 if( NULL == parser->ast.data_bytes ) {
312 mdata_vector_lock( &(parser->ast) );
313 debug_printf( MLISP_TRACE_LVL,
314 MLISP_TRACE_SIGIL
" --- BEGIN AST DUMP ---" );
319 assert( depth < 100 );
320 for( i = 0 ; depth > i ; i++ ) {
329 n = mdata_vector_get( &(parser->ast), ast_node_idx,
struct MLISP_AST_NODE );
330 mdata_strpool_lock( &(parser->strpool), strpool );
331 debug_printf( MLISP_TRACE_LVL,
332 MLISP_TRACE_SIGIL
" %s%c: \"%s\" (i: " SIZE_T_FMT
", t: " SSIZE_T_FMT
333 ", c: " SSIZE_T_FMT
", f: 0x%02x)",
334 indent, ab, 0 <= n->token_idx ? &(strpool[n->token_idx]) :
"",
336 mdata_strpool_unlock( &(parser->strpool), strpool );
337 for( i = 0 ; MLISP_AST_IDX_CHILDREN_MAX > i ; i++ ) {
338 if( -1 == n->ast_idx_children[i] ) {
342 mlisp_ast_dump( parser, n->ast_idx_children[i], depth + 1,
'0' + i );
347 if( NULL != parser->ast.data_bytes && autolock ) {
348 mdata_vector_unlock( &(parser->ast) );
349 debug_printf( MLISP_TRACE_LVL,
350 MLISP_TRACE_SIGIL
" --- END AST DUMP ---" );
364 mdata_strpool_idx_t str_idx = -1;
366 size_t n_children = 0;
369#ifdef MPARSER_TRACE_NAMES
370 debug_printf( MLISP_PARSE_TRACE_LVL,
371 SIZE_T_FMT
": \"%c\" (last: \"%c\") (%s (%d)) (sz: " SIZE_T_FMT
")",
372 parser->base.i, c, parser->base.last_c,
373 gc_mlisp_pstate_names[mlisp_parser_pstate( parser )],
374 mlisp_parser_pstate( parser ),
375 parser->base.pstate_sz );
378 mdata_vector_lock( &(parser->ast) );
379 n = mdata_vector_get(
385 mdata_vector_unlock( &(parser->ast) );
390 if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
392 mlisp_parser_pstate_pop( parser );
399 MLISP_PSTATE_SYMBOL_OP == mlisp_parser_pstate( parser )
403 &&
'\r' != parser->base.last_c
404 &&
'\n' != parser->base.last_c
405 &&
'\t' != parser->base.last_c
406 &&
' ' != parser->base.last_c
407 &&
')' != parser->base.last_c
408 &&
'(' != parser->base.last_c
410 assert( 0 < parser->base.token_sz );
411 debug_printf( MLISP_PARSE_TRACE_LVL,
412 "found symbol: %s (" SIZE_T_FMT
")",
413 parser->base.token, parser->base.token_sz );
418 str_idx = mdata_strpool_append( &(parser->strpool),
419 parser->base.token, parser->base.token_sz );
420 mlisp_parser_reset_token( parser );
421 _mlisp_ast_set_child_token( parser, str_idx, parser->base.token_sz );
424 mlisp_parser_pstate_pop( parser );
425 retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL );
426 maug_cleanup_if_not_ok();
432 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser ) ||
433 MLISP_PSTATE_LAMBDA_ARGS == mlisp_parser_pstate( parser )
438 &&
'\r' != parser->base.last_c
439 &&
'\n' != parser->base.last_c
440 &&
'\t' != parser->base.last_c
441 &&
' ' != parser->base.last_c
442 &&
')' != parser->base.last_c
443 &&
'(' != parser->base.last_c
445 assert( 0 < parser->base.token_sz );
446 debug_printf( MLISP_PARSE_TRACE_LVL,
447 "found symbol: %s (" SIZE_T_FMT
")",
448 parser->base.token, parser->base.token_sz );
453 _mlisp_ast_add_raw_token( parser );
455 }
else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
456 retval = mlisp_parser_append_token( parser, c );
457 maug_cleanup_if_not_ok();
464 MLISP_PSTATE_NONE == mlisp_parser_pstate( parser ) ||
465 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser )
468 MLISP_AST_FLAG_LAMBDA == (MLISP_AST_FLAG_LAMBDA & n_flags) &&
473 mlisp_parser_pstate_push( parser, MLISP_PSTATE_LAMBDA_ARGS );
476 retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL_OP );
478 maug_cleanup_if_not_ok();
479 mlisp_parser_reset_token( parser );
482 _mlisp_ast_add_child( parser, 0 );
484 }
else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
485 retval = mlisp_parser_append_token( parser, c );
486 maug_cleanup_if_not_ok();
489 mlisp_parser_invalid_c( parser, c, retval );
495 MLISP_PSTATE_SYMBOL_OP == mlisp_parser_pstate( parser ) ||
496 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser ) ||
497 MLISP_PSTATE_LAMBDA_ARGS == mlisp_parser_pstate( parser )
499 if( 0 < parser->base.token_sz ) {
503 _mlisp_ast_add_raw_token( parser );
507 mlisp_parser_pstate_pop( parser );
508 _mlisp_ast_traverse_parent( parser );
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 );
522 if( MLISP_PSTATE_COMMENT != mlisp_parser_pstate( parser ) ) {
523 mlisp_parser_pstate_push( parser, MLISP_PSTATE_COMMENT );
528 if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
531 retval = mlisp_parser_append_token( parser, c );
532 maug_cleanup_if_not_ok();
536 mparser_wait( &(parser->base) );
542 parser->base.last_c = c;
551 ssize_t append_retval = 0;
553 debug_printf( MLISP_TRACE_LVL,
554 "initializing mlisp parser (" SIZE_T_FMT
" bytes)...",
559 parser->ast_node_iter = -1;
568 append_retval = mdata_vector_alloc(
569 &(parser->ast),
sizeof(
struct MLISP_AST_NODE ), MDATA_VECTOR_INIT_SZ );
570 if( 0 > append_retval ) {
571 retval = mdata_retval( append_retval );
573 maug_cleanup_if_not_ok();
577 if( MERROR_OK != retval ) {
578 error_printf(
"mlisp parser initialization failed: %d", retval );
587 mdata_strpool_free( &(parser->strpool) );
588 mdata_vector_free( &(parser->ast) );
593# define _MLISP_TYPE_TABLE_CONSTS( idx, ctype, name, const_name, fmt ) \
594 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
#define MLISP_TYPE_TABLE(f)
Table of other types.
Definition mlisps.h:60
MLISP Interpreter/Parser Structs.
size_t ast_idx_children_sz
Number of children in MLISP_AST_NODE::ast_idx_children.
Definition mlisps.h:106