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)
: db::TechnologyComponent (d25_component_name (), d25_description ())
{
m_layers = d.m_layers;
m_src = d.m_src;
}
void
D25TechnologyComponent::compile_from_source (const std::string &src)
D25TechnologyComponent::layers_type
D25TechnologyComponent::compile_from_source () const
{
layers_type layers;
int current_line = 0;
m_layers.clear ();
try {
tl::Eval eval;
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) {
++current_line;
@ -254,12 +254,28 @@ D25TechnologyComponent::compile_from_source (const std::string &src)
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 {
db::D25LayerInfo info;
if (! m_layers.empty ()) {
info.set_zstart (m_layers.back ().zstop ());
info.set_zstop (m_layers.back ().zstop ());
if (! layers.empty ()) {
info.set_zstart (layers.back ().zstop ());
info.set_zstop (layers.back ().zstop ());
}
tl::Variant z0, z1, h;
@ -308,7 +324,7 @@ D25TechnologyComponent::compile_from_source (const std::string &src)
if (args.size () == 0) {
if (z0.is_nil () && z1.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 ()) {
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)")));
}
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));
}
m_src = src;
return layers;
}
std::string
D25TechnologyComponent::to_string () const
{
layers_type layers = compile_from_source ();
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 ()) {
res += "\n";
}
@ -407,11 +426,6 @@ public:
virtual tl::XMLElementBase *xml_element () const
{
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")
);
}

View File

@ -76,55 +76,8 @@ public:
D25TechnologyComponent (const D25TechnologyComponent &d);
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);
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 ();
}
layers_type compile_from_source () const;
const std::string &src () const
{
@ -145,7 +98,6 @@ public:
}
private:
layers_type m_layers;
std::string m_src;
};

View File

@ -30,44 +30,73 @@ TEST(1)
{
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");
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");
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");
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");
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");
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");
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");
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 {
comp.compile_from_source ("blabla");
comp.set_src ("blabla");
comp.compile_from_source ();
EXPECT_EQ (false, true);
} catch (...) { }
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);
} catch (...) { }
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);
} catch (...) { }
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);
} catch (...) { }
}

View File

@ -72,7 +72,13 @@ D25TechnologyComponentEditor::commit ()
}
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

View File

@ -24,6 +24,8 @@
<RegExpr attribute="Normal" String="\s*" context="#stay"/>
<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="elsif" context="Expression"/>
<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)
{
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 ()) {
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 ()) {
return l->second;
return &l->second;
} else {
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;
@ -440,16 +440,18 @@ namespace {
if (comp) {
std::map<db::LayerProperties, const 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-> ()));
std::map<db::LayerProperties, db::D25LayerInfo, db::LPLogicalLessFunc> zi_by_lp;
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 ();
for (int l = 0; l < int (ly.layers ()); ++l) {
if (ly.is_valid_layer (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 possible, try by name only
z = zi_by_lp.find (db::LayerProperties (lp.name));
@ -468,7 +470,7 @@ namespace {
private:
std::map<int, std::map<int, const db::D25LayerInfo *> > m_cache;
std::map<int, std::map<int, db::D25LayerInfo> > m_cache;
};
}