@@ -88,6 +88,7 @@ typedef struct _parser_t {
8888 uint rule_stack_top ;
8989 rule_stack_t * rule_stack ;
9090
91+ uint result_stack_alloc ;
9192 uint result_stack_top ;
9293 mp_parse_node_t * result_stack ;
9394} parser_t ;
@@ -121,7 +122,7 @@ mp_parse_node_t mp_parse_node_new_leaf(machine_int_t kind, machine_int_t arg) {
121122
122123int num_parse_nodes_allocated = 0 ;
123124mp_parse_node_struct_t * parse_node_new_struct (int rule_id , int num_args ) {
124- mp_parse_node_struct_t * pn = m_malloc ( sizeof ( mp_parse_node_struct_t ) + num_args * sizeof ( mp_parse_node_t ) );
125+ mp_parse_node_struct_t * pn = m_new_obj_var ( mp_parse_node_struct_t , mp_parse_node_t , num_args );
125126 pn -> source = 0 ; // TODO
126127 pn -> kind_num_nodes = (rule_id & 0xff ) | (num_args << 8 );
127128 num_parse_nodes_allocated += 1 ;
@@ -180,6 +181,10 @@ static mp_parse_node_t peek_result(parser_t *parser, int pos) {
180181}
181182
182183static void push_result_node (parser_t * parser , mp_parse_node_t pn ) {
184+ if (parser -> result_stack_top >= parser -> result_stack_alloc ) {
185+ parser -> result_stack = m_renew (mp_parse_node_t , parser -> result_stack , parser -> result_stack_alloc , parser -> result_stack_alloc * 2 );
186+ parser -> result_stack_alloc *= 2 ;
187+ }
183188 parser -> result_stack [parser -> result_stack_top ++ ] = pn ;
184189}
185190
@@ -252,14 +257,20 @@ static void push_result_rule(parser_t *parser, const rule_t *rule, int num_args)
252257}
253258
254259mp_parse_node_t mp_parse (mp_lexer_t * lex , mp_parse_input_kind_t input_kind ) {
255- parser_t * parser = m_new (parser_t , 1 );
260+
261+ // allocate memory for the parser and its stacks
262+
263+ parser_t * parser = m_new_obj (parser_t );
264+
256265 parser -> rule_stack_alloc = 64 ;
257266 parser -> rule_stack_top = 0 ;
258267 parser -> rule_stack = m_new (rule_stack_t , parser -> rule_stack_alloc );
259268
260- parser -> result_stack = m_new ( mp_parse_node_t , 1000 ) ;
269+ parser -> result_stack_alloc = 64 ;
261270 parser -> result_stack_top = 0 ;
271+ parser -> result_stack = m_new (mp_parse_node_t , parser -> result_stack_alloc );
262272
273+ // work out the top-level rule to use, and push it on the stack
263274 int top_level_rule ;
264275 switch (input_kind ) {
265276 case MP_PARSE_SINGLE_INPUT : top_level_rule = RULE_single_input ; break ;
@@ -268,6 +279,8 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) {
268279 }
269280 push_rule (parser , rules [top_level_rule ], 0 );
270281
282+ // parse!
283+
271284 uint n , i ;
272285 bool backtrack = false;
273286 const rule_t * rule ;
@@ -558,12 +571,25 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) {
558571
559572 //printf("--------------\n");
560573 //result_stack_show(parser);
561- assert ( parser -> result_stack_top == 1 );
562- //printf("maximum depth : %d\n", parser->rule_stack_alloc );
574+ //printf("rule stack alloc: %d\n", parser->rule_stack_alloc );
575+ //printf("result stack alloc : %d\n", parser->result_stack_alloc );
563576 //printf("number of parse nodes allocated: %d\n", num_parse_nodes_allocated);
564- return parser -> result_stack [0 ];
577+
578+ // get the root parse node that we created
579+ assert (parser -> result_stack_top == 1 );
580+ mp_parse_node_t result = parser -> result_stack [0 ];
581+
582+ finished :
583+ // free the memory that we don't need anymore
584+ m_del (rule_stack_t , parser -> rule_stack , parser -> rule_stack_alloc );
585+ m_del (mp_parse_node_t , parser -> result_stack , parser -> result_stack_alloc );
586+ m_del_obj (parser_t , parser );
587+
588+ // return the result
589+ return result ;
565590
566591syntax_error :
592+ // TODO these should raise a proper exception
567593 if (mp_lexer_is_kind (lex , MP_TOKEN_INDENT )) {
568594 mp_lexer_show_error_pythonic (lex , "IndentationError: unexpected indent" );
569595 } else if (mp_lexer_is_kind (lex , MP_TOKEN_DEDENT_MISMATCH )) {
@@ -575,5 +601,6 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) {
575601#endif
576602 mp_token_show (mp_lexer_cur (lex ));
577603 }
578- return MP_PARSE_NODE_NULL ;
604+ result = MP_PARSE_NODE_NULL ;
605+ goto finished ;
579606}
0 commit comments