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