Miscellaneous SystemVerilog syntax.

... and sorry messages.
This commit is contained in:
Stephen Williams 2012-03-04 19:33:16 -08:00
parent 31d4aa9a77
commit 0e01dcf2b9
5 changed files with 136 additions and 61 deletions

View File

@ -41,7 +41,9 @@ enum PTaskFuncEnum {
PTF_REALTIME, PTF_REALTIME,
PTF_TIME, PTF_TIME,
PTF_ATOM2, PTF_ATOM2,
PTF_ATOM2_S PTF_ATOM2_S,
PTF_STRING,
PTF_VOID
}; };
struct PTaskFuncArg { struct PTaskFuncArg {

View File

@ -582,6 +582,15 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
ret_sig->data_type(IVL_VT_BOOL); ret_sig->data_type(IVL_VT_BOOL);
break; break;
case PTF_STRING:
cerr << get_fileline() << ": sorry: String functions are not supported yet" << endl;
break;
case PTF_VOID:
// Void functions have no return value, so there is no
// signal to create here.
break;
default: default:
if (ports_) { if (ports_) {
cerr << get_fileline() << ": internal error: I don't know " cerr << get_fileline() << ": internal error: I don't know "

161
parse.y
View File

@ -505,8 +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> loop_statement for_step %type <statement> loop_statement for_step
%type <statement_list> statement_list statement_or_null_list %type <statement_list> statement_or_null_list statement_or_null_list_opt
%type <statement_list> statement_list_or_null
%type <statement> analog_statement %type <statement> analog_statement
@ -656,11 +655,23 @@ class_items /* IEEE1800-2005: A.1.2 */
class_item /* IEEE1800-2005: A.1.8 */ class_item /* IEEE1800-2005: A.1.8 */
/* class_constructor_declaration */ /* IEEE1800 A.1.8: class_constructor_declaration */
: K_function K_new '(' tf_port_list_opt ')' ';' : method_qualifier_opt K_function K_new '(' tf_port_list_opt ')' ';'
statement_list_or_null statement_or_null_list_opt
K_endfunction endnew_opt K_endfunction endnew_opt
{ yyerror(@1, "sorry: Class constructors not supported yet."); { yyerror(@3, "sorry: Class constructors not supported yet.");
yyerrok;
}
/* IEEE1800 A.1.8: class_constructor_declaration with a call to
parent constructor. Note that the implicit_class_handle must
be K_super ("this.new" makes little sense) but that would
cause a conflict. */
| method_qualifier_opt K_function K_new '(' tf_port_list_opt ')' ';'
implicit_class_handle '.' K_new '(' ')'
statement_or_null_list_opt
K_endfunction endnew_opt
{ yyerror(@3, "sorry: Class constructors not supported yet.");
yyerrok; yyerrok;
} }
@ -671,9 +682,9 @@ class_item /* IEEE1800-2005: A.1.8 */
/* Class methods... */ /* Class methods... */
| task_declaration | method_qualifier_opt task_declaration
| function_declaration | method_qualifier_opt function_declaration
/* Here are some error matching rules to help recover from various /* Here are some error matching rules to help recover from various
syntax errors within a class declaration. */ syntax errors within a class declaration. */
@ -688,7 +699,7 @@ class_item /* IEEE1800-2005: A.1.8 */
yyerrok; yyerrok;
} }
| K_function K_new error K_endfunction endnew_opt | method_qualifier_opt K_function K_new error K_endfunction endnew_opt
{ yyerror(@1, "error: I give up on this class constructor declaration."); { yyerror(@1, "error: I give up on this class constructor declaration.");
yyerrok; yyerrok;
} }
@ -797,7 +808,7 @@ function_declaration /* IEEE1800-2005: A.2.6 */
{ assert(current_function == 0); { assert(current_function == 0);
current_function = pform_push_function_scope(@1, $4, $2); current_function = pform_push_function_scope(@1, $4, $2);
} }
function_item_list statement_list function_item_list statement_or_null_list
K_endfunction K_endfunction
{ current_function->set_ports($7); { current_function->set_ports($7);
current_function->set_return($3); current_function->set_return($3);
@ -836,7 +847,7 @@ function_declaration /* IEEE1800-2005: A.2.6 */
} }
'(' tf_port_list_opt ')' ';' '(' tf_port_list_opt ')' ';'
block_item_decls_opt block_item_decls_opt
statement_list statement_or_null_list
K_endfunction K_endfunction
{ current_function->set_ports($7); { current_function->set_ports($7);
current_function->set_return($3); current_function->set_return($3);
@ -1044,6 +1055,13 @@ variable_decl_assignment /* IEEE1800-2005 A.2.3 */
delete[]$1; delete[]$1;
$$ = tmp; $$ = tmp;
} }
| IDENTIFIER '=' K_new '(' ')'
{ decl_assignment_t*tmp = new decl_assignment_t;
tmp->name = lex_strings.make($1);
yyerror("sorry: Class initialization assignment not supported here.");
delete[]$1;
$$ = tmp;
}
| IDENTIFIER '[' '$' ']' | IDENTIFIER '[' '$' ']'
{ decl_assignment_t*tmp = new decl_assignment_t; { decl_assignment_t*tmp = new decl_assignment_t;
tmp->name = lex_strings.make($1); tmp->name = lex_strings.make($1);
@ -1069,6 +1087,17 @@ loop_variables /* IEEE1800-2005: A.6.8 */
} }
; ;
method_qualifier /* IEEE1800-2005: A.1.8 */
: K_virtual
| class_item_qualifier
;
method_qualifier_opt
: method_qualifier
|
;
non_integer_type /* IEEE1800-2005: A.2.2.1 */ non_integer_type /* IEEE1800-2005: A.2.2.1 */
: K_real { $$ = K_real; } : K_real { $$ = K_real; }
| K_realtime { $$ = K_real; } | K_realtime { $$ = K_real; }
@ -1389,6 +1418,19 @@ tf_port_item /* IEEE1800-2005: A.2.7 */
} }
} }
| port_direction_opt data_type_or_implicit IDENTIFIER '[' '$' ']'
{ yyerror(@5, "sorry: Queues not supported here.");
delete[]$3;
$$ = 0;
}
/* Rules to match error cases... */
| port_direction_opt data_type_or_implicit IDENTIFIER error
{ yyerror(@3, "error: Error in task/function port item after port name %s.", $3);
yyerrok;
$$ = 0;
}
; ;
/* This rule matches the [ = <expression> ] part of the tf_port_item rules. */ /* This rule matches the [ = <expression> ] part of the tf_port_item rules. */
@ -2612,6 +2654,11 @@ expr_primary
} }
} }
| implicit_class_handle
{ yyerror(@1, "sorry: Implicit class handles (this/super) are not supported.");
$$ = 0;
}
/* Many of the VAMS built-in functions are available as builtin /* Many of the VAMS built-in functions are available as builtin
functions with $system_function equivalents. */ functions with $system_function equivalents. */
@ -4695,7 +4742,9 @@ dimensions
} }
; ;
/* This is used to express the return type of a function. */ /* This is used to express the return type of a function. This is
not quite right, and should be replaced with a variant that uses
the data_type rule. This will get us by for now. */
function_range_or_type_opt function_range_or_type_opt
: unsigned_signed_opt range_opt : unsigned_signed_opt range_opt
{ /* the default type is reg unsigned and no range */ { /* the default type is reg unsigned and no range */
@ -4727,7 +4776,9 @@ function_range_or_type_opt
| K_integer { $$.range = 0; $$.type = PTF_INTEGER; } | K_integer { $$.range = 0; $$.type = PTF_INTEGER; }
| K_real { $$.range = 0; $$.type = PTF_REAL; } | K_real { $$.range = 0; $$.type = PTF_REAL; }
| K_realtime { $$.range = 0; $$.type = PTF_REALTIME; } | K_realtime { $$.range = 0; $$.type = PTF_REALTIME; }
| K_string { $$.range = 0; $$.type = PTF_STRING; }
| K_time { $$.range = 0; $$.type = PTF_TIME; } | K_time { $$.range = 0; $$.type = PTF_TIME; }
| K_void { $$.range = 0; $$.type = PTF_VOID; }
| atom2_type { $$.range = make_range_from_width($1); $$.type = PTF_ATOM2_S; } | atom2_type { $$.range = make_range_from_width($1); $$.type = PTF_ATOM2_S; }
| atom2_type K_signed { $$.range = make_range_from_width($1); $$.type = PTF_ATOM2_S; } | atom2_type K_signed { $$.range = make_range_from_width($1); $$.type = PTF_ATOM2_S; }
| atom2_type K_unsigned { $$.range = make_range_from_width($1); $$.type = PTF_ATOM2; } | atom2_type K_unsigned { $$.range = make_range_from_width($1); $$.type = PTF_ATOM2; }
@ -5191,7 +5242,7 @@ statement /* This is roughly statement_item in the LRM */
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
$$ = tmp; $$ = tmp;
} }
| K_begin statement_list K_end | K_begin statement_or_null_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);
tmp->set_statement(*$2); tmp->set_statement(*$2);
@ -5204,7 +5255,7 @@ statement /* This is roughly statement_item in the LRM */
current_block_stack.push(tmp); current_block_stack.push(tmp);
} }
block_item_decls_opt block_item_decls_opt
statement_list_or_null K_end statement_or_null_list_opt 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();
@ -5227,7 +5278,7 @@ statement /* This is roughly statement_item in the LRM */
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
$$ = tmp; $$ = tmp;
} }
| K_fork statement_list K_join | K_fork statement_or_null_list K_join
{ PBlock*tmp = new PBlock(PBlock::BL_PAR); { PBlock*tmp = new PBlock(PBlock::BL_PAR);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
tmp->set_statement(*$2); tmp->set_statement(*$2);
@ -5240,7 +5291,7 @@ statement /* This is roughly statement_item in the LRM */
current_block_stack.push(tmp); current_block_stack.push(tmp);
} }
block_item_decls_opt block_item_decls_opt
statement_list_or_null K_join statement_or_null_list_opt 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();
@ -5362,6 +5413,7 @@ statement /* This is roughly statement_item in the LRM */
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
$$ = tmp; $$ = tmp;
} }
| error '=' expression ';' | error '=' expression ';'
{ yyerror(@2, "Syntax in assignment statement l-value."); { yyerror(@2, "Syntax in assignment statement l-value.");
yyerrok; yyerrok;
@ -5446,25 +5498,46 @@ statement /* This is roughly statement_item in the LRM */
delete[]$1; delete[]$1;
$$ = tmp; $$ = tmp;
} }
| hierarchy_identifier '(' expression_list_proper ')' ';'
{ PCallTask*tmp = new PCallTask(*$1, *$3); | hierarchy_identifier '(' expression_list_proper ')' ';'
FILE_NAME(tmp, @1); { PCallTask*tmp = new PCallTask(*$1, *$3);
delete $1; FILE_NAME(tmp, @1);
delete $3; delete $1;
$$ = tmp; delete $3;
} $$ = tmp;
}
| implicit_class_handle '.' hierarchy_identifier '(' expression_list_proper ')' ';'
{ PCallTask*tmp = new PCallTask(*$3, *$5);
yyerror(@1, "sorry: Implicit class handle not supported in front of task names.");
FILE_NAME(tmp, @1);
delete $3;
delete $5;
$$ = tmp;
}
/* NOTE: The standard doesn't really support an empty argument list /* NOTE: The standard doesn't really support an empty argument list
between parentheses, but it seems natural, and people commonly between parentheses, but it seems natural, and people commonly
want it. So accept it explicitly. */ want it. So accept it explicitly. */
| hierarchy_identifier '(' ')' ';' | hierarchy_identifier '(' ')' ';'
{ list<PExpr*>pt; { list<PExpr*>pt;
PCallTask*tmp = new PCallTask(*$1, pt); PCallTask*tmp = new PCallTask(*$1, pt);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
delete $1; delete $1;
$$ = tmp; $$ = tmp;
} }
| implicit_class_handle '.' hierarchy_identifier '(' ')' ';'
{ list<PExpr*>pt;
yyerror(@1, "sorry: Implicit class handle not supported in front of task names.");
PCallTask*tmp = new PCallTask(*$3, pt);
FILE_NAME(tmp, @3);
delete $3;
$$ = tmp;
}
| hierarchy_identifier ';' | hierarchy_identifier ';'
{ list<PExpr*>pt; { list<PExpr*>pt;
PCallTask*tmp = new PCallTask(*$1, pt); PCallTask*tmp = new PCallTask(*$1, pt);
@ -5537,34 +5610,14 @@ compressed_statement
} }
; ;
statement_list_or_null
: statement_list_or_null statement statement_or_null_list_opt
{ vector<Statement*>*tmp = $1; : statement_or_null_list
if (tmp) { { $$ = $1; }
tmp->push_back($2);
} else {
tmp = new vector<Statement*>(1);
tmp->at(0) = $2;
}
$$ = tmp;
}
| |
{ $$ = 0; } { $$ = 0; }
; ;
statement_list
: statement_list statement
{ vector<Statement*>*tmp = $1;
tmp->push_back($2);
$$ = tmp;
}
| statement
{ vector<Statement*>*tmp = new vector<Statement*>(1);
tmp->at(0) = $1;
$$ = tmp;
}
;
statement_or_null_list statement_or_null_list
: statement_or_null_list statement_or_null : statement_or_null_list statement_or_null
{ vector<Statement*>*tmp = $1; { vector<Statement*>*tmp = $1;

View File

@ -416,11 +416,16 @@ data_type_t* pform_test_type_identifier(const char*txt)
return false; return false;
perm_string name = lex_strings.make(txt); perm_string name = lex_strings.make(txt);
map<perm_string,data_type_t*>::iterator cur = lexical_scope->typedefs.find(name); map<perm_string,data_type_t*>::iterator cur;
if (cur != lexical_scope->typedefs.end()) LexicalScope*cur_scope = lexical_scope;
return cur->second; do {
else cur = cur_scope->typedefs.find(name);
return 0; if (cur != cur_scope->typedefs.end())
return cur->second;
cur_scope = cur_scope->parent_scope();
} while (cur_scope);
return 0;
} }
static void pform_put_behavior_in_scope(PProcess*pp) static void pform_put_behavior_in_scope(PProcess*pp)

View File

@ -812,7 +812,13 @@ void PFunction::dump(ostream&out, unsigned ind) const
out << "int unsigned "; out << "int unsigned ";
break; break;
case PTF_ATOM2_S: case PTF_ATOM2_S:
cout << "int signed "; out << "int signed ";
break;
case PTF_STRING:
out << "string ";
break;
case PTF_VOID:
out << "void ";
break; break;
} }