diff --git a/parse.y b/parse.y index eaf4064d5..d75a8fbe1 100644 --- a/parse.y +++ b/parse.y @@ -447,7 +447,7 @@ static void current_task_set_statement(vector*s) %type from_exclude %type number pos_neg_number -%type unsigned_signed_opt signed_unsigned_opt +%type signing unsigned_signed_opt signed_unsigned_opt %type K_automatic_opt K_packed_opt K_reg_opt K_virtual_opt %type udp_reg_opt edge_operator %type drive_strength drive_strength_opt dr_strength0 dr_strength1 @@ -670,18 +670,34 @@ data_type /* IEEE1800-2005: A.2.2.1 */ } ; + /* The data_type_or_implicit rule is a little more complex then the + rule documented in the IEEE format syntax in order to allow for + signaling the special case that the data_type is completely + absent. The context may need that information to decide to resort + to left context. */ + data_type_or_implicit /* IEEE1800-2005: A.2.2.1 */ : data_type { $$ = $1; } - | unsigned_signed_opt range_opt + | signing range_opt { vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, $1, $2); FILE_NAME(tmp, @1); $$ = tmp; } + | range + { vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, false, $1); + FILE_NAME(tmp, @1); + $$ = tmp; + } + | + { $$ = 0; } ; + /* This implements the [ : INDENTIFIER ] part of the constructure + rule documented in IEEE1800-2005: A.1.8 */ endnew_opt : ':' K_new | ; + for_step /* IEEE1800-2005: A.6.8 */ : lpvalue '=' expression { PAssign*tmp = new PAssign($1,$3); @@ -824,12 +840,13 @@ port_direction /* IEEE1800-2005 A.1.3 */ } ; - /* port_direction_opt is used in places where the prot direction is - option, and defaults to input. */ + /* port_direction_opt is used in places where the port direction is + optional. The default direction is selected by the context, + which needs to notice the PIMPLICIT direction. */ port_direction_opt : port_direction { $$ = $1; } - | { $$ = NetNet::PINPUT; } + | { $$ = NetNet::PIMPLICIT; } ; /* real and realtime are exactly the same so save some code @@ -839,6 +856,11 @@ real_or_realtime | K_realtime ; +signing /* IEEE1800-2005: A.2.2.1 */ + : K_signed { $$ = true; } + | K_unsigned { $$ = false; } + ; + /* Many places where statements are allowed can actually take a statement or a null statement marked with a naked semi-colon. */ @@ -992,7 +1014,9 @@ tf_port_item /* IEEE1800-2005: A.2.7 */ : port_direction_opt K_integer IDENTIFIER range_opt tf_port_item_expr_opt { list*range_stub = make_range_from_width(integer_width); - port_declaration_context.port_type = $1; + NetNet::PortType use_port_type = $1==NetNet::PIMPLICIT? NetNet::PINPUT : $1; + + port_declaration_context.port_type = use_port_type; port_declaration_context.var_type = IVL_VT_LOGIC; port_declaration_context.sign_flag = true; delete port_declaration_context.range; @@ -1015,13 +1039,15 @@ tf_port_item /* IEEE1800-2005: A.2.7 */ | port_direction_opt K_time IDENTIFIER range_opt tf_port_item_expr_opt { list*range_stub = make_range_from_width(64); - port_declaration_context.port_type = $1; + NetNet::PortType use_port_type = $1==NetNet::PIMPLICIT? NetNet::PINPUT : $1; + + port_declaration_context.port_type = use_port_type; port_declaration_context.var_type = IVL_VT_LOGIC; port_declaration_context.sign_flag = false; delete port_declaration_context.range; port_declaration_context.range = copy_range(range_stub); - svector*tmp = pform_make_task_ports(@3, $1, IVL_VT_LOGIC, false, - range_stub, + svector*tmp = pform_make_task_ports(@3, use_port_type, IVL_VT_LOGIC, + false, range_stub, list_from_identifier($3)); $$ = tmp; if ($4) { @@ -1034,15 +1060,43 @@ tf_port_item /* IEEE1800-2005: A.2.7 */ } } - | port_direction data_type_or_implicit IDENTIFIER range_opt tf_port_item_expr_opt - { port_declaration_context.port_type = $1; - port_declaration_context.var_type = IVL_VT_NO_TYPE; - port_declaration_context.sign_flag = false; - delete port_declaration_context.range; - port_declaration_context.range = 0; - port_declaration_context.data_type = $2; - svector*tmp = pform_make_task_ports(@3, $1, $2, - list_from_identifier($3)); + | port_direction_opt data_type_or_implicit IDENTIFIER range_opt tf_port_item_expr_opt + { svector*tmp; + NetNet::PortType use_port_type = $1==NetNet::PIMPLICIT? NetNet::PINPUT : $1; + list* ilist = list_from_identifier($3); + + if (($2 == 0) && ($1==NetNet::PIMPLICIT)) { + // Detect special case this is an undecorated + // identifier and we need to get the declaration from + // left context. + if (port_declaration_context.var_type == IVL_VT_NO_TYPE) { + tmp = pform_make_task_ports(@3, use_port_type, + port_declaration_context.data_type, + ilist); + } else { + tmp = pform_make_task_ports(@3, use_port_type, + port_declaration_context.var_type, + port_declaration_context.sign_flag, + copy_range(port_declaration_context.range), + ilist); + } + + } else { + // Otherwise, the decorations for this identifier + // indicate the type. Save the type for any right + // context thta may come later. + port_declaration_context.port_type = use_port_type; + port_declaration_context.var_type = IVL_VT_NO_TYPE; + port_declaration_context.sign_flag = false; + delete port_declaration_context.range; + port_declaration_context.range = 0; + if ($2 == 0) { + $2 = new vector_type_t(IVL_VT_LOGIC, false, 0); + FILE_NAME($2, @3); + } + port_declaration_context.data_type = $2; + tmp = pform_make_task_ports(@3, $1, $2, ilist); + } $$ = tmp; if ($4) { yyerror(@4, "sorry: Port variable dimensions not supported yet."); @@ -1067,12 +1121,14 @@ tf_port_list /* IEEE1800-2005: A.2.7 */ : tf_port_list ',' tf_port_item { svector*tmp; - if ($3) { + if ($1 && $3) { tmp = new svector(*$1, *$3); delete $1; delete $3; - } else { + } else if ($1) { tmp = $1; + } else { + tmp = $3; } $$ = tmp; } @@ -1080,31 +1136,6 @@ tf_port_list /* IEEE1800-2005: A.2.7 */ | tf_port_item { $$ = $1; } - /* This rule handles the special case of a set of port items leading - an undecorated identifier. Undeconated identifiers in this case - pick up the details from the list to its lift. */ - - | tf_port_list ',' IDENTIFIER - { // The declaration is already parsed, apply it to IDENTIFIER - svector*new_decl; - if (port_declaration_context.var_type == IVL_VT_NO_TYPE) { - assert(port_declaration_context.data_type); - new_decl = pform_make_task_ports(@3, port_declaration_context.port_type, - port_declaration_context.data_type, - list_from_identifier($3)); - } else { - new_decl = pform_make_task_ports(@3, port_declaration_context.port_type, - port_declaration_context.var_type, - port_declaration_context.sign_flag, - copy_range(port_declaration_context.range), - list_from_identifier($3)); - } - svector*tmp = new svector(*$1, *new_decl); - delete $1; - delete new_decl; - $$ = tmp; - } - /* Rules to handle some errors in tf_port_list items. */ | error ',' tf_port_item