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 = 0;
299
300 str_idx = mdata_strpool_append( &(parser->strpool),
301 parser->base.token, parser->base.token_sz, MDATA_STRPOOL_FLAG_DEDUPE );
302 maug_cleanup_if_eq( str_idx, 0, SIZE_T_FMT, MERROR_ALLOC );
303
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 );
308
309cleanup:
310 return retval;
311}
312
313/* === */
314
315#if defined( MLISP_DUMP_ENABLED ) || defined( DOCUMENTATION )
316
318 struct MLISP_PARSER* parser, size_t ast_node_idx, size_t depth, char ab
319) {
320 MERROR_RETVAL retval = MERROR_OK;
321 uint8_t autolock = 0;
322 struct MLISP_AST_NODE* n = NULL;
323 char indent[101];
324 size_t i = 0;
325
326 if( NULL == parser->ast.data_bytes ) {
327 autolock = 1;
328 mdata_vector_lock( &(parser->ast) );
329 debug_printf( 1,
330 MLISP_TRACE_SIGIL " --- BEGIN AST DUMP ---" );
331 }
332
333 /* Make indent. */
334 maug_mzero( indent, 101 );
335 assert( depth < 100 );
336 for( i = 0 ; depth > i ; i++ ) {
337 indent[i] = ' ';
338 }
339
340 if( 0 == ab ) {
341 ab = 'X';
342 }
343
344 /* Iterate node and children .*/
345 n = mdata_vector_get( &(parser->ast), ast_node_idx, struct MLISP_AST_NODE );
346 mdata_strpool_lock( &(parser->strpool) );
347 debug_printf( 1,
348 MLISP_TRACE_SIGIL " %s%c: \"%s\" (i: " SIZE_T_FMT ", t: " SSIZE_T_FMT
349 ", c: " SSIZE_T_FMT ", f: 0x%02x)",
350 indent, ab, 0 <= n->token_idx ?
351 mdata_strpool_get( &(parser->strpool), n->token_idx ) : "",
352 ast_node_idx, n->token_idx, n->ast_idx_children_sz, n->flags );
353 mdata_strpool_unlock( &(parser->strpool) );
354 for( i = 0 ; MLISP_AST_IDX_CHILDREN_MAX > i ; i++ ) {
355 if( -1 == n->ast_idx_children[i] ) {
356 continue;
357 }
358
359 mlisp_ast_dump( parser, n->ast_idx_children[i], depth + 1, '0' + i );
360 }
361
362cleanup:
363
364 if( NULL != parser->ast.data_bytes && autolock ) {
365 mdata_vector_unlock( &(parser->ast) );
366 debug_printf( 1,
367 MLISP_TRACE_SIGIL " --- END AST DUMP ---" );
368 }
369
370 return retval;
371}
372
373#endif /* MLISP_DUMP_ENABLED */
374
375/* === */
376
377/* Parse Functions */
378
379/* === */
380
381MERROR_RETVAL mlisp_parse_c( struct MLISP_PARSER* parser, char c ) {
382 MERROR_RETVAL retval = MERROR_OK;
383 mdata_strpool_idx_t str_idx = 0;
384 uint8_t n_flags = 0;
385 size_t n_children = 0;
386 struct MLISP_AST_NODE* n = NULL;
387
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 );
395#endif /* MPARSER_TRACE_NAMES */
396
397 mdata_vector_lock( &(parser->ast) );
398 n = mdata_vector_get(
399 &(parser->ast), parser->ast_node_iter, struct MLISP_AST_NODE );
400 if( NULL != n ) {
401 n_flags = n->flags;
402 n_children = n->ast_idx_children_sz;
403 }
404 mdata_vector_unlock( &(parser->ast) );
405
406 switch( c ) {
407 case '\r':
408 case '\n':
409 if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
410 /* End comment on newline. */
411 mlisp_parser_pstate_pop( parser );
412 break;
413 }
414
415 case '\t':
416 case ' ':
417 if(
418 MLISP_PSTATE_SYMBOL_OP == mlisp_parser_pstate( parser )
419 /* Don't terminate the current symbol if the last_c was *any* of the
420 * other terminating characters.
421 */
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
428 ) {
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 );
433
434 /* Grab the symbol to use for the op of the child created by the last
435 * open paren.
436 */
437 str_idx = mdata_strpool_append( &(parser->strpool),
438 parser->base.token, parser->base.token_sz,
439 MDATA_STRPOOL_FLAG_DEDUPE );
440 maug_cleanup_if_eq( str_idx, 0, SIZE_T_FMT, MERROR_ALLOC );
441 mlisp_parser_reset_token( parser );
442 _mlisp_ast_set_child_token( parser, str_idx, parser->base.token_sz );
443
444 /* Switch from OP to SYMBOL for subsequent tokens. */
445 mlisp_parser_pstate_pop( parser );
446 retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL );
447 maug_cleanup_if_not_ok();
448
449 /* mlisp_ast_dump( parser, 0, 0, 0 ); */
450
451 } else if(
452 (
453 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser ) ||
454 MLISP_PSTATE_LAMBDA_ARGS == mlisp_parser_pstate( parser )
455 )
456 /* Don't terminate the current symbol if the last_c was *any* of the
457 * other terminating characters.
458 */
459 && '\r' != parser->base.last_c
460 && '\n' != parser->base.last_c
461 && '\t' != parser->base.last_c
462 && ' ' != parser->base.last_c
463 && ')' != parser->base.last_c
464 && '(' != parser->base.last_c
465 ) {
466 assert( 0 < parser->base.token_sz );
467 debug_printf( MLISP_PARSE_TRACE_LVL,
468 "found symbol: %s (" SIZE_T_FMT ")",
469 parser->base.token, parser->base.token_sz );
470
471 /* A raw token without parens terminated by whitespace can't have
472 * children, so just create a one-off.
473 */
474 _mlisp_ast_add_raw_token( parser );
475
476 } else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
477 retval = mlisp_parser_append_token( parser, c );
478 maug_cleanup_if_not_ok();
479
480 }
481 break;
482
483 case '"':
484 /* TODO: Handle escaped mode. */
485 if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
486 mlisp_parser_pstate_pop( parser );
487 } else {
488 mlisp_parser_pstate_push( parser, MLISP_PSTATE_STRING );
489 }
490 break;
491
492 case '(':
493 if(
494 MLISP_PSTATE_NONE == mlisp_parser_pstate( parser ) ||
495 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser )
496 ) {
497 if(
498 MLISP_AST_FLAG_LAMBDA == (MLISP_AST_FLAG_LAMBDA & n_flags) &&
499 0 == n_children
500 ) {
501 /* Special case: all tokens in this parent are lambda args. */
502 retval =
503 mlisp_parser_pstate_push( parser, MLISP_PSTATE_LAMBDA_ARGS );
504 } else {
505 /* Otherwise, first symbol after an open paren is an op. */
506 retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL_OP );
507 }
508 maug_cleanup_if_not_ok();
509 mlisp_parser_reset_token( parser );
510
511 /* Add a new empty child to be filled out when tokens are parsed. */
512 _mlisp_ast_add_child( parser, 0 );
513
514 } else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
515 retval = mlisp_parser_append_token( parser, c );
516 maug_cleanup_if_not_ok();
517
518 } else {
519 mlisp_parser_invalid_c( parser, c, retval );
520 }
521 break;
522
523 case ')':
524 if(
525 MLISP_PSTATE_SYMBOL_OP == mlisp_parser_pstate( parser ) ||
526 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser ) ||
527 MLISP_PSTATE_LAMBDA_ARGS == mlisp_parser_pstate( parser )
528 ) {
529 if( 0 < parser->base.token_sz ) {
530 /* A raw token without parens terminated by whitespace can't have
531 * children, so just create a one-off.
532 */
533 _mlisp_ast_add_raw_token( parser );
534 }
535
536 /* Reset the parser and AST cursor up one level. */
537 mlisp_parser_pstate_pop( parser );
538 _mlisp_ast_traverse_parent( parser );
539
540 /* mlisp_ast_dump( parser, 0, 0, 0 ); */
541
542 } else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
543 retval = mlisp_parser_append_token( parser, c );
544 maug_cleanup_if_not_ok();
545
546 } else {
547 mlisp_parser_invalid_c( parser, c, retval );
548 }
549 break;
550
551 case ';':
552 if( MLISP_PSTATE_COMMENT != mlisp_parser_pstate( parser ) ) {
553 mlisp_parser_pstate_push( parser, MLISP_PSTATE_COMMENT );
554 break;
555 }
556
557 default:
558 if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
559 break;
560 }
561 retval = mlisp_parser_append_token( parser, c );
562 maug_cleanup_if_not_ok();
563 break;
564 }
565
566 mparser_wait( &(parser->base) );
567
568 parser->base.i++;
569
570cleanup:
571
572 parser->base.last_c = c;
573
574 return retval;
575}
576
577/* === */
578
579MERROR_RETVAL mlisp_parse_file(
580 struct MLISP_PARSER* parser, const retroflat_asset_path ai_path
581) {
582 MERROR_RETVAL retval = MERROR_OK;
583 struct MFILE_CADDY ai_file;
584 char c;
585 size_t i = 0;
586
587 debug_printf( MLISP_TRACE_LVL, "loading mlisp AST..." );
588
589 retval = mfile_open_read( ai_path, &ai_file );
590 maug_cleanup_if_not_ok();
591
592 retval = mlisp_parser_init( parser );
593 maug_cleanup_if_not_ok();
594
595 for( i = 0 ; mfile_get_sz( &ai_file ) > i ; i++ ) {
596 retval = ai_file.read_int( &ai_file, (uint8_t*)&c, 1, 0 );
597 maug_cleanup_if_not_ok();
598 retval = mlisp_parse_c( parser, c );
599 maug_cleanup_if_not_ok();
600 }
601#if defined( MLISP_DUMP_ENABLED )
602 mlisp_ast_dump( parser, 0, 0, 0 );
603#endif /* MLISP_DUMP_ENABLED */
604 if( 0 < parser->base.pstate_sz ) {
605 error_printf( "invalid parser state!" );
606 retval = MERROR_EXEC;
607 goto cleanup;
608 }
609
610cleanup:
611
612 return retval;
613}
614
615/* === */
616
617MERROR_RETVAL mlisp_parser_init( struct MLISP_PARSER* parser ) {
618 MERROR_RETVAL retval = MERROR_OK;
619 ssize_t append_retval = 0;
620
621 debug_printf( MLISP_TRACE_LVL,
622 "initializing mlisp parser (" SIZE_T_FMT " bytes)...",
623 sizeof( struct MLISP_PARSER ) );
624
625 maug_mzero( parser, sizeof( struct MLISP_PARSER ) );
626
627 parser->ast_node_iter = -1;
628 /*
629 for( i = 0 ; MLISP_AST_IDX_CHILDREN_MAX > i ; i++ ) {
630 parser->ast_idx_children[i] = -1;
631 }
632 */
633
634 /* Allocate the vectors for AST and ENV. */
635
636 append_retval = mdata_vector_alloc(
637 &(parser->ast), sizeof( struct MLISP_AST_NODE ), 0 );
638 if( 0 > append_retval ) {
639 retval = mdata_retval( append_retval );
640 }
641 maug_cleanup_if_not_ok();
642
643cleanup:
644
645 if( MERROR_OK != retval ) {
646 error_printf( "mlisp parser initialization failed: %d", retval );
647 }
648
649 return retval;
650}
651
652/* === */
653
654void mlisp_parser_free( struct MLISP_PARSER* parser ) {
655 debug_printf( MLISP_TRACE_LVL,
656 "destroying parser (ast: " SIZE_T_FMT ")...",
657 mdata_vector_ct( &(parser->ast) ) );
658 mdata_strpool_free( &(parser->strpool) );
659 mdata_vector_free( &(parser->ast) );
660 debug_printf( MLISP_PARSE_TRACE_LVL, "parser destroyed!" );
661}
662
663#else
664
665# define _MLISP_TYPE_TABLE_CONSTS( idx, ctype, name, const_name, fmt ) \
666 extern MAUG_CONST uint8_t SEG_MCONST MLISP_TYPE_ ## const_name;
667
668MLISP_TYPE_TABLE( _MLISP_TYPE_TABLE_CONSTS )
669
670#endif /* MLISPP_C */
671
672#endif /* !MLISPP_H */
673
uint16_t 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:129
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:98
Definition mfile.h:194
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::fla...
Definition mlisps.h:207