Commit 2104f96e authored by Tobias WEBER's avatar Tobias WEBER
Browse files

continued with data treatment interpreter

parent 8d70ecfa
......@@ -95,6 +95,18 @@ std::shared_ptr<Symbol> Symbol::add(const Symbol &sym1, const Symbol &sym2)
dynamic_cast<const SymbolDataset&>(sym1).GetValue() +
dynamic_cast<const SymbolDataset&>(sym2).GetValue());
}
else if(sym1.GetType()==SymbolType::DATASET && sym2.GetType()==SymbolType::REAL)
{ // data + 1.23
return std::make_shared<SymbolDataset>(
dynamic_cast<const SymbolDataset&>(sym1).GetValue() +
dynamic_cast<const SymbolReal&>(sym2).GetValue());
}
else if(sym1.GetType()==SymbolType::DATASET && sym2.GetType()==SymbolType::REAL)
{ // 1.23 + data
return std::make_shared<SymbolDataset>(
dynamic_cast<const SymbolReal&>(sym1).GetValue() +
dynamic_cast<const SymbolDataset&>(sym2).GetValue());
}
else if(sym1.GetType()==SymbolType::STRING && sym2.GetType()==SymbolType::REAL)
{ // "abc" + 3
const std::string &str = dynamic_cast<const SymbolString&>(sym1).GetValue();
......@@ -147,6 +159,12 @@ std::shared_ptr<Symbol> Symbol::sub(const Symbol &sym1, const Symbol &sym2)
dynamic_cast<const SymbolDataset&>(sym1).GetValue() -
dynamic_cast<const SymbolDataset&>(sym2).GetValue());
}
else if(sym1.GetType()==SymbolType::DATASET && sym2.GetType()==SymbolType::REAL)
{ // data - 1.23
return std::make_shared<SymbolDataset>(
dynamic_cast<const SymbolDataset&>(sym1).GetValue() -
dynamic_cast<const SymbolReal&>(sym2).GetValue());
}
return nullptr;
}
......@@ -398,6 +416,65 @@ std::shared_ptr<Symbol> CliASTArray::Eval(CliParserContext& ctx) const
}
/**
* array element access, e.g. a[5]
*/
std::shared_ptr<Symbol> CliASTArrayAccess::Eval(CliParserContext& ctx) const
{
if(!m_left && !m_right)
return nullptr;
if(auto lefteval=m_left->Eval(ctx), righteval=m_right->Eval(ctx); lefteval && righteval)
{
if(righteval->GetType() != SymbolType::REAL)
{
ctx.PrintError("Array index has to be of scalar type.");
return nullptr;
}
// index
std::size_t idx = std::size_t(dynamic_cast<SymbolReal&>(*righteval).GetValue());
if(lefteval->GetType() == SymbolType::ARRAY)
{ // get array elements
const auto& arr = dynamic_cast<SymbolList&>(*lefteval).GetValue();
if(idx >= arr.size())
{
ctx.PrintError("Array index is out of bounds.");
return nullptr;
}
return arr[idx]->copy();
}
else if(lefteval->GetType() == SymbolType::DATASET)
{ // get channels of a dataset
const auto& dataset = dynamic_cast<SymbolDataset&>(*lefteval).GetValue();
if(idx >= dataset.GetNumChannels())
{
ctx.PrintError("Dataset channel index is out of bounds.");
return nullptr;
}
Dataset newdataset;
Data dat = dataset.GetChannel(idx);
newdataset.AddChannel(std::move(dat));
return std::make_shared<SymbolDataset>(newdataset);
}
else
{
ctx.PrintError("Variables of type ", Symbol::get_type_name(*lefteval),
" do not support element access.");
return nullptr;
}
}
ctx.PrintError("Invalid element access request.");
return nullptr;
}
/**
* variable identifier in symbol or constants map
*/
......@@ -800,4 +877,11 @@ void CliASTArray::Print(std::ostringstream &ostr, int indent) const
ostr << "op: array\n";
CliAST::Print(ostr, indent);
}
void CliASTArrayAccess::Print(std::ostringstream &ostr, int indent) const
{
for(int i=0; i<indent; ++i) ostr << "\t";
ostr << "op: array_access\n";
CliAST::Print(ostr, indent);
}
// ----------------------------------------------------------------------------
......@@ -258,6 +258,7 @@ enum class CliASTType
CALL,
EXPRLIST,
ARRAY,
ARRAYACCESS,
};
......@@ -446,6 +447,19 @@ public:
virtual CliASTType GetType() const override { return CliASTType::ARRAY; }
};
class CliASTArrayAccess : public CliAST
{
public:
using CliAST::CliAST;
virtual void Print(std::ostringstream &ostr, int indent = 0) const override;
virtual std::shared_ptr<Symbol> Eval(CliParserContext& ctx) const override;
virtual CliASTType GetType() const override { return CliASTType::ARRAYACCESS; }
};
// ----------------------------------------------------------------------------
......
......@@ -83,6 +83,8 @@ expression
| TOK_SQBRACKET_OPEN expressions TOK_SQBRACKET_CLOSE
{ $$ = std::make_shared<CliASTArray>($2); }
| expression TOK_SQBRACKET_OPEN expression TOK_SQBRACKET_CLOSE
{ $$ = std::make_shared<CliASTArrayAccess>($1, $3); }
| TOK_BRACKET_OPEN expression TOK_BRACKET_CLOSE
{ $$ = $2; }
......
......@@ -92,12 +92,39 @@ static std::shared_ptr<Symbol> func_typeof(std::shared_ptr<Symbol> sym)
}
/**
* sizeof function
*/
static std::shared_ptr<Symbol> func_sizeof(std::shared_ptr<Symbol> sym)
{
if(sym->GetType() == SymbolType::ARRAY)
{ // array length
std::size_t len = dynamic_cast<SymbolList&>(*sym).GetValue().size();
return std::make_shared<SymbolReal>(len);
}
else if(sym->GetType() == SymbolType::STRING)
{ // string length
std::size_t len = dynamic_cast<SymbolString&>(*sym).GetValue().length();
return std::make_shared<SymbolReal>(len);
}
else if(sym->GetType() == SymbolType::DATASET)
{ // number of channels in dataset
std::size_t len = dynamic_cast<SymbolDataset&>(*sym).GetValue().GetNumChannels();
return std::make_shared<SymbolReal>(len);
}
// 1 for other types
return std::make_shared<SymbolReal>(1);
}
/**
* map of general functions with one argument
*/
std::unordered_map<std::string, std::shared_ptr<Symbol>(*)(std::shared_ptr<Symbol>)> g_funcs_gen_1arg =
{
std::make_pair("typeof", &func_typeof),
std::make_pair("sizeof", &func_sizeof),
};
/**
......
......@@ -220,6 +220,61 @@ Data operator +(const Data& dat1, const Data& dat2)
}
Data operator +(const Data& dat, t_real_dat d)
{
Data datret = dat;
t_real_dat d_err = std::sqrt(d);
t_real_dat d_mon = 0.; // TODO
t_real_dat d_mon_err = std::sqrt(d_mon);
// detectors
for(std::size_t detidx=0; detidx<datret.m_counts.size(); ++detidx)
{
auto& det = datret.m_counts[detidx];
for(std::size_t cntidx=0; cntidx<det.size(); ++cntidx)
{
auto& cnt = det[cntidx];
cnt += d;
datret.m_counts_err[detidx][cntidx] =
std::sqrt(dat.m_counts_err[detidx][cntidx]*dat.m_counts_err[detidx][cntidx]
+ d*d_err);
}
}
// monitors
for(std::size_t detidx=0; detidx<datret.m_monitors.size(); ++detidx)
{
auto& det = datret.m_monitors[detidx];
for(std::size_t cntidx=0; cntidx<det.size(); ++cntidx)
{
auto& cnt = det[cntidx];
cnt += d_mon;
datret.m_monitors_err[detidx][cntidx] =
std::sqrt(dat.m_monitors_err[detidx][cntidx]*dat.m_monitors_err[detidx][cntidx]
+ d_mon*d_mon_err);
}
}
return datret;
}
Data operator +(t_real_dat d, const Data& dat)
{
return dat + d;
}
Data operator -(const Data& dat, t_real_dat d)
{
return dat + (-d);
}
Data operator -(const Data& dat1, const Data& dat2)
{
return dat1 + (-dat2);
......@@ -306,6 +361,32 @@ Dataset operator -(const Dataset& dat1, const Dataset& dat2)
}
Dataset operator +(const Dataset& dat, t_real_dat d)
{
Dataset dataset;
for(std::size_t ch=0; ch<dat.GetNumChannels(); ++ch)
{
Data data = dat.GetChannel(ch) + d;
dataset.AddChannel(std::move(data));
}
return dataset;
}
Dataset operator +(t_real_dat d, const Dataset& dat)
{
return dat + d;
}
Dataset operator -(const Dataset& dat, t_real_dat d)
{
return dat + (-d);
}
Dataset operator *(const Dataset& dat1, t_real_dat d)
{
Dataset dataset;
......
......@@ -99,7 +99,10 @@ public:
// binary operators
friend Data operator +(const Data& dat1, const Data& dat2);
friend Data operator +(const Data& dat, t_real_dat d);
friend Data operator +(t_real_dat d, const Data& dat);
friend Data operator -(const Data& dat1, const Data& dat2);
friend Data operator -(const Data& dat, t_real_dat d);
friend Data operator *(const Data& dat1, t_real_dat d);
friend Data operator *(t_real_dat d, const Data& dat1);
friend Data operator /(const Data& dat1, t_real_dat d);
......@@ -128,7 +131,10 @@ public:
// binary operators
friend Dataset operator +(const Dataset& dat1, const Dataset& dat2);
friend Dataset operator +(const Dataset& dat, t_real_dat d);
friend Dataset operator +(t_real_dat d, const Dataset& dat);
friend Dataset operator -(const Dataset& dat1, const Dataset& dat2);
friend Dataset operator -(const Dataset& dat, t_real_dat d);
friend Dataset operator *(const Dataset& dat1, t_real_dat d);
friend Dataset operator *(t_real_dat d, const Dataset& dat1);
friend Dataset operator /(const Dataset& dat1, t_real_dat d);
......
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