Add parser support for concatenations/conditional assignment/elsif
Some of these should be easy to translate, but get the parsing out of the way first.
This commit is contained in:
parent
3362fbc0db
commit
2e28782af3
|
|
@ -163,6 +163,9 @@ void ExpArithmetic::dump(ostream&out, int indent) const
|
||||||
case POW:
|
case POW:
|
||||||
fun_name = "**";
|
fun_name = "**";
|
||||||
break;
|
break;
|
||||||
|
case CONCAT:
|
||||||
|
fun_name = "&";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out << setw(indent) << "" << "Arithmetic " << fun_name
|
out << setw(indent) << "" << "Arithmetic " << fun_name
|
||||||
|
|
@ -183,6 +186,16 @@ void ExpBinary::dump_operands(ostream&out, int indent) const
|
||||||
operand2_->dump(out, indent);
|
operand2_->dump(out, indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExpBitstring::dump(ostream&out, int indent) const
|
||||||
|
{
|
||||||
|
out << setw(indent) << "" << "Bit string " << value_.size()
|
||||||
|
<< "b\"";
|
||||||
|
for (size_t idx = value_.size() ; idx > 0 ; idx -= 1) {
|
||||||
|
out << value_[idx-1];
|
||||||
|
}
|
||||||
|
out << "\"";
|
||||||
|
}
|
||||||
|
|
||||||
void ExpCharacter::dump(ostream&out, int indent) const
|
void ExpCharacter::dump(ostream&out, int indent) const
|
||||||
{
|
{
|
||||||
out << setw(indent) << "" << "Character '" << value_ << "'"
|
out << setw(indent) << "" << "Character '" << value_ << "'"
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
# include "scope.h"
|
# include "scope.h"
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
# include <typeinfo>
|
# include <typeinfo>
|
||||||
|
# include <cstring>
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
@ -161,11 +162,27 @@ bool ExpArithmetic::evaluate(ScopeBase*scope, int64_t&val) const
|
||||||
return false;
|
return false;
|
||||||
case POW:
|
case POW:
|
||||||
return false;
|
return false;
|
||||||
|
case CONCAT:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Store bitstrings in little-endian order.
|
||||||
|
*/
|
||||||
|
ExpBitstring::ExpBitstring(const char*val)
|
||||||
|
: value_(strlen(val))
|
||||||
|
{
|
||||||
|
for (size_t idx = value_.size() ; idx > 0 ; idx -= 1)
|
||||||
|
value_[idx-1] = *val++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpBitstring::~ExpBitstring()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ExpCharacter::ExpCharacter(char val)
|
ExpCharacter::ExpCharacter(char val)
|
||||||
: value_(val)
|
: value_(val)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
# include "StringHeap.h"
|
# include "StringHeap.h"
|
||||||
# include "LineInfo.h"
|
# include "LineInfo.h"
|
||||||
# include <inttypes.h>
|
# include <inttypes.h>
|
||||||
|
# include <vector>
|
||||||
|
|
||||||
class Entity;
|
class Entity;
|
||||||
class Architecture;
|
class Architecture;
|
||||||
|
|
@ -146,7 +147,7 @@ class ExpBinary : public Expression {
|
||||||
class ExpArithmetic : public ExpBinary {
|
class ExpArithmetic : public ExpBinary {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum fun_t { PLUS, MINUS, MULT, DIV, MOD, REM, POW };
|
enum fun_t { PLUS, MINUS, MULT, DIV, MOD, REM, POW, CONCAT };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ExpArithmetic(ExpArithmetic::fun_t op, Expression*op1, Expression*op2);
|
ExpArithmetic(ExpArithmetic::fun_t op, Expression*op1, Expression*op2);
|
||||||
|
|
@ -177,6 +178,19 @@ class ExpAttribute : public Expression {
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ExpBitstring : public Expression {
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ExpBitstring(const char*);
|
||||||
|
~ExpBitstring();
|
||||||
|
|
||||||
|
int emit(ostream&out, Entity*ent, Architecture*arc);
|
||||||
|
void dump(ostream&out, int indent = 0) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<char>value_;
|
||||||
|
};
|
||||||
|
|
||||||
class ExpCharacter : public Expression {
|
class ExpCharacter : public Expression {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,9 @@ int ExpArithmetic::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
case REM:
|
case REM:
|
||||||
out << " /* ?remainder? */ ";
|
out << " /* ?remainder? */ ";
|
||||||
break;
|
break;
|
||||||
|
case CONCAT:
|
||||||
|
out << " /* ?concat? */ ";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
errors += emit_operand2(out, ent, arc);
|
errors += emit_operand2(out, ent, arc);
|
||||||
|
|
@ -108,6 +111,13 @@ int ExpArithmetic::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ExpBitstring::emit(ostream&out, Entity*, Architecture*)
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
errors += 1;
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
int ExpCharacter::emit(ostream&out, Entity*, Architecture*)
|
int ExpCharacter::emit(ostream&out, Entity*, Architecture*)
|
||||||
{
|
{
|
||||||
const VType*etype = peek_type();
|
const VType*etype = peek_type();
|
||||||
|
|
|
||||||
236
vhdlpp/lexor.lex
236
vhdlpp/lexor.lex
|
|
@ -54,6 +54,7 @@ static char* escape_apostrophe_and_dup(char* text);
|
||||||
|
|
||||||
static double make_double_from_based(char* text);
|
static double make_double_from_based(char* text);
|
||||||
static int64_t make_long_from_based(char* text);
|
static int64_t make_long_from_based(char* text);
|
||||||
|
static char* make_bitstring_literal(const char*text);
|
||||||
|
|
||||||
static int64_t lpow(int64_t left, int64_t right);
|
static int64_t lpow(int64_t left, int64_t right);
|
||||||
static unsigned short short_from_hex_char(char ch);
|
static unsigned short short_from_hex_char(char ch);
|
||||||
|
|
@ -175,6 +176,10 @@ based_integer [0-9a-fA-F](_?[0-9a-fA-F])*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{integer}?[sSuU]?[xXbBoOdD]\"[^\"]+\" {
|
||||||
|
yylval.text = make_bitstring_literal(yytext);
|
||||||
|
return BITSTRING_LITERAL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Compound symbols */
|
/* Compound symbols */
|
||||||
"<=" { return LEQ; }
|
"<=" { return LEQ; }
|
||||||
|
|
@ -381,6 +386,237 @@ static char* escape_apostrophe_and_dup(char* text)
|
||||||
return newstr;
|
return newstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char*make_bitstring_bin(int width_prefix, bool sflag, bool,
|
||||||
|
const char*src)
|
||||||
|
{
|
||||||
|
int src_len = strlen(src);
|
||||||
|
if (width_prefix < 0)
|
||||||
|
width_prefix = src_len;
|
||||||
|
|
||||||
|
char*res = new char[width_prefix+1];
|
||||||
|
char*rp = res;
|
||||||
|
|
||||||
|
if (width_prefix > src_len) {
|
||||||
|
size_t pad = width_prefix - src_len;
|
||||||
|
for (size_t idx = 0 ; idx < pad ; idx += 1)
|
||||||
|
*rp++ = sflag? src[0] : '0';
|
||||||
|
|
||||||
|
} else if (src_len > width_prefix) {
|
||||||
|
src += src_len - width_prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*src) {
|
||||||
|
*rp++ = *src++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char*make_bitstring_oct(int width_prefix, bool sflag, bool,
|
||||||
|
const char*src)
|
||||||
|
{
|
||||||
|
int src_len = strlen(src);
|
||||||
|
if (width_prefix < 0)
|
||||||
|
width_prefix = 3*src_len;
|
||||||
|
|
||||||
|
char*res = new char[width_prefix+1];
|
||||||
|
char*rp = res + width_prefix;
|
||||||
|
*rp = 0;
|
||||||
|
rp -= 1;
|
||||||
|
|
||||||
|
for (const char*sp = src + src_len - 1; sp >= src ; sp -= 1) {
|
||||||
|
int val;
|
||||||
|
switch (*sp) {
|
||||||
|
case '0':
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '3':
|
||||||
|
case '4':
|
||||||
|
case '5':
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
val = *sp - '0';
|
||||||
|
*rp-- = (val&1)? '1' : '0';
|
||||||
|
if (rp >= res) *rp-- = (val&2)? '1' : '0';
|
||||||
|
if (rp >= res) *rp-- = (val&4)? '1' : '0';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*rp-- = *sp;
|
||||||
|
if (rp >= res) *rp-- = *sp;
|
||||||
|
if (rp >= res) *rp-- = *sp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (rp < res)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rp >= res) {
|
||||||
|
char pad = sflag? src[0] : '0';
|
||||||
|
while (rp >= res)
|
||||||
|
*rp-- = pad;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char*make_bitstring_hex(int width_prefix, bool sflag, bool,
|
||||||
|
const char*src)
|
||||||
|
{
|
||||||
|
int src_len = strlen(src);
|
||||||
|
if (width_prefix <= 0)
|
||||||
|
width_prefix = 4*src_len;
|
||||||
|
|
||||||
|
char*res = new char[width_prefix+1];
|
||||||
|
char*rp = res + width_prefix;
|
||||||
|
*rp = 0;
|
||||||
|
rp -= 1;
|
||||||
|
|
||||||
|
for (const char*sp = src + src_len - 1; sp >= src ; sp -= 1) {
|
||||||
|
int val;
|
||||||
|
switch (*sp) {
|
||||||
|
case '0':
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '3':
|
||||||
|
case '4':
|
||||||
|
case '5':
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
case '8':
|
||||||
|
case '9':
|
||||||
|
val = *sp - '0';
|
||||||
|
*rp-- = (val&1)? '1' : '0';
|
||||||
|
if (rp >= res) *rp-- = (val&2)? '1' : '0';
|
||||||
|
if (rp >= res) *rp-- = (val&4)? '1' : '0';
|
||||||
|
if (rp >= res) *rp-- = (val&8)? '1' : '0';
|
||||||
|
break;
|
||||||
|
case 'a': case 'A':
|
||||||
|
case 'b': case 'B':
|
||||||
|
case 'c': case 'C':
|
||||||
|
case 'd': case 'D':
|
||||||
|
case 'e': case 'E':
|
||||||
|
case 'f': case 'F':
|
||||||
|
val = 10 + toupper(*sp) - 'A';
|
||||||
|
*rp-- = (val&1)? '1' : '0';
|
||||||
|
if (rp >= res) *rp-- = (val&2)? '1' : '0';
|
||||||
|
if (rp >= res) *rp-- = (val&4)? '1' : '0';
|
||||||
|
if (rp >= res) *rp-- = (val&8)? '1' : '0';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*rp-- = *sp;
|
||||||
|
if (rp >= res) *rp-- = *sp;
|
||||||
|
if (rp >= res) *rp-- = *sp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (rp < res)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rp >= res) {
|
||||||
|
char pad = sflag? src[0] : '0';
|
||||||
|
while (rp >= res)
|
||||||
|
*rp-- = pad;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char*make_bitstring_dec(int, bool, bool, const char*)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* make_bitstring_literal(const char*text)
|
||||||
|
{
|
||||||
|
int width_prefix = -1;
|
||||||
|
const char*cp = text;
|
||||||
|
bool signed_flag = false;
|
||||||
|
bool unsigned_flag = false;
|
||||||
|
unsigned base = 0;
|
||||||
|
|
||||||
|
// Parse out the explicit width, if present.
|
||||||
|
if (size_t len = strspn(cp, "0123456789")) {
|
||||||
|
width_prefix = 0;
|
||||||
|
while (len > 0) {
|
||||||
|
width_prefix *= 10;
|
||||||
|
width_prefix += *cp - '0';
|
||||||
|
cp += 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
width_prefix = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect and s/u flags.
|
||||||
|
if (*cp == 's' || *cp == 'S') {
|
||||||
|
signed_flag = true;
|
||||||
|
cp += 1;
|
||||||
|
} else if (*cp == 'u' || *cp == 'U') {
|
||||||
|
unsigned_flag = true;
|
||||||
|
cp += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now get the base marker.
|
||||||
|
switch (*cp) {
|
||||||
|
case 'b':
|
||||||
|
case 'B':
|
||||||
|
base = 2;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
case 'O':
|
||||||
|
base = 8;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
case 'X':
|
||||||
|
base = 16;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
base = 10;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
cp += 1;
|
||||||
|
|
||||||
|
char*simplified = new char [strlen(cp) + 1];
|
||||||
|
char*dp = simplified;
|
||||||
|
assert(*cp == '"');
|
||||||
|
cp += 1;
|
||||||
|
|
||||||
|
while (*cp && *cp != '"') {
|
||||||
|
if (*cp == '_') {
|
||||||
|
cp += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
*dp++ = *cp++;
|
||||||
|
}
|
||||||
|
*dp = 0;
|
||||||
|
|
||||||
|
char*res;
|
||||||
|
switch (base) {
|
||||||
|
case 2:
|
||||||
|
res = make_bitstring_bin(width_prefix, signed_flag, unsigned_flag, simplified);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
res = make_bitstring_oct(width_prefix, signed_flag, unsigned_flag, simplified);
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
res = make_bitstring_dec(width_prefix, signed_flag, unsigned_flag, simplified);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
res = make_bitstring_hex(width_prefix, signed_flag, unsigned_flag, simplified);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
res = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[]simplified;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function takes a floating point based number
|
* This function takes a floating point based number
|
||||||
* in form of a C-strings and converts it to a double.
|
* in form of a C-strings and converts it to a double.
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,7 @@ const VType*parse_type_by_name(perm_string name)
|
||||||
%token <text> IDENTIFIER
|
%token <text> IDENTIFIER
|
||||||
%token <uni_integer> INT_LITERAL
|
%token <uni_integer> INT_LITERAL
|
||||||
%token <uni_real> REAL_LITERAL
|
%token <uni_real> REAL_LITERAL
|
||||||
%token <text> STRING_LITERAL CHARACTER_LITERAL
|
%token <text> STRING_LITERAL CHARACTER_LITERAL BITSTRING_LITERAL
|
||||||
/* compound symbols */
|
/* compound symbols */
|
||||||
%token LEQ GEQ VASSIGN NE BOX EXP ARROW DLT DGT
|
%token LEQ GEQ VASSIGN NE BOX EXP ARROW DLT DGT
|
||||||
|
|
||||||
|
|
@ -275,11 +275,20 @@ architecture_statement_part
|
||||||
;
|
;
|
||||||
|
|
||||||
association_element
|
association_element
|
||||||
: IDENTIFIER ARROW name
|
: IDENTIFIER ARROW expression
|
||||||
{ named_expr_t*tmp = new named_expr_t(lex_strings.make($1), $3);
|
{ named_expr_t*tmp = new named_expr_t(lex_strings.make($1), $3);
|
||||||
delete[]$1;
|
delete[]$1;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
| IDENTIFIER ARROW K_open
|
||||||
|
{ sorrymsg(@3, "Port map \"open\" not supported.\n");
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| IDENTIFIER ARROW error
|
||||||
|
{ errormsg(@3, "Invalid target for port map association.\n");
|
||||||
|
yyerrok;
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
association_list
|
association_list
|
||||||
|
|
@ -443,6 +452,16 @@ concurrent_signal_assignment_statement
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
delete $3;
|
delete $3;
|
||||||
}
|
}
|
||||||
|
| name LEQ waveform K_when expression K_else waveform ';'
|
||||||
|
{ ExpName*name = dynamic_cast<ExpName*> ($1);
|
||||||
|
assert(name);
|
||||||
|
SignalAssignment*tmp = new SignalAssignment(name, *$3);
|
||||||
|
FILE_NAME(tmp, @1);
|
||||||
|
|
||||||
|
$$ = tmp;
|
||||||
|
delete $3;
|
||||||
|
sorrymsg(@4, "Conditional signal assignment not supported here.\n");
|
||||||
|
}
|
||||||
| name LEQ error ';'
|
| name LEQ error ';'
|
||||||
{ errormsg(@2, "Syntax error in signal assignment waveform.\n");
|
{ errormsg(@2, "Syntax error in signal assignment waveform.\n");
|
||||||
delete $1;
|
delete $1;
|
||||||
|
|
@ -755,15 +774,15 @@ identifier_opt : IDENTIFIER { $$ = $1; } | { $$ = 0; } ;
|
||||||
|
|
||||||
if_statement
|
if_statement
|
||||||
: K_if expression K_then sequence_of_statements
|
: K_if expression K_then sequence_of_statements
|
||||||
if_statement_else
|
if_statement_elsif_list_opt if_statement_else
|
||||||
K_end K_if ';'
|
K_end K_if ';'
|
||||||
{ IfSequential*tmp = new IfSequential($2, $4, $5);
|
{ IfSequential*tmp = new IfSequential($2, $4, $6);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
| K_if error K_then sequence_of_statements
|
| K_if error K_then sequence_of_statements
|
||||||
if_statement_else
|
if_statement_elsif_list_opt if_statement_else
|
||||||
K_end K_if ';'
|
K_end K_if ';'
|
||||||
{ errormsg(@2, "Error in if_statement condition expression.\n");
|
{ errormsg(@2, "Error in if_statement condition expression.\n");
|
||||||
yyerrok;
|
yyerrok;
|
||||||
|
|
@ -772,7 +791,7 @@ if_statement
|
||||||
}
|
}
|
||||||
|
|
||||||
| K_if expression K_then error K_end K_if ';'
|
| K_if expression K_then error K_end K_if ';'
|
||||||
{ errormsg(@2, "Too many errors in sequence within if_statement.\n");
|
{ errormsg(@4, "Too many errors in sequence within if_statement.\n");
|
||||||
yyerrok;
|
yyerrok;
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -784,9 +803,33 @@ if_statement
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
if_statement_elsif_list_opt
|
||||||
|
: if_statement_elsif_list
|
||||||
|
|
|
||||||
|
;
|
||||||
|
|
||||||
|
if_statement_elsif_list
|
||||||
|
: if_statement_elsif_list if_statement_elsif
|
||||||
|
| if_statement_elsif
|
||||||
|
;
|
||||||
|
|
||||||
|
if_statement_elsif
|
||||||
|
: K_elsif expression K_then sequence_of_statements
|
||||||
|
{ sorrymsg(@1, "elsif sub-statements are not supported.\n"); }
|
||||||
|
| K_elsif expression K_then error
|
||||||
|
{ errormsg(@4, "Too many errors in elsif sub-statements.\n");
|
||||||
|
yyerrok;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
if_statement_else
|
if_statement_else
|
||||||
: K_else sequence_of_statements
|
: K_else sequence_of_statements
|
||||||
{ $$ = $2; }
|
{ $$ = $2; }
|
||||||
|
| K_else error
|
||||||
|
{ errormsg(@2, "Too many errors in else sub-statements.\n");
|
||||||
|
yyerrok;
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
|
|
|
||||||
{ $$ = 0; }
|
{ $$ = 0; }
|
||||||
;
|
;
|
||||||
|
|
@ -1004,8 +1047,7 @@ port_map_aspect
|
||||||
: K_port K_map '(' association_list ')'
|
: K_port K_map '(' association_list ')'
|
||||||
{ $$ = $4; }
|
{ $$ = $4; }
|
||||||
| K_port K_map '(' error ')'
|
| K_port K_map '(' error ')'
|
||||||
{
|
{ errormsg(@1, "Syntax error in port map aspect.\n");
|
||||||
errormsg(@1, "Syntax error in port map aspect.\n");
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -1053,6 +1095,12 @@ primary
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
| BITSTRING_LITERAL
|
||||||
|
{ ExpBitstring*tmp = new ExpBitstring($1);
|
||||||
|
FILE_NAME(tmp, @1);
|
||||||
|
delete[]$1;
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
| '(' expression ')'
|
| '(' expression ')'
|
||||||
{ $$ = $2; }
|
{ $$ = $2; }
|
||||||
;
|
;
|
||||||
|
|
@ -1248,6 +1296,11 @@ simple_expression
|
||||||
FILE_NAME(tmp, @2);
|
FILE_NAME(tmp, @2);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
| term '&' term
|
||||||
|
{ ExpArithmetic*tmp = new ExpArithmetic(ExpArithmetic::CONCAT, $1, $3);
|
||||||
|
FILE_NAME(tmp, @2);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
signal_assignment_statement
|
signal_assignment_statement
|
||||||
|
|
@ -1257,6 +1310,12 @@ signal_assignment_statement
|
||||||
delete $3;
|
delete $3;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
| name LEQ waveform K_when expression K_else waveform ';'
|
||||||
|
{ SignalSeqAssignment*tmp = new SignalSeqAssignment($1, $3);
|
||||||
|
FILE_NAME(tmp, @1);
|
||||||
|
sorrymsg(@4, "Conditional signal assignment not supported.\n");
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
subtype_declaration
|
subtype_declaration
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue