diff --git a/parse.y b/parse.y index 9d51b2312..49b5b7fa3 100644 --- a/parse.y +++ b/parse.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: parse.y,v 1.22 1999/05/06 04:37:17 steve Exp $" +#ident "$Id: parse.y,v 1.23 1999/05/07 04:26:49 steve Exp $" #endif # include "parse_misc.h" @@ -88,7 +88,7 @@ extern void lex_end_table(); %type udp_port_decl udp_port_decls %type udp_initial udp_init_opt -%type identifier lvalue register_variable +%type identifier lpvalue register_variable %type register_variable_list %type list_of_variables @@ -102,6 +102,7 @@ extern void lex_end_table(); %type gate_instance_list %type bitsel delay delay_opt expression expr_primary const_expression +%type lavalue %type expression_list %type range range_opt @@ -534,9 +535,39 @@ list_of_variables } ; - /* An lvalue is the expression that can go on the left side of an - assignment. This rule handles only procedural assignments. */ -lvalue + /* An lavalue is the expression that can go on the left side of a + continuous assign statement. This checks (where it can) that the + expression meets the constraints of continuous assignments. */ +lavalue + : IDENTIFIER + { PEIdent*tmp = new PEIdent(*$1); + delete $1; + $$ = tmp; + } + | IDENTIFIER bitsel + { PEIdent*tmp = new PEIdent(*$1); + tmp->msb_ = $2; + delete $1; + $$ = tmp; + } + | IDENTIFIER range + { PEIdent*tmp = new PEIdent(*$1); + yyerror(@3, "Sorry, lvalue bit range not supported."); + delete $1; + delete $2; + $$ = tmp; + } + | '{' expression_list '}' + { yyerror(@1, "Sorry, concatenation expressions" + " not supported in lvalue."); + $$ = 0; + delete $2; + } + ; + + /* An lpvalue is the expression that can go on the left side of a + procedural assignment. This rule handles only procedural assignments. */ +lpvalue : identifier { $$ = $1; } | identifier '[' expression ']' { yyerror(@2, "Sorry, bit/memory selects " @@ -544,6 +575,12 @@ lvalue $$ = $1; delete $3; } + | '{' expression_list '}' + { yyerror(@1, "Sorry, concatenation expressions" + " not supported in lvalue."); + $$ = 0; + delete $2; + } ; module @@ -581,6 +618,8 @@ module_item } | K_reg register_variable_list ';' { delete $2; } + | K_integer list_of_variables ';' + { yyerror(@1, "Sorry, integer types not supported."); } | K_parameter parameter_assign_list ';' | gatetype delay_opt gate_instance_list ';' { pform_makegates($1, $2, $3); @@ -589,20 +628,9 @@ module_item { pform_make_modgates(*$1, $2); delete $1; } - | K_assign IDENTIFIER '=' expression ';' - { pform_make_pgassign(*$2, $4); - delete $2; - } - | K_assign IDENTIFIER bitsel '=' expression ';' - { pform_make_pgassign(*$2, $3, $5); - delete $2; - } - | K_assign IDENTIFIER range '=' expression ';' - { pform_make_pgassign(*$2, $5); - yyerror(@3, "Sorry, lvalue bit range not supported."); - delete $2; - delete $3; - } + | K_assign lavalue '=' expression ';' + { pform_make_pgassign($2, $4); } + | K_assign error '=' expression ';' | K_always statement { PProcess*tmp = pform_make_behavior(PProcess::PR_ALWAYS, $2); tmp->set_file(@1.text); @@ -757,19 +785,19 @@ statement { yyerror(@1, "Malformed conditional expression."); $$ = $5; } - | K_for '(' lvalue '=' expression ';' expression ';' - lvalue '=' expression ')' statement + | K_for '(' lpvalue '=' expression ';' expression ';' + lpvalue '=' expression ')' statement { $$ = new PForStatement(*$3, $5, $7, *$9, $11, $13); delete $3; delete $9; } - | K_for '(' lvalue '=' expression ';' expression ';' + | K_for '(' lpvalue '=' expression ';' expression ';' error ')' statement { $$ = 0; yyerror(@9, "Error in for loop step assigment."); } - | K_for '(' lvalue '=' expression ';' error ';' - lvalue '=' expression ')' statement + | K_for '(' lpvalue '=' expression ';' error ';' + lpvalue '=' expression ')' statement { $$ = 0; yyerror(@7, "Error in for loop condition expression."); } @@ -801,13 +829,13 @@ statement $$ = tmp; } } - | lvalue '=' expression ';' + | lpvalue '=' expression ';' { Statement*tmp = pform_make_assignment($1, $3); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); $$ = tmp; } - | lvalue K_LE expression ';' + | lpvalue K_LE expression ';' { $$ = pform_make_assignment($1, $3); yyerror(@1, "Sorry, non-blocking assignment not implemented."); } diff --git a/pform.cc b/pform.cc index bea5c0869..dd1a9ec92 100644 --- a/pform.cc +++ b/pform.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: pform.cc,v 1.14 1999/05/06 04:37:17 steve Exp $" +#ident "$Id: pform.cc,v 1.15 1999/05/07 04:26:49 steve Exp $" #endif # include "pform.h" @@ -303,21 +303,10 @@ void pform_make_modgates(const string&type, svector*gates) delete gates; } -void pform_make_pgassign(const string&lval, PExpr*rval) +void pform_make_pgassign(PExpr*lval, PExpr*rval) { vector wires (2); - wires[0] = new PEIdent(lval); - wires[1] = rval; - PGAssign*cur = new PGAssign(wires); - cur_module->add_gate(cur); -} - -void pform_make_pgassign(const string&lval, PExpr*sel, PExpr*rval) -{ - vector wires (2); - PEIdent*tmp = new PEIdent(lval); - tmp->msb_ = sel; - wires[0] = tmp; + wires[0] = lval; wires[1] = rval; PGAssign*cur = new PGAssign(wires); cur_module->add_gate(cur); @@ -544,6 +533,9 @@ int pform_parse(const char*path, map&modules, /* * $Log: pform.cc,v $ + * Revision 1.15 1999/05/07 04:26:49 steve + * Parse more complex continuous assign lvalues. + * * Revision 1.14 1999/05/06 04:37:17 steve * Get rid of list types. * diff --git a/pform.h b/pform.h index 0b579e9db..59e73fc11 100644 --- a/pform.h +++ b/pform.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: pform.h,v 1.11 1999/05/06 04:37:17 steve Exp $" +#ident "$Id: pform.h,v 1.12 1999/05/07 04:26:49 steve Exp $" #endif # include "netlist.h" @@ -126,8 +126,7 @@ extern void pform_makegates(PGBuiltin::Type type, extern void pform_make_modgates(const string&type, svector*gates); /* Make a continuous assignment node, with optional bit- or part- select. */ -extern void pform_make_pgassign(const string&lval, PExpr*rval); -extern void pform_make_pgassign(const string&lval, PExpr*sel, PExpr*rval); +extern void pform_make_pgassign(PExpr*lval, PExpr*rval); /* * These are functions that the outside-the-parser code uses the do @@ -141,6 +140,9 @@ extern void pform_dump(ostream&out, Module*mod); /* * $Log: pform.h,v $ + * Revision 1.12 1999/05/07 04:26:49 steve + * Parse more complex continuous assign lvalues. + * * Revision 1.11 1999/05/06 04:37:17 steve * Get rid of list types. *