15#ifndef MLISP_PARSE_TRACE_LVL 
   16#  define MLISP_PARSE_TRACE_LVL 0 
   19#define MLISP_AST_FLAG_LAMBDA 0x02 
   21#define MLISP_AST_FLAG_IF     0x04 
   23#define MLISP_AST_FLAG_DEFINE 0x08 
   25#define MLISP_AST_FLAG_BEGIN  0x20 
   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 ) 
   40#define mlisp_parser_pstate( parser ) \ 
   41   ((parser)->base.pstate_sz > 0 ? \ 
   42      (parser)->base.pstate[(parser)->base.pstate_sz - 1] : MLISP_PSTATE_NONE) 
   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 );
 
   49#  define mlisp_parser_pstate_pop( parser ) \ 
   51         "mlisp", &((parser)->base), gc_mlisp_pstate_names );
 
   53#  define mlisp_parser_pstate_push( parser, new_pstate ) \ 
   54      mparser_pstate_push( "mlisp", &((parser)->base), new_pstate )
 
   56#  define mlisp_parser_pstate_pop( parser ) \ 
   57      mparser_pstate_pop( "mlisp", &((parser)->base) )
 
   60#define mlisp_parser_invalid_c( parser, c, retval ) \ 
   61   mparser_invalid_c( mlisp, &((parser)->base), c, retval ) 
   63#define mlisp_parser_reset_token( parser ) \ 
   64   mparser_reset_token( "mlisp", &((parser)->base) )
 
   66#define mlisp_parser_append_token( parser, c ) \ 
   67   mparser_append_token( "mlisp", &((parser)->base), c )
 
   69#define mlisp_parser_parse_token( parser ) \ 
   70   parser->token_parser( \ 
   71      (parser)->token, (parser)->token_sz, (parser)->token_parser_arg ) 
   77#define mlisp_check_ast( parser ) (0 < mdata_vector_ct( &((parser)->ast) )) 
   79#if defined( MLISP_DUMP_ENABLED ) || defined( DOCUMENTATION ) 
   87   struct MLISP_PARSER* parser, 
size_t ast_node_idx, 
size_t depth, 
char ab );
 
  106#define _MLISP_TYPE_TABLE_CONSTS( idx, ctype, name, const_name, fmt ) \ 
  107   MAUG_CONST uint8_t SEG_MCONST MLISP_TYPE_ ## const_name = idx; 
  111MLISP_PARSER_PSTATE_TABLE( MPARSER_PSTATE_TABLE_CONST )
 
  113MPARSER_PSTATE_NAMES( MLISP_PARSER_PSTATE_TABLE, mlisp )
 
  122_mlisp_ast_add_child( 
struct MLISP_PARSER* parser, uint8_t flags ) {
 
  126   ssize_t parent_child_idx = -1;
 
  127   ssize_t new_idx_out = 0;
 
