From 2e8d93d5be57ef7b57d11f7ad19b278be0798557 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 25 Nov 2014 17:08:14 -0500 Subject: [PATCH] Some Expression refactoring --- src/expr.cc | 135 +++++++++++++++++++---------------------------- src/expression.h | 40 ++++++++------ src/parser.y | 22 +++----- 3 files changed, 87 insertions(+), 110 deletions(-) diff --git a/src/expr.cc b/src/expr.cc index 6131984e..77c5ac77 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -67,49 +67,27 @@ namespace { } } -Expression::Expression() +Expression::Expression() : first(NULL), second(NULL), third(NULL) { } -Expression::Expression(const ValuePtr &val) -{ - 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) +Expression::Expression(Expression *expr) : first(expr), second(NULL), third(NULL) { 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(right); - first = left; - second = right; } Expression::Expression(Expression *expr1, Expression *expr2, Expression *expr3) + : first(expr1), second(expr2), third(expr3) { children.push_back(expr1); children.push_back(expr2); children.push_back(expr3); - first = expr1; - second = expr2; - third = expr3; } Expression::~Expression() @@ -373,7 +351,7 @@ void ExpressionInvert::print(std::ostream &stream) const 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 << "]"; } -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; } -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); if (v->type() == Value::VECTOR) { - if (this->var_name == "x") return v[0]; - if (this->var_name == "y") return v[1]; - if (this->var_name == "z") return v[2]; + if (this->member == "x") return v[0]; + if (this->member == "y") return v[1]; + if (this->member == "z") return v[2]; } else if (v->type() == Value::RANGE) { - if (this->var_name == "begin") return v[0]; - if (this->var_name == "step") return v[1]; - if (this->var_name == "end") return v[2]; + if (this->member == "begin") return v[0]; + if (this->member == "step") return v[1]; + if (this->member == "end") return v[2]; } return ValuePtr::undefined; } 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()) { - throw RecursionException("function", call_funcname); + throw RecursionException("function", funcname); } 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; } -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); 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 @@ -529,38 +511,23 @@ ExpressionLcExpression::ExpressionLcExpression(Expression *expr) : Expression(ex 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 { - Expression const* c = 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 << "]"; + stream << "[" << *this->first << "]"; } -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; - if (this->call_funcname == "if") { - if (this->children[0]->evaluate(context)) { - if (this->children[1]->isListComprehension()) { - return this->children[1]->evaluate(context); + if (this->name == "if") { + if (this->first->evaluate(context)) { + if (this->second->isListComprehension()) { + return this->second->evaluate(context); } else { - vec.push_back((*this->children[1]->evaluate(context))); + vec.push_back((*this->second->evaluate(context))); } } return ValuePtr(vec); - } else if (this->call_funcname == "for") { + } else if (this->name == "for") { EvalContext for_context(context, this->call_arguments); Context assign_context(context); @@ -601,30 +568,30 @@ ValuePtr ExpressionLc::evaluate(const Context *context) const } else { for (Value::RangeType::iterator it = range.begin();it != range.end();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) { for (size_t i = 0; i < it_values->toVector().size(); 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) { 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)); } else { return ValuePtr(vec); } - } else if (this->call_funcname == "let") { + } else if (this->name == "let") { Context c(context); evaluate_sequential_assignment(this->call_arguments, &c); - return this->children[0]->evaluate(&c); + return this->first->evaluate(&c); } else { abort(); } @@ -632,7 +599,15 @@ ValuePtr ExpressionLc::evaluate(const Context *context) 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) diff --git a/src/expression.h b/src/expression.h index 2b95ffa0..2cd1bded 100644 --- a/src/expression.h +++ b/src/expression.h @@ -13,16 +13,7 @@ public: Expression *second; Expression *third; - ValuePtr const_value; - std::string var_name; - - std::string call_funcname; - AssignmentList call_arguments; - Expression(); - Expression(const ValuePtr &val); - Expression(const std::string &val); - Expression(const std::string &val, Expression *expr); Expression(Expression *expr); Expression(Expression *left, Expression *right); Expression(Expression *expr1, Expression *expr2, Expression *expr3); @@ -161,6 +152,7 @@ public: ExpressionArrayLookup(Expression *left, Expression *right); ValuePtr evaluate(const class Context *context) const; virtual void print(std::ostream &stream) const; +private: }; class ExpressionInvert : public Expression @@ -177,6 +169,8 @@ public: ExpressionConst(const ValuePtr &val); ValuePtr evaluate(const class Context *) const; virtual void print(std::ostream &stream) const; +private: + ValuePtr const_value; }; class ExpressionRange : public Expression @@ -199,33 +193,42 @@ public: class ExpressionLookup : public Expression { public: - ExpressionLookup(const std::string &val); + ExpressionLookup(const std::string &var_name); ValuePtr evaluate(const class Context *context) const; virtual void print(std::ostream &stream) const; +private: + std::string var_name; }; class ExpressionMember : public Expression { public: - ExpressionMember(const std::string &val, Expression *expr); + ExpressionMember(Expression *expr, const std::string &member); ValuePtr evaluate(const class Context *context) const; virtual void print(std::ostream &stream) const; +private: + std::string member; }; -class ExpressionFunction : public Expression +class ExpressionFunctionCall : public Expression { public: - ExpressionFunction(); + ExpressionFunctionCall(const std::string &funcname, const AssignmentList &arglist); ValuePtr evaluate(const class Context *context) const; virtual void print(std::ostream &stream) const; +public: + std::string funcname; + AssignmentList call_arguments; }; class ExpressionLet : public Expression { public: - ExpressionLet(Expression *expr); + ExpressionLet(const AssignmentList &arglist, Expression *expr); ValuePtr evaluate(const class Context *context) const; virtual void print(std::ostream &stream) const; +private: + AssignmentList call_arguments; }; class ExpressionLcExpression : public Expression @@ -240,8 +243,13 @@ class ExpressionLc : public Expression { virtual bool isListComprehension() const; public: - ExpressionLc(Expression *expr); - ExpressionLc(Expression *expr1, Expression *expr2); + ExpressionLc(const std::string &name, + const AssignmentList &arglist, Expression *expr); + ExpressionLc(const std::string &name, + Expression *expr1, Expression *expr2); ValuePtr evaluate(const class Context *context) const; virtual void print(std::ostream &stream) const; +private: + std::string name; + AssignmentList call_arguments; }; diff --git a/src/parser.y b/src/parser.y index 04dbdb8f..dfa1ab2e 100644 --- a/src/parser.y +++ b/src/parser.y @@ -319,7 +319,7 @@ expr: } | expr '.' TOK_ID { - $$ = new ExpressionMember($3, $1); + $$ = new ExpressionMember($1, $3); free($3); } | TOK_STRING @@ -333,8 +333,7 @@ expr: } | TOK_LET '(' arguments_call ')' expr %prec LET { - $$ = new ExpressionLet($5); - $$->call_arguments = *$3; + $$ = new ExpressionLet(*$3, $5); delete $3; } | '[' expr ':' expr ']' @@ -435,9 +434,7 @@ expr: } | TOK_ID '(' arguments_call ')' { - $$ = new ExpressionFunction(); - $$->call_funcname = $1; - $$->call_arguments = *$3; + $$ = new ExpressionFunctionCall($1, *$3); free($1); delete $3; } @@ -448,9 +445,7 @@ list_comprehension_elements: be parsed as an expression) */ TOK_LET '(' arguments_call ')' list_comprehension_elements { - $$ = new ExpressionLc($5); - $$->call_funcname = "let"; - $$->call_arguments = *$3; + $$ = new ExpressionLc("let", *$3, $5); delete $3; } | TOK_FOR '(' arguments_call ')' list_comprehension_elements_or_expr @@ -459,17 +454,16 @@ list_comprehension_elements: /* transform for(i=...,j=...) -> for(i=...) for(j=...) */ for (int i = $3->size()-1; i >= 0; i--) { - Expression *e = new ExpressionLc($$); - e->call_funcname = "for"; - e->call_arguments.push_back((*$3)[i]); + AssignmentList arglist; + arglist.push_back((*$3)[i]); + Expression *e = new ExpressionLc("for", arglist, $$); $$ = e; } delete $3; } | TOK_IF '(' expr ')' list_comprehension_elements_or_expr { - $$ = new ExpressionLc($3, $5); - $$->call_funcname = "if"; + $$ = new ExpressionLc("if", $3, $5); } ;