Skip to content

Commit

Permalink
Implement While, ITE, IT evaluation
Browse files Browse the repository at this point in the history
  • Loading branch information
Borja Lorente committed May 3, 2017
1 parent 9773f48 commit 01b9891
Show file tree
Hide file tree
Showing 13 changed files with 130 additions and 54 deletions.
6 changes: 3 additions & 3 deletions interpreter/src/core/model/ast/control/IfThen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
#include "IfThen.h"

namespace naylang {
IfThen::IfThen(ExpressionPtr condition, BlockPtr thenExp, int line, int col) :
IfThen::IfThen(ExpressionPtr condition, std::vector<StatementPtr> thenExp, int line, int col) :
_condition{condition}, _then{thenExp}, IfThen::Statement(line, col) {}

IfThen::IfThen(ExpressionPtr condition, BlockPtr thenExp) :
IfThen::IfThen(ExpressionPtr condition, std::vector<StatementPtr> thenExp) :
IfThen(condition, thenExp, -1, -1) {}

void IfThen::accept(Evaluator &evaluator) {
Expand All @@ -20,7 +20,7 @@ ExpressionPtr IfThen::condition() const {
return _condition;
}

BlockPtr IfThen::thenExpression() const {
const std::vector<StatementPtr> &IfThen::thenPart() const {
return _then;
}
}
14 changes: 7 additions & 7 deletions interpreter/src/core/model/ast/control/IfThen.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
// Distributed under the GPLv3 license.
//

#ifndef NAYLANG_IFTHENELSE_H
#define NAYLANG_IFTHENELSE_H
#ifndef NAYLANG_IFTHEN_H
#define NAYLANG_IFTHEN_H

#include <memory>
#include <core/model/ast/Statement.h>
Expand All @@ -14,24 +14,24 @@ namespace naylang {
class IfThen : public Statement {

ExpressionPtr _condition;
BlockPtr _then;
std::vector<StatementPtr> _then;

public:

IfThen(
ExpressionPtr condition,
BlockPtr thenExp,
std::vector<StatementPtr> thenExp,
int line, int col);

IfThen(
ExpressionPtr condition,
BlockPtr thenExp);
std::vector<StatementPtr> thenExp);

virtual void accept(Evaluator &evaluator);
ExpressionPtr condition() const;
BlockPtr thenExpression() const;
const std::vector<StatementPtr> &thenPart() const;
};
}


#endif //NAYLANG_IFTHENELSE_H
#endif //NAYLANG_IFTHEN_H
14 changes: 7 additions & 7 deletions interpreter/src/core/model/ast/control/IfThenElse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
namespace naylang {
IfThenElse::IfThenElse(
ExpressionPtr condition,
BlockPtr thenExp,
BlockPtr elseExp) :
std::vector<StatementPtr> thenExp,
std::vector<StatementPtr> elseExp) :
IfThenElse(condition, thenExp, elseExp, -1, -1) {}

IfThenElse::IfThenElse(ExpressionPtr condition, BlockPtr thenExp, BlockPtr elseExp, int line, int col) :
IfThenElse::IfThenElse(ExpressionPtr condition, std::vector<StatementPtr> thenExp, std::vector<StatementPtr> elseExp, int line, int col) :
IfThenElse::Statement(line, col) {
_condition = std::move(condition);
_then = std::move(thenExp);
_else = std::move(elseExp);
_then = thenExp;
_else = elseExp;
}

void IfThenElse::accept(Evaluator &evaluator) {
Expand All @@ -27,11 +27,11 @@ ExpressionPtr IfThenElse::condition() const {
return _condition;
}

BlockPtr IfThenElse::thenExpression() const {
const std::vector<StatementPtr> &IfThenElse::thenPart() const {
return _then;
}

BlockPtr IfThenElse::elseExpression() const {
const std::vector<StatementPtr> &IfThenElse::elsePart() const {
return _else;
}

Expand Down
16 changes: 8 additions & 8 deletions interpreter/src/core/model/ast/control/IfThenElse.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,25 @@ namespace naylang {
class IfThenElse : public Statement {

ExpressionPtr _condition;
BlockPtr _then;
BlockPtr _else;
std::vector<StatementPtr> _then;
std::vector<StatementPtr> _else;

public:

IfThenElse(
ExpressionPtr condition,
BlockPtr thenExp,
BlockPtr elseExp,
std::vector<StatementPtr> thenExp,
std::vector<StatementPtr> elseExp,
int line, int col);
IfThenElse(
ExpressionPtr condition,
BlockPtr thenExp,
BlockPtr elseExp);
std::vector<StatementPtr> thenExp,
std::vector<StatementPtr> elseExp);

virtual void accept(Evaluator &evaluator);
ExpressionPtr condition() const;
BlockPtr thenExpression() const;
BlockPtr elseExpression() const;
const std::vector<StatementPtr> &thenPart() const;
const std::vector<StatementPtr> &elsePart() const;
};
}

Expand Down
8 changes: 4 additions & 4 deletions interpreter/src/core/model/ast/control/While.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@

namespace naylang {

While::While(BlockPtr condition, BlockPtr body, int line, int col) :
While::While(ExpressionPtr condition, const std::vector<StatementPtr> &body, int line, int col) :
_condition{condition}, _body{body}, While::Statement(line, col) {}

While::While(BlockPtr condition, BlockPtr body) :
While::While(ExpressionPtr condition, const std::vector<StatementPtr> &body) :
While(condition, body, -1, -1) {}

void While::accept(Evaluator &evaluator) {
evaluator.evaluate(*this);
}

const std::shared_ptr<Block> &While::condition() const {
ExpressionPtr While::condition() const {
return _condition;
}

const std::shared_ptr<Block> &While::body() const {
const std::vector<StatementPtr> &While::body() const {
return _body;
}
}
12 changes: 6 additions & 6 deletions interpreter/src/core/model/ast/control/While.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ namespace naylang {

class While : public Statement {

BlockPtr _condition;
BlockPtr _body;
ExpressionPtr _condition;
std::vector<StatementPtr> _body;

public:
While(BlockPtr condition, BlockPtr body, int line, int col);
While(BlockPtr condition, BlockPtr body);
While(ExpressionPtr condition, const std::vector<StatementPtr> &body, int line, int col);
While(ExpressionPtr condition, const std::vector<StatementPtr> &body);

void accept(Evaluator &evaluator) override;

const std::shared_ptr<Block> &condition() const;
const std::shared_ptr<Block> &body() const;
ExpressionPtr condition() const;
const std::vector<StatementPtr> &body() const;
};

} // end namespace naylang
Expand Down
37 changes: 36 additions & 1 deletion interpreter/src/core/model/evaluators/ExecutionEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,42 @@ void ExecutionEvaluator::evaluate(Assignment &expression) {
_currentScope = _partial;

_currentScope->setField(expression.field(), val);

_currentScope = oldScope;
}

void ExecutionEvaluator::evaluate(IfThen &expression) {
expression.condition()->accept(*this);
auto cond = _partial->asBoolean().value();
if (cond) {
for (auto exp : expression.thenPart()) {
exp->accept(*this);
}
}
}

void ExecutionEvaluator::evaluate(IfThenElse &expression) {
expression.condition()->accept(*this);
auto cond = _partial->asBoolean().value();
if (cond) {
for (auto exp : expression.thenPart()) {
exp->accept(*this);
}
} else {
for (auto exp : expression.elsePart()) {
exp->accept(*this);
}
}
}

void ExecutionEvaluator::evaluate(While &expression) {
expression.condition()->accept(*this);
auto cond = _partial->asBoolean().value();
while (cond) {
for (auto exp : expression.body()) {
exp->accept(*this);
}
expression.condition()->accept(*this);
cond = _partial->asBoolean().value();
}
}
}
6 changes: 5 additions & 1 deletion interpreter/src/core/model/evaluators/ExecutionEvaluator.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@ class ExecutionEvaluator : public Evaluator {
virtual void evaluate(Block &expression) override;
virtual void evaluate(ObjectConstructor &expression) override;
virtual void evaluate(VariableDeclaration &expression) override;
void evaluate(Assignment &expression) override;
virtual void evaluate(Assignment &expression) override;
void evaluate(IfThen &expression) override;
void evaluate(IfThenElse &expression) override;

void evaluate(While &expression) override;

// Debug Methods
void setDebugState(DebugState state);
Expand Down
4 changes: 4 additions & 0 deletions interpreter/src/core/model/execution/objects/GraceNumber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ void GraceNumber::addDefaultMethods() {
_nativeMethods["prefix!"] = make_native<Negative>();
_nativeMethods["==(_)"] = make_native<Equals>();
_nativeMethods["!=(_)"] = make_native<NotEquals>();
_nativeMethods["<(_)"] = make_native<Less>();
_nativeMethods["<=(_)"] = make_native<LessEq>();
_nativeMethods[">(_)"] = make_native<Greater>();
_nativeMethods[">=(_)"] = make_native<GreaterEq>();
_nativeMethods["+(_)"] = make_native<Add>();
_nativeMethods["-(_)"] = make_native<Sub>();
_nativeMethods["*(_)"] = make_native<Mul>();
Expand Down
10 changes: 4 additions & 6 deletions tests/src/core/model/ast/control/IfThenElse_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ TEST_CASE("If Then Else Expressions", "[Control]") {
auto tru = make_node<BooleanLiteral>(true);
auto five = make_node<NumberLiteral>(5.0);
auto six = make_node<NumberLiteral>(6.0);
auto thenBlock = make_node<Block>();
thenBlock->addStatement(five);
auto elseBlock = make_node<Block>();
elseBlock->addStatement(six);
std::vector<StatementPtr> thenBlock{five};
std::vector<StatementPtr> elseBlock{six};

SECTION("ITE Expressions take a condition expression and two consequence blocks") {
REQUIRE_NOTHROW(IfThenElse ite(tru, thenBlock, elseBlock););
Expand All @@ -28,7 +26,7 @@ TEST_CASE("If Then Else Expressions", "[Control]") {
SECTION("ITE Expressions can return either of their fields") {
IfThenElse ite(tru, thenBlock, elseBlock);
REQUIRE(ite.condition() == tru);
REQUIRE(ite.thenExpression() == thenBlock);
REQUIRE(ite.elseExpression() == elseBlock);
REQUIRE(ite.thenPart() == thenBlock);
REQUIRE(ite.elsePart() == elseBlock);
}
}
5 changes: 2 additions & 3 deletions tests/src/core/model/ast/control/IfThen_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ TEST_CASE("If Then Expressions", "[Control]") {
auto tru = make_node<BooleanLiteral>(true);
auto five = make_node<NumberLiteral>(5.0);
auto six = make_node<NumberLiteral>(6.0);
auto thenBlock = make_node<Block>();
thenBlock->addStatement(five);
std::vector<StatementPtr> thenBlock{five};

SECTION("IThen Expressions take a condition expression and a then block") {
REQUIRE_NOTHROW(IfThen it(tru, thenBlock););
Expand All @@ -26,6 +25,6 @@ TEST_CASE("If Then Expressions", "[Control]") {
SECTION("ITE Expressions can return either of their fields") {
IfThen it(tru, thenBlock);
REQUIRE(it.condition() == tru);
REQUIRE(it.thenExpression() == thenBlock);
REQUIRE(it.thenPart() == thenBlock);
}
}
11 changes: 4 additions & 7 deletions tests/src/core/model/ast/control/WhileLoop_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,17 @@ using namespace naylang;
TEST_CASE("While Loop", "[Control]") {

auto tru = make_node<BooleanLiteral>(true);
auto truBlock = make_node<Block>();
truBlock->addStatement(tru);

auto five = make_node<NumberLiteral>(5.0);
auto fiveBlock = make_node<Block>();
fiveBlock->addStatement(five);
std::vector<StatementPtr> fiveBlock{five};

SECTION("A while loop accepts a condition block and a body block") {
REQUIRE_NOTHROW(While loop(truBlock, fiveBlock););
REQUIRE_NOTHROW(While loop(tru, fiveBlock););
}

SECTION("A while loop can return it's condition and body") {
While loop(truBlock, fiveBlock);
REQUIRE(loop.condition() == truBlock);
While loop(tru, fiveBlock);
REQUIRE(loop.condition() == tru);
REQUIRE(loop.body() == fiveBlock);
}
}
Expand Down
41 changes: 40 additions & 1 deletion tests/src/core/model/evaluators/ExecutionEvaluator_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ TEST_CASE("Execution Evaluator", "[Evaluators]") {
auto ctruConstDecl = make_node<ConstantDeclaration>("ctru", trueLiteral);
auto five = make_node<NumberLiteral>(5.0);
auto six = make_node<NumberLiteral>(6.0);
auto zero = make_node<NumberLiteral>(0.0);
auto twentyTwo = make_node<NumberLiteral>(22.0);
auto hiStr = make_node<StringLiteral>("Hi");

SECTION("An execution evaluator has a partial GraceObject") {
Expand Down Expand Up @@ -125,7 +127,44 @@ TEST_CASE("Execution Evaluator", "[Evaluators]") {
REQUIRE(eval.partial()->hasField("x"));
}

SECTION("Evaluating an AssignmentNode places the value into the field of the receiver") {
SECTION("IfThen & IfThenElse") {
ExecutionEvaluator eval;

auto five = make_node<NumberLiteral>(5.0);
auto six = make_node<NumberLiteral>(6.0);
std::vector<StatementPtr> thenBlock{five};
std::vector<StatementPtr> elseBlock{six};

IfThenElse ite(falseLiteral, thenBlock, elseBlock);
ite.accept(eval);
REQUIRE(eval.partial()->asNumber().value() == 6.0);

IfThen it(trueLiteral, thenBlock);
it.accept(eval);
REQUIRE(eval.partial()->asNumber().value() == 5.0);
}

SECTION("While loop") {
ExecutionEvaluator eval;

auto xDeclToZero = make_node<VariableDeclaration>("x", zero);
xDeclToZero->accept(eval);

std::vector<ExpressionPtr> addParams{five};
auto addFive = make_node<ExplicitRequestNode>("+(_)", xRef, addParams);
auto assign = make_node<Assignment>("x", addFive);
std::vector<StatementPtr> whileBody{assign};
std::vector<ExpressionPtr> lessThanParams{twentyTwo};
auto whileCond = make_node<ExplicitRequestNode>("<(_)", xRef, lessThanParams);

While wh(whileCond, whileBody);
wh.accept(eval);

xRef->accept(eval);
REQUIRE(eval.partial()->asNumber().value() == 25.0);
}

SECTION("Evaluating an Assignment places the value into the field of the receiver") {
SECTION("Number assignment") {
ExecutionEvaluator eval;
xDec->accept(eval);
Expand Down

0 comments on commit 01b9891

Please sign in to comment.