Some Expression refactoring

master
Marius Kintel 2014-11-25 17:08:14 -05:00
parent 74475395f4
commit 2e8d93d5be
3 changed files with 87 additions and 110 deletions

View File

@ -67,49 +67,27 @@ namespace {
} }
} }
Expression::Expression() Expression::Expression() : first(NULL), second(NULL), third(NULL)
{ {
} }
Expression::Expression(const ValuePtr &val) Expression::Expression(Expression *expr) : first(expr), second(NULL), third(NULL)
{
const_value = val;
}
Expression::Expression(const std::string &val)
{
var_name = val;
}
Expression::Expression(const std::string &val, Expression *expr)
{
var_name = val;
children.push_back(expr);
first = expr;
}
Expression::Expression(Expression *expr)
{ {
children.push_back(expr); children.push_back(expr);
first = expr;
} }
Expression::Expression(Expression *left, Expression *right) Expression::Expression(Expression *left, Expression *right) : first(left), second(right), third(NULL)
{ {
children.push_back(left); children.push_back(left);
children.push_back(right); children.push_back(right);
first = left;
second = right;
} }
Expression::Expression(Expression *expr1, Expression *expr2, Expression *expr3) Expression::Expression(Expression *expr1, Expression *expr2, Expression *expr3)
: first(expr1), second(expr2), third(expr3)
{ {
children.push_back(expr1); children.push_back(expr1);
children.push_back(expr2); children.push_back(expr2);
children.push_back(expr3); children.push_back(expr3);
first = expr1;
second = expr2;
third = expr3;
} }
Expression::~Expression() Expression::~Expression()
@ -373,7 +351,7 @@ void ExpressionInvert::print(std::ostream &stream) const
stream << "-" << *first; stream << "-" << *first;
} }
ExpressionConst::ExpressionConst(const ValuePtr &val) : Expression(val) ExpressionConst::ExpressionConst(const ValuePtr &val) : const_value(val)
{ {
} }
@ -446,7 +424,7 @@ void ExpressionVector::print(std::ostream &stream) const
stream << "]"; stream << "]";
} }
ExpressionLookup::ExpressionLookup(const std::string &val) : Expression(val) ExpressionLookup::ExpressionLookup(const std::string &var_name) : var_name(var_name)
{ {
} }
@ -460,7 +438,8 @@ void ExpressionLookup::print(std::ostream &stream) const
stream << this->var_name; stream << this->var_name;
} }
ExpressionMember::ExpressionMember(const std::string &val, Expression *expr) : Expression(val, expr) ExpressionMember::ExpressionMember(Expression *expr, const std::string &member)
: Expression(expr), member(member)
{ {
} }
@ -469,44 +448,47 @@ ValuePtr ExpressionMember::evaluate(const Context *context) const
ValuePtr v = this->first->evaluate(context); ValuePtr v = this->first->evaluate(context);
if (v->type() == Value::VECTOR) { if (v->type() == Value::VECTOR) {
if (this->var_name == "x") return v[0]; if (this->member == "x") return v[0];
if (this->var_name == "y") return v[1]; if (this->member == "y") return v[1];
if (this->var_name == "z") return v[2]; if (this->member == "z") return v[2];
} else if (v->type() == Value::RANGE) { } else if (v->type() == Value::RANGE) {
if (this->var_name == "begin") return v[0]; if (this->member == "begin") return v[0];
if (this->var_name == "step") return v[1]; if (this->member == "step") return v[1];
if (this->var_name == "end") return v[2]; if (this->member == "end") return v[2];
} }
return ValuePtr::undefined; return ValuePtr::undefined;
} }
void ExpressionMember::print(std::ostream &stream) const void ExpressionMember::print(std::ostream &stream) const
{ {
stream << *first << "." << this->var_name; stream << *first << "." << this->member;
} }
ExpressionFunction::ExpressionFunction() ExpressionFunctionCall::ExpressionFunctionCall(const std::string &funcname,
const AssignmentList &arglist)
: funcname(funcname), call_arguments(arglist)
{ {
} }
ValuePtr ExpressionFunction::evaluate(const Context *context) const ValuePtr ExpressionFunctionCall::evaluate(const Context *context) const
{ {
if (StackCheck::inst()->check()) { if (StackCheck::inst()->check()) {
throw RecursionException("function", call_funcname); throw RecursionException("function", funcname);
} }
EvalContext c(context, this->call_arguments); EvalContext c(context, this->call_arguments);
ValuePtr result = context->evaluate_function(this->call_funcname, &c); ValuePtr result = context->evaluate_function(this->funcname, &c);
return result; return result;
} }
void ExpressionFunction::print(std::ostream &stream) const void ExpressionFunctionCall::print(std::ostream &stream) const
{ {
stream << this->call_funcname << "(" << this->call_arguments << ")"; stream << this->funcname << "(" << this->call_arguments << ")";
} }
ExpressionLet::ExpressionLet(Expression *expr) : Expression(expr) ExpressionLet::ExpressionLet(const AssignmentList &arglist, Expression *expr)
: Expression(expr), call_arguments(arglist)
{ {
} }
@ -515,7 +497,7 @@ ValuePtr ExpressionLet::evaluate(const Context *context) const
Context c(context); Context c(context);
evaluate_sequential_assignment(this->call_arguments, &c); evaluate_sequential_assignment(this->call_arguments, &c);
return this->children[0]->evaluate(&c); return this->first->evaluate(&c);
} }
void ExpressionLet::print(std::ostream &stream) const void ExpressionLet::print(std::ostream &stream) const
@ -529,38 +511,23 @@ ExpressionLcExpression::ExpressionLcExpression(Expression *expr) : Expression(ex
ValuePtr ExpressionLcExpression::evaluate(const Context *context) const ValuePtr ExpressionLcExpression::evaluate(const Context *context) const
{ {
return this->children[0]->evaluate(context); return this->first->evaluate(context);
} }
void ExpressionLcExpression::print(std::ostream &stream) const void ExpressionLcExpression::print(std::ostream &stream) const
{ {
Expression const* c = this->first; stream << "[" << *this->first << "]";
stream << "[";
do {
if (c->call_funcname == "for") {
stream << "for(" << c->call_arguments << ") ";
c = c->children[0];
} else if (c->call_funcname == "if") {
stream << "if(" << c->children[0] << ") ";
c = c->children[1];
} else if (c->call_funcname == "let") {
stream << "let(" << c->call_arguments << ") ";
c = c->children[0];
} else {
assert(false && "Illegal list comprehension element");
}
} while (c->isListComprehension());
stream << *c << "]";
} }
ExpressionLc::ExpressionLc(Expression *expr) : Expression(expr) ExpressionLc::ExpressionLc(const std::string &name,
const AssignmentList &arglist, Expression *expr)
: Expression(expr), name(name), call_arguments(arglist)
{ {
} }
ExpressionLc::ExpressionLc(Expression *expr1, Expression *expr2) : Expression(expr1, expr2) ExpressionLc::ExpressionLc(const std::string &name,
Expression *expr1, Expression *expr2)
: Expression(expr1, expr2), name(name)
{ {
} }
@ -573,16 +540,16 @@ ValuePtr ExpressionLc::evaluate(const Context *context) const
{ {
Value::VectorType vec; Value::VectorType vec;
if (this->call_funcname == "if") { if (this->name == "if") {
if (this->children[0]->evaluate(context)) { if (this->first->evaluate(context)) {
if (this->children[1]->isListComprehension()) { if (this->second->isListComprehension()) {
return this->children[1]->evaluate(context); return this->second->evaluate(context);
} else { } else {
vec.push_back((*this->children[1]->evaluate(context))); vec.push_back((*this->second->evaluate(context)));
} }
} }
return ValuePtr(vec); return ValuePtr(vec);
} else if (this->call_funcname == "for") { } else if (this->name == "for") {
EvalContext for_context(context, this->call_arguments); EvalContext for_context(context, this->call_arguments);
Context assign_context(context); Context assign_context(context);
@ -601,30 +568,30 @@ ValuePtr ExpressionLc::evaluate(const Context *context) const
} else { } else {
for (Value::RangeType::iterator it = range.begin();it != range.end();it++) { for (Value::RangeType::iterator it = range.begin();it != range.end();it++) {
c.set_variable(it_name, ValuePtr(*it)); c.set_variable(it_name, ValuePtr(*it));
vec.push_back((*this->children[0]->evaluate(&c))); vec.push_back((*this->first->evaluate(&c)));
} }
} }
} }
else if (it_values->type() == Value::VECTOR) { else if (it_values->type() == Value::VECTOR) {
for (size_t i = 0; i < it_values->toVector().size(); i++) { for (size_t i = 0; i < it_values->toVector().size(); i++) {
c.set_variable(it_name, it_values->toVector()[i]); c.set_variable(it_name, it_values->toVector()[i]);
vec.push_back((*this->children[0]->evaluate(&c))); vec.push_back((*this->first->evaluate(&c)));
} }
} }
else if (it_values->type() != Value::UNDEFINED) { else if (it_values->type() != Value::UNDEFINED) {
c.set_variable(it_name, it_values); c.set_variable(it_name, it_values);
vec.push_back((*this->children[0]->evaluate(&c))); vec.push_back((*this->first->evaluate(&c)));
} }
if (this->children[0]->isListComprehension()) { if (this->first->isListComprehension()) {
return ValuePtr(flatten(vec)); return ValuePtr(flatten(vec));
} else { } else {
return ValuePtr(vec); return ValuePtr(vec);
} }
} else if (this->call_funcname == "let") { } else if (this->name == "let") {
Context c(context); Context c(context);
evaluate_sequential_assignment(this->call_arguments, &c); evaluate_sequential_assignment(this->call_arguments, &c);
return this->children[0]->evaluate(&c); return this->first->evaluate(&c);
} else { } else {
abort(); abort();
} }
@ -632,7 +599,15 @@ ValuePtr ExpressionLc::evaluate(const Context *context) const
void ExpressionLc::print(std::ostream &stream) const void ExpressionLc::print(std::ostream &stream) const
{ {
// FIXME: Implement? stream << this->name;
if (this->name == "if") {
stream << "(" << *this->first << ") " << *this->second;
}
else if (this->name == "for" || this->name == "let") {
stream << "(" << this->call_arguments << ") " << *this->first;
} else {
assert(false && "Illegal list comprehension element");
}
} }
std::ostream &operator<<(std::ostream &stream, const Expression &expr) std::ostream &operator<<(std::ostream &stream, const Expression &expr)

