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;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
out << setw(indent) << "" << "Integer" << endl;
|
||||
|
|
@ -147,8 +180,8 @@ void ExpLogical::dump(ostream&out, int indent) const
|
|||
|
||||
out << setw(indent) << "" << "Logical " << fun_name
|
||||
<< " at " << get_fileline() << endl;
|
||||
operand1_->dump(out, indent+4);
|
||||
operand2_->dump(out, indent+4);
|
||||
operand1()->dump(out, indent+4);
|
||||
operand2()->dump(out, indent+4);
|
||||
}
|
||||
|
||||
void ExpName::dump(ostream&out, int indent) const
|
||||
|
|
|
|||
|
|
@ -32,6 +32,26 @@ bool Expression::evaluate(int64_t&) const
|
|||
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)
|
||||
: value_(val)
|
||||
{
|
||||
|
|
@ -48,14 +68,12 @@ bool ExpInteger::evaluate(int64_t&val) const
|
|||
}
|
||||
|
||||
ExpLogical::ExpLogical(ExpLogical::fun_t ty, Expression*op1, Expression*op2)
|
||||
: fun_(ty), operand1_(op1), operand2_(op2)
|
||||
: ExpBinary(op1, op2), fun_(ty)
|
||||
{
|
||||
}
|
||||
|
||||
ExpLogical::~ExpLogical()
|
||||
{
|
||||
delete operand1_;
|
||||
delete operand2_;
|
||||
}
|
||||
|
||||
ExpName::ExpName(perm_string nn)
|
||||
|
|
|
|||
|
|
@ -58,6 +58,43 @@ class Expression : public LineInfo {
|
|||
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 {
|
||||
|
||||
public:
|
||||
|
|
@ -72,7 +109,7 @@ class ExpInteger : public Expression {
|
|||
int64_t value_;
|
||||
};
|
||||
|
||||
class ExpLogical : public Expression {
|
||||
class ExpLogical : public ExpBinary {
|
||||
|
||||
public:
|
||||
enum fun_t { AND, OR, NAND, NOR, XOR, XNOR };
|
||||
|
|
@ -86,8 +123,6 @@ class ExpLogical : public Expression {
|
|||
|
||||
private:
|
||||
fun_t fun_;
|
||||
Expression*operand1_;
|
||||
Expression*operand2_;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -31,6 +31,41 @@ int Expression::emit(ostream&out, Entity*, Architecture*)
|
|||
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*)
|
||||
{
|
||||
out << " /* " << get_fileline() << ": internal error: "
|
||||
|
|
@ -42,7 +77,7 @@ int ExpLogical::emit(ostream&out, Entity*ent, Architecture*arc)
|
|||
{
|
||||
int errors = 0;
|
||||
|
||||
errors += operand1_->emit(out, ent, arc);
|
||||
errors += operand1()->emit(out, ent, arc);
|
||||
|
||||
switch (fun_) {
|
||||
case AND:
|
||||
|
|
@ -65,7 +100,7 @@ int ExpLogical::emit(ostream&out, Entity*ent, Architecture*arc)
|
|||
break;
|
||||
}
|
||||
|
||||
errors += operand2_->emit(out, ent, arc);
|
||||
errors += operand2()->emit(out, ent, arc);
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -253,7 +253,8 @@ expression
|
|||
;
|
||||
|
||||
expression_logical
|
||||
: relation K_and relation
|
||||
: relation { $$ = $1; }
|
||||
| relation K_and relation
|
||||
{ ExpLogical*tmp = new ExpLogical(ExpLogical::AND, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = 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; } ;
|
||||
|
||||
|
|
@ -401,7 +410,20 @@ selected_names_use
|
|||
|
||||
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
|
||||
: 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
|
||||
: K_use selected_names_use ';'
|
||||
|
|
|
|||
Loading…
Reference in New Issue