Commit 83fe2936 authored by Tobias WEBER's avatar Tobias WEBER
Browse files

arrays

parent 94d28dcc
......@@ -29,6 +29,7 @@ const std::string& Symbol::get_type_name(const Symbol &sym)
std::make_pair(SymbolType::REAL, "real"),
std::make_pair(SymbolType::STRING, "string"),
std::make_pair(SymbolType::LIST, "list"),
std::make_pair(SymbolType::ARRAY, "array"),
std::make_pair(SymbolType::DATASET, "dataset"),
};
......@@ -251,6 +252,69 @@ std::shared_ptr<Symbol> CliASTString::Eval(CliParserContext& ctx) const
}
/**
* recursively evaluate a list and collect symbols into a vector
*/
static std::vector<std::shared_ptr<Symbol>>
list_eval(CliParserContext& ctx, std::shared_ptr<CliAST> left, std::shared_ptr<CliAST> right)
{
std::vector<std::shared_ptr<Symbol>> vec;
if(left)
{
if(auto lefteval = left->Eval(ctx); lefteval)
{
// lhs of AST
if(lefteval->GetType() == SymbolType::LIST)
{
auto &leftvec = dynamic_cast<SymbolList&>(*lefteval).GetValue();
for(auto& val : leftvec)
vec.emplace_back(val);
}
else
{
vec.emplace_back(lefteval);
}
}
}
if(right)
{
if(auto righteval = right->Eval(ctx); righteval)
{
// rhs of AST
if(righteval->GetType() == SymbolType::LIST)
{
auto &rightvec = dynamic_cast<SymbolList&>(*righteval).GetValue();
for(auto& val : rightvec)
vec.emplace_back(val);
}
else
{
vec.emplace_back(righteval);
}
}
}
return vec;
}
/**
* array, e.g. [1, 2, 3, 4]
* an array is composed of a list: [ list ]
*/
std::shared_ptr<Symbol> CliASTArray::Eval(CliParserContext& ctx) const
{
if(!m_left && !m_right)
return nullptr;
// transform the tree into a flat vector
auto vec = list_eval(ctx, m_left, m_right);
return std::make_shared<SymbolList>(vec, false);
}
/**
* variable identifier in symbol or constants map
*/
......@@ -271,12 +335,12 @@ std::shared_ptr<Symbol> CliASTIdent::Eval(CliParserContext& ctx) const
auto iter = workspace->find(m_val);
if(iter == workspace->end() && iterConst == g_consts_real.end())
{
ctx.PrintError("Variable \"", m_val, "\" is neither a constant nor a workspace variable.");
ctx.PrintError("Identifier \"", m_val, "\" names neither a constant nor a workspace variable.");
return nullptr;
}
else if(iter != workspace->end() && iterConst != g_consts_real.end())
{
ctx.PrintError("Variable \"", m_val, "\" is both a constant and a workspace variable, using constant.");
ctx.PrintError("Identifier \"", m_val, "\" names both a constant and a workspace variable, using constant.");
return std::make_shared<SymbolReal>(iterConst->second);
}
else if(iter != workspace->end())
......@@ -330,8 +394,10 @@ std::shared_ptr<Symbol> CliASTAssign::Eval(CliParserContext& ctx) const
// assign variable
if(auto righteval=m_right->Eval(ctx); righteval)
{
const auto [iter, insert_ok] =
workspace->emplace(std::make_pair(ident, righteval));
const auto [iter, inserted] =
workspace->insert_or_assign(ident, righteval);
if(!inserted)
print_out("Variable \"", ident, "\" was overwritten.");
ctx.EmitWorkspaceUpdated(ident);
return iter->second;
......@@ -521,7 +587,7 @@ std::shared_ptr<Symbol> CliASTCall::Eval(CliParserContext& ctx) const
/**
* list of expressions
* list of expressions: e.g. 1,2,3,4
*/
std::shared_ptr<Symbol> CliASTExprList::Eval(CliParserContext& ctx) const
{
......@@ -529,50 +595,11 @@ std::shared_ptr<Symbol> CliASTExprList::Eval(CliParserContext& ctx) const
return nullptr;
// transform the tree into a flat vector
std::vector<std::shared_ptr<Symbol>> vec;
if(auto lefteval=m_left->Eval(ctx), righteval=m_right->Eval(ctx); lefteval && righteval)
{
// lhs of AST
if(lefteval->GetType() == SymbolType::LIST)
{
auto &leftvec = dynamic_cast<SymbolList&>(*lefteval).GetValue();
for(auto& val : leftvec)
vec.emplace_back(val);
}
else
{
vec.emplace_back(lefteval);
}
// rhs of AST
if(righteval->GetType() == SymbolType::LIST)
{
auto &rightvec = dynamic_cast<SymbolList&>(*righteval).GetValue();
for(auto& val : rightvec)
vec.emplace_back(val);
}
else
{
vec.emplace_back(righteval);
}
}
auto vec = list_eval(ctx, m_left, m_right);
return std::make_shared<SymbolList>(vec);
}
/**
* array
*/
std::shared_ptr<Symbol> CliASTArray::Eval(CliParserContext& ctx) const
{
if(!m_left)
return nullptr;
return nullptr;
}
// ----------------------------------------------------------------------------
......
......@@ -107,9 +107,10 @@ public:
enum class SymbolType
{
REAL,
STRING,
LIST,
REAL, // e.g. 12.3
STRING, // e.g. "abc"
LIST, // e.g. 1, 2, 3
ARRAY, // e.g. [1, 2, 3]
DATASET
};
......@@ -121,6 +122,7 @@ public:
virtual SymbolType GetType() const = 0;
virtual std::shared_ptr<Symbol> copy() const = 0;
virtual void print(std::ostream& ostr) const = 0;
static std::shared_ptr<Symbol> uminus(const Symbol &sym2);
static std::shared_ptr<Symbol> add(const Symbol &sym1, const Symbol &sym2);
......@@ -148,6 +150,7 @@ public:
t_real_cli GetValue() const { return m_val; }
virtual std::shared_ptr<Symbol> copy() const override { return std::make_shared<SymbolReal>(m_val); }
virtual void print(std::ostream& ostr) const override { ostr << GetValue(); }
};
......@@ -166,6 +169,7 @@ public:
const std::string& GetValue() const { return m_val; }
virtual std::shared_ptr<Symbol> copy() const override { return std::make_shared<SymbolString>(m_val); }
virtual void print(std::ostream& ostr) const override { ostr << GetValue(); }
};
......@@ -173,17 +177,30 @@ class SymbolList : public Symbol
{
private:
std::vector<std::shared_ptr<Symbol>> m_val;
bool m_islist = true; // list or array
public:
SymbolList() = default;
SymbolList(const std::vector<std::shared_ptr<Symbol>>& val) : m_val(val) {}
SymbolList(std::vector<std::shared_ptr<Symbol>>&& val) : m_val(val) {}
SymbolList(const std::vector<std::shared_ptr<Symbol>>& val, bool islist=1) : m_val(val), m_islist(islist) {}
SymbolList(std::vector<std::shared_ptr<Symbol>>&& val, bool islist=1) : m_val(val), m_islist(islist) {}
virtual ~SymbolList() {}
virtual SymbolType GetType() const override { return SymbolType::LIST; }
virtual SymbolType GetType() const override { return m_islist ? SymbolType::LIST : SymbolType::ARRAY; }
const std::vector<std::shared_ptr<Symbol>>& GetValue() const { return m_val; }
virtual std::shared_ptr<Symbol> copy() const override { return std::make_shared<SymbolList>(m_val); }
virtual std::shared_ptr<Symbol> copy() const override { return std::make_shared<SymbolList>(m_val, m_islist); }
virtual void print(std::ostream& ostr) const override
{
if(!m_islist) ostr << "[ ";
for(std::size_t i=0; i<GetValue().size(); ++i)
{
GetValue()[i]->print(ostr);
if(i < GetValue().size()-1)
ostr << ", ";
}
if(!m_islist) ostr << " ]";
}
};
......@@ -202,6 +219,7 @@ public:
const Dataset& GetValue() const { return m_val; }
virtual std::shared_ptr<Symbol> copy() const override { return std::make_shared<SymbolDataset>(m_val); }
virtual void print(std::ostream& ostr) const override { ostr << "&lt;Dataset&gt;"; }
};
......
......@@ -106,14 +106,7 @@ void CommandLineWidget::CommandEntered()
if(sym)
{
std::ostringstream ostrRes;
if(sym->GetType() == SymbolType::REAL)
ostrRes /*<< "real: "*/ << dynamic_cast<SymbolReal&>(*sym).GetValue();
else if(sym->GetType() == SymbolType::STRING)
ostrRes /*<< "string: "*/ << dynamic_cast<SymbolString&>(*sym).GetValue();
else if(sym->GetType() == SymbolType::DATASET)
ostrRes << "&lt;Dataset&gt;";
sym->print(ostrRes);
PrintOutput(0, ostrRes.str().c_str());
}
else
......
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