View File

@ -13,16 +13,7 @@ public:
Expression *second; Expression *second;
Expression *third; Expression *third;
ValuePtr const_value;
std::string var_name;
std::string call_funcname;
AssignmentList call_arguments;
Expression(); Expression();
Expression(const ValuePtr &val);
Expression(const std::string &val);
Expression(const std::string &val, Expression *expr);
Expression(Expression *expr); Expression(Expression *expr);
Expression(Expression *left, Expression *right); Expression(Expression *left, Expression *right);
Expression(Expression *expr1, Expression *expr2, Expression *expr3); Expression(Expression *expr1, Expression *expr2, Expression *expr3);
@ -161,6 +152,7 @@ public:
ExpressionArrayLookup(Expression *left, Expression *right); ExpressionArrayLookup(Expression *left, Expression *right);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
private:
}; };
class ExpressionInvert : public Expression class ExpressionInvert : public Expression
@ -177,6 +169,8 @@ public:
ExpressionConst(const ValuePtr &val); ExpressionConst(const ValuePtr &val);
ValuePtr evaluate(const class Context *) const; ValuePtr evaluate(const class Context *) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
private:
ValuePtr const_value;
}; };
class ExpressionRange : public Expression class ExpressionRange : public Expression
@ -199,33 +193,42 @@ public:
class ExpressionLookup : public Expression class ExpressionLookup : public Expression
{ {
public: public:
ExpressionLookup(const std::string &val); ExpressionLookup(const std::string &var_name);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
private:
std::string var_name;
}; };
class ExpressionMember : public Expression class ExpressionMember : public Expression
{ {
public: public:
ExpressionMember(const std::string &val, Expression *expr); ExpressionMember(Expression *expr, const std::string &member);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
private:
std::string member;
}; };
class ExpressionFunction : public Expression class ExpressionFunctionCall : public Expression
{ {
public: public:
ExpressionFunction(); ExpressionFunctionCall(const std::string &funcname, const AssignmentList &arglist);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
public:
std::string funcname;
AssignmentList call_arguments;
}; };
class ExpressionLet : public Expression class ExpressionLet : public Expression
{ {
public: public:
ExpressionLet(Expression *expr); ExpressionLet(const AssignmentList &arglist, Expression *expr);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
private:
AssignmentList call_arguments;
}; };
class ExpressionLcExpression : public Expression class ExpressionLcExpression : public Expression
@ -240,8 +243,13 @@ class ExpressionLc : public Expression
{ {
virtual bool isListComprehension() const; virtual bool isListComprehension() const;
public: public:
ExpressionLc(Expression *expr); ExpressionLc(const std::string &name,
ExpressionLc(Expression *expr1, Expression *expr2); const AssignmentList &arglist, Expression *expr);
ExpressionLc(const std::string &name,
Expression *expr1, Expression *expr2);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
private:
std::string name;
AssignmentList call_arguments;
}; };

