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 char* strpool = NULL;
198 struct MLISP_AST_NODE* n = 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), strpool );
207 if( 0 == token_sz ) {
208 token_sz = maug_strlen( &(strpool[token_idx]) );
209 }
210 assert( 0 < token_sz );
211
212 /* Setup flags based on token name. */
213 if( 0 == strncmp( &(strpool[token_idx]), "lambda", token_sz + 1 ) ) {
214 /* Special node: lambda. */
215 debug_printf( MLISP_PARSE_TRACE_LVL,
216 "setting node \"%s\" (" SIZE_T_FMT ") flag: LAMBDA",
217 &(strpool[token_idx]), token_sz );
218 n->flags |= MLISP_AST_FLAG_LAMBDA;
219
220 } else if( 0 == strncmp( &(strpool[token_idx]), "if", token_sz + 1 ) ) {
221 /* Special node: if. */
222 debug_printf( MLISP_PARSE_TRACE_LVL,
223 "setting node \"%s\" (" SIZE_T_FMT ") flag: IF",
224 &(strpool[token_idx]), token_sz );
225 n->flags |= MLISP_AST_FLAG_IF;
226
227 } else if( 0 == strncmp( &(strpool[token_idx]), "begin", token_sz + 1 ) ) {
228 /* Special node: begin. */
229 debug_printf( MLISP_PARSE_TRACE_LVL,
230 "setting node \"%s\" (" SIZE_T_FMT ") flag: BEGIN",
231 &(strpool[token_idx]), token_sz );
232 n->flags |= MLISP_AST_FLAG_BEGIN;
233
234 } else if( 0 == strncmp( &(strpool[token_idx]), "define", token_sz + 1 ) ) {
235 /* Special node: define. */
236 debug_printf( MLISP_PARSE_TRACE_LVL,
237 "setting node \"%s\" (" SIZE_T_FMT ") flag: DEFINE",
238 &(strpool[token_idx]), token_sz );
239 n->flags |= MLISP_AST_FLAG_DEFINE;
240 }
241
242 /* Debug report. */
243 debug_printf( MLISP_PARSE_TRACE_LVL, "setting node " SSIZE_T_FMT
244 " token: \"%s\" (" SIZE_T_FMT ")",
245 parser->ast_node_iter, &(strpool[token_idx]), token_sz );
246 mdata_strpool_unlock( &(parser->strpool), strpool );
247
248 /* Set the token from the strpool. */
249 n->token_idx = token_idx;
250 n->token_sz = token_sz;
251
252cleanup:
253
254 if( NULL != strpool ) {
255 mdata_strpool_unlock( &(parser->strpool), strpool );
256 }
257
258 mdata_vector_unlock( &(parser->ast) );
259
260 return retval;
261}
262
263/* === */
264
265static
266MERROR_RETVAL _mlisp_ast_traverse_parent( struct MLISP_PARSER* parser ) {
267 MERROR_RETVAL retval = MERROR_OK;
268 struct MLISP_AST_NODE* n = NULL;
269
270 mdata_vector_lock( &(parser->ast) );
271
272 assert( 0 <= parser->ast_node_iter );
273
274 n = mdata_vector_get(
275 &(parser->ast), parser->ast_node_iter, struct MLISP_AST_NODE );
276
277 parser->ast_node_iter = n->ast_idx_parent;
278
279 debug_printf( MLISP_PARSE_TRACE_LVL, "moved up to node: " SSIZE_T_FMT,
280 parser->ast_node_iter );
281
282cleanup:
283
284 mdata_vector_unlock( &(parser->ast) );
285
286 return retval;
287}
288
289/* === */
290
291static
292MERROR_RETVAL _mlisp_ast_add_raw_token( struct MLISP_PARSER* parser ) {
293 MERROR_RETVAL retval = MERROR_OK;
294 mdata_strpool_idx_t str_idx = -1;
295
296 str_idx = mdata_strpool_append( &(parser->strpool),
297 parser->base.token, parser->base.token_sz );
298 if( 0 > str_idx ) {
299 error_printf( "invalid str_idx: " SSIZE_T_FMT, str_idx );
300 retval = MERROR_ALLOC;
301 goto cleanup;
302 }
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 char* strpool = NULL;
326
327 if( NULL == parser->ast.data_bytes ) {
328 autolock = 1;
329 mdata_vector_lock( &(parser->ast) );
330 debug_printf( 1,
331 MLISP_TRACE_SIGIL " --- BEGIN AST DUMP ---" );
332 }
333
334 /* Make indent. */
335 maug_mzero( indent, 101 );
336 assert( depth < 100 );
337 for( i = 0 ; depth > i ; i++ ) {
338 indent[i] = ' ';
339 }
340
341 if( 0 == ab ) {
342 ab = 'X';
343 }
344
345 /* Iterate node and children .*/
346 n = mdata_vector_get( &(parser->ast), ast_node_idx, struct MLISP_AST_NODE );
347 mdata_strpool_lock( &(parser->strpool), strpool );
348 debug_printf( 1,
349 MLISP_TRACE_SIGIL " %s%c: \"%s\" (i: " SIZE_T_FMT ", t: " SSIZE_T_FMT
350 ", c: " SSIZE_T_FMT ", f: 0x%02x)",
351 indent, ab, 0 <= n->token_idx ? &(strpool[n->token_idx]) : "",
352 ast_node_idx, n->token_idx, n->ast_idx_children_sz, n->flags );
353 mdata_strpool_unlock( &(parser->strpool), 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 = -1;
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 mlisp_parser_reset_token( parser );
440 _mlisp_ast_set_child_token( parser, str_idx, parser->base.token_sz );
441
442 /* Switch from OP to SYMBOL for subsequent tokens. */
443 mlisp_parser_pstate_pop( parser );
444 retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL );
445 maug_cleanup_if_not_ok();
446
447 /* mlisp_ast_dump( parser, 0, 0, 0 ); */
448
449 } else if(
450 (
451 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser ) ||
452 MLISP_PSTATE_LAMBDA_ARGS == mlisp_parser_pstate( parser )
453 )
454 /* Don't terminate the current symbol if the last_c was *any* of the
455 * other terminating characters.
456 */
457 && '\r' != parser->base.last_c
458 && '\n' != parser->base.last_c
459 && '\t' != parser->base.last_c
460 && ' ' != parser->base.last_c
461 && ')' != parser->base.last_c
462 && '(' != parser->base.last_c
463 ) {
464 assert( 0 < parser->base.token_sz );
465 debug_printf( MLISP_PARSE_TRACE_LVL,
466 "found symbol: %s (" SIZE_T_FMT ")",
467 parser->base.token, parser->base.token_sz );
468
469 /* A raw token without parens terminated by whitespace can't have
470 * children, so just create a one-off.
471 */
472 _mlisp_ast_add_raw_token( parser );
473
474 } else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
475 retval = mlisp_parser_append_token( parser, c );
476 maug_cleanup_if_not_ok();
477
478 }
479 break;
480
481 case '"':
482 /* TODO: Handle escaped mode. */
483 if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
484 mlisp_parser_pstate_pop( parser );
485 } else {
486 mlisp_parser_pstate_push( parser, MLISP_PSTATE_STRING );
487 }
488 break;
489
490 case '(':
491 if(
492 MLISP_PSTATE_NONE == mlisp_parser_pstate( parser ) ||
493 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser )
494 ) {
495 if(
496 MLISP_AST_FLAG_LAMBDA == (MLISP_AST_FLAG_LAMBDA & n_flags) &&
497 0 == n_children
498 ) {
499 /* Special case: all tokens in this parent are lambda args. */
500 retval =
501 mlisp_parser_pstate_push( parser, MLISP_PSTATE_LAMBDA_ARGS );
502 } else {
503 /* Otherwise, first symbol after an open paren is an op. */
504 retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL_OP );
505 }
506 maug_cleanup_if_not_ok();
507 mlisp_parser_reset_token( parser );
508
509 /* Add a new empty child to be filled out when tokens are parsed. */
510 _mlisp_ast_add_child( parser, 0 );
511
512 } else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
513 retval = mlisp_parser_append_token( parser, c );
514 maug_cleanup_if_not_ok();
515
516 } else {
517 mlisp_parser_invalid_c( parser, c, retval );
518 }
519 break;
520
521 case ')':
522 if(
523 MLISP_PSTATE_SYMBOL_OP == mlisp_parser_pstate( parser ) ||
524 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser ) ||
525 MLISP_PSTATE_LAMBDA_ARGS == mlisp_parser_pstate( parser )
526 ) {
527 if( 0 < parser->base.token_sz ) {
528 /* A raw token without parens terminated by whitespace can't have
529 * children, so just create a one-off.
530 */
531 _mlisp_ast_add_raw_token( parser );
532 }
533
534 /* Reset the parser and AST cursor up one level. */
535 mlisp_parser_pstate_pop( parser );
536 _mlisp_ast_traverse_parent( parser );
537
538 /* mlisp_ast_dump( parser, 0, 0, 0 ); */
539
540 } else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
541 retval = mlisp_parser_append_token( parser, c );
542 maug_cleanup_if_not_ok();
543
544 } else {
545 mlisp_parser_invalid_c( parser, c, retval );
546 }
547 break;
548
549 case ';':
550 if( MLISP_PSTATE_COMMENT != mlisp_parser_pstate( parser ) ) {
551 mlisp_parser_pstate_push( parser, MLISP_PSTATE_COMMENT );
552 break;
553 }
554
555 default:
556 if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
557 break;
558 }
559 retval = mlisp_parser_append_token( parser, c );
560 maug_cleanup_if_not_ok();
561 break;
562 }
563
564 mparser_wait( &(parser->base) );
565
566 parser->base.i++;
567
568cleanup:
569
570 parser->base.last_c = c;
571
572 return retval;
573}
574
575/* === */
576
577MERROR_RETVAL mlisp_parse_file(
578 struct MLISP_PARSER* parser, const retroflat_asset_path ai_path
579) {
580 MERROR_RETVAL retval = MERROR_OK;
581 struct MFILE_CADDY ai_file;
582 char c;
583 size_t i = 0;
584
585 debug_printf( MLISP_TRACE_LVL, "loading mlisp AST..." );
586
587 retval = mfile_open_read( ai_path, &ai_file );
588 maug_cleanup_if_not_ok();
589
590 retval = mlisp_parser_init( parser );
591 maug_cleanup_if_not_ok();
592
593 for( i = 0 ; mfile_get_sz( &ai_file ) > i ; i++ ) {
594 retval = ai_file.read_int( &ai_file, (uint8_t*)&c, 1, 0 );
595 maug_cleanup_if_not_ok();
596 retval = mlisp_parse_c( parser, c );
597 maug_cleanup_if_not_ok();
598 }
599#if defined( MLISP_DUMP_ENABLED )
600 mlisp_ast_dump( parser, 0, 0, 0 );
601#endif /* MLISP_DUMP_ENABLED */
602 if( 0 < parser->base.pstate_sz ) {
603 error_printf( "invalid parser state!" );
604 retval = MERROR_EXEC;
605 goto cleanup;
606 }
607
608cleanup:
609
610 return retval;
611}
612
613/* === */
614
615MERROR_RETVAL mlisp_parser_init( struct MLISP_PARSER* parser ) {
616 MERROR_RETVAL retval = MERROR_OK;
617 ssize_t append_retval = 0;
618
619 assert( (MAUG_MHANDLE)NULL == parser->env.data_h );
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 ", env: " SIZE_T_FMT ")...",
657 mdata_vector_ct( &(parser->ast) ), mdata_vector_ct( &(parser->env) ) );
658 mdata_strpool_free( &(parser->strpool) );
659 mdata_vector_free( &(parser->ast) );
660 mdata_vector_free( &(parser->env) );
661 debug_printf( MLISP_PARSE_TRACE_LVL, "parser destroyed!" );
662}
663
664#else
665
666# define _MLISP_TYPE_TABLE_CONSTS( idx, ctype, name, const_name, fmt ) \
667 extern MAUG_CONST uint8_t SEG_MCONST MLISP_TYPE_ ## const_name;
668
669MLISP_TYPE_TABLE( _MLISP_TYPE_TABLE_CONSTS );
670
671#endif /* MLISPP_C */
672
673#endif /* !MLISPP_H */
674
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:103
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:80
MLISP Interpreter/Parser Structs.
MAUG_MHANDLE data_h
Handle for allocated items (unlocked).
Definition mdata.h:90
uint8_t * data_bytes
Handle for allocated items (locked).
Definition mdata.h:92
Definition mfile.h:152
Definition mlisps.h:125
size_t ast_idx_children_sz
Number of children in MLISP_AST_NODE::ast_idx_children.
Definition mlisps.h:133
Definition mlisps.h:178
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:186