Commit 81e189e5 authored by Tobias WEBER's avatar Tobias WEBER
Browse files

got basic functionality working

parent 6a9c2a74
......@@ -214,128 +214,183 @@ std::shared_ptr<Symbol> Symbol::pow(const Symbol &sym1, const Symbol &sym2)
/**
* real constant
*/
std::shared_ptr<Symbol> CliASTReal::Eval() const
std::shared_ptr<Symbol> CliASTReal::Eval(CliParserContext& ctx) const
{
return std::make_shared<SymbolReal>(m_val);
}
/**
* string constant
*/
std::shared_ptr<Symbol> CliASTString::Eval() const
std::shared_ptr<Symbol> CliASTString::Eval(CliParserContext& ctx) const
{
return std::make_shared<SymbolString>(m_val);
}
/**
* variable identifier
* variable identifier in symbol map
*/
std::shared_ptr<Symbol> CliASTIdent::Eval() const
std::shared_ptr<Symbol> CliASTIdent::Eval(CliParserContext& ctx) const
{
return nullptr;
auto *workspace = ctx.GetWorkspace();
if(!workspace)
{
std::cerr << "No workspace linked to parser." << std::endl;
return nullptr;
}
auto iter = workspace->find(m_val);
if(iter == workspace->end())
{
std::cerr << "Variable \"" << m_val << "\" is not in workspace." << std::endl;
return nullptr;
}
return iter->second;
}
/**
* assignment operation
*/
std::shared_ptr<Symbol> CliASTAssign::Eval() const
std::shared_ptr<Symbol> CliASTAssign::Eval(CliParserContext& ctx) const
{
auto *workspace = ctx.GetWorkspace();
if(!workspace)
{
std::cerr << "No workspace linked to parser." << std::endl;
return nullptr;
}
if(!m_left || !m_right)
return nullptr;
if(m_left->GetType() != CliASTType::IDENT && m_left->GetType() != CliASTType::STRING)
{
std::cerr << "Left-hand side of assignment has to be an identifier." << std::endl;
return nullptr;
}
if(auto righteval=m_right->Eval(ctx); righteval)
{
std::string ident;
if(m_left->GetType() == CliASTType::IDENT)
ident = dynamic_cast<CliASTIdent&>(*m_left).GetValue();
else if(m_left->GetType() == CliASTType::STRING)
ident = dynamic_cast<CliASTString&>(*m_left).GetValue();
// TODO: Check if string is also a valid identifier!
const auto [iter, insert_ok] =
workspace->emplace(std::make_pair(ident, righteval));
ctx.EmitWorkspaceUpdated(ident);
return iter->second;
}
return nullptr;
}
/**
* addition
*/
std::shared_ptr<Symbol> CliASTPlus::Eval() const
std::shared_ptr<Symbol> CliASTPlus::Eval(CliParserContext& ctx) const
{
if(!m_left || !m_right)
return nullptr;
if(auto lefteval=m_left->Eval(), righteval=m_right->Eval(); lefteval && righteval)
if(auto lefteval=m_left->Eval(ctx), righteval=m_right->Eval(ctx); lefteval && righteval)
return Symbol::add(*lefteval, *righteval);
return nullptr;
}
/**
* subtraction
*/
std::shared_ptr<Symbol> CliASTMinus::Eval() const
std::shared_ptr<Symbol> CliASTMinus::Eval(CliParserContext& ctx) const
{
if(m_left && m_right)
{
if(auto lefteval=m_left->Eval(), righteval=m_right->Eval(); lefteval && righteval)
if(auto lefteval=m_left->Eval(ctx), righteval=m_right->Eval(ctx); lefteval && righteval)
return Symbol::sub(*lefteval, *righteval);
}
else if(m_right && !m_left)
{
if(auto righteval=m_right->Eval(); righteval)
if(auto righteval=m_right->Eval(ctx); righteval)
return Symbol::uminus(*righteval);
return Symbol::uminus(*m_right->Eval());
return Symbol::uminus(*m_right->Eval(ctx));
}
return nullptr;
}
/**
* multiplication
*/
std::shared_ptr<Symbol> CliASTMult::Eval() const
std::shared_ptr<Symbol> CliASTMult::Eval(CliParserContext& ctx) const
{
if(!m_left || !m_right)
return nullptr;
if(auto lefteval=m_left->Eval(), righteval=m_right->Eval(); lefteval && righteval)
if(auto lefteval=m_left->Eval(ctx), righteval=m_right->Eval(ctx); lefteval && righteval)
return Symbol::mul(*lefteval, *righteval);
return nullptr;
}
/**
* division
*/
std::shared_ptr<Symbol> CliASTDiv::Eval() const
std::shared_ptr<Symbol> CliASTDiv::Eval(CliParserContext& ctx) const
{
if(!m_left || !m_right)
return nullptr;
if(auto lefteval=m_left->Eval(), righteval=m_right->Eval(); lefteval && righteval)
if(auto lefteval=m_left->Eval(ctx), righteval=m_right->Eval(ctx); lefteval && righteval)
return Symbol::div(*lefteval, *righteval);
return nullptr;
}
/**
* modulo
*/
std::shared_ptr<Symbol> CliASTMod::Eval() const
std::shared_ptr<Symbol> CliASTMod::Eval(CliParserContext& ctx) const
{
if(!m_left || !m_right)
return nullptr;
if(auto lefteval=m_left->Eval(), righteval=m_right->Eval(); lefteval && righteval)
if(auto lefteval=m_left->Eval(ctx), righteval=m_right->Eval(ctx); lefteval && righteval)
return Symbol::mod(*lefteval, *righteval);
return nullptr;
}
/**
* power
*/
std::shared_ptr<Symbol> CliASTPow::Eval() const
std::shared_ptr<Symbol> CliASTPow::Eval(CliParserContext& ctx) const
{
if(!m_left || !m_right)
return nullptr;
if(auto lefteval=m_left->Eval(), righteval=m_right->Eval(); lefteval && righteval)
if(auto lefteval=m_left->Eval(ctx), righteval=m_right->Eval(ctx); lefteval && righteval)
return Symbol::pow(*lefteval, *righteval);
return nullptr;
}
/**
* function call operation
*/
std::shared_ptr<Symbol> CliASTCall::Eval() const
std::shared_ptr<Symbol> CliASTCall::Eval(CliParserContext& ctx) const
{
return nullptr;
}
......
......@@ -11,7 +11,9 @@
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <memory>
#include <boost/signals2/signal.hpp>
#undef yyFlexLexer
#include <FlexLexer.h>
......@@ -23,8 +25,10 @@
using t_real = t_real_cli;
class CliAST;
class CliParserContext;
class Symbol;
......@@ -63,6 +67,10 @@ private:
std::vector<std::shared_ptr<CliAST>> m_asts;
std::vector<std::string> m_errors;
// symbol tables and update signal
std::map<std::string, std::shared_ptr<Symbol>> *m_workspace = nullptr;
boost::signals2::signal<void(const std::string&)> m_WorkspaceUpdated;
public:
CliLexer& GetLexer() { return m_lex; }
......@@ -75,6 +83,12 @@ public:
void AddAST(std::shared_ptr<CliAST> ast) { m_asts.push_back(ast); }
void ClearASTs() { m_asts.clear(); }
const std::vector<std::shared_ptr<CliAST>>& GetASTs() const { return m_asts; }
void SetWorkspace(std::map<std::string, std::shared_ptr<Symbol>> *ws) { m_workspace = ws; }
std::map<std::string, std::shared_ptr<Symbol>> * GetWorkspace() { return m_workspace; }
void EmitWorkspaceUpdated(const std::string& ident="") { m_WorkspaceUpdated(ident); }
boost::signals2::signal<void(const std::string&)>& GetWorkspaceUpdatedSignal() { return m_WorkspaceUpdated; }
};
// ----------------------------------------------------------------------------
......@@ -154,6 +168,7 @@ private:
public:
SymbolDataset() = default;
SymbolDataset(const Dataset& val) : m_val(val) {}
SymbolDataset(Dataset&& val) : m_val(val) {}
virtual ~SymbolDataset() {}
virtual SymbolType GetType() const override { return SymbolType::DATASET; }
......@@ -171,6 +186,22 @@ public:
// AST
// ----------------------------------------------------------------------------
enum class CliASTType
{
REAL,
STRING,
IDENT,
ASSIGN,
PLUS,
MINUS,
MULT,
DIV,
MOD,
POW,
CALL
};
class CliAST
{
protected:
......@@ -184,7 +215,8 @@ public:
void SetRight(std::shared_ptr<CliAST> right) { m_right = right; }
virtual void Print(int indent = 0) const;
virtual std::shared_ptr<Symbol> Eval() const = 0;
virtual std::shared_ptr<Symbol> Eval(CliParserContext& ctx) const = 0;
virtual CliASTType GetType() const = 0;
};
......@@ -197,7 +229,10 @@ public:
CliASTReal(t_real_cli val) : m_val(val) { }
virtual void Print(int indent = 0) const override;
virtual std::shared_ptr<Symbol> Eval() const override;
virtual std::shared_ptr<Symbol> Eval(CliParserContext& ctx) const override;
virtual CliASTType GetType() const override { return CliASTType::REAL; }
t_real_cli GetValue() const { return m_val; }
};
......@@ -210,7 +245,10 @@ public:
CliASTString(const std::string& val) : m_val(val) { }
virtual void Print(int indent = 0) const override;
virtual std::shared_ptr<Symbol> Eval() const override;
virtual std::shared_ptr<Symbol> Eval(CliParserContext& ctx) const override;
virtual CliASTType GetType() const override { return CliASTType::STRING; }
const std::string& GetValue() const { return m_val; }
};
......@@ -223,7 +261,10 @@ public:
CliASTIdent(const std::string& val) : m_val(val) { }
virtual void Print(int indent = 0) const override;
virtual std::shared_ptr<Symbol> Eval() const override;
virtual std::shared_ptr<Symbol> Eval(CliParserContext& ctx) const override;
virtual CliASTType GetType() const override { return CliASTType::IDENT; }
const std::string& GetValue() const { return m_val; }
};
......@@ -233,7 +274,9 @@ public:
using CliAST::CliAST;
virtual void Print(int indent = 0) const override;
virtual std::shared_ptr<Symbol> Eval() const override;
virtual std::shared_ptr<Symbol> Eval(CliParserContext& ctx) const override;
virtual CliASTType GetType() const override { return CliASTType::ASSIGN; }
};
......@@ -243,7 +286,9 @@ public:
using CliAST::CliAST;
virtual void Print(int indent = 0) const override;
virtual std::shared_ptr<Symbol> Eval() const override;
virtual std::shared_ptr<Symbol> Eval(CliParserContext& ctx) const override;
virtual CliASTType GetType() const override { return CliASTType::PLUS; }
};
......@@ -253,7 +298,9 @@ public:
using CliAST::CliAST;
virtual void Print(int indent = 0) const override;
virtual std::shared_ptr<Symbol> Eval() const override;
virtual std::shared_ptr<Symbol> Eval(CliParserContext& ctx) const override;
virtual CliASTType GetType() const override { return CliASTType::MINUS; }
};
......@@ -263,7 +310,9 @@ public:
using CliAST::CliAST;
virtual void Print(int indent = 0) const override;
virtual std::shared_ptr<Symbol> Eval() const override;
virtual std::shared_ptr<Symbol> Eval(CliParserContext& ctx) const override;
virtual CliASTType GetType() const override { return CliASTType::MULT; }
};
......@@ -273,7 +322,9 @@ public:
using CliAST::CliAST;
virtual void Print(int indent = 0) const override;
virtual std::shared_ptr<Symbol> Eval() const override;
virtual std::shared_ptr<Symbol> Eval(CliParserContext& ctx) const override;
virtual CliASTType GetType() const override { return CliASTType::DIV; }
};
......@@ -283,7 +334,9 @@ public:
using CliAST::CliAST;
virtual void Print(int indent = 0) const override;
virtual std::shared_ptr<Symbol> Eval() const override;
virtual std::shared_ptr<Symbol> Eval(CliParserContext& ctx) const override;
virtual CliASTType GetType() const override { return CliASTType::MOD; }
};
......@@ -293,7 +346,9 @@ public:
using CliAST::CliAST;
virtual void Print(int indent = 0) const override;
virtual std::shared_ptr<Symbol> Eval() const override;
virtual std::shared_ptr<Symbol> Eval(CliParserContext& ctx) const override;
virtual CliASTType GetType() const override { return CliASTType::POW; }
};
......@@ -303,7 +358,9 @@ public:
using CliAST::CliAST;
virtual void Print(int indent = 0) const override;
virtual std::shared_ptr<Symbol> Eval() const override;
virtual std::shared_ptr<Symbol> Eval(CliParserContext& ctx) const override;
virtual CliASTType GetType() const override { return CliASTType::CALL; }
};
// ----------------------------------------------------------------------------
......
......@@ -84,17 +84,17 @@ void CommandLineWidget::CommandEntered()
if(!ast) continue;
//ast->Print(); std::cout.flush();
auto sym = ast->Eval();
auto sym = ast->Eval(m_parsectx);
if(sym)
{
std::ostringstream ostrRes;
if(sym->GetType() == SymbolType::REAL)
ostrRes << dynamic_cast<SymbolReal&>(*sym).GetValue();
ostrRes /*<< "real: "*/ << dynamic_cast<SymbolReal&>(*sym).GetValue();
else if(sym->GetType() == SymbolType::STRING)
ostrRes << dynamic_cast<SymbolString&>(*sym).GetValue();
ostrRes /*<< "string: "*/ << dynamic_cast<SymbolString&>(*sym).GetValue();
else if(sym->GetType() == SymbolType::DATASET)
ostrRes << "<Dataset>";
ostrRes << "&lt;Dataset&gt;";
m_pEditHistory->insertHtml((("<font color=\"#000000\">" + ostrRes.str() + "</font><br>").c_str()));
}
......
......@@ -39,6 +39,8 @@ protected:
public:
CommandLineWidget(QWidget *pParent = nullptr, QSettings *pSettings = nullptr);
virtual ~CommandLineWidget();
CliParserContext& GetParserContext() { return m_parsectx; }
};
......@@ -54,6 +56,9 @@ private:
public:
CommandLine(QWidget* pParent = nullptr, QSettings *pSettings = nullptr);
virtual ~CommandLine();
const CommandLineWidget* GetWidget() const { return m_pCLI.get(); }
CommandLineWidget* GetWidget() { return m_pCLI.get(); }
};
......
......@@ -55,6 +55,15 @@ MainWnd::MainWnd(QSettings* pSettings)
// connections
connect(m_pBrowser->GetWidget(), &FileBrowserWidget::TransferFiles,
m_pWS->GetWidget(), &WorkSpaceWidget::ReceiveFiles);
// link symbol maps of workspace widget and command line parser
m_pCLI->GetWidget()->GetParserContext().SetWorkspace(m_pWS->GetWidget()->GetWorkspace());
// connect the "workspace updated" signal from the command line parser
m_pCLI->GetWidget()->GetParserContext().GetWorkspaceUpdatedSignal().connect([this](const std::string& ident)
{
m_pWS->GetWidget()->UpdateList();
});
// ------------------------------------------------------------------------
......
......@@ -64,11 +64,18 @@ void WorkSpaceWidget::ItemSelected(QListWidgetItem* pCur)
auto iter = m_workspace.find(ident);
if(iter == m_workspace.end())
{
std::cerr << "Identifier \"" << ident << "\" is not in workspace." << std::endl;
std::cerr << "Variable \"" << ident << "\" is not in workspace." << std::endl;
return;
}
const Dataset& dataset = iter->second;
auto symdataset = iter->second;
if(symdataset->GetType() != SymbolType::DATASET)
{
std::cerr << "Variable \"" << ident << "\" is not of dataset type." << std::endl;
return;
}
const Dataset& dataset = dynamic_cast<const SymbolDataset&>(*symdataset).GetValue();
m_pPlotter->Plot(dataset);
}
......@@ -104,8 +111,8 @@ void WorkSpaceWidget::ReceiveFiles(const std::vector<std::string> &files)
}
// insert the dataset into the workspace
std::string fileident = "data" + filepath.baseName().toStdString();
const auto [iter, insert_ok] = m_workspace.emplace(std::make_pair(fileident, std::move(dataset)));
std::string fileident = "sc" + filepath.baseName().toStdString();
const auto [iter, insert_ok] = m_workspace.emplace(std::make_pair(fileident, std::make_shared<SymbolDataset>(std::move(dataset))));
}
UpdateList();
......@@ -117,8 +124,13 @@ void WorkSpaceWidget::ReceiveFiles(const std::vector<std::string> &files)
*/
void WorkSpaceWidget::UpdateList()
{
for(const auto& [ident, dataset] : m_workspace)
for(const auto& [ident, symdataset] : m_workspace)
{
// skip real or string variables
if(symdataset->GetType() != SymbolType::DATASET)
continue;
const Dataset& dataset = dynamic_cast<const SymbolDataset&>(*symdataset).GetValue();
QString qident(ident.c_str());
// dataset with this identifier already in list?
if(m_pListFiles->findItems(qident, Qt::MatchCaseSensitive|Qt::MatchExactly).size())
......
......@@ -19,6 +19,7 @@
#include "data.h"
#include "plot.h"
#include "tools/cli/cliparser.h"
......@@ -34,20 +35,21 @@ private:
Plotter *m_pPlotter = new Plotter(this);
// maps an identifier to a dataset
std::map<std::string, Dataset> m_workspace;
std::map<std::string, std::shared_ptr<Symbol>> m_workspace;
public:
WorkSpaceWidget(QWidget *pParent = nullptr, QSettings *pSettings = nullptr);
virtual ~WorkSpaceWidget();
std::map<std::string, std::shared_ptr<Symbol>>* GetWorkspace() { return &m_workspace; }
protected:
void ItemSelected(QListWidgetItem* pCur);
void ItemDoubleClicked(QListWidgetItem* pCur);
void UpdateList();
public:
void ReceiveFiles(const std::vector<std::string>&);
void UpdateList();
};
......@@ -65,6 +67,7 @@ public:
virtual ~WorkSpace();
const WorkSpaceWidget* GetWidget() const { return m_pWS.get(); }
WorkSpaceWidget* GetWidget() { return m_pWS.get(); }
};
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment