Parse more constant expressions.

This commit is contained in:
steve 1999-05-06 04:09:28 +00:00
parent df0c894cb0
commit b2b9097488
4 changed files with 98 additions and 14 deletions

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: lexor.lex,v 1.11 1999/03/16 04:44:45 steve Exp $"
#ident "$Id: lexor.lex,v 1.12 1999/05/06 04:09:28 steve Exp $"
#endif
//# define YYSTYPE lexval
@ -44,6 +44,10 @@ static verinum*make_sized_binary(const char*txt);
static verinum*make_sized_dec(const char*txt);
static verinum*make_sized_octal(const char*txt);
static verinum*make_sized_hex(const char*txt);
static verinum*make_unsized_binary(const char*txt);
static verinum*make_unsized_dec(const char*txt);
static verinum*make_unsized_octal(const char*txt);
static verinum*make_unsized_hex(const char*txt);
%}
@ -73,7 +77,7 @@ static verinum*make_sized_hex(const char*txt);
"||" { return K_LOR; }
"&&" { return K_LAND; }
[;:\[\],()#=.@&!<|^~+*/-] { return yytext[0]; }
[}{;:\[\],()#=.@&!<|^~+*/-] { return yytext[0]; }
\" { BEGIN(CSTRING); }
<CSTRING>\\\" { yymore(); }
@ -130,6 +134,11 @@ static verinum*make_sized_hex(const char*txt);
[0-9][0-9_]*\'[hH][0-9a-fA-Fxz_]+ { yylval.number = make_sized_hex(yytext);
return NUMBER; }
\'[bB][0-1xz_]+ { yylval.number = make_unsized_binary(yytext); return NUMBER; }
\'[oO][0-7xz_]+ { yylval.number = make_unsized_octal(yytext); return NUMBER; }
\'[hH][0-9a-fA-Fxz_]+ { yylval.number = make_unsized_hex(yytext);
return NUMBER; }
[0-9][0-9_]* {
/* Handle the special case of the unsized decimal number. */
unsigned long value = 0;
@ -298,18 +307,13 @@ static int check_identifier(const char*name)
return IDENTIFIER;
}
static verinum*make_sized_binary(const char*txt)
static verinum*make_binary_with_size(unsigned size, const char*ptr)
{
char*ptr;
unsigned size = strtoul(txt,&ptr,10);
assert(*ptr == '\'');
ptr += 1;
assert(tolower(*ptr) == 'b');
verinum::V*bits = new verinum::V[size];
unsigned idx = 0;
char*eptr = ptr + strlen(ptr) - 1;
const char*eptr = ptr + strlen(ptr) - 1;
while ((eptr > ptr) && (idx < size)) {
if (*eptr == '_') {
@ -336,7 +340,6 @@ static verinum*make_sized_binary(const char*txt)
eptr -= 1;
}
// Zero-extend binary number, except that z or x is extended
// if it is the highest supplied digit.
while (idx < size) {
@ -359,6 +362,24 @@ static verinum*make_sized_binary(const char*txt)
return new verinum(bits, size);
}
static verinum*make_sized_binary(const char*txt)
{
char*ptr;
unsigned size = strtoul(txt,&ptr,10);
assert(*ptr == '\'');
ptr += 1;
assert(tolower(*ptr) == 'b');
return make_binary_with_size(size, ptr);
}
static verinum*make_unsized_binary(const char*txt)
{
assert(*txt == '\'');
txt += 1;
return make_binary_with_size(64, txt);
}
static verinum*make_sized_octal(const char*txt)
{
char*ptr;
@ -410,6 +431,11 @@ static verinum*make_sized_octal(const char*txt)
return new verinum(bits, size);
}
static verinum*make_unsized_octal(const char*txt)
{
assert(0);
}
static verinum*make_sized_hex(const char*txt)
{
char*ptr;
@ -479,6 +505,11 @@ static verinum*make_sized_hex(const char*txt)
return new verinum(bits, size);
}
static verinum*make_unsized_hex(const char*txt)
{
assert(0);
}
/*
* Making a deciman number is much easier then the other base numbers
* because there are no z or x values to worry about.

35
parse.y
View File

@ -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.20 1999/05/05 03:27:15 steve Exp $"
#ident "$Id: parse.y,v 1.21 1999/05/06 04:09:28 steve Exp $"
#endif
# include "parse_misc.h"
@ -170,6 +170,10 @@ case_items
}
;
/* const_expressions are restricted expressions that have guaranteed
known values at compile time. I treat them differently at parse
time so that I can tack correctness checking onto the parse
process. */
const_expression
: NUMBER
{ verinum*tmp = $1;
@ -184,6 +188,23 @@ const_expression
{ $$ = new PEString(*$1);
delete $1;
}
| IDENTIFIER
{ if (!pform_is_parameter(*$1)) {
yyerror(@1, "Identifier in constant expression"
" must be a parameter name.");
delete $1;
$$ = 0;
} else {
PEIdent*tmp = new PEIdent(*$1);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
delete $1;
}
}
| const_expression '-' const_expression
{ $$ = new PEBinary('-', $1, $3);
}
;
delay
@ -277,6 +298,10 @@ expression
{ $$ = $1; }
| '(' expression ')'
{ $$ = $2; }
| '{' expression_list '}'
{ yyerror(@1, "Sorry, concatenation operator not supported.");
$$ = 0;
}
| '~' expression %prec UNARY_PREC
{ $$ = new PEUnary('~', $2);
}
@ -507,8 +532,16 @@ 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
: identifier { $$ = $1; }
| identifier '[' expression ']'
{ yyerror(@2, "Sorry, bit/memory selects "
"not supported in lvalue.");
$$ = $1;
delete $3;
}
;
module

View File

@ -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.12 1999/05/02 23:25:32 steve Exp $"
#ident "$Id: pform.cc,v 1.13 1999/05/06 04:09:28 steve Exp $"
#endif
# include "pform.h"
@ -426,8 +426,14 @@ static void pform_set_net_range(const string&name, list<PExpr*>*range)
PExpr*msb = *idx;
idx ++;
PExpr*lsb = *idx;
if (! (cur->msb->is_the_same(msb) && cur->lsb->is_the_same(lsb)))
if (msb == 0) {
VLerror(yylloc, "failed to parse msb of range.");
} else if (lsb == 0) {
VLerror(yylloc, "failed to parse lsb of range.");
} else if (! (cur->msb->is_the_same(msb) &&
cur->lsb->is_the_same(lsb))) {
VLerror(yylloc, "net ranges are not identical.");
}
delete msb;
delete lsb;
}
@ -438,6 +444,13 @@ void pform_set_parameter(const string&name, PExpr*expr)
cur_module->parameters[name] = expr;
}
bool pform_is_parameter(const string&name)
{
map<string,PExpr*>::const_iterator cur =
cur_module->parameters.find(name);
return cur != cur_module->parameters.end();
}
void pform_set_port_type(list<string>*names, NetNet::PortType pt)
{
for (list<string>::const_iterator cur = names->begin()
@ -535,6 +548,9 @@ int pform_parse(const char*path, map<string,Module*>&modules,
/*
* $Log: pform.cc,v $
* Revision 1.13 1999/05/06 04:09:28 steve
* Parse more constant expressions.
*
* Revision 1.12 1999/05/02 23:25:32 steve
* Enforce module instance names.
*

View File

@ -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.9 1999/04/19 01:59:37 steve Exp $"
#ident "$Id: pform.h,v 1.10 1999/05/06 04:09:28 steve Exp $"
#endif
# include "netlist.h"
@ -107,6 +107,7 @@ extern void pform_set_attrib(const string&name, const string&key,
extern void pform_set_type_attrib(const string&name, const string&key,
const string&value);
extern void pform_set_parameter(const string&name, PExpr*expr);
extern bool pform_is_parameter(const string&name);
extern PProcess* pform_make_behavior(PProcess::Type, Statement*);
extern Statement* pform_make_block(PBlock::BL_TYPE, list<Statement*>*);
extern Statement* pform_make_assignment(string*t, PExpr*e);
@ -140,6 +141,9 @@ extern void pform_dump(ostream&out, Module*mod);
/*
* $Log: pform.h,v $
* Revision 1.10 1999/05/06 04:09:28 steve
* Parse more constant expressions.
*
* Revision 1.9 1999/04/19 01:59:37 steve
* Add memories to the parse and elaboration phases.
*