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
79MERROR_RETVAL mlisp_ast_dump(
80 struct MLISP_PARSER* parser, size_t ast_node_idx, size_t depth, char ab );
81 /* mlisp_parser */
83
84MERROR_RETVAL mlisp_parse_c( struct MLISP_PARSER* parser, char c );
85
86MERROR_RETVAL mlisp_parse_file(
87 struct MLISP_PARSER* parser, const retroflat_asset_path ai_path );
88
89MERROR_RETVAL mlisp_parser_init( struct MLISP_PARSER* parser );
90
91void mlisp_parser_free( struct MLISP_PARSER* parser );
92 /* mlisp */
94
95#ifdef MLISPP_C
96
97#define _MLISP_TYPE_TABLE_CONSTS( idx, ctype, name, const_name, fmt ) \
98 MAUG_CONST uint8_t SEG_MCONST MLISP_TYPE_ ## const_name = idx;
99
100MLISP_TYPE_TABLE( _MLISP_TYPE_TABLE_CONSTS );
101
102MLISP_PARSER_PSTATE_TABLE( MPARSER_PSTATE_TABLE_CONST )
103
104MPARSER_PSTATE_NAMES( MLISP_PARSER_PSTATE_TABLE, mlisp )
105
106/* === */
107
108/* AST Functions */
109
110/* === */
111
112static MERROR_RETVAL
113_mlisp_ast_add_child( struct MLISP_PARSER* parser, uint8_t flags ) {
114 MERROR_RETVAL retval = MERROR_OK;
115 struct MLISP_AST_NODE* n_parent = NULL;
116 struct MLISP_AST_NODE ast_node;
117 ssize_t parent_child_idx = -1;
118 ssize_t new_idx_out = 0;
119 size_t i = 0;
120
121 /* Setup the new node to copy. */
122 maug_mzero( &ast_node, sizeof( struct MLISP_AST_NODE ) );
123 ast_node.ast_idx_parent = parser->ast_node_iter;
124 for( i = 0 ; MLISP_AST_IDX_CHILDREN_MAX > i ; i++ ) {
125 ast_node.ast_idx_children[i] = -1;
126 }
127 ast_node.token_idx = -1;
128 ast_node.ast_idx_children_sz = 0;
129 ast_node.flags = flags;
130
131 debug_printf( MLISP_PARSE_TRACE_LVL, "adding node under " SSIZE_T_FMT "...",
132 ast_node.ast_idx_parent );
133
134 /* Add the node to the AST and set it as the current node. */
135 new_idx_out = mdata_vector_append(
136 &(parser->ast), &ast_node, sizeof( struct MLISP_AST_NODE ) );
137 if( 0 > new_idx_out ) {
138 retval = mdata_retval( new_idx_out );
139 }
140
141 /* Find an available child slot on the parent, if there is one. */
142 if( 0 <= ast_node.ast_idx_parent ) {
143 mdata_vector_lock( &(parser->ast) );
144
145 n_parent = mdata_vector_get(
146 &(parser->ast), ast_node.ast_idx_parent, struct MLISP_AST_NODE );
147
148 /* Find the first free child slot. */
149 parent_child_idx = 0;
150 while( -1 != n_parent->ast_idx_children[parent_child_idx] ) {
151 parent_child_idx++;
152 }
153
154 n_parent->ast_idx_children[parent_child_idx] = new_idx_out;
155 n_parent->ast_idx_children_sz++;
156
157 n_parent = NULL;
158 mdata_vector_unlock( &(parser->ast) );
159 } else {
160 /* Find the first free child slot *on the parser*. */
161 /*
162 parent_child_idx = 0;
163 while( -1 != parser->ast_idx_children[parent_child_idx] ) {
164 parent_child_idx++;
165 }
166
167 parser->ast_idx_children[parent_child_idx] = new_idx_out;
168 */
169 }
170
171 parser->ast_node_iter = new_idx_out;
172
173 debug_printf( MLISP_PARSE_TRACE_LVL, "added node " SSIZE_T_FMT
174 " under parent: " SSIZE_T_FMT " as child " SSIZE_T_FMT,
175 new_idx_out, ast_node.ast_idx_parent, parent_child_idx );
176
177cleanup:
178
179 return retval;
180}
181
182/* === */
183
184static MERROR_RETVAL _mlisp_ast_set_child_token(
185 struct MLISP_PARSER* parser, mdata_strpool_idx_t token_idx, size_t token_sz
186) {
187 MERROR_RETVAL retval = MERROR_OK;
188 char* strpool = NULL;
189 struct MLISP_AST_NODE* n = NULL;
190
191 mdata_vector_lock( &(parser->ast) );
192
193 n = mdata_vector_get(
194 &(parser->ast), parser->ast_node_iter, struct MLISP_AST_NODE );
195 assert( NULL != n );
196
197 mdata_strpool_lock( &(parser->strpool), strpool );
198 if( 0 == token_sz ) {
199 token_sz = maug_strlen( &(strpool[token_idx]) );
200 }
201 assert( 0 < token_sz );
202
203 /* Setup flags based on token name. */
204 if( 0 == strncmp( &(strpool[token_idx]), "lambda", token_sz + 1 ) ) {
205 /* Special node: lambda. */
206 debug_printf( MLISP_PARSE_TRACE_LVL,
207 "setting node \"%s\" (" SIZE_T_FMT ") flag: LAMBDA",
208 &(strpool[token_idx]), token_sz );
209 n->flags |= MLISP_AST_FLAG_LAMBDA;
210
211 } else if( 0 == strncmp( &(strpool[token_idx]), "if", token_sz + 1 ) ) {
212 /* Special node: if. */
213 debug_printf( MLISP_PARSE_TRACE_LVL,
214 "setting node \"%s\" (" SIZE_T_FMT ") flag: IF",
215 &(strpool[token_idx]), token_sz );
216 n->flags |= MLISP_AST_FLAG_IF;
217
218 } else if( 0 == strncmp( &(strpool[token_idx]), "begin", token_sz + 1 ) ) {
219 /* Special node: begin. */
220 debug_printf( MLISP_PARSE_TRACE_LVL,
221 "setting node \"%s\" (" SIZE_T_FMT ") flag: BEGIN",
222 &(strpool[token_idx]), token_sz );
223 n->flags |= MLISP_AST_FLAG_BEGIN;
224
225 } else if( 0 == strncmp( &(strpool[token_idx]), "define", token_sz + 1 ) ) {
226 /* Special node: define. */
227 debug_printf( MLISP_PARSE_TRACE_LVL,
228 "setting node \"%s\" (" SIZE_T_FMT ") flag: DEFINE",
229 &(strpool[token_idx]), token_sz );
230 n->flags |= MLISP_AST_FLAG_DEFINE;
231 }
232
233 /* Debug report. */
234 debug_printf( MLISP_PARSE_TRACE_LVL, "setting node " SSIZE_T_FMT
235 " token: \"%s\" (" SIZE_T_FMT ")",
236 parser->ast_node_iter, &(strpool[token_idx]), token_sz );
237 mdata_strpool_unlock( &(parser->strpool), strpool );
238
239 /* Set the token from the strpool. */
240 n->token_idx = token_idx;
241 n->token_sz = token_sz;
242
243cleanup:
244
245 if( NULL != strpool ) {
246 mdata_strpool_unlock( &(parser->strpool), strpool );
247 }
248
249 mdata_vector_unlock( &(parser->ast) );
250
251 return retval;
252}
253
254/* === */
255
256static
257MERROR_RETVAL _mlisp_ast_traverse_parent( struct MLISP_PARSER* parser ) {
258 MERROR_RETVAL retval = MERROR_OK;
259 struct MLISP_AST_NODE* n = NULL;
260
261 mdata_vector_lock( &(parser->ast) );
262
263 assert( 0 <= parser->ast_node_iter );
264
265 n = mdata_vector_get(
266 &(parser->ast), parser->ast_node_iter, struct MLISP_AST_NODE );
267
268 parser->ast_node_iter = n->ast_idx_parent;
269
270 debug_printf( MLISP_PARSE_TRACE_LVL, "moved up to node: " SSIZE_T_FMT,
271 parser->ast_node_iter );
272
273cleanup:
274
275 mdata_vector_unlock( &(parser->ast) );
276
277 return retval;
278}
279
280/* === */
281
282static
283MERROR_RETVAL _mlisp_ast_add_raw_token( struct MLISP_PARSER* parser ) {
284 MERROR_RETVAL retval = MERROR_OK;
285 mdata_strpool_idx_t str_idx = -1;
286
287 str_idx = mdata_strpool_append( &(parser->strpool),
288 parser->base.token, parser->base.token_sz );
289 if( 0 > str_idx ) {
290 error_printf( "invalid str_idx: " SSIZE_T_FMT, str_idx );
291 retval = MERROR_ALLOC;
292 goto cleanup;
293 }
294
295 _mlisp_ast_add_child( parser, 0 );
296 _mlisp_ast_set_child_token( parser, str_idx, parser->base.token_sz );
297 mlisp_parser_reset_token( parser );
298 retval = _mlisp_ast_traverse_parent( parser );
299
300cleanup:
301 return retval;
302}
303
304/* === */
305
306MERROR_RETVAL mlisp_ast_dump(
307 struct MLISP_PARSER* parser, size_t ast_node_idx, size_t depth, char ab
308) {
309 MERROR_RETVAL retval = MERROR_OK;
310 uint8_t autolock = 0;
311 struct MLISP_AST_NODE* n = NULL;
312 char indent[101];
313 size_t i = 0;
314 char* strpool = NULL;
315
316 if( NULL == parser->ast.data_bytes ) {
317 autolock = 1;
318 mdata_vector_lock( &(parser->ast) );
319 debug_printf( MLISP_TRACE_LVL,
320 MLISP_TRACE_SIGIL " --- BEGIN AST DUMP ---" );
321 }
322
323 /* Make indent. */
324 maug_mzero( indent, 101 );
325 assert( depth < 100 );
326 for( i = 0 ; depth > i ; i++ ) {
327 indent[i] = ' ';
328 }
329
330 if( 0 == ab ) {
331 ab = 'X';
332 }
333
334 /* Iterate node and children .*/
335 n = mdata_vector_get( &(parser->ast), ast_node_idx, struct MLISP_AST_NODE );
336 mdata_strpool_lock( &(parser->strpool), strpool );
337 debug_printf( MLISP_TRACE_LVL,
338 MLISP_TRACE_SIGIL " %s%c: \"%s\" (i: " SIZE_T_FMT ", t: " SSIZE_T_FMT
339 ", c: " SSIZE_T_FMT ", f: 0x%02x)",
340 indent, ab, 0 <= n->token_idx ? &(strpool[n->token_idx]) : "",
341 ast_node_idx, n->token_idx, n->ast_idx_children_sz, n->flags );
342 mdata_strpool_unlock( &(parser->strpool), strpool );
343 for( i = 0 ; MLISP_AST_IDX_CHILDREN_MAX > i ; i++ ) {
344 if( -1 == n->ast_idx_children[i] ) {
345 continue;
346 }
347
348 mlisp_ast_dump( parser, n->ast_idx_children[i], depth + 1, '0' + i );
349 }
350
351cleanup:
352
353 if( NULL != parser->ast.data_bytes && autolock ) {
354 mdata_vector_unlock( &(parser->ast) );
355 debug_printf( MLISP_TRACE_LVL,
356 MLISP_TRACE_SIGIL " --- END AST DUMP ---" );
357 }
358
359 return retval;
360}
361
362/* === */
363
364/* Parse Functions */
365
366/* === */
367
368MERROR_RETVAL mlisp_parse_c( struct MLISP_PARSER* parser, char c ) {
369 MERROR_RETVAL retval = MERROR_OK;
370 mdata_strpool_idx_t str_idx = -1;
371 uint8_t n_flags = 0;
372 size_t n_children = 0;
373 struct MLISP_AST_NODE* n = NULL;
374
375#ifdef MPARSER_TRACE_NAMES
376 debug_printf( MLISP_PARSE_TRACE_LVL,
377 SIZE_T_FMT ": \"%c\" (last: \"%c\") (%s (%d)) (sz: " SIZE_T_FMT ")",
378 parser->base.i, c, parser->base.last_c,
379 gc_mlisp_pstate_names[mlisp_parser_pstate( parser )],
380 mlisp_parser_pstate( parser ),
381 parser->base.pstate_sz );
382#endif /* MPARSER_TRACE_NAMES */
383
384 mdata_vector_lock( &(parser->ast) );
385 n = mdata_vector_get(
386 &(parser->ast), parser->ast_node_iter, struct MLISP_AST_NODE );
387 if( NULL != n ) {
388 n_flags = n->flags;
389 n_children = n->ast_idx_children_sz;
390 }
391 mdata_vector_unlock( &(parser->ast) );
392
393 switch( c ) {
394 case '\r':
395 case '\n':
396 if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
397 /* End comment on newline. */
398 mlisp_parser_pstate_pop( parser );
399 break;
400 }
401
402 case '\t':
403 case ' ':
404 if(
405 MLISP_PSTATE_SYMBOL_OP == mlisp_parser_pstate( parser )
406 /* Don't terminate the current symbol if the last_c was *any* of the
407 * other terminating characters.
408 */
409 && '\r' != parser->base.last_c
410 && '\n' != parser->base.last_c
411 && '\t' != parser->base.last_c
412 && ' ' != parser->base.last_c
413 && ')' != parser->base.last_c
414 && '(' != parser->base.last_c
415 ) {
416 assert( 0 < parser->base.token_sz );
417 debug_printf( MLISP_PARSE_TRACE_LVL,
418 "found symbol: %s (" SIZE_T_FMT ")",
419 parser->base.token, parser->base.token_sz );
420
421 /* Grab the symbol to use for the op of the child created by the last
422 * open paren.
423 */
424 str_idx = mdata_strpool_append( &(parser->strpool),
425 parser->base.token, parser->base.token_sz );
426 mlisp_parser_reset_token( parser );
427 _mlisp_ast_set_child_token( parser, str_idx, parser->base.token_sz );
428
429 /* Switch from OP to SYMBOL for subsequent tokens. */
430 mlisp_parser_pstate_pop( parser );
431 retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL );
432 maug_cleanup_if_not_ok();
433
434 /* mlisp_ast_dump( parser, 0, 0, 0 ); */
435
436 } else if(
437 (
438 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser ) ||
439 MLISP_PSTATE_LAMBDA_ARGS == mlisp_parser_pstate( parser )
440 )
441 /* Don't terminate the current symbol if the last_c was *any* of the
442 * other terminating characters.
443 */
444 && '\r' != parser->base.last_c
445 && '\n' != parser->base.last_c
446 && '\t' != parser->base.last_c
447 && ' ' != parser->base.last_c
448 && ')' != parser->base.last_c
449 && '(' != parser->base.last_c
450 ) {
451 assert( 0 < parser->base.token_sz );
452 debug_printf( MLISP_PARSE_TRACE_LVL,
453 "found symbol: %s (" SIZE_T_FMT ")",
454 parser->base.token, parser->base.token_sz );
455
456 /* A raw token without parens terminated by whitespace can't have
457 * children, so just create a one-off.
458 */
459 _mlisp_ast_add_raw_token( parser );
460
461 } else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
462 retval = mlisp_parser_append_token( parser, c );
463 maug_cleanup_if_not_ok();
464
465 }
466 break;
467
468 case '"':
469 /* TODO: Handle escaped mode. */
470 if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
471 mlisp_parser_pstate_pop( parser );
472 } else {
473 mlisp_parser_pstate_push( parser, MLISP_PSTATE_STRING );
474 }
475 break;
476
477 case '(':
478 if(
479 MLISP_PSTATE_NONE == mlisp_parser_pstate( parser ) ||
480 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser )
481 ) {
482 if(
483 MLISP_AST_FLAG_LAMBDA == (MLISP_AST_FLAG_LAMBDA & n_flags) &&
484 0 == n_children
485 ) {
486 /* Special case: all tokens in this parent are lambda args. */
487 retval =
488 mlisp_parser_pstate_push( parser, MLISP_PSTATE_LAMBDA_ARGS );
489 } else {
490 /* Otherwise, first symbol after an open paren is an op. */
491 retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL_OP );
492 }
493 maug_cleanup_if_not_ok();
494 mlisp_parser_reset_token( parser );
495
496 /* Add a new empty child to be filled out when tokens are parsed. */
497 _mlisp_ast_add_child( parser, 0 );
498
499 } else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
500 retval = mlisp_parser_append_token( parser, c );
501 maug_cleanup_if_not_ok();
502
503 } else {
504 mlisp_parser_invalid_c( parser, c, retval );
505 }
506 break;
507
508 case ')':
509 if(
510 MLISP_PSTATE_SYMBOL_OP == mlisp_parser_pstate( parser ) ||
511 MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser ) ||
512 MLISP_PSTATE_LAMBDA_ARGS == mlisp_parser_pstate( parser )
513 ) {
514 if( 0 < parser->base.token_sz ) {
515 /* A raw token without parens terminated by whitespace can't have
516 * children, so just create a one-off.
517 */
518 _mlisp_ast_add_raw_token( parser );
519 }
520
521 /* Reset the parser and AST cursor up one level. */
522 mlisp_parser_pstate_pop( parser );
523 _mlisp_ast_traverse_parent( parser );
524
525 /* mlisp_ast_dump( parser, 0, 0, 0 ); */
526
527 } else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
528 retval = mlisp_parser_append_token( parser, c );
529 maug_cleanup_if_not_ok();
530
531 } else {
532 mlisp_parser_invalid_c( parser, c, retval );
533 }
534 break;
535
536 case ';':
537 if( MLISP_PSTATE_COMMENT != mlisp_parser_pstate( parser ) ) {
538 mlisp_parser_pstate_push( parser, MLISP_PSTATE_COMMENT );
539 break;
540 }
541
542 default:
543 if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
544 break;
545 }
546 retval = mlisp_parser_append_token( parser, c );
547 maug_cleanup_if_not_ok();
548 break;
549 }
550
551 mparser_wait( &(parser->base) );
552
553 parser->base.i++;
554
555cleanup:
556
557 parser->base.last_c = c;
558
559 return retval;
560}
561
562/* === */
563
564MERROR_RETVAL mlisp_parse_file(
565 struct MLISP_PARSER* parser, const retroflat_asset_path ai_path
566) {
567 MERROR_RETVAL retval = MERROR_OK;
568 struct MFILE_CADDY ai_file;
569 char c;
570 size_t i = 0;
571
572 debug_printf( MLISP_TRACE_LVL, "loading mlisp AST..." );
573
574 retval = mfile_open_read( ai_path, &ai_file );
575 maug_cleanup_if_not_ok();
576
577 retval = mlisp_parser_init( parser );
578 maug_cleanup_if_not_ok();
579
580 for( i = 0 ; mfile_get_sz( &ai_file ) > i ; i++ ) {
581 retval = ai_file.read_int( &ai_file, (uint8_t*)&c, 1, 0 );
582 maug_cleanup_if_not_ok();
583 retval = mlisp_parse_c( parser, c );
584 maug_cleanup_if_not_ok();
585 }
586 mlisp_ast_dump( parser, 0, 0, 0 );
587 if( 0 < parser->base.pstate_sz ) {
588 error_printf( "invalid parser state!" );
589 retval = MERROR_EXEC;
590 goto cleanup;
591 }
592
593cleanup:
594
595 return retval;
596}
597
598/* === */
599
600MERROR_RETVAL mlisp_parser_init( struct MLISP_PARSER* parser ) {
601 MERROR_RETVAL retval = MERROR_OK;
602 ssize_t append_retval = 0;
603
604 assert( NULL == parser->env.data_h );
605
606 debug_printf( MLISP_TRACE_LVL,
607 "initializing mlisp parser (" SIZE_T_FMT " bytes)...",
608 sizeof( struct MLISP_PARSER ) );
609
610 maug_mzero( parser, sizeof( struct MLISP_PARSER ) );
611
612 parser->ast_node_iter = -1;
613 /*
614 for( i = 0 ; MLISP_AST_IDX_CHILDREN_MAX > i ; i++ ) {
615 parser->ast_idx_children[i] = -1;
616 }
617 */
618
619 /* Allocate the vectors for AST and ENV. */
620
621 append_retval = mdata_vector_alloc(
622 &(parser->ast), sizeof( struct MLISP_AST_NODE ), MDATA_VECTOR_INIT_SZ );
623 if( 0 > append_retval ) {
624 retval = mdata_retval( append_retval );
625 }
626 maug_cleanup_if_not_ok();
627
628cleanup:
629
630 if( MERROR_OK != retval ) {
631 error_printf( "mlisp parser initialization failed: %d", retval );
632 }
633
634 return retval;
635}
636
637/* === */
638
639void mlisp_parser_free( struct MLISP_PARSER* parser ) {
640 debug_printf( MLISP_TRACE_LVL,
641 "destroying parser (ast: " SIZE_T_FMT ", env: " SIZE_T_FMT ")...",
642 mdata_vector_ct( &(parser->ast) ), mdata_vector_ct( &(parser->env) ) );
643 mdata_strpool_free( &(parser->strpool) );
644 mdata_vector_free( &(parser->ast) );
645 mdata_vector_free( &(parser->env) );
646 debug_printf( MLISP_PARSE_TRACE_LVL, "parser destroyed!" );
647}
648
649#else
650
651# define _MLISP_TYPE_TABLE_CONSTS( idx, ctype, name, const_name, fmt ) \
652 extern MAUG_CONST uint8_t SEG_MCONST MLISP_TYPE_ ## const_name;
653
654MLISP_TYPE_TABLE( _MLISP_TYPE_TABLE_CONSTS );
655
656#endif /* MLISPP_C */
657
658#endif /* !MLISPP_H */
659
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
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[RETROFLAT_PATH_MAX]
Path/name used to load an asset from disk.
Definition retroflt.h:771
MERROR_RETVAL mdata_vector_alloc(struct MDATA_VECTOR *v, size_t item_sz, size_t item_ct_init)
#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:92
uint8_t * data_bytes
Handle for allocated items (locked).
Definition mdata.h:94
Definition mfile.h:74
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:169
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:177