  133   for( i = 0 ; MLISP_AST_IDX_CHILDREN_MAX > i ; i++ ) {
 
  134      ast_node.ast_idx_children[i] = -1;
 
  136   ast_node.token_idx = -1;
 
  137   ast_node.ast_idx_children_sz = 0;
 
  138   ast_node.flags = flags;
 
  140   debug_printf( MLISP_PARSE_TRACE_LVL, 
"adding node under " SSIZE_T_FMT 
"...",
 
  141      ast_node.ast_idx_parent );
 
  146   if( 0 > new_idx_out ) {
 
  147      retval = mdata_retval( new_idx_out );
 
  151   if( 0 <= ast_node.ast_idx_parent ) {
 
  154      n_parent = mdata_vector_get(
 
  158      parent_child_idx = 0;
 
  159      while( -1 != n_parent->ast_idx_children[parent_child_idx] ) {
 
  163      n_parent->ast_idx_children[parent_child_idx] = new_idx_out;
 
  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 );
 
  194   struct MLISP_PARSER* parser, mdata_strpool_idx_t token_idx, 
size_t token_sz
 
  198   char* strpool_token = NULL;
 
  202   n = mdata_vector_get(
 
  206   mdata_strpool_lock( &(parser->strpool) );
 
  208   strpool_token = mdata_strpool_get( &(parser->strpool), token_idx );
 
  209   assert( NULL != strpool_token );
 
  211   if( 0 == token_sz ) {
 
  212      token_sz = maug_strlen( strpool_token );
 
  214   assert( 0 < token_sz );
 
  217   if( 0 == strncmp( strpool_token, 
"lambda", token_sz + 1 ) ) {
 
  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;
 
  224   } 
else if( 0 == strncmp( strpool_token, 
"if", token_sz + 1 ) ) {
 
  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;
 
  231   } 
else if( 0 == strncmp( strpool_token, 
"begin", token_sz + 1 ) ) {
 
  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;
 
  238   } 
else if( 0 == strncmp( strpool_token, 
"define", token_sz + 1 ) ) {
 
  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;
 
  247   debug_printf( MLISP_PARSE_TRACE_LVL,
 
  248      "setting node " SSIZE_T_FMT 
" token: \"%s\" (" SIZE_T_FMT 
")",
 
  253   n->token_idx = token_idx;
 
  254   n->token_sz = token_sz;
 
  258   if( mdata_strpool_is_locked( &(parser->strpool) ) ) {
 
  259      mdata_strpool_unlock( &(parser->strpool) );
 
  278   n = mdata_vector_get(
 
  283   debug_printf( MLISP_PARSE_TRACE_LVL, 
"moved up to node: " SSIZE_T_FMT,
 
  298   mdata_strpool_idx_t str_idx = 0;
 
  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 );
 
  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 );
 
  315#if defined( MLISP_DUMP_ENABLED ) || defined( DOCUMENTATION ) 
  318   struct MLISP_PARSER* parser, 
size_t ast_node_idx, 
size_t depth, 
char ab
 
  321   uint8_t autolock = 0;
 
  330         MLISP_TRACE_SIGIL 
" --- BEGIN AST DUMP ---" );
 
  334   maug_mzero( indent, 101 );
 
  335   assert( depth < 100 );
 
  336   for( i = 0 ; depth > i ; i++ ) {
 
  345   n = mdata_vector_get( &(parser->ast), ast_node_idx, 
struct MLISP_AST_NODE );
 
  346   mdata_strpool_lock( &(parser->strpool) );
 
  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 ) : 
"",
 
  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] ) {
 
  359      mlisp_ast_dump( parser, n->ast_idx_children[i], depth + 1, 
'0' + i );
 
  364   if( NULL != parser->ast.
data_bytes && autolock ) {
 
  367         MLISP_TRACE_SIGIL 
" --- END AST DUMP ---" );
 
  383   mdata_strpool_idx_t str_idx = 0;
 
  385   size_t n_children = 0;
 
  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 );
 
  398   n = mdata_vector_get(
 
  409      if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
 
  411         mlisp_parser_pstate_pop( parser );
 
  418         MLISP_PSTATE_SYMBOL_OP == mlisp_parser_pstate( parser )
 
  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
 
  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 );
 
  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 );
 
  445         mlisp_parser_pstate_pop( parser );
 
  446         retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL );
 
  447         maug_cleanup_if_not_ok();
 
  453            MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser ) ||
 
  454            MLISP_PSTATE_LAMBDA_ARGS == mlisp_parser_pstate( parser )
 
  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
 
  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 );
 
  474         _mlisp_ast_add_raw_token( parser );
 
  476      } 
else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
 
  477         retval = mlisp_parser_append_token( parser, c );
 
  478         maug_cleanup_if_not_ok();
 
  485      if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
 
  486         mlisp_parser_pstate_pop( parser );
 
  488         mlisp_parser_pstate_push( parser, MLISP_PSTATE_STRING );
 
  494         MLISP_PSTATE_NONE == mlisp_parser_pstate( parser ) ||
 
  495         MLISP_PSTATE_SYMBOL == mlisp_parser_pstate( parser )
 
  498            MLISP_AST_FLAG_LAMBDA == (MLISP_AST_FLAG_LAMBDA & n_flags) &&
 
  503               mlisp_parser_pstate_push( parser, MLISP_PSTATE_LAMBDA_ARGS );
 
  506            retval = mlisp_parser_pstate_push( parser, MLISP_PSTATE_SYMBOL_OP );
 
  508         maug_cleanup_if_not_ok();
 
  509         mlisp_parser_reset_token( parser );
 
  512         _mlisp_ast_add_child( parser, 0 );
 
  514      } 
else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
 