View File

@ -319,7 +319,7 @@ expr:
} }
| expr '.' TOK_ID | expr '.' TOK_ID
{ {
$$ = new ExpressionMember($3, $1); $$ = new ExpressionMember($1, $3);
free($3); free($3);
} }
| TOK_STRING | TOK_STRING
@ -333,8 +333,7 @@ expr:
} }
| TOK_LET '(' arguments_call ')' expr %prec LET | TOK_LET '(' arguments_call ')' expr %prec LET
{ {
$$ = new ExpressionLet($5); $$ = new ExpressionLet(*$3, $5);
$$->call_arguments = *$3;
delete $3; delete $3;
} }
| '[' expr ':' expr ']' | '[' expr ':' expr ']'
@ -435,9 +434,7 @@ expr:
} }
| TOK_ID '(' arguments_call ')' | TOK_ID '(' arguments_call ')'
{ {
$$ = new ExpressionFunction(); $$ = new ExpressionFunctionCall($1, *$3);
$$->call_funcname = $1;
$$->call_arguments = *$3;
free($1); free($1);
delete $3; delete $3;
} }
@ -448,9 +445,7 @@ list_comprehension_elements:
be parsed as an expression) */ be parsed as an expression) */
TOK_LET '(' arguments_call ')' list_comprehension_elements TOK_LET '(' arguments_call ')' list_comprehension_elements
{ {
$$ = new ExpressionLc($5); $$ = new ExpressionLc("let", *$3, $5);
$$->call_funcname = "let";
$$->call_arguments = *$3;
delete $3; delete $3;
} }
| TOK_FOR '(' arguments_call ')' list_comprehension_elements_or_expr | TOK_FOR '(' arguments_call ')' list_comprehension_elements_or_expr
@ -459,17 +454,16 @@ list_comprehension_elements:
/* transform for(i=...,j=...) -> for(i=...) for(j=...) */ /* transform for(i=...,j=...) -> for(i=...) for(j=...) */
for (int i = $3->size()-1; i >= 0; i--) { for (int i = $3->size()-1; i >= 0; i--) {
Expression *e = new ExpressionLc($$); AssignmentList arglist;
e->call_funcname = "for"; arglist.push_back((*$3)[i]);
e->call_arguments.push_back((*$3)[i]); Expression *e = new ExpressionLc("for", arglist, $$);
$$ = e; $$ = e;
} }
delete $3; delete $3;
} }
| TOK_IF '(' expr ')' list_comprehension_elements_or_expr | TOK_IF '(' expr ')' list_comprehension_elements_or_expr
{ {
$$ = new ExpressionLc($3, $5); $$ = new ExpressionLc("if", $3, $5);
$$->call_funcname = "if";
} }
; ;