maug
Quick and dirty C mini-augmentation library.
mlispp.h
Go to the documentation of this file.
1
2#ifndef MLISPP_H
3#define MLISPP_H
4
5#include <mlisps.h>
6
15#ifndef MLISP_PARSE_TRACE_LVL
16# define MLISP_PARSE_TRACE_LVL 0
17#endif /* !MLISP_PARSE_TRACE_LVL */
18
19#define MLISP_AST_FLAG_LAMBDA 0x02
20
21#define MLISP_AST_FLAG_IF 0x04
22
23#define MLISP_AST_FLAG_DEFINE 0x08
24
25#define MLISP_AST_FLAG_BEGIN 0x20
26
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 )
34
40#define mlisp_parser_pstate( parser ) \
41 ((parser)->base.pstate_sz > 0 ? \
42 (parser)->base.pstate[(parser)->base.pstate_sz - 1] : MLISP_PSTATE_NONE)
43
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 );
48
49# define mlisp_parser_pstate_pop( parser ) \
50 mparser_pstate_pop( \
51 "mlisp", &((parser)->base), gc_mlisp_pstate_names );
52#else
53# define mlisp_parser_pstate_push( parser, new_pstate ) \
54 mparser_pstate_push( "mlisp", &((parser)->base), new_pstate )
55
56# define mlisp_parser_pstate_pop( parser ) \
57 mparser_pstate_pop( "mlisp", &((parser)->base) )
58#endif /* MPARSER_TRACE_NAMES */
59
60#define mlisp_parser_invalid_c( parser, c, retval ) \
61 mparser_invalid_c( mlisp, &((parser)->base), c, retval )
62
63#define mlisp_parser_reset_token( parser ) \
64 mparser_reset_token( "mlisp", &((parser)->base) )
65
66#define mlisp_parser_append_token( parser, c ) \
67 mparser_append_token( "mlisp", &((parser)->base), c )
68
69#define mlisp_parser_parse_token( parser ) \
70 parser->token_parser( \
71 (parser)->token, (parser)->token_sz, (parser)->token_parser_arg )
72
73#define mlisp_parser_is_loaded( p ) (0 < mdata_vector_sz( &((p)->ast) ))
74
75
80#define mlisp_check_ast( parser ) (0 < mdata_vector_ct( &((parser)->ast) ))
81
82#if defined( MLISP_DUMP_ENABLED ) || defined( DOCUMENTATION )
83
90 struct MLISP_PARSER* parser, size_t ast_node_idx, size_t depth, char ab );
91
92#endif /* MLISP_DUMP_ENABLED || DOCUMENTATION */
93 /* mlisp_parser */
95
96MERROR_RETVAL mlisp_parse_c( struct MLISP_PARSER* parser, char c );
97
98MERROR_RETVAL mlisp_parse_file(
99 struct MLISP_PARSER* parser, const maug_path ai_path );
100
101MERROR_RETVAL mlisp_parser_init( struct MLISP_PARSER* parser );
102
103void mlisp_parser_free( struct MLISP_PARSER* parser );
104 /* mlisp */
106
107#ifdef MLISPP_C
108
109#define _MLISP_TYPE_TABLE_CONSTS( idx, ctype, name, const_name, fmt ) \
110 MAUG_CONST uint8_t SEG_MCONST MLISP_TYPE_ ## const_name = idx;
111
112MLISP_TYPE_TABLE( _MLISP_TYPE_TABLE_CONSTS );
113
114MLISP_PARSER_PSTATE_TABLE( MPARSER_PSTATE_TABLE_CONST )
115
116MPARSER_PSTATE_NAMES( MLISP_PARSER_PSTATE_TABLE, mlisp )
117
118/* === */
119
120/* AST Functions */
121
122/* === */
123
124static MERROR_RETVAL
125_mlisp_ast_add_child( struct MLISP_PARSER* parser, uint8_t flags ) {
126 MERROR_RETVAL retval = MERROR_OK;
127 struct MLISP_AST_NODE* n_parent = NULL;
128 struct MLISP_AST_NODE ast_node;
129 ssize_t parent_child_idx = -1;
130 ssize_t new_idx_out = 0;
131 size_t i = 0;
132
133 /* Setup the new node to copy. */
134 maug_mzero( &ast_node, sizeof( struct MLISP_AST_NODE ) );
135 ast_node.ast_idx_parent = parser->ast_node_iter;
136 for( i = 0 ; MLISP_AST_IDX_CHILDREN_MAX > i ; i++ ) {
137 ast_node.ast_idx_children[i] = -1;
138 }
139 ast_node.token_idx = -1;
140 ast_node.ast_idx_children_sz = 0;
141 ast_node.flags = flags;
142
143 debug_printf( MLISP_PARSE_TRACE_LVL, "adding node under " SSIZE_T_FMT "...",
144 ast_node.ast_idx_parent );
145
146 /* Add the node to the AST and set it as the current node. */
147 new_idx_out = mdata_vector_append(
148 &(parser->ast), &ast_node, sizeof( struct MLISP_AST_NODE ) );
149 if( 0 > new_idx_out ) {
150 retval = mdata_retval( new_idx_out );
151 }
152
153 /* Find an available child slot on the parent, if there is one. */
154 if( 0 <= ast_node.ast_idx_parent ) {
155 mdata_vector_lock( &(parser->ast) );
156
157 n_parent = mdata_vector_get(
158 &(parser->ast), ast_node.ast_idx_parent, struct MLISP_AST_NODE );
159
160 /* Find the first free child slot. */
161 parent_child_idx = 0;
162 while( -1 != n_parent->ast_idx_children[parent_child_idx] ) {
163 parent_child_idx++;
164 }
165
166 n_parent->ast_idx_children[parent_child_idx] = new_idx_out;
167 n_parent->ast_idx_children_sz++;
168
169 n_parent = NULL;
170 mdata_vector_unlock( &(parser->ast) );
171 } else {
172 /* Find the first free child slot *on the parser*. */
173 /*
174 parent_child_idx = 0;
175 while( -1 != parser->ast_idx_children[parent_child_idx] ) {
176 parent_child_idx++;
177 }
178
179 parser->ast_idx_children[parent_child_idx] = new_idx_out;
180 */
181 }
182
183 parser->ast_node_iter = new_idx_out;
184
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 );
188
189cleanup:
190
191 return retval;
192}
193
194/* === */
195
196static MERROR_RETVAL _mlisp_ast_set_child_token(
197 struct MLISP_PARSER* parser, mdata_strpool_idx_t token_idx, size_t token_sz
198) {
199 MERROR_RETVAL retval = MERROR_OK;
200 struct MLISP_AST_NODE* n = NULL;
201 char* strpool_token = NULL;
202
203 mdata_vector_lock( &(parser->ast) );
204
205 n = mdata_vector_get(
206 &(parser->ast), parser->ast_node_iter, struct MLISP_AST_NODE );
207 assert( NULL != n );
208
209 mdata_strpool_lock( &(parser->strpool) );
210
211 strpool_token = mdata_strpool_get( &(parser->strpool), token_idx );
212 assert( NULL != strpool_token );
213
214 if( 0 == token_sz ) {
215 token_sz = maug_strlen( strpool_token );
216 }
217 assert( 0 < token_sz );
218
219 /* Setup flags based on token name. */
220 if( 0 == maug_strncmp( strpool_token, "lambda", 7 ) ) {
221 /* Special node: lambda. */
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;
226
227 } else if( 0 == maug_strncmp( strpool_token, "if", 3 ) ) {
228 /* Special node: if. */
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;
233
234 } else if( 0 == maug_strncmp( strpool_token, "begin", 6 ) ) {
235 /* Special node: begin. */
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;
240
241 } else if( 0 == maug_strncmp( strpool_token, "define", 7 ) ) {
242 /* Special node: define. */
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;
247 }
248
249 /* Debug report. */
250 debug_printf( MLISP_PARSE_TRACE_LVL,
251 "setting node " SSIZE_T_FMT " token: \"%s\" (" SIZE_T_FMT ")",
252 parser->ast_node_iter, strpool_token, token_sz );
253 /* mdata_strpool_unlock( &(parser->strpool), strpool ); */
254
255 /* Set the token from the strpool. */
256 n->token_idx = token_idx;
257 n->token_sz = token_sz;
258
259cleanup:
260
261 if( mdata_strpool_is_locked( &(parser->strpool) ) ) {
262 mdata_strpool_unlock( &(parser->strpool) );
263 }
264
265 mdata_vector_unlock( &(parser->ast) );
266
267 return retval;
268}
269
270/* === */
271
272static
273MERROR_RETVAL _mlisp_ast_traverse_parent( struct MLISP_PARSER* parser ) {
274 MERROR_RETVAL retval = MERROR_OK;
275 struct MLISP_AST_NODE* n = NULL;
276
277 mdata_vector_lock( &(parser->ast) );
278
279 assert( 0 <= parser->ast_node_iter );
280
281 n = mdata_vector_get(
282 &(parser->ast), parser->ast_node_iter, struct MLISP_AST_NODE );
283
284 parser->ast_node_iter = n->ast_idx_parent;
285
286 debug_printf( MLISP_PARSE_TRACE_LVL, "moved up to node: " SSIZE_T_FMT,
287 parser->ast_node_iter );
288
289cleanup:
290
291 mdata_vector_unlock( &(parser->ast) );
292
293 return retval;
294}
295
296/* === */
297
298static
299MERROR_RETVAL _mlisp_ast_add_raw_token( struct MLISP_PARSER* parser ) {
300 MERROR_RETVAL retval = MERROR_OK;
301 mdata_strpool_idx_t str_idx = 0;
302
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 );
306
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 );
311
312cleanup:
313 return retval;
314}
315
316/* === */
317
318#if defined( MLISP_DUMP_ENABLED ) || defined( DOCUMENTATION )
319
321 struct MLISP_PARSER* parser, size_t ast_node_idx, size_t depth, char ab
322) {
323 MERROR_RETVAL retval = MERROR_OK;
324 uint8_t autolock = 0;
325 struct MLISP_AST_NODE* n = NULL;
326 char indent[101];
327 size_t i = 0;
328
329 if( NULL == parser->ast.data_bytes ) {
330 autolock = 1;
331 mdata_vector_lock( &(parser->ast) );
332 debug_printf( 1,
333 MLISP_TRACE_SIGIL " --- BEGIN AST DUMP ---" );
334 }
335
336 /* Make indent. */
337 maug_mzero( indent, 101 );
338 assert( depth < 100 );
339 for( i = 0 ; depth > i ; i++ ) {
340 indent[i] = ' ';
341 }
342
343 if( 0 == ab ) {
344 ab = 'X';
345 }
346
347 /* Iterate node and children .*/
348 n = mdata_vector_get( &(parser->ast), ast_node_idx, struct MLISP_AST_NODE );
349 mdata_strpool_lock( &(parser->strpool) );
350 debug_printf( 1,
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 ?
354 mdata_strpool_get( &(parser->strpool), n->token_idx ) : "",
355 ast_node_idx, n->token_idx, n->ast_idx_children_sz, n->flags );
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] ) {
359 continue;
360 }
361
362 mlisp_ast_dump( parser, n->ast_idx_children[i], depth + 1, '0' + i );
363 }
364
365cleanup:
366
367 if( NULL != parser->ast.data_bytes && autolock ) {
368 mdata_vector_unlock( &(parser->ast) );
369 debug_printf( 1,
370 MLISP_TRACE_SIGIL " --- END AST DUMP ---" );
371 }
372
373 return retval;
374}
375
376#endif /* MLISP_DUMP_ENABLED */
377
378/* === */
379
380/* Parse Functions */
381
382/* === */
383
384MERROR_RETVAL mlisp_parse_c( struct MLISP_PARSER* parser, char c ) {
385 MERROR_RETVAL retval = MERROR_OK;
386 mdata_strpool_idx_t str_idx = 0;
387 uint8_t n_flags = 0;
388 size_t n_children = 0;
389 struct MLISP_AST_NODE* n = NULL;
390
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 );
398#endif /* MPARSER_TRACE_NAMES */
399
400 mdata_vector_lock( &(parser->ast) );
401 n = mdata_vector_get(
402 &(parser->ast), parser->ast_node_iter, struct MLISP_AST_NODE );
403 if( NULL != n ) {
404 n_flags = n->flags;
405 n_children = n->ast_idx_children_sz;
406 }
407 mdata_vector_unlock( &(parser->ast) );
408
409 switch( c ) {
410 case '\r':
411 case '\n':
412 if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
413 /* End comment on newline. */
414 mlisp_parser_pstate_pop( parser );
415 break;
416 }
417
418 case '\t':
419 case ' ':
420 if(
421 MLISP_PSTATE_SYMBOL_OP == mlisp_parser_pstate( parser )
422 /* Don't terminate the current symbol if the last_c was *any* of the
423 * other terminating characters.
424 */
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
431 ) {
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 );
436
437 /* Grab the symbol to use for the op of the child created by the last
438 * open paren.
439 */
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 );
446
447 /* Switch from OP to SYMBOL for subsequent tokens. */
448 mlisp_parser_pstate_pop( parser );
449 retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL );
450 maug_cleanup_if_not_ok();
451
452 /* mlisp_ast_dump( parser, 0, 0, 0 ); */
453
454 } else if(
455 (
456 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser ) ||
457 MLISP_PSTATE_LAMBDA_ARGS == mlisp_parser_pstate( parser )
458 )
459 /* Don't terminate the current symbol if the last_c was *any* of the
460 * other terminating characters.
461 */
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
468 ) {
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 );
473
474 /* A raw token without parens terminated by whitespace can't have
475 * children, so just create a one-off.
476 */
477 _mlisp_ast_add_raw_token( parser );
478 }
479
480 } else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
481 retval = mlisp_parser_append_token( parser, c );
482 maug_cleanup_if_not_ok();
483
484 }
485 break;
486
487 case '"':
488 /* TODO: Handle escaped mode. */
489 if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
490 mlisp_parser_pstate_pop( parser );
491 } else {
492 mlisp_parser_pstate_push( parser, MLISP_PSTATE_STRING );
493 }
494 break;
495
496 case '(':
497 if(
498 MLISP_PSTATE_NONE == mlisp_parser_pstate( parser ) ||
499 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser )
500 ) {
501 if(
502 MLISP_AST_FLAG_LAMBDA == (MLISP_AST_FLAG_LAMBDA & n_flags) &&
503 0 == n_children
504 ) {
505 /* Special case: all tokens in this parent are lambda args. */
506 retval =
507 mlisp_parser_pstate_push( parser, MLISP_PSTATE_LAMBDA_ARGS );
508 } else {
509 /* Otherwise, first symbol after an open paren is an op. */
510 retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL_OP );
511 }
512 maug_cleanup_if_not_ok();
513 mlisp_parser_reset_token( parser );
514
515 /* Add a new empty child to be filled out when tokens are parsed. */
516 _mlisp_ast_add_child( parser, 0 );
517
518 } else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
519 retval = mlisp_parser_append_token( parser, c );
520 maug_cleanup_if_not_ok();
521
522 } else {
523 mlisp_parser_invalid_c( parser, c, retval );
524 }
525 break;
526
527 case ')':
528 if(
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 )
532 ) {
533 if( 0 < parser->base.token_sz ) {
534 /* A raw token without parens terminated by whitespace can't have
535 * children, so just create a one-off.
536 */
537 _mlisp_ast_add_raw_token( parser );
538 }
539
540 /* Reset the parser and AST cursor up one level. */
541 mlisp_parser_pstate_pop( parser );
542 _mlisp_ast_traverse_parent( parser );
543
544 /* mlisp_ast_dump( parser, 0, 0, 0 ); */
545
546 } else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
547 retval = mlisp_parser_append_token( parser, c );
548 maug_cleanup_if_not_ok();
549
550 } else {
551 mlisp_parser_invalid_c( parser, c, retval );
552 }
553 break;
554
555 case ';':
556 if( MLISP_PSTATE_COMMENT != mlisp_parser_pstate( parser ) ) {
557 mlisp_parser_pstate_push( parser, MLISP_PSTATE_COMMENT );
558 break;
559 }
560
561 default:
562 if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
563 break;
564 }
565 retval = mlisp_parser_append_token( parser, c );
566 maug_cleanup_if_not_ok();
567 break;
568 }
569
570 mparser_wait( &(parser->base) );
571
572 parser->base.i++;
573
574cleanup:
575
576 parser->base.last_c = c;
577
578 return retval;
579}
580
581/* === */
582
583MERROR_RETVAL mlisp_parse_file(
584 struct MLISP_PARSER* parser, const maug_path ai_path
585) {
586 MERROR_RETVAL retval = MERROR_OK;
587 struct MFILE_CADDY ai_file;
588 char c;
589 size_t i = 0;
590
591 debug_printf( MLISP_TRACE_LVL, "loading mlisp AST..." );
592
593 retval = mfile_open_read( ai_path, &ai_file );
594 maug_cleanup_if_not_ok();
595
596 retval = mlisp_parser_init( parser );
597 maug_cleanup_if_not_ok();
598
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();
604 }
605#if defined( MLISP_DUMP_ENABLED )
606 mlisp_ast_dump( parser, 0, 0, 0 );
607#endif /* MLISP_DUMP_ENABLED */
608 if( 0 < parser->base.pstate_sz ) {
609 error_printf( "invalid parser state!" );
610 retval = MERROR_EXEC;
611 goto cleanup;
612 }
613
614cleanup:
615
616 return retval;
617}
618
619/* === */
620
621MERROR_RETVAL mlisp_parser_init( struct MLISP_PARSER* parser ) {
622 MERROR_RETVAL retval = MERROR_OK;
623 ssize_t append_retval = 0;
624
625 debug_printf( MLISP_TRACE_LVL,
626 "initializing mlisp parser (" SIZE_T_FMT " bytes)...",
627 sizeof( struct MLISP_PARSER ) );
628
629 maug_mzero( parser, sizeof( struct MLISP_PARSER ) );
630
631 parser->ast_node_iter = -1;
632 /*
633 for( i = 0 ; MLISP_AST_IDX_CHILDREN_MAX > i ; i++ ) {
634 parser->ast_idx_children[i] = -1;
635 }
636 */
637
638 /* Allocate the vectors for AST and ENV. */
639
640 append_retval = mdata_vector_alloc(
641 &(parser->ast), sizeof( struct MLISP_AST_NODE ), 0 );
642 if( 0 > append_retval ) {
643 retval = mdata_retval( append_retval );
644 }
645 maug_cleanup_if_not_ok();
646
647cleanup:
648
649 if( MERROR_OK != retval ) {
650 error_printf( "mlisp parser initialization failed: %d", retval );
651 }
652
653 return retval;
654}
655
656/* === */
657
658void mlisp_parser_free( struct MLISP_PARSER* parser ) {
659 debug_printf( MLISP_TRACE_LVL,
660 "destroying parser (ast: " SIZE_T_FMT ")...",
661 mdata_vector_ct( &(parser->ast) ) );
662 mdata_strpool_free( &(parser->strpool) );
663 mdata_vector_free( &(parser->ast) );
664 debug_printf( MLISP_PARSE_TRACE_LVL, "parser destroyed!" );
665}
666
667#else
668
669# define _MLISP_TYPE_TABLE_CONSTS( idx, ctype, name, const_name, fmt ) \
670 extern MAUG_CONST uint8_t SEG_MCONST MLISP_TYPE_ ## const_name;
671
672MLISP_TYPE_TABLE( _MLISP_TYPE_TABLE_CONSTS )
673
674#endif /* MLISPP_C */
675
676#endif /* !MLISPP_H */
677
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
Definition: mfile.h:206
Definition: mlisps.h:118
size_t ast_idx_children_sz
Number of children in MLISP_AST_NODE::ast_idx_children.
Definition: mlisps.h:126
Definition: mlisps.h:199
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