diff options
| Commit | 0ba5eb38f9e6974271c5efa09438f11055820933 (patch) | |
|---|---|---|
| Author | 2018-10-28 17:08:32 +0200 | |
| Committer | 2018-10-28 17:08:32 +0200 | |
| Files | 51effc8b809c5d71ed323181ad6bb585f72c2ee0 /JSImpl/src | |
| IPL-0ba5eb38f9e6974271c5efa09438f11055820933.tar IPL-0ba5eb38f9e6974271c5efa09438f11055820933.tar.gz IPL-0ba5eb38f9e6974271c5efa09438f11055820933.zip | ||
| Parent | 0bf63ffd7e8643198223e3820260082cfbb3b654 (diff) | |
Fixed for increment step filling up the stack
3 files changed, 101 insertions, 71 deletions
| -rw-r--r-- | JSImpl/src/ASTInterpreter.cpp | 101 | ||||
| -rw-r--r-- | JSImpl/src/ASTInterpreter.h | 67 | ||||
| -rw-r--r-- | JSImpl/src/main.cpp | 4 |
diff --git a/JSImpl/src/ASTInterpreter.cpp b/JSImpl/src/ASTInterpreter.cpp index d66a9ce..edfdc9c 100644 --- a/JSImpl/src/ASTInterpreter.cpp +++ b/JSImpl/src/ASTInterpreter.cpp @@ -68,6 +68,27 @@ struct VariableScope ASTInterpreter* m_Interpreter; }; +struct StackScope +{ + StackScope(ASTInterpreter* interpreter) + : m_Interpreter(interpreter) + , m_StackSize(m_Interpreter->m_Evaluation.size()) + { + } + + ~StackScope() { + m_Interpreter->m_Evaluation.resize(m_StackSize); + } + + StackScope(StackScope&) = delete; + StackScope(StackScope&&) = delete; + StackScope& operator=(StackScope&) = delete; + StackScope& operator=(StackScope&&) = delete; + + ASTInterpreter* m_Interpreter; + size_t m_StackSize; +}; + ASTInterpreter::ASTInterpreter() { // Allow globals @@ -95,8 +116,8 @@ void ASTInterpreter::RunExpression(const ExpressionPtr& e) bool ASTInterpreter::EvalToBool(const ExpressionPtr& e) { e->Accept(*this); - auto result = m_Evaluation.top(); - m_Evaluation.pop(); + auto result = m_Evaluation.back(); + m_Evaluation.pop_back(); return result != 0.0; } @@ -110,7 +131,7 @@ void ASTInterpreter::LeaveScope() const auto& scope = m_Scopes.top(); for (auto& var : scope) { auto values = m_Variables.find(var); - values->second.pop(); + values->second.pop_back(); if (values->second.empty()) { m_Variables.erase(values); } @@ -122,7 +143,7 @@ ASTInterpreter::value_type& ASTInterpreter::ModifyVariable(const IPLString& name { auto values = m_Variables.find(name); if (values != m_Variables.end()) { - return values->second.top(); + return values->second.back(); } else { assert(0 && "not-defined"); @@ -143,40 +164,39 @@ void ASTInterpreter::Visit(LiteralString* e) { } void ASTInterpreter::Visit(LiteralNumber* e) { - m_Evaluation.push(e->GetValue()); + m_Evaluation.push_back(e->GetValue()); } void ASTInterpreter::Visit(LiteralBoolean* e) { - m_Evaluation.push(e->GetValue()); + m_Evaluation.push_back(e->GetValue()); } void ASTInterpreter::Visit(BinaryExpression* e) { e->GetLeft()->Accept(*this); e->GetRight()->Accept(*this); - auto right = m_Evaluation.top(); - m_Evaluation.pop(); + auto right = m_Evaluation.back(); + m_Evaluation.pop_back(); - auto left = m_Evaluation.top(); - m_Evaluation.pop(); + auto left = m_Evaluation.back(); + m_Evaluation.pop_back(); switch (e->GetOperator()) { case TokenType::Plus: - std::cout << "PLUS:" << left << ':' << right << std::endl; - m_Evaluation.push(left + right); + m_Evaluation.push_back(left + right); break; case TokenType::Minus: - m_Evaluation.push(left - right); + m_Evaluation.push_back(left - right); break; case TokenType::Star: - m_Evaluation.push(left * right); + m_Evaluation.push_back(left * right); break; case TokenType::Division: - m_Evaluation.push(left / right); + m_Evaluation.push_back(left / right); break; case TokenType::Less: - m_Evaluation.push(left < right); + m_Evaluation.push_back(left < right); break; case TokenType::Comma: - m_Evaluation.push(right); + m_Evaluation.push_back(right); break; default: NOT_IMPLEMENTED; @@ -188,27 +208,27 @@ void ASTInterpreter::Visit(UnaryExpression* e) { auto lvalue = extractor.Run(e->GetExpr().get()); if (e->GetSuffix()) { - m_Evaluation.push(*lvalue); + m_Evaluation.push_back(*lvalue); } - switch (e->GetOperator())
- {
- case TokenType::PlusPlus:
- ++(*lvalue);
- break;
- case TokenType::MinusMinus:
- --(*lvalue);
- break;
+ switch (e->GetOperator()) + { + case TokenType::PlusPlus: + ++(*lvalue); + break; + case TokenType::MinusMinus: + --(*lvalue); + break; default: - NOT_IMPLEMENTED;
+ NOT_IMPLEMENTED; } if (!e->GetSuffix()) { - m_Evaluation.push(*lvalue); + m_Evaluation.push_back(*lvalue); } } void ASTInterpreter::Visit(IdentifierExpression* e) { - m_Evaluation.push(ModifyVariable(e->GetName())); + m_Evaluation.push_back(ModifyVariable(e->GetName())); } void ASTInterpreter::Visit(ListExpression* e) { @@ -220,9 +240,9 @@ void ASTInterpreter::Visit(ListExpression* e) { void ASTInterpreter::Visit(VariableDefinitionExpression* e) { e->GetValue()->Accept(*this); auto& name = e->GetName(); - m_Variables[name].push(m_Evaluation.top()); + m_Variables[name].push_back(m_Evaluation.back()); m_Scopes.top().push_back(name); - m_Evaluation.pop(); + m_Evaluation.pop_back(); } void ASTInterpreter::Visit(BlockStatement* e) { @@ -264,11 +284,20 @@ void ASTInterpreter::Visit(WhileStatement* e) { void ASTInterpreter::Visit(ForStatement* e) { VariableScope scope(this); - for (RunExpression(e->GetInitialization()); - EvalToBool(e->GetCondition()); - RunExpression(e->GetIteration())) { - VariableScope bodyScope(this); - RunExpression(e->GetBody()); + { + StackScope stackScope(this); + RunExpression(e->GetInitialization()); + } + while (EvalToBool(e->GetCondition())) + { + { + VariableScope bodyScope(this); + RunExpression(e->GetBody()); + } + { + StackScope stackScope(this); + RunExpression(e->GetIteration()); + } } } diff --git a/JSImpl/src/ASTInterpreter.h b/JSImpl/src/ASTInterpreter.h index 4d5b46f..7dc58de 100644 --- a/JSImpl/src/ASTInterpreter.h +++ b/JSImpl/src/ASTInterpreter.h @@ -1,54 +1,55 @@ #pragma once #include "ExpressionVisitor.h" -#include <stack> -#include <string> -#include <unordered_map> class ASTInterpreter : public ExpressionVisitor { public: - ASTInterpreter(); - ~ASTInterpreter(); + ASTInterpreter(); + ~ASTInterpreter(); + + // TODO: Changing this to a shared_ptr<Value> (or GC-enabled value*) will + // allow for much simpler implementation of all varible assignments. typedef double value_type; - typedef IPLStack<value_type> ValueStack; + typedef IPLVector<value_type> ValueStack; ValueStack Run(Expression* program); - virtual void Visit(LiteralNull* e) override; - virtual void Visit(LiteralUndefined* e) override; - virtual void Visit(LiteralString* e) override; - virtual void Visit(LiteralNumber* e) override; - virtual void Visit(LiteralBoolean* e) override; - virtual void Visit(BinaryExpression* e) override; - virtual void Visit(UnaryExpression* e) override; - virtual void Visit(IdentifierExpression* e) override; - virtual void Visit(ListExpression* e) override; - virtual void Visit(VariableDefinitionExpression* e) override; - virtual void Visit(BlockStatement* e) override; - virtual void Visit(LabeledStatement* e) override; - virtual void Visit(IfStatement* e) override; - virtual void Visit(SwitchStatement* e) override; - virtual void Visit(CaseStatement *) override; - virtual void Visit(WhileStatement* e) override; - virtual void Visit(ForStatement* e) override; - virtual void Visit(FunctionDeclaration* e) override; - virtual void Visit(TopStatements* e) override; - virtual void Visit(EmptyExpression* e) override; + virtual void Visit(LiteralNull* e) override; + virtual void Visit(LiteralUndefined* e) override; + virtual void Visit(LiteralString* e) override; + virtual void Visit(LiteralNumber* e) override; + virtual void Visit(LiteralBoolean* e) override; + virtual void Visit(BinaryExpression* e) override; + virtual void Visit(UnaryExpression* e) override; + virtual void Visit(IdentifierExpression* e) override; + virtual void Visit(ListExpression* e) override; + virtual void Visit(VariableDefinitionExpression* e) override; + virtual void Visit(BlockStatement* e) override; + virtual void Visit(LabeledStatement* e) override; + virtual void Visit(IfStatement* e) override; + virtual void Visit(SwitchStatement* e) override; + virtual void Visit(CaseStatement *) override; + virtual void Visit(WhileStatement* e) override; + virtual void Visit(ForStatement* e) override; + virtual void Visit(FunctionDeclaration* e) override; + virtual void Visit(TopStatements* e) override; + virtual void Visit(EmptyExpression* e) override; - value_type& ModifyVariable(const IPLString& name); + value_type& ModifyVariable(const IPLString& name); private: void RunExpression(const ExpressionPtr& e); bool EvalToBool(const ExpressionPtr& e); - void EnterScope(); - void LeaveScope(); - friend struct VariableScope; + void EnterScope(); + void LeaveScope(); + friend struct VariableScope; + friend struct StackScope;; ValueStack m_Evaluation; - IPLUnorderedMap<IPLString, ValueStack> m_Variables; + IPLUnorderedMap<IPLString, ValueStack> m_Variables; - typedef IPLVector<IPLString> Scope; - IPLStack<Scope> m_Scopes; + typedef IPLVector<IPLString> Scope; + IPLStack<Scope> m_Scopes; }; diff --git a/JSImpl/src/main.cpp b/JSImpl/src/main.cpp index 1cc7de8..3fe6f99 100644 --- a/JSImpl/src/main.cpp +++ b/JSImpl/src/main.cpp @@ -19,8 +19,8 @@ void RunParseCalc() auto result = i.Run(expr.get()); std::cout << "Stack after run, top to bottom:" << std::endl; while (!result.empty()) { - std::cout << result.top() << std::endl; - result.pop(); + std::cout << result.back() << std::endl; + result.pop_back(); } std::cout << "S = " << i.ModifyVariable("s") << std::endl; } |
