Rework for D25 tech management - compilation happens dynamically now.

This commit is contained in:
Matthias Koefferlein 2021-04-02 18:48:00 +02:00
parent 773fcb6b67
commit 173ba147b1
6 changed files with 91 additions and 86 deletions

View File

@ -170,22 +170,22 @@ D25TechnologyComponent::D25TechnologyComponent ()
D25TechnologyComponent::D25TechnologyComponent (const D25TechnologyComponent &d) D25TechnologyComponent::D25TechnologyComponent (const D25TechnologyComponent &d)
: db::TechnologyComponent (d25_component_name (), d25_description ()) : db::TechnologyComponent (d25_component_name (), d25_description ())
{ {
m_layers = d.m_layers;
m_src = d.m_src; m_src = d.m_src;
} }
void D25TechnologyComponent::layers_type
D25TechnologyComponent::compile_from_source (const std::string &src) D25TechnologyComponent::compile_from_source () const
{ {
layers_type layers;
int current_line = 0; int current_line = 0;
m_layers.clear ();
try { try {
tl::Eval eval; tl::Eval eval;
std::vector<bool> conditional_stack; std::vector<bool> conditional_stack;
std::vector<std::string> lines = tl::split (src, "\n"); std::vector<std::string> lines = tl::split (m_src, "\n");
for (std::vector<std::string>::const_iterator l = lines.begin (); l != lines.end (); ++l) { for (std::vector<std::string>::const_iterator l = lines.begin (); l != lines.end (); ++l) {
++current_line; ++current_line;
@ -254,12 +254,28 @@ D25TechnologyComponent::compile_from_source (const std::string &src)
ex.expect_end (); ex.expect_end ();
} else if (ex.test ("print")) {
tl::Expression x;
eval.parse (x, ex);
ex.expect_end ();
tl::info << x.execute ().to_string ();
} else if (ex.test ("error")) {
tl::Expression x;
eval.parse (x, ex);
ex.expect_end ();
throw tl::Exception (x.execute ().to_string ());
} else { } else {
db::D25LayerInfo info; db::D25LayerInfo info;
if (! m_layers.empty ()) { if (! layers.empty ()) {
info.set_zstart (m_layers.back ().zstop ()); info.set_zstart (layers.back ().zstop ());
info.set_zstop (m_layers.back ().zstop ()); info.set_zstop (layers.back ().zstop ());
} }
tl::Variant z0, z1, h; tl::Variant z0, z1, h;
@ -308,7 +324,7 @@ D25TechnologyComponent::compile_from_source (const std::string &src)
if (args.size () == 0) { if (args.size () == 0) {
if (z0.is_nil () && z1.is_nil ()) { if (z0.is_nil () && z1.is_nil ()) {
if (! h.is_nil ()) { if (! h.is_nil ()) {
info.set_zstop (info.zstart () + h.to_double ()); info.set_zstop (info.zstop () + h.to_double ());
} }
} else if (z0.is_nil ()) { } else if (z0.is_nil ()) {
info.set_zstop (z1.to_double ()); info.set_zstop (z1.to_double ());
@ -356,6 +372,8 @@ D25TechnologyComponent::compile_from_source (const std::string &src)
throw tl::Exception (tl::to_string (tr ("Too many parameters (max 2)"))); throw tl::Exception (tl::to_string (tr ("Too many parameters (max 2)")));
} }
layers.push_back (info);
} }
} }
@ -368,15 +386,16 @@ D25TechnologyComponent::compile_from_source (const std::string &src)
throw tl::Exception (ex.msg () + tl::sprintf (tl::to_string (tr (" in line %d")), current_line)); throw tl::Exception (ex.msg () + tl::sprintf (tl::to_string (tr (" in line %d")), current_line));
} }
m_src = src; return layers;
} }
std::string std::string
D25TechnologyComponent::to_string () const D25TechnologyComponent::to_string () const
{ {
layers_type layers = compile_from_source ();
std::string res; std::string res;
for (const_iterator i = begin (); i != end (); ++i) { for (layers_type::const_iterator i = layers.begin (); i != layers.end (); ++i) {
if (! res.empty ()) { if (! res.empty ()) {
res += "\n"; res += "\n";
} }
@ -407,11 +426,6 @@ public:
virtual tl::XMLElementBase *xml_element () const virtual tl::XMLElementBase *xml_element () const
{ {
return new db::TechnologyComponentXMLElement<D25TechnologyComponent> (d25_component_name (), return new db::TechnologyComponentXMLElement<D25TechnologyComponent> (d25_component_name (),
tl::make_element ((D25TechnologyComponent::const_iterator (D25TechnologyComponent::*) () const) &D25TechnologyComponent::begin, (D25TechnologyComponent::const_iterator (D25TechnologyComponent::*) () const) &D25TechnologyComponent::end, &D25TechnologyComponent::add, "layer",
tl::make_member (&D25LayerInfo::layer_as_string, &D25LayerInfo::set_layer_from_string, "layer") +
tl::make_member (&D25LayerInfo::zstart, &D25LayerInfo::set_zstart, "zstart") +
tl::make_member (&D25LayerInfo::zstop, &D25LayerInfo::set_zstop, "zstop")
) +
tl::make_member (&D25TechnologyComponent::src, &D25TechnologyComponent::set_src, "src") tl::make_member (&D25TechnologyComponent::src, &D25TechnologyComponent::set_src, "src")
); );
} }

View File

@ -76,55 +76,8 @@ public:
D25TechnologyComponent (const D25TechnologyComponent &d); D25TechnologyComponent (const D25TechnologyComponent &d);
typedef std::list<D25LayerInfo> layers_type; typedef std::list<D25LayerInfo> layers_type;
typedef layers_type::const_iterator const_iterator;
typedef layers_type::iterator iterator;
void compile_from_source (const std::string &src); layers_type compile_from_source () const;
const_iterator begin () const
{
return m_layers.begin ();
}
iterator begin ()
{
return m_layers.begin ();
}
const_iterator end () const
{
return m_layers.end ();
}
iterator end ()
{
return m_layers.end ();
}
void clear ()
{
m_layers.clear ();
}
void erase (iterator p)
{
m_layers.erase (p);
}
void insert (iterator p, const D25LayerInfo &info)
{
m_layers.insert (p, info);
}
void add (const D25LayerInfo &info)
{
m_layers.push_back (info);
}
size_t size () const
{
return m_layers.size ();
}
const std::string &src () const const std::string &src () const
{ {
@ -145,7 +98,6 @@ public:
} }
private: private:
layers_type m_layers;
std::string m_src; std::string m_src;
}; };

View File

@ -30,44 +30,73 @@ TEST(1)
{ {
db::D25TechnologyComponent comp; db::D25TechnologyComponent comp;
comp.compile_from_source ("1/0: 1.0 1.5 # a comment"); comp.set_src ("1/0: 1.0 1.5 # a comment");
comp.compile_from_source ();
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5"); EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5");
comp.compile_from_source ("1/0: zstart=1.0 zstop=1.5"); comp.set_src ("1/0: zstart=1.0 zstop=1.5");
comp.compile_from_source ();
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5"); EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5");
comp.compile_from_source ("1/0: zstart=1.0 height=0.5"); comp.set_src ("1/0: zstart=1.0 height=0.5");
comp.compile_from_source ();
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5"); EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5");
comp.compile_from_source ("1/0: 1.0 height=0.5"); comp.set_src ("1/0: 1.0 height=0.5");
comp.compile_from_source ();
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5"); EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5");
comp.compile_from_source ("1/0: zstop=1.5 height=0.5"); comp.set_src ("1/0: zstop=1.5 height=0.5");
comp.compile_from_source ();
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5"); EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5");
comp.compile_from_source ("1/0: zstart=1.0 zstop=1.5\nname: height=3"); comp.set_src ("1/0: zstart=1.0 zstop=1.5\nname: height=3");
comp.compile_from_source ();
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5\nname: zstart=1.5, zstop=4.5"); EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5\nname: zstart=1.5, zstop=4.5");
comp.compile_from_source ("1/0: zstart=1.0 zstop=1.5\nname: zstart=4.0 height=3\n\n# a comment line"); comp.set_src ("1/0: zstart=1.0 zstop=1.5\nname: zstart=4.0 height=3\n\n# a comment line");
comp.compile_from_source ();
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5\nname: zstart=4, zstop=7"); EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5\nname: zstart=4, zstop=7");
comp.set_src ("var x=1.0\n1/0: zstart=x zstop=x+0.5\nname: zstart=4.0 height=3\n\n# a comment line");
comp.compile_from_source ();
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5\nname: zstart=4, zstop=7");
comp.set_src ("var x=1.0\nif x == 1.0\n1/0: zstart=x zstop=x+0.5\nelse\n1/0: zstart=0 zstop=0\nend\nname: zstart=4.0 height=3\n\n# a comment line");
comp.compile_from_source ();
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5\nname: zstart=4, zstop=7");
comp.set_src ("var x=2.0\nif x == 1.0\n1/0: zstart=x zstop=x+0.5\nelse\n1/0: zstart=0 zstop=0\nend\nname: zstart=4.0 height=3\n\n# a comment line");
comp.compile_from_source ();
EXPECT_EQ (comp.to_string (), "1/0: zstart=0, zstop=0\nname: zstart=4, zstop=7");
try { try {
comp.compile_from_source ("blabla"); comp.set_src ("blabla");
comp.compile_from_source ();
EXPECT_EQ (false, true); EXPECT_EQ (false, true);
} catch (...) { } } catch (...) { }
try { try {
comp.compile_from_source ("1/0: 1 2 3"); comp.set_src ("1/0: 1 2 3");
comp.compile_from_source ();
EXPECT_EQ (false, true); EXPECT_EQ (false, true);
} catch (...) { } } catch (...) { }
try { try {
comp.compile_from_source ("1/0: foo=1 bar=2"); comp.set_src ("1/0: foo=1 bar=2");
comp.compile_from_source ();
EXPECT_EQ (false, true); EXPECT_EQ (false, true);
} catch (...) { } } catch (...) { }
try { try {
comp.compile_from_source ("1/0: 1;2"); comp.set_src ("1/0: 1;*2");
comp.compile_from_source ();
EXPECT_EQ (false, true);
} catch (...) { }
try {
comp.set_src ("error 42");
comp.compile_from_source ();
EXPECT_EQ (false, true); EXPECT_EQ (false, true);
} catch (...) { } } catch (...) { }
} }

