Support for some arithmetic operators.
This commit is contained in:
parent
acc4f73186
commit
cbb213d79e
|
|
@ -116,6 +116,39 @@ void Expression::dump(ostream&out, int indent) const
|
||||||
<< " at " << get_fileline()<< endl;
|
<< " at " << get_fileline()<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExpArithmetic::dump(ostream&out, int indent) const
|
||||||
|
{
|
||||||
|
const char*fun_name = "?";
|
||||||
|
switch (fun_) {
|
||||||
|
case PLUS:
|
||||||
|
fun_name = "+";
|
||||||
|
break;
|
||||||
|
case MINUS:
|
||||||
|
fun_name = "-";
|
||||||
|
break;
|
||||||
|
case MULT:
|
||||||
|
fun_name = "*";
|
||||||
|
break;
|
||||||
|
case DIV:
|
||||||
|
fun_name = "/";
|
||||||
|
break;
|
||||||
|
case MOD:
|
||||||
|
fun_name = "mod";
|
||||||
|
break;
|
||||||
|
case REM:
|
||||||
|
fun_name = "rem";
|
||||||
|
break;
|
||||||
|
case POW:
|
||||||
|
fun_name = "**";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out << setw(indent) << "" << "Arithmetic " << fun_name
|
||||||
|
<< " at " << get_fileline() << endl;
|
||||||
|
operand1()->dump(out, indent+4);
|
||||||
|
operand2()->dump(out, indent+4);
|
||||||
|
}
|
||||||
|
|
||||||
void ExpInteger::dump(ostream&out, int indent) const
|
void ExpInteger::dump(ostream&out, int indent) const
|
||||||
{
|
{
|
||||||
out << setw(indent) << "" << "Integer" << endl;
|
out << setw(indent) << "" << "Integer" << endl;
|
||||||
|
|
@ -147,8 +180,8 @@ void ExpLogical::dump(ostream&out, int indent) const
|
||||||
|
|
||||||
out << setw(indent) << "" << "Logical " << fun_name
|
out << setw(indent) << "" << "Logical " << fun_name
|
||||||
<< " at " << get_fileline() << endl;
|
<< " at " << get_fileline() << endl;
|
||||||
operand1_->dump(out, indent+4);
|
operand1()->dump(out, indent+4);
|
||||||
operand2_->dump(out, indent+4);
|
operand2()->dump(out, indent+4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpName::dump(ostream&out, int indent) const
|
void ExpName::dump(ostream&out, int indent) const
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,26 @@ bool Expression::evaluate(int64_t&) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExpBinary::ExpBinary(Expression*op1, Expression*op2)
|
||||||
|
: operand1_(op1), operand2_(op2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpBinary::~ExpBinary()
|
||||||
|
{
|
||||||
|
delete operand1_;
|
||||||
|
delete operand2_;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpArithmetic::ExpArithmetic(ExpArithmetic::fun_t op, Expression*op1, Expression*op2)
|
||||||
|
: ExpBinary(op1, op2), fun_(op)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpArithmetic::~ExpArithmetic()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ExpInteger::ExpInteger(int64_t val)
|
ExpInteger::ExpInteger(int64_t val)
|
||||||
: value_(val)
|
: value_(val)
|
||||||
{
|
{
|
||||||
|
|
@ -48,14 +68,12 @@ bool ExpInteger::evaluate(int64_t&val) const
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpLogical::ExpLogical(ExpLogical::fun_t ty, Expression*op1, Expression*op2)
|
ExpLogical::ExpLogical(ExpLogical::fun_t ty, Expression*op1, Expression*op2)
|
||||||
: fun_(ty), operand1_(op1), operand2_(op2)
|
: ExpBinary(op1, op2), fun_(ty)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpLogical::~ExpLogical()
|
ExpLogical::~ExpLogical()
|
||||||
{
|
{
|
||||||
delete operand1_;
|
|
||||||
delete operand2_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpName::ExpName(perm_string nn)
|
ExpName::ExpName(perm_string nn)
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,43 @@ class Expression : public LineInfo {
|
||||||
Expression& operator = (const Expression&);
|
Expression& operator = (const Expression&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is an abstract class that collects some of the common features
|
||||||
|
* of binary operators.
|
||||||
|
*/
|
||||||
|
class ExpBinary : public Expression {
|
||||||
|
|
||||||
|
public:
|
||||||
|
ExpBinary(Expression*op1, Expression*op2);
|
||||||
|
~ExpBinary();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
inline Expression* operand1() { return operand1_; }
|
||||||
|
inline Expression* operand2() { return operand2_; }
|
||||||
|
inline const Expression* operand1() const { return operand1_; }
|
||||||
|
inline const Expression* operand2() const { return operand2_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Expression*operand1_;
|
||||||
|
Expression*operand2_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ExpArithmetic : public ExpBinary {
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum fun_t { PLUS, MINUS, MULT, DIV, MOD, REM, POW };
|
||||||
|
|
||||||
|
public:
|
||||||
|
ExpArithmetic(ExpArithmetic::fun_t op, Expression*op1, Expression*op2);
|
||||||
|
~ExpArithmetic();
|
||||||
|
|
||||||
|
int emit(ostream&out, Entity*ent, Architecture*arc);
|
||||||
|
void dump(ostream&out, int indent) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
fun_t fun_;
|
||||||
|
};
|
||||||
|
|
||||||
class ExpInteger : public Expression {
|
class ExpInteger : public Expression {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -72,7 +109,7 @@ class ExpInteger : public Expression {
|
||||||
int64_t value_;
|
int64_t value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExpLogical : public Expression {
|
class ExpLogical : public ExpBinary {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum fun_t { AND, OR, NAND, NOR, XOR, XNOR };
|
enum fun_t { AND, OR, NAND, NOR, XOR, XNOR };
|
||||||
|
|
@ -86,8 +123,6 @@ class ExpLogical : public Expression {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
fun_t fun_;
|
fun_t fun_;
|
||||||
Expression*operand1_;
|
|
||||||
Expression*operand2_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,41 @@ int Expression::emit(ostream&out, Entity*, Architecture*)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ExpArithmetic::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
|
||||||
|
errors += operand1()->emit(out, ent, arc);
|
||||||
|
|
||||||
|
switch (fun_) {
|
||||||
|
case PLUS:
|
||||||
|
out << " + ";
|
||||||
|
break;
|
||||||
|
case MINUS:
|
||||||
|
out << " - ";
|
||||||
|
break;
|
||||||
|
case MULT:
|
||||||
|
out << " * ";
|
||||||
|
break;
|
||||||
|
case DIV:
|
||||||
|
out << " / ";
|
||||||
|
break;
|
||||||
|
case MOD:
|
||||||
|
out << " % ";
|
||||||
|
break;
|
||||||
|
case POW:
|
||||||
|
out << " ** ";
|
||||||
|
break;
|
||||||
|
case REM:
|
||||||
|
out << " /* ?remainder? */ ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
errors += operand2()->emit(out, ent, arc);
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
int ExpInteger::emit(ostream&out, Entity*, Architecture*)
|
int ExpInteger::emit(ostream&out, Entity*, Architecture*)
|
||||||
{
|
{
|
||||||
out << " /* " << get_fileline() << ": internal error: "
|
out << " /* " << get_fileline() << ": internal error: "
|
||||||
|
|
@ -42,7 +77,7 @@ int ExpLogical::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
{
|
{
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
|
||||||
errors += operand1_->emit(out, ent, arc);
|
errors += operand1()->emit(out, ent, arc);
|
||||||
|
|
||||||
switch (fun_) {
|
switch (fun_) {
|
||||||
case AND:
|
case AND:
|
||||||
|
|
@ -65,7 +100,7 @@ int ExpLogical::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
errors += operand2_->emit(out, ent, arc);
|
errors += operand2()->emit(out, ent, arc);
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -253,7 +253,8 @@ expression
|
||||||
;
|
;
|
||||||
|
|
||||||
expression_logical
|
expression_logical
|
||||||
: relation K_and relation
|
: relation { $$ = $1; }
|
||||||
|
| relation K_and relation
|
||||||
{ ExpLogical*tmp = new ExpLogical(ExpLogical::AND, $1, $3);
|
{ ExpLogical*tmp = new ExpLogical(ExpLogical::AND, $1, $3);
|
||||||
FILE_NAME(tmp, @2);
|
FILE_NAME(tmp, @2);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
|
|
@ -285,7 +286,15 @@ expression_logical
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
factor : primary { $$ = $1; } ;
|
factor
|
||||||
|
: primary
|
||||||
|
{ $$ = $1; }
|
||||||
|
| primary EXP primary
|
||||||
|
{ ExpArithmetic*tmp = new ExpArithmetic(ExpArithmetic::POW, $1, $3);
|
||||||
|
FILE_NAME(tmp, @2);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
identifier_opt : IDENTIFIER { $$ = $1; } | { $$ = 0; } ;
|
identifier_opt : IDENTIFIER { $$ = $1; } | { $$ = 0; } ;
|
||||||
|
|
||||||
|
|
@ -401,7 +410,20 @@ selected_names_use
|
||||||
|
|
||||||
shift_expression : simple_expression { $$ = $1; } ;
|
shift_expression : simple_expression { $$ = $1; } ;
|
||||||
|
|
||||||
simple_expression : term { $$ = $1; } ;
|
simple_expression
|
||||||
|
: term
|
||||||
|
{ $$ = $1; }
|
||||||
|
| term '+' term
|
||||||
|
{ ExpArithmetic*tmp = new ExpArithmetic(ExpArithmetic::PLUS, $1, $3);
|
||||||
|
FILE_NAME(tmp, @2);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| term '-' term
|
||||||
|
{ ExpArithmetic*tmp = new ExpArithmetic(ExpArithmetic::MINUS, $1, $3);
|
||||||
|
FILE_NAME(tmp, @2);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
subtype_indication
|
subtype_indication
|
||||||
: IDENTIFIER
|
: IDENTIFIER
|
||||||
|
|
@ -416,7 +438,30 @@ subtype_indication
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
term : factor { $$ = $1; } ;
|
term
|
||||||
|
: factor
|
||||||
|
{ $$ = $1; }
|
||||||
|
| factor '*' factor
|
||||||
|
{ ExpArithmetic*tmp = new ExpArithmetic(ExpArithmetic::MULT, $1, $3);
|
||||||
|
FILE_NAME(tmp, @2);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| factor '/' factor
|
||||||
|
{ ExpArithmetic*tmp = new ExpArithmetic(ExpArithmetic::DIV, $1, $3);
|
||||||
|
FILE_NAME(tmp, @2);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| factor K_mod factor
|
||||||
|
{ ExpArithmetic*tmp = new ExpArithmetic(ExpArithmetic::MOD, $1, $3);
|
||||||
|
FILE_NAME(tmp, @2);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| factor K_rem factor
|
||||||
|
{ ExpArithmetic*tmp = new ExpArithmetic(ExpArithmetic::REM, $1, $3);
|
||||||
|
FILE_NAME(tmp, @2);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
use_clause
|
use_clause
|
||||||
: K_use selected_names_use ';'
|
: K_use selected_names_use ';'
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue