Do a better job of figuring the vtype of an expression.

This commit is contained in:
Stephen Williams 2013-06-07 15:49:19 -07:00
parent d630e4dfe9
commit 8487cb5616
4 changed files with 34 additions and 1 deletions

View File

@ -40,7 +40,7 @@ Expression::~Expression()
void Expression::set_type(const VType*typ)
{
assert(type_ == 0);
assert(type_==0 || type_==typ);
type_ = typ;
}

View File

@ -193,6 +193,9 @@ class ExpBinary : public Expression {
void dump_operands(ostream&out, int indent = 0) const;
private:
virtual const VType*resolve_operand_types_(const VType*t1, const VType*t2) const;
private:
Expression*operand1_;
Expression*operand2_;
@ -305,6 +308,9 @@ class ExpArithmetic : public ExpBinary {
virtual bool evaluate(ScopeBase*scope, int64_t&val) const;
void dump(ostream&out, int indent = 0) const;
private:
const VType* resolve_operand_types_(const VType*t1, const VType*t2) const;
private:
fun_t fun_;
};

View File

@ -328,6 +328,9 @@ const VType* ExpBinary::probe_type(Entity*ent, Architecture*arc) const
if (t1 == t2)
return t1;
if (const VType*tb = resolve_operand_types_(t1, t2))
return tb;
// FIXME: I should at this point try harder to find an
// operator that has the proper argument list and use this
// here, but for now we leave it for the back-end to figure out.
@ -337,6 +340,11 @@ const VType* ExpBinary::probe_type(Entity*ent, Architecture*arc) const
return 0;
}
const VType*ExpBinary::resolve_operand_types_(const VType*t1, const VType*t2) const
{
return 0;
}
int ExpBinary::elaborate_exprs(Entity*ent, Architecture*arc, const VType*ltype)
{
int errors = 0;
@ -491,6 +499,21 @@ int ExpArithmetic::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltyp
return errors;
}
const VType* ExpArithmetic::resolve_operand_types_(const VType*t1, const VType*t2) const
{
while (const VTypeRange*tmp = dynamic_cast<const VTypeRange*> (t1))
t1 = tmp->base_type();
while (const VTypeRange*tmp = dynamic_cast<const VTypeRange*> (t2))
t2 = tmp->base_type();
if (t1->type_match(t2))
return t1;
if (t2->type_match(t2))
return t2;
return 0;
}
const VType* ExpAttribute::probe_type(Entity*ent, Architecture*arc) const
{
base_->probe_type(ent, arc);

View File

@ -205,6 +205,10 @@ class VTypeRange : public VType {
VTypeRange(const VType*base, int64_t max_val, int64_t min_val);
~VTypeRange();
// Get the type that is limited by the range.
inline const VType* base_type() const { return base_; }
public: // Virtual methods
void write_to_stream(std::ostream&fd) const;
int emit_def(std::ostream&out) const;