View File

@ -72,7 +72,13 @@ D25TechnologyComponentEditor::commit ()
} }
std::string src = tl::to_string (src_te->toPlainText ()); std::string src = tl::to_string (src_te->toPlainText ());
data->compile_from_source (src);
// test-compile before setting it
db::D25TechnologyComponent tc;
tc.set_src (src);
tc.compile_from_source ();
data->set_src (src);
} }
void void

View File

@ -24,6 +24,8 @@
<RegExpr attribute="Normal" String="\s*" context="#stay"/> <RegExpr attribute="Normal" String="\s*" context="#stay"/>
<StringDetect attribute="Symbol" String="var" context="Expect Assignment"/> <StringDetect attribute="Symbol" String="var" context="Expect Assignment"/>
<StringDetect attribute="Symbol" String="print" context="Expression"/>
<StringDetect attribute="Symbol" String="error" context="Expression"/>
<StringDetect attribute="Symbol" String="if" context="Expression"/> <StringDetect attribute="Symbol" String="if" context="Expression"/>
<StringDetect attribute="Symbol" String="elsif" context="Expression"/> <StringDetect attribute="Symbol" String="elsif" context="Expression"/>
<StringDetect attribute="Symbol" String="else" context="Expect Lineend"/> <StringDetect attribute="Symbol" String="else" context="Expect Lineend"/>

