From 0ba5eb38f9e6974271c5efa09438f11055820933 Mon Sep 17 00:00:00 2001 From: Dimitar Trendafilov Date: Sun, 28 Oct 2018 17:08:32 +0200 Subject: Fixed for increment step filling up the stack --- JSImpl/src/ASTInterpreter.cpp | 101 +++++++++++++++++++++++++++--------------- JSImpl/src/ASTInterpreter.h | 69 +++++++++++++++-------------- JSImpl/src/main.cpp | 4 +- 3 files changed, 102 insertions(+), 72 deletions(-) (limited to 'JSImpl/src') 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 -#include -#include class ASTInterpreter : public ExpressionVisitor { public: - ASTInterpreter(); - ~ASTInterpreter(); + ASTInterpreter(); + ~ASTInterpreter(); + + // TODO: Changing this to a shared_ptr (or GC-enabled value*) will + // allow for much simpler implementation of all varible assignments. typedef double value_type; - typedef IPLStack ValueStack; + typedef IPLVector 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; - - value_type& ModifyVariable(const IPLString& name); + 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); 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 m_Variables; + IPLUnorderedMap m_Variables; - typedef IPLVector Scope; - IPLStack m_Scopes; + typedef IPLVector Scope; + IPLStack 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; } -- cgit v1.3.1-23-gd82d