  515         retval = mlisp_parser_append_token( parser, c );
 
  516         maug_cleanup_if_not_ok();
 
  519         mlisp_parser_invalid_c( parser, c, retval );
 
  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 )
 
  529         if( 0 < parser->base.token_sz ) {
 
  533            _mlisp_ast_add_raw_token( parser );
 
  537         mlisp_parser_pstate_pop( parser );
 
  538         _mlisp_ast_traverse_parent( parser );
 
  542      } 
else if( MLISP_PSTATE_STRING == mlisp_parser_pstate( parser ) ) {
 
  543         retval = mlisp_parser_append_token( parser, c );
 
  544         maug_cleanup_if_not_ok();
 
  547         mlisp_parser_invalid_c( parser, c, retval );
 
  552      if( MLISP_PSTATE_COMMENT != mlisp_parser_pstate( parser ) ) {
 
  553         mlisp_parser_pstate_push( parser, MLISP_PSTATE_COMMENT );
 
  558      if( MLISP_PSTATE_COMMENT == mlisp_parser_pstate( parser ) ) {
 
  561      retval = mlisp_parser_append_token( parser, c );
 
  562      maug_cleanup_if_not_ok();
 
  566   mparser_wait( &(parser->base) );
 
  572   parser->base.last_c = c;
 
  587   debug_printf( MLISP_TRACE_LVL, 
"loading mlisp AST..." );
 
  590   maug_cleanup_if_not_ok();
 
  592   retval = mlisp_parser_init( parser );
 
  593   maug_cleanup_if_not_ok();
 
  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();
 
  601#if defined( MLISP_DUMP_ENABLED ) 
  604   if( 0 < parser->base.pstate_sz ) {
 
  605      error_printf( 
"invalid parser state!" );
 
  606      retval = MERROR_EXEC;
 
  619   ssize_t append_retval = 0;
 
  621   debug_printf( MLISP_TRACE_LVL,
 
  622      "initializing mlisp parser (" SIZE_T_FMT 
" bytes)...",
 
  638   if( 0 > append_retval ) {
 
  639      retval = mdata_retval( append_retval );
 
  641   maug_cleanup_if_not_ok();
 
  645   if( MERROR_OK != retval ) {
 
  646      error_printf( 
"mlisp parser initialization failed: %d", retval );
 
  655   debug_printf( MLISP_TRACE_LVL,
 
  656         "destroying parser (ast: " SIZE_T_FMT 
")...",
 
  658   mdata_strpool_free( &(parser->strpool) );
 
  659   mdata_vector_free( &(parser->ast) );
 
  660   debug_printf( MLISP_PARSE_TRACE_LVL, 
"parser destroyed!" );
 
  665#  define _MLISP_TYPE_TABLE_CONSTS( idx, ctype, name, const_name, fmt ) \ 
  666      extern MAUG_CONST uint8_t SEG_MCONST MLISP_TYPE_ ## const_name; 
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
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:320
#define mdata_vector_unlock(v)
Unlock the vector so items may be added and removed.
Definition: mdata.h:353
uint8_t * data_bytes
Handle for allocated items (locked).
Definition: mdata.h:98
#define mdata_vector_ct(v)
Number of items of MDATA_VECTOR::item_sz bytes actively stored in this vector.
Definition: mdata.h:396
size_t ast_idx_children_sz
Number of children in MLISP_AST_NODE::ast_idx_children.
Definition: mlisps.h:126
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