netlist: Added && and || operators to preprocessor expressions. (nw)

This commit is contained in:
couriersud 2019-01-13 13:59:54 +01:00
parent 01584c0c26
commit b57ceef133
2 changed files with 30 additions and 45 deletions

View File

@ -283,6 +283,8 @@ ppreprocessor::ppreprocessor(std::vector<define_t> *defines)
m_expr_sep.push_back("-"); m_expr_sep.push_back("-");
m_expr_sep.push_back("*"); m_expr_sep.push_back("*");
m_expr_sep.push_back("/"); m_expr_sep.push_back("/");
m_expr_sep.push_back("&&");
m_expr_sep.push_back("||");
m_expr_sep.push_back("=="); m_expr_sep.push_back("==");
m_expr_sep.push_back(" "); m_expr_sep.push_back(" ");
m_expr_sep.push_back("\t"); m_expr_sep.push_back("\t");
@ -302,36 +304,30 @@ void ppreprocessor::error(const pstring &err)
throw pexception("PREPRO ERROR: " + err); throw pexception("PREPRO ERROR: " + err);
} }
#define CHECKTOK2(p_op, p_prio) \
else if (tok == # p_op) \
{ \
if (prio < p_prio) \
return val; \
start++; \
const auto v2 = expr(sexpr, start, p_prio); \
val = (val p_op v2); \
} \
// Operator precedence see https://en.cppreference.com/w/cpp/language/operator_precedence
double ppreprocessor::expr(const std::vector<pstring> &sexpr, std::size_t &start, int prio) int ppreprocessor::expr(const std::vector<pstring> &sexpr, std::size_t &start, int prio)
{ {
double val; int val;
pstring tok=sexpr[start]; pstring tok=sexpr[start];
if (tok == "(") if (tok == "(")
{ {
start++; start++;
val = expr(sexpr, start, /*prio*/ 0); val = expr(sexpr, start, /*prio*/ 255);
if (sexpr[start] != ")") if (sexpr[start] != ")")
error("parsing error!"); error("parsing error!");
start++; start++;
} }
else if (tok == "!")
{
start++;
val = expr(sexpr, start, 90);
if (val != 0)
val = 0;
else
val = 1;
}
else
{
tok=sexpr[start];
// FIXME: error handling
val = plib::pstonum<decltype(val)>(tok);
start++;
}
while (start < sexpr.size()) while (start < sexpr.size())
{ {
tok=sexpr[start]; tok=sexpr[start];
@ -340,36 +336,25 @@ double ppreprocessor::expr(const std::vector<pstring> &sexpr, std::size_t &start
// FIXME: catch error // FIXME: catch error
return val; return val;
} }
else if (tok == "+") else if (tok == "!")
{ {
if (prio > 10) if (prio < 3)
return val; return val;
start++; start++;
val = val + expr(sexpr, start, 10); val = !expr(sexpr, start, 3);
} }
else if (tok == "-") CHECKTOK2(*, 5)
CHECKTOK2(/, 5)
CHECKTOK2(+, 6)
CHECKTOK2(-, 6)
CHECKTOK2(==, 10)
CHECKTOK2(&&, 14)
CHECKTOK2(||, 15)
else
{ {
if (prio > 10) // FIXME: error handling
return val; val = plib::pstonum<decltype(val)>(tok);
start++; start++;
val = val - expr(sexpr, start, 10);
}
else if (tok == "*")
{
start++;
val = val * expr(sexpr, start, 20);
}
else if (tok == "/")
{
start++;
val = val / expr(sexpr, start, 20);
}
else if (tok == "==")
{
if (prio > 5)
return val;
start++;
val = (val == expr(sexpr, start, 5)) ? 1.0 : 0.0;
} }
} }
return val; return val;
@ -418,7 +403,7 @@ pstring ppreprocessor::process_line(const pstring &line)
std::size_t start = 0; std::size_t start = 0;
lt = replace_macros(lt); lt = replace_macros(lt);
std::vector<pstring> t(psplit(replace_all(lt.substr(3), pstring(" "), pstring("")), m_expr_sep)); std::vector<pstring> t(psplit(replace_all(lt.substr(3), pstring(" "), pstring("")), m_expr_sep));
int val = static_cast<int>(expr(t, start, 0)); int val = static_cast<int>(expr(t, start, 255));
if (val == 0) if (val == 0)
m_ifflag |= (1 << m_level); m_ifflag |= (1 << m_level);
} }

View File

@ -164,7 +164,7 @@ public:
void process(putf8_reader &istrm, putf8_writer &ostrm); void process(putf8_reader &istrm, putf8_writer &ostrm);
protected: protected:
double expr(const std::vector<pstring> &sexpr, std::size_t &start, int prio); int expr(const std::vector<pstring> &sexpr, std::size_t &start, int prio);
define_t *get_define(const pstring &name); define_t *get_define(const pstring &name);
pstring replace_macros(const pstring &line); pstring replace_macros(const pstring &line);
virtual void error(const pstring &err); virtual void error(const pstring &err);