Add support for a named block to only have variable definitions.

It is legal for a named block to contain variable definitions and
no statements. This patch fixes this for both style of blocks. It
also organizes the block parsing code to be a bit more clear, adds
an error case for fork/join and changes on check for size() > 0 for
the more efficient ! empty().
This commit is contained in:
Cary R 2011-11-22 20:33:19 -08:00
parent cc5efa45ba
commit 9fbeb78d5f
1 changed files with 40 additions and 34 deletions

74
parse.y
View File

@ -255,7 +255,7 @@ static long check_enum_seq_value(const YYLTYPE&loc, verinum *arg, bool zero_ok)
static void current_task_set_statement(vector<Statement*>*s) static void current_task_set_statement(vector<Statement*>*s)
{ {
assert(s && s->size() > 0); assert(s && !s->empty());
if (s->size() == 1) { if (s->size() == 1) {
current_task->set_statement((*s)[0]); current_task->set_statement((*s)[0]);
return; return;
@ -505,6 +505,7 @@ static void current_task_set_statement(vector<Statement*>*s)
%type <event_statement> event_control %type <event_statement> event_control
%type <statement> statement statement_or_null compressed_statement %type <statement> statement statement_or_null compressed_statement
%type <statement_list> statement_list statement_or_null_list %type <statement_list> statement_list statement_or_null_list
%type <statement_list> statement_list_or_null
%type <statement> analog_statement %type <statement> analog_statement
@ -4285,6 +4286,11 @@ statement
name. These are handled by pushing the scope name, then matching name. These are handled by pushing the scope name, then matching
the declarations. The scope is popped at the end of the block. */ the declarations. The scope is popped at the end of the block. */
| K_begin K_end
{ PBlock*tmp = new PBlock(PBlock::BL_SEQ);
FILE_NAME(tmp, @1);
$$ = tmp;
}
| K_begin statement_list K_end | K_begin statement_list K_end
{ PBlock*tmp = new PBlock(PBlock::BL_SEQ); { PBlock*tmp = new PBlock(PBlock::BL_SEQ);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
@ -4298,27 +4304,16 @@ statement
current_block_stack.push(tmp); current_block_stack.push(tmp);
} }
block_item_decls_opt block_item_decls_opt
statement_list K_end statement_list_or_null K_end
{ pform_pop_scope(); { pform_pop_scope();
assert(! current_block_stack.empty()); assert(! current_block_stack.empty());
PBlock*tmp = current_block_stack.top(); PBlock*tmp = current_block_stack.top();
current_block_stack.pop(); current_block_stack.pop();
tmp->set_statement(*$6); if ($6) tmp->set_statement(*$6);
delete[]$3; delete[]$3;
delete $6; delete $6;
$$ = tmp; $$ = tmp;
} }
| K_begin K_end
{ PBlock*tmp = new PBlock(PBlock::BL_SEQ);
FILE_NAME(tmp, @1);
$$ = tmp;
}
| K_begin ':' IDENTIFIER K_end
{ PBlock*tmp = new PBlock(PBlock::BL_SEQ);
FILE_NAME(tmp, @1);
delete[]$3;
$$ = tmp;
}
| K_begin error K_end | K_begin error K_end
{ yyerrok; } { yyerrok; }
@ -4327,33 +4322,36 @@ statement
need to do is remember that this is a parallel block so that the need to do is remember that this is a parallel block so that the
code generator can do the right thing. */ code generator can do the right thing. */
| K_fork K_join
{ PBlock*tmp = new PBlock(PBlock::BL_PAR);
FILE_NAME(tmp, @1);
$$ = tmp;
}
| K_fork statement_list K_join
{ PBlock*tmp = new PBlock(PBlock::BL_PAR);
FILE_NAME(tmp, @1);
tmp->set_statement(*$2);
delete $2;
$$ = tmp;
}
| K_fork ':' IDENTIFIER | K_fork ':' IDENTIFIER
{ PBlock*tmp = pform_push_block_scope($3, PBlock::BL_PAR); { PBlock*tmp = pform_push_block_scope($3, PBlock::BL_PAR);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
current_block_stack.push(tmp); current_block_stack.push(tmp);
} }
block_item_decls_opt block_item_decls_opt
statement_list K_join statement_list_or_null K_join
{ pform_pop_scope(); { pform_pop_scope();
assert(! current_block_stack.empty()); assert(! current_block_stack.empty());
PBlock*tmp = current_block_stack.top(); PBlock*tmp = current_block_stack.top();
current_block_stack.pop(); current_block_stack.pop();
tmp->set_statement(*$6); if ($6) tmp->set_statement(*$6);
delete[]$3; delete[]$3;
delete $6; delete $6;
$$ = tmp; $$ = tmp;
} }
| K_fork K_join | K_fork error K_join
{ PBlock*tmp = new PBlock(PBlock::BL_PAR); { yyerrok; }
FILE_NAME(tmp, @1);
$$ = tmp;
}
| K_fork ':' IDENTIFIER K_join
{ PBlock*tmp = new PBlock(PBlock::BL_PAR);
FILE_NAME(tmp, @1);
delete[]$3;
$$ = tmp;
}
| K_disable hierarchy_identifier ';' | K_disable hierarchy_identifier ';'
{ PDisable*tmp = new PDisable(*$2); { PDisable*tmp = new PDisable(*$2);
@ -4372,13 +4370,6 @@ statement
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
$$ = tmp; $$ = tmp;
} }
| K_fork statement_list K_join
{ PBlock*tmp = new PBlock(PBlock::BL_PAR);
FILE_NAME(tmp, @1);
tmp->set_statement(*$2);
delete $2;
$$ = tmp;
}
| K_repeat '(' expression ')' statement | K_repeat '(' expression ')' statement
{ PRepeat*tmp = new PRepeat($3, $5); { PRepeat*tmp = new PRepeat($3, $5);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
@ -4677,6 +4668,21 @@ compressed_statement
} }
; ;
statement_list_or_null
: statement_list_or_null statement
{ vector<Statement*>*tmp = $1;
if (tmp) {
tmp->push_back($2);
} else {
tmp = new vector<Statement*>(1);
tmp->at(0) = $2;
}
$$ = tmp;
}
|
{ $$ = 0; }
;
statement_list statement_list
: statement_list statement : statement_list statement
{ vector<Statement*>*tmp = $1; { vector<Statement*>*tmp = $1;