View File

@ -418,17 +418,17 @@ namespace {
const db::D25LayerInfo *operator() (lay::LayoutView *view, int cv_index, int layer_index) const db::D25LayerInfo *operator() (lay::LayoutView *view, int cv_index, int layer_index)
{ {
std::map<int, std::map<int, const db::D25LayerInfo *> >::const_iterator c = m_cache.find (cv_index); std::map<int, std::map<int, db::D25LayerInfo> >::const_iterator c = m_cache.find (cv_index);
if (c != m_cache.end ()) { if (c != m_cache.end ()) {
std::map<int, const db::D25LayerInfo *>::const_iterator l = c->second.find (layer_index); std::map<int, db::D25LayerInfo>::const_iterator l = c->second.find (layer_index);
if (l != c->second.end ()) { if (l != c->second.end ()) {
return l->second; return &l->second;
} else { } else {
return 0; return 0;
} }
} }
std::map<int, const db::D25LayerInfo *> &lcache = m_cache [cv_index]; std::map<int, db::D25LayerInfo> &lcache = m_cache [cv_index];
const db::D25TechnologyComponent *comp = 0; const db::D25TechnologyComponent *comp = 0;
@ -440,16 +440,18 @@ namespace {
if (comp) { if (comp) {
std::map<db::LayerProperties, const db::D25LayerInfo *, db::LPLogicalLessFunc> zi_by_lp; std::map<db::LayerProperties, db::D25LayerInfo, db::LPLogicalLessFunc> zi_by_lp;
for (db::D25TechnologyComponent::const_iterator i = comp->begin (); i != comp->end (); ++i) {
zi_by_lp.insert (std::make_pair (i->layer (), i.operator-> ())); db::D25TechnologyComponent::layers_type layers = comp->compile_from_source ();
for (db::D25TechnologyComponent::layers_type::const_iterator i = layers.begin (); i != layers.end (); ++i) {
zi_by_lp.insert (std::make_pair (i->layer (), *i));
} }
const db::Layout &ly = cv->layout (); const db::Layout &ly = cv->layout ();
for (int l = 0; l < int (ly.layers ()); ++l) { for (int l = 0; l < int (ly.layers ()); ++l) {
if (ly.is_valid_layer (l)) { if (ly.is_valid_layer (l)) {
const db::LayerProperties &lp = ly.get_properties (l); const db::LayerProperties &lp = ly.get_properties (l);
std::map<db::LayerProperties, const db::D25LayerInfo *, db::LPLogicalLessFunc>::const_iterator z = zi_by_lp.find (lp); std::map<db::LayerProperties, db::D25LayerInfo, db::LPLogicalLessFunc>::const_iterator z = zi_by_lp.find (lp);
if (z == zi_by_lp.end () && ! lp.name.empty ()) { if (z == zi_by_lp.end () && ! lp.name.empty ()) {
// If possible, try by name only // If possible, try by name only
z = zi_by_lp.find (db::LayerProperties (lp.name)); z = zi_by_lp.find (db::LayerProperties (lp.name));
@ -468,7 +470,7 @@ namespace {
private: private:
std::map<int, std::map<int, const db::D25LayerInfo *> > m_cache; std::map<int, std::map<int, db::D25LayerInfo> > m_cache;
}; };
} }