/* KLayout Layout Viewer Copyright (C) 2006-2016 Matthias Koefferlein This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "tlExpression.h" #include "tlVariantUserClasses.h" #include "dbBox.h" #include "dbEdge.h" #include "dbLayout.h" #include "dbLayoutContextHandler.h" #include "utHead.h" #include #include // basics TEST(1) { tl::Eval e; tl::Variant v; v = e.parse ("1").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("1+2").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("1.2e3").execute (); EXPECT_EQ (v.to_string (), std::string ("1200")); v = e.parse ("-0.25e-2").execute (); EXPECT_EQ (v.to_string (), std::string ("-0.0025")); v = e.parse ("0xffff").execute (); EXPECT_EQ (v.to_string (), std::string ("65535")); v = e.parse ("0x1001").execute (); EXPECT_EQ (v.to_string (), std::string ("4097")); v = e.parse ("0x1").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("1-2+3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("1-4*2+3").execute (); EXPECT_EQ (v.to_string (), std::string ("-4")); v = e.parse ("(1-4)*2+3").execute (); EXPECT_EQ (v.to_string (), std::string ("-3")); v = e.parse ("(4-1)*2%4").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("7%4").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("2+3/2").execute (); EXPECT_EQ (v.to_string (), std::string ("3.5")); v = e.parse ("to_i(1)*to_i(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_i(1)*to_ui(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_i(1)*to_l(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_i(1)*to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_i(1)*to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_i(1)*2.4").execute (); EXPECT_EQ (v.to_string (), std::string ("2.4")); v = e.parse ("to_i(1)*'2'").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_ui(1)*to_i(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_ui(1)*to_ui(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_ui(1)*to_l(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_ui(1)*to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_ui(1)*to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_ui(1)*2.4").execute (); EXPECT_EQ (v.to_string (), std::string ("2.4")); v = e.parse ("to_ui(1)*'2'").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_l(1)*to_i(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_l(1)*to_ui(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_l(1)*to_l(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_l(1)*to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_l(1)*to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_l(1)*2.4").execute (); EXPECT_EQ (v.to_string (), std::string ("2.4")); v = e.parse ("to_l(1)*'2'").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_ul(1)*to_i(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_ul(1)*to_ui(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_ul(1)*to_l(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_ul(1)*to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_ul(1)*to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("to_ul(1)*2.4").execute (); EXPECT_EQ (v.to_string (), std::string ("2.4")); v = e.parse ("to_ul(1)*'2'").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("1.4*to_i(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2.8")); v = e.parse ("1.4*to_ui(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2.8")); v = e.parse ("1.4*to_l(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2.8")); v = e.parse ("1.4*to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2.8")); v = e.parse ("1.4*to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("2.8")); v = e.parse ("1.2*2.0").execute (); EXPECT_EQ (v.to_string (), std::string ("2.4")); v = e.parse ("'1'*2.4").execute (); EXPECT_EQ (v.to_string (), std::string ("11")); v = e.parse ("'3'*'2'").execute (); EXPECT_EQ (v.to_string (), std::string ("33")); v = e.parse ("to_i(1)+to_i(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_i(1)+to_ui(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_i(1)+to_l(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_i(1)+to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_i(1)+to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_i(1)+2.4").execute (); EXPECT_EQ (v.to_string (), std::string ("3.4")); v = e.parse ("to_i(1)+'2'").execute (); EXPECT_EQ (v.to_string (), std::string ("12")); v = e.parse ("to_ui(1)+to_i(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_ui(1)+to_ui(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_ui(1)+to_l(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_ui(1)+to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_ui(1)+to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_ui(1)+2.4").execute (); EXPECT_EQ (v.to_string (), std::string ("3.4")); v = e.parse ("to_ui(1)+'2'").execute (); EXPECT_EQ (v.to_string (), std::string ("12")); v = e.parse ("to_l(1)+to_i(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_l(1)+to_ui(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_l(1)+to_l(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_l(1)+to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_l(1)+to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_l(1)+2.4").execute (); EXPECT_EQ (v.to_string (), std::string ("3.4")); v = e.parse ("to_l(1)+'2'").execute (); EXPECT_EQ (v.to_string (), std::string ("12")); v = e.parse ("to_ul(1)+to_i(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_ul(1)+to_ui(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_ul(1)+to_l(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_ul(1)+to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_ul(1)+to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("to_ul(1)+2.4").execute (); EXPECT_EQ (v.to_string (), std::string ("3.4")); v = e.parse ("to_ul(1)+'2'").execute (); EXPECT_EQ (v.to_string (), std::string ("12")); v = e.parse ("1.4+to_i(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3.4")); v = e.parse ("1.4+to_ui(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3.4")); v = e.parse ("1.4+to_l(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3.4")); v = e.parse ("1.4+to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3.4")); v = e.parse ("1.4+to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("3.4")); v = e.parse ("1.4+2.4").execute (); EXPECT_EQ (v.to_string (), std::string ("3.8")); v = e.parse ("'1'+2.4").execute (); EXPECT_EQ (v.to_string (), std::string ("12.4")); v = e.parse ("'3'+'2'").execute (); EXPECT_EQ (v.to_string (), std::string ("32")); v = e.parse ("to_i(1)-to_i(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("-1")); v = e.parse ("to_i(1)-to_ui(2)").execute (); if (sizeof(long) == 8) { EXPECT_EQ (v.to_string (), std::string ("18446744073709551615")); } else { EXPECT_EQ (v.to_string (), std::string ("4294967295")); } v = e.parse ("to_i(1)-to_l(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("-1")); v = e.parse ("to_i(1)-to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("18446744073709551615")); v = e.parse ("to_i(1)-to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("18446744073709551615")); v = e.parse ("to_i(1)-2.4").execute (); EXPECT_EQ (v.to_string (), std::string ("-1.4")); v = e.parse ("to_i(1)-'2'").execute (); EXPECT_EQ (v.to_string (), std::string ("-1")); v = e.parse ("to_ui(1)-to_i(2)").execute (); if (sizeof(long) == 8) { EXPECT_EQ (v.to_string (), std::string ("18446744073709551615")); } else { EXPECT_EQ (v.to_string (), std::string ("4294967295")); } v = e.parse ("to_ui(1)-to_ui(2)").execute (); if (sizeof(long) == 8) { EXPECT_EQ (v.to_string (), std::string ("18446744073709551615")); } else { EXPECT_EQ (v.to_string (), std::string ("4294967295")); } v = e.parse ("to_ui(1)-to_l(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("-1")); v = e.parse ("to_ui(1)-to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("18446744073709551615")); v = e.parse ("to_ui(1)-to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("18446744073709551615")); v = e.parse ("to_ui(1)-2.4").execute (); EXPECT_EQ (v.to_string (), std::string ("-1.4")); v = e.parse ("to_ui(1)-'2'").execute (); if (sizeof(long) == 8) { EXPECT_EQ (v.to_string (), std::string ("18446744073709551615")); } else { EXPECT_EQ (v.to_string (), std::string ("4294967295")); } v = e.parse ("to_l(1)-to_i(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("-1")); v = e.parse ("to_l(1)-to_ui(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("-1")); v = e.parse ("to_l(1)-to_l(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("-1")); v = e.parse ("to_l(1)-to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("18446744073709551615")); v = e.parse ("to_l(1)-to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("18446744073709551615")); v = e.parse ("to_l(1)-2.4").execute (); EXPECT_EQ (v.to_string (), std::string ("-1.4")); v = e.parse ("to_l(1)-'2'").execute (); EXPECT_EQ (v.to_string (), std::string ("-1")); v = e.parse ("to_ul(1)-to_i(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("18446744073709551615")); v = e.parse ("to_ul(1)-to_ui(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("18446744073709551615")); v = e.parse ("to_ul(1)-to_l(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("18446744073709551615")); v = e.parse ("to_ul(1)-to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("18446744073709551615")); v = e.parse ("to_ul(1)-to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("18446744073709551615")); v = e.parse ("to_ul(1)-2.4").execute (); EXPECT_EQ (v.to_string (), std::string ("-1.4")); v = e.parse ("to_ul(1)-'2'").execute (); EXPECT_EQ (v.to_string (), std::string ("18446744073709551615")); v = e.parse ("1.4-to_i(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("-0.6")); v = e.parse ("1.4-to_ui(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("-0.6")); v = e.parse ("1.4-to_l(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("-0.6")); v = e.parse ("1.4-to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("-0.6")); v = e.parse ("1.4-to_ul(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("-0.6")); v = e.parse ("1.4-2.4").execute (); EXPECT_EQ (v.to_string (), std::string ("-1")); v = e.parse ("'1'-2.4").execute (); EXPECT_EQ (v.to_string (), std::string ("-1.4")); v = e.parse ("'3'-'2'").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("[1,2,3]").execute (); EXPECT_EQ (v.to_string (), std::string ("1,2,3")); v = e.parse ("1?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("false?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("nil?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("true?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("'a'+'x'").execute (); EXPECT_EQ (v.to_string (), std::string ("ax")); v = e.parse ("'a'*4").execute (); EXPECT_EQ (v.to_string (), std::string ("aaaa")); } class BoxClassClass : public tl::VariantUserClassBase, private tl::EvalClass { public: virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector &args) const; virtual void *create () const { tl_assert (false); } virtual void destroy (void *) const { tl_assert (false); } virtual bool equal (const void *, const void *) const { tl_assert (false); } virtual bool less (const void *, const void *) const { tl_assert (false); } virtual void *clone (const void *) const { tl_assert (false); } virtual void assign (void *, const void *) const { tl_assert (false); } virtual std::string to_string (const void *) const { tl_assert (false); } virtual void read (void *, tl::Extractor &) const { } virtual const char *name () const { return "Box"; } virtual unsigned int type_code () const { return 0; } virtual const tl::EvalClass *eval_cls () const { return this; } virtual bool is_const () const { return false; } virtual bool is_ref () const { return false; } virtual void *deref_proxy (tl::Object *) const { return 0; } virtual const gsi::ClassBase*gsi_cls() const { return 0; } static BoxClassClass instance; }; BoxClassClass BoxClassClass::instance; class BoxClass : public tl::VariantUserClassImpl, private tl::EvalClass { public: virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector &args) const; virtual const tl::EvalClass *eval_cls () const { return this; } static BoxClass instance; }; BoxClass BoxClass::instance; void BoxClass::execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector &args) const { if (method == "width") { out = object.to_user ().width (); } else if (method == "height") { out = object.to_user ().height (); } else if (method == "&") { tl_assert (args.size () == 1); out = tl::Variant (new db::Box (object.to_user () & args[0].to_user ()), &BoxClass::instance, true); } else if (method == "to_s") { out = object.to_user ().to_string (); } else if (method == "is_box") { out = true; } else if (method == "is_edge") { out = false; } else { throw tl::NoMethodError("Box", method, context); } } void BoxClassClass::execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant & /*object*/, const std::string &method, const std::vector &args) const { if (method == "new") { out = tl::Variant (new db::Box (args[0].to_long(), args[1].to_long(), args[2].to_long(), args[3].to_long()), &BoxClass::instance, true); } else { throw tl::NoMethodError("Box", method, context); } } class EdgeClassClass : public tl::VariantUserClassBase, private tl::EvalClass { public: virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector &args) const; virtual void *create () const { tl_assert (false); } virtual void destroy (void *) const { tl_assert (false); } virtual bool equal (const void *, const void *) const { tl_assert (false); } virtual bool less (const void *, const void *) const { tl_assert (false); } virtual void *clone (const void *) const { tl_assert (false); } virtual void assign (void *, const void *) const { tl_assert (false); } virtual std::string to_string (const void *) const { tl_assert (false); } virtual void read (void *, tl::Extractor &) const { } virtual const char *name () const { return "Edge"; } virtual unsigned int type_code () const { return 0; } virtual const tl::EvalClass *eval_cls () const { return this; } virtual bool is_const () const { return false; } virtual bool is_ref () const { return false; } virtual void *deref_proxy (tl::Object *) const { return 0; } virtual const gsi::ClassBase*gsi_cls() const { return 0; } static EdgeClassClass instance; }; EdgeClassClass EdgeClassClass::instance; class EdgeClass : public tl::VariantUserClassImpl, private tl::EvalClass { public: virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector &args) const { if (method == "dx") { out = object.to_user ().dx (); } else if (method == "dy") { out = object.to_user ().dy (); } else if (method == "to_s") { out = object.to_user ().to_string (); } else if (method == "is_box") { out = false; } else if (method == "is_edge") { out = true; } else if (method == "*") { out.set_user (new db::Edge (object.to_user () * args [0].to_double ()), object.user_cls (), true); } else { throw tl::NoMethodError("Edge", method, context); } } virtual const tl::EvalClass *eval_cls () const { return this; } static EdgeClass instance; }; EdgeClass EdgeClass::instance; void EdgeClassClass::execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant & /*object*/, const std::string &method, const std::vector &args) const { if (method == "new") { out = tl::Variant (new db::Edge (args[0].to_long(), args[1].to_long(), args[2].to_long(), args[3].to_long()), &EdgeClass::instance, true); } else { throw tl::NoMethodError("Edge", method, context); } } // basics: custom objects TEST(1b) { tl::Eval e; tl::Variant v; e.set_var ("XBox", tl::Variant ((db::Box *) 0, &BoxClassClass::instance, false)); e.set_var ("XEdge", tl::Variant ((db::Edge *) 0, &EdgeClassClass::instance, false)); e.set_var ("b", tl::Variant (new db::Box (0, 10, 20, 40), &BoxClass::instance, true)); e.set_var ("e", tl::Variant (new db::Edge (0, 10, 20, 40), &EdgeClass::instance, true)); v = e.parse ("b.width").execute (); EXPECT_EQ (v.to_string (), std::string ("20")); v = e.parse ("b.width()").execute (); EXPECT_EQ (v.to_string (), std::string ("20")); v = e.parse ("b.height").execute (); EXPECT_EQ (v.to_string (), std::string ("30")); v = e.parse ("e.dx").execute (); EXPECT_EQ (v.to_string (), std::string ("20")); v = e.parse ("e.dy").execute (); EXPECT_EQ (v.to_string (), std::string ("30")); v = e.parse ("e.to_s").execute (); EXPECT_EQ (v.to_string (), std::string ("(0,10;20,40)")); v = e.parse ("(e*5).to_s").execute (); EXPECT_EQ (v.to_string (), std::string ("(0,50;100,200)")); v = e.parse ("(e.*(5)).to_s").execute (); EXPECT_EQ (v.to_string (), std::string ("(0,50;100,200)")); v = e.parse ("b.is_box").execute (); EXPECT_EQ (v.to_string (), std::string ("true")); v = e.parse ("b.is_edge").execute (); EXPECT_EQ (v.to_string (), std::string ("false")); v = e.parse ("XBox.new(1,2,3,4).is_box").execute (); EXPECT_EQ (v.to_string (), std::string ("true")); v = e.parse ("XBox.new(1,2,3,4).is_edge").execute (); EXPECT_EQ (v.to_string (), std::string ("false")); v = e.parse ("XBox.new(0, 0, 100, 200) & XBox.new(10, 10, 110, 210)").execute (); EXPECT_EQ (v.to_string (), std::string ("(10,10;100,200)")); v = e.parse ("XBox.new(0, 0, 100, 200) & XBox.new(1000, 1000, 1010, 1010)").execute (); EXPECT_EQ (v.to_string (), std::string ("()")); v = e.parse ("e.is_edge").execute (); EXPECT_EQ (v.to_string (), std::string ("true")); v = e.parse ("e.is_box").execute (); EXPECT_EQ (v.to_string (), std::string ("false")); v = e.parse ("XBox.new(1,2,3,4).width").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("XBox.new(1,2,3,4).width==2").execute (); EXPECT_EQ (v.to_string (), std::string ("true")); v = e.parse ("XBox.new(1,2,3,4).width==3").execute (); EXPECT_EQ (v.to_string (), std::string ("false")); } // to_bool TEST(2) { tl::Eval e; tl::Variant v; v = e.parse ("1?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("false?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("nil?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("[]?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("[1]?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("'1'?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("''?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); } // to_double TEST(3) { tl::Eval e; tl::Variant v; v = e.parse ("[1,2,3]/2").execute (); EXPECT_EQ (v.to_string (), std::string ("1.5")); } // functions TEST(5) { tl::Eval e; tl::Variant v; v = e.parse ("pow(sin(M_PI/4),2)").execute (); EXPECT_EQ (v.to_string (), std::string ("0.5")); v = e.parse ("sinh(log(2))").execute (); EXPECT_EQ (v.to_string (), std::string ("0.75")); v = e.parse ("cos(0.0)").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("cos(M_PI/3)").execute (); EXPECT_EQ (v.to_string (), std::string ("0.5")); v = e.parse ("cosh(log(2))").execute (); EXPECT_EQ (v.to_string (), std::string ("1.25")); v = e.parse ("tan(M_PI/4)").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("tanh(log(2))").execute (); EXPECT_EQ (v.to_string (), std::string ("0.6")); v = e.parse ("log(M_E)").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("exp(log(1.5))").execute (); EXPECT_EQ (v.to_string (), std::string ("1.5")); v = e.parse ("log10(0.1)").execute (); EXPECT_EQ (v.to_string (), std::string ("-1")); v = e.parse ("floor(0.5)").execute (); EXPECT_EQ (v.to_string (), std::string ("0")); v = e.parse ("floor(-0.5)").execute (); EXPECT_EQ (v.to_string (), std::string ("-1")); v = e.parse ("floor(1.5)").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("round(1.5)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("round(1.6)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("round(1.4)").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("ceil(0.5)").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("ceil(-0.5)").execute (); EXPECT_EQ (v.to_string () == std::string ("-0") || v.to_string () == std::string ("0"), true); v = e.parse ("ceil(1.5)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("sqrt(4)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("abs('-2')").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("abs(-1234567)").execute (); EXPECT_EQ (v.to_string (), std::string ("1234567")); v = e.parse ("abs(-0.2)").execute (); EXPECT_EQ (v.to_string (), std::string ("0.2")); v = e.parse ("acos(0)/M_PI").execute (); EXPECT_EQ (v.to_string (), std::string ("0.5")); // v = e.parse ("acosh(cosh(1.0))").execute (); // EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("asin(1)/M_PI").execute (); EXPECT_EQ (v.to_string (), std::string ("0.5")); // v = e.parse ("asinh(sinh(1.0))").execute (); // EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("atan(1)/M_PI").execute (); EXPECT_EQ (v.to_string (), std::string ("0.25")); // v = e.parse ("atanh(tanh(1))").execute (); // EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("min(1,6)").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("min(2,0,5)").execute (); EXPECT_EQ (v.to_string (), std::string ("0")); v = e.parse ("max(1,6)").execute (); EXPECT_EQ (v.to_string (), std::string ("6")); v = e.parse ("max(2,0,5)").execute (); EXPECT_EQ (v.to_string (), std::string ("5")); v = e.parse ("atan2(2,2)/M_PI").execute (); EXPECT_EQ (v.to_string (), std::string ("0.25")); v = e.parse ("to_i(6)/to_i(4)").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("to_i('6')/to_i('4')").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("to_f('6')/to_f('4')").execute (); EXPECT_EQ (v.to_string (), std::string ("1.5")); v = e.parse ("is_string('6')?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("is_string(6)?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("is_numeric('6')?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("is_numeric('a')?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("is_numeric(6)?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("is_array('6')?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("is_array(6)?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("is_array([])?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("is_nil([])?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("is_nil(nil)?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); } // string functions TEST(6) { tl::Eval e; tl::Variant v; v = e.parse ("gsub('bcabc','b','xx')").execute (); EXPECT_EQ (v.to_string (), std::string ("xxcaxxc")); v = e.parse ("gsub('abcabc','b','xx')").execute (); EXPECT_EQ (v.to_string (), std::string ("axxcaxxc")); v = e.parse ("sub('abcabc','b','xx')").execute (); EXPECT_EQ (v.to_string (), std::string ("axxcabc")); v = e.parse ("sub('bcabc','b','xx')").execute (); EXPECT_EQ (v.to_string (), std::string ("xxcabc")); v = e.parse ("find('abcabc','b')").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("rfind('abcabc','b')").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("find('abcabc','x')").execute (); EXPECT_EQ (v.to_string (), std::string ("nil")); v = e.parse ("rfind('abcabc','c')").execute (); EXPECT_EQ (v.to_string (), std::string ("0")); v = e.parse ("rfind('abcabc','x')").execute (); EXPECT_EQ (v.to_string (), std::string ("nil")); v = e.parse ("len('abcabc')").execute (); EXPECT_EQ (v.to_string (), std::string ("6")); v = e.parse ("len([])").execute (); EXPECT_EQ (v.to_string (), std::string ("0")); v = e.parse ("len([1,2,3])").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("substr('abcabc',2)").execute (); EXPECT_EQ (v.to_string (), std::string ("cabc")); v = e.parse ("substr('abcabc',2,1)").execute (); EXPECT_EQ (v.to_string (), std::string ("c")); v = e.parse ("substr('abcabc',8,1)").execute (); EXPECT_EQ (v.to_string (), std::string ("")); v = e.parse ("substr('abcabc',3,-1)").execute (); EXPECT_EQ (v.to_string (), std::string ("")); v = e.parse ("substr('abcabc',3,8)").execute (); EXPECT_EQ (v.to_string (), std::string ("abc")); v = e.parse ("substr('abcabc',6,8)").execute (); EXPECT_EQ (v.to_string (), std::string ("")); v = e.parse ("substr('abcabc',7,8)").execute (); EXPECT_EQ (v.to_string (), std::string ("")); v = e.parse ("join([],':')").execute (); EXPECT_EQ (v.to_string (), std::string ("")); v = e.parse ("item([1,2],-1)").execute (); EXPECT_EQ (v.to_string (), std::string ("nil")); v = e.parse ("item([1,2],0)").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("item([1,2],1)").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("item([1,2],2)").execute (); EXPECT_EQ (v.to_string (), std::string ("nil")); v = e.parse ("split('',':')").execute (); EXPECT_EQ (v.to_string (), std::string ("")); v = e.parse ("split('1:2',':')").execute (); EXPECT_EQ (v.to_string (), std::string ("1,2")); v = e.parse ("env('HJASK')").execute (); EXPECT_EQ (v.to_string (), std::string ("nil")); v = e.parse ("env('PATH')").execute (); EXPECT_EQ (v.to_string (), std::string (getenv ("PATH"))); v = e.parse ("absolute_path('./x.gds')").execute (); // EXPECT_EQ (v.to_string (), std::string ()); // not universal v = e.parse ("absolute_file_path('./x.gds')").execute (); // EXPECT_EQ (v.to_string (), std::string ()); // not universal v = e.parse ("path('../irgendwas/file.tar.gz')").execute (); EXPECT_EQ (v.to_string (), std::string ("../irgendwas")); v = e.parse ("basename('../irgendwas/file.tar.gz')").execute (); EXPECT_EQ (v.to_string (), std::string ("file")); v = e.parse ("extension('../irgendwas/file.tar.gz')").execute (); EXPECT_EQ (v.to_string (), std::string ("tar.gz")); v = e.parse ("file_exists('x.gds')?1:0").execute (); // EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("is_dir('x.gds')?1:0").execute (); EXPECT_EQ (v.to_string (), std::string ("0")); v = e.parse ("combine('.', 'x.gds')").execute (); // EXPECT_EQ (v.to_string (), std::string ("./x.gds")); // not universal v = e.parse ("is_dir('.')?1:0").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("sprintf('%g %e %f',M_PI,M_PI*1e6,M_PI*0.001)").execute (); EXPECT_EQ (v.to_string (), tl::sprintf("%g %e %f", M_PI, M_PI*1e6, M_PI*0.001)); v = e.parse ("sprintf('%g %e %f',M_PI*1e6,M_PI*1e6,M_PI*1e6)").execute (); EXPECT_EQ (v.to_string (), tl::sprintf("%g %e %f", M_PI*1e6, M_PI*1e6, M_PI*1e6)); v = e.parse ("sprintf('%-15g %015.8e %15.12f %g',M_PI,M_PI*1e6,M_PI*0.001,M_PI)").execute (); EXPECT_EQ (v.to_string (), tl::sprintf("%-15g %015.8e %15.12f %g", M_PI, M_PI*1e6, M_PI*0.001,M_PI)); v = e.parse ("sprintf('%-5s %5s %x %u %d (%s)','a','b',1234,2345,3456)").execute (); EXPECT_EQ (v.to_string (), tl::sprintf("%-5s %5s %x %u %d ()", "a", "b", 1234, 2345, 3456)); std::string msg; try { v = e.parse ("error('My error')").execute (); } catch (tl::Exception &ex) { msg = ex.msg(); } EXPECT_EQ (msg, std::string ("My error")); } // compare ops TEST(7) { tl::Eval e; tl::Variant v; v = e.parse ("1==2?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("1==1?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("1!=1?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("1!=2?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("1<1?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("1<2?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("2<1?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("1<=1?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("1<=2?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("2<=1?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("1>1?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("1>2?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("2>1?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("1>=1?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("1>=2?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("2>=1?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("1+1==2?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("2*3-4==2?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("2*3-3==2?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); } // boolean ops TEST(8) { tl::Eval e; tl::Variant v; bool t; v = e.parse ("1==2?log('a'):log(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("0.69314718056")); t = false; try { v = e.parse ("1==1?log('a'):log(2)").execute (); EXPECT_EQ (v.to_string (), std::string ("abc")); } catch (tl::EvalError) { t = true; } EXPECT_EQ (t, true); t = false; try { v = e.parse ("1==2||log('a')").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); } catch (tl::EvalError) { t = true; } EXPECT_EQ (t, true); v = e.parse ("1==1||log('a')").execute (); EXPECT_EQ (v.to_string (), std::string ("true")); v = e.parse ("1==2||1==1||log('a')").execute (); EXPECT_EQ (v.to_string (), std::string ("true")); t = false; try { v = e.parse ("1==1&&log('a')").execute (); EXPECT_EQ (v.to_string (), std::string ("false")); } catch (tl::EvalError) { t = true; } EXPECT_EQ (t, true); v = e.parse ("1==2&&log('a')").execute (); EXPECT_EQ (v.to_string (), std::string ("false")); v = e.parse ("1==1&&1==2&&log('a')").execute (); EXPECT_EQ (v.to_string (), std::string ("false")); } // shift ops TEST(9) { tl::Eval e; tl::Variant v; v = e.parse ("1<<2+3").execute (); EXPECT_EQ (v.to_string (), std::string ("32")); v = e.parse ("8*8>>2+3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); } // bitwise ops TEST(10) { tl::Eval e; tl::Variant v; v = e.parse ("(1<<2)|(1<<4)").execute (); EXPECT_EQ (v.to_string (), std::string ("20")); v = e.parse ("31&63").execute (); EXPECT_EQ (v.to_string (), std::string ("31")); v = e.parse ("31^63").execute (); EXPECT_EQ (v.to_string (), std::string ("32")); } // unary ops TEST(11) { tl::Eval e; tl::Variant v; v = e.parse ("!(1==2)?2:3").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("~1").execute (); EXPECT_EQ (v.to_string (), std::string ("-2")); v = e.parse ("-1").execute (); EXPECT_EQ (v.to_string (), std::string ("-1")); v = e.parse ("--1").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); } class F0 : public tl::EvalFunction { public: void execute (const tl::ExpressionParserContext &, tl::Variant &out, const std::vector &) const { out = tl::Variant (17); } }; class F1 : public tl::EvalFunction { public: void execute (const tl::ExpressionParserContext &, tl::Variant &out, const std::vector &vv) const { out = tl::Variant (vv[0].to_long() + 1); } }; class F2 : public tl::EvalFunction { public: void execute (const tl::ExpressionParserContext &, tl::Variant &out, const std::vector &vv) const { out = tl::Variant (vv[0].to_long() + 2); } }; class F3 : public tl::EvalFunction { public: void execute (const tl::ExpressionParserContext &, tl::Variant &out, const std::vector &vv) const { out = tl::Variant (vv[0].to_long() + 3); } }; // variables and functions TEST(12) { tl::Eval e, ee; e.set_global_var ("GV", tl::Variant("gg")); e.set_var ("L", tl::Variant((long) 89)); ee.set_var ("L", tl::Variant((long) 123)); e.define_global_function ("f0", new F0()); e.define_global_function ("fg", new F1()); e.define_function ("fl", new F2()); ee.define_function ("fl", new F3()); tl::Variant v; v = e.parse ("f0").execute (); EXPECT_EQ (v.to_string (), std::string ("17")); v = e.parse ("f0()").execute (); EXPECT_EQ (v.to_string (), std::string ("17")); v = e.parse ("GV+(L+1)").execute (); EXPECT_EQ (v.to_string (), std::string ("gg90")); v = ee.parse ("GV+(L+1)").execute (); EXPECT_EQ (v.to_string (), std::string ("gg124")); v = e.parse ("to_s(fg(17))+fl(L)").execute (); EXPECT_EQ (v.to_string (), std::string ("1891")); e.define_function ("fl", new F3()); v = e.parse ("to_s(fg(17))+fl(L)").execute (); EXPECT_EQ (v.to_string (), std::string ("1892")); v = ee.parse ("to_s(fg(17))+fl(L)").execute (); EXPECT_EQ (v.to_string (), std::string ("18126")); } // interpolation TEST(13) { tl::Eval e, ee; e.set_var ("L", tl::Variant((long) 89)); ee.set_var ("L", tl::Variant((long) 123)); EXPECT_EQ (e.interpolate("A$L B$(L+100)C"), std::string ("A89 B189C")); EXPECT_EQ (ee.interpolate("123*11=$(L*11)."), std::string ("123*11=1353.")); } // assignment TEST(14) { tl::Eval e; tl::Variant v; v = e.parse ("var x=1; x=x+1").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("x").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("x=x*2").execute (); EXPECT_EQ (v.to_string (), std::string ("4")); v = e.parse ("x").execute (); EXPECT_EQ (v.to_string (), std::string ("4")); v = e.parse ("var y=x==4; y").execute (); EXPECT_EQ (v.to_string (), std::string ("true")); } // index TEST(15) { tl::Eval e; tl::Variant v; v = e.parse ("var x=[1,2,3]; x[1]").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("var x=[1,2,3]; x.size").execute (); EXPECT_EQ (v.to_string (), std::string ("3")); v = e.parse ("var x=[1,2,3]; x[6]").execute (); EXPECT_EQ (v.to_string (), std::string ("nil")); v = e.parse ("var x=[1,2,3]; x[1]=5; x").execute (); EXPECT_EQ (v.to_string (), std::string ("1,5,3")); v = e.parse ("var x=[1,2,3]; x.push('A'); x").execute (); EXPECT_EQ (v.to_string (), std::string ("1,2,3,A")); v = e.parse ("var x={1=>'A','B'=>5}; x[1]").execute (); EXPECT_EQ (v.to_string (), std::string ("A")); v = e.parse ("var x={1=>'A','B'=>5}; x.keys").execute (); EXPECT_EQ (v.to_string (), std::string ("1,B")); v = e.parse ("var x={1=>'A','B'=>5}; x.values").execute (); EXPECT_EQ (v.to_string (), std::string ("A,5")); v = e.parse ("var x={1=>'A','B'=>5}; x['B']").execute (); EXPECT_EQ (v.to_string (), std::string ("5")); v = e.parse ("var x={1=>'A','B'=>5}; x[0]").execute (); EXPECT_EQ (v.to_string (), std::string ("nil")); v = e.parse ("{1=>'A','B'=>5}['B']").execute (); EXPECT_EQ (v.to_string (), std::string ("5")); v = e.parse ("var x={1=>'A','B'=>5}; x[1]=5; x").execute (); EXPECT_EQ (v.to_string (), std::string ("1=>5,B=>5")); v = e.parse ("var x={1=>'A','B'=>5}; x.size").execute (); EXPECT_EQ (v.to_string (), std::string ("2")); v = e.parse ("var x={1=>'A','B'=>5}; x.insert(17, 3); x").execute (); EXPECT_EQ (v.to_string (), std::string ("1=>A,17=>3,B=>5")); } // match/nomatch TEST(16) { tl::Eval e; tl::Variant v; v = e.parse ("'abc' ~ '*a*'").execute (); EXPECT_EQ (v.to_string (), std::string ("true")); v = e.parse ("'abc' ~ '(*)a(*)'").execute (); EXPECT_EQ (v.to_string (), std::string ("true")); v = e.parse ("$1+'.'+$2+'.'+$3").execute (); EXPECT_EQ (v.to_string (), std::string (".bc.nil")); v = e.parse ("'abc' ~ 'b*'").execute (); EXPECT_EQ (v.to_string (), std::string ("false")); v = e.parse ("'abc' !~ '*a*'").execute (); EXPECT_EQ (v.to_string (), std::string ("false")); v = e.parse ("'abc' !~ 'b*'").execute (); EXPECT_EQ (v.to_string (), std::string ("true")); } // ref layout TEST(17) { db::Layout l; l.dbu (0.05); l.insert_layer (db::LayerProperties (1, 15)); l.insert_layer (db::LayerProperties ("name")); l.add_cell ("c1"); l.add_cell ("c2"); tl::Eval e, ee; db::LayoutContextHandler ctx (&l); e.set_ctx_handler (&ctx); tl::Variant v; bool error = false; v = e.parse ("1um").execute (); EXPECT_EQ (v.to_string (), std::string ("20")); v = e.parse ("1um2").execute (); EXPECT_EQ (v.to_string (), std::string ("400")); v = e.parse ("1micron").execute (); EXPECT_EQ (v.to_string (), std::string ("20")); v = e.parse ("1micron2").execute (); EXPECT_EQ (v.to_string (), std::string ("400")); v = e.parse ("1mic").execute (); EXPECT_EQ (v.to_string (), std::string ("20")); v = e.parse ("1mic2").execute (); EXPECT_EQ (v.to_string (), std::string ("400")); v = e.parse ("1m").execute (); EXPECT_EQ (v.to_string (), std::string ("20000000")); v = e.parse ("1m2/1e14").execute (); EXPECT_EQ (v.to_string (), std::string ("4")); v = e.parse ("1mm").execute (); EXPECT_EQ (v.to_string (), std::string ("20000")); v = e.parse ("1mm2").execute (); EXPECT_EQ (v.to_string (), std::string ("400000000")); v = e.parse ("50nm").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("<1/15>").execute (); EXPECT_EQ (v.to_string (), std::string ("0")); v = e.parse ("< name >").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("<'n' + 'ame'>").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("<>").execute (); EXPECT_EQ (v.to_string (), std::string ("0")); v = e.parse ("<< c2 >>").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); v = e.parse ("<<'c' + '2'>>").execute (); EXPECT_EQ (v.to_string (), std::string ("1")); error = true; try { v = e.parse ("60nm").execute (); // not a multiple of DBU error = false; } catch (...) { } EXPECT_EQ (error, true); error = true; try { v = ee.parse ("1 um").execute (); error = false; } catch (...) { } EXPECT_EQ (error, true); error = true; try { v = e.parse ("<1/1>").execute (); error = false; } catch (...) { } EXPECT_EQ (error, true); error = true; try { v = ee.parse ("<1/15>").execute (); error = false; } catch (...) { } EXPECT_EQ (error, true); error = true; try { v = ee.parse ("<>").execute (); error = false; } catch (...) { } EXPECT_EQ (error, true); error = true; try { v = e.parse ("<>").execute (); error = false; } catch (...) { } EXPECT_EQ (error, true); } // polymorphic functions TEST(18) { tl::Eval e; tl::Variant v; e.parse ("var tr=Trans.new(1,false,Vector.new(10,20))").execute (); e.parse ("var a=Point.new(1,2)").execute (); e.parse ("var b=Point.new(11,22)").execute (); v = e.parse ("var i=CellInstArray.new(17,tr,a,b,100,200); i.to_s()").execute (); EXPECT_EQ (v.to_string (), std::string ("#17 r90 10,20 [1,2*100;11,22*200]")); v = e.parse ("var i=CellInstArray.new(17,tr,a,b,100,200); i.is_complex()").execute (); EXPECT_EQ (v.to_string (), std::string ("false")); } // comments TEST(19) { tl::Eval e; e.parse ("var tr=Trans.new(1,false,Vector.new(10,20))").execute (); e.parse ("var a=Point.new(1,2)").execute (); e.parse ("var b=Point.new(11,22)").execute (); tl::Variant v; v = e.parse ("# A comment\nvar i=CellInstArray.new(17,tr,a,b,100,200); i.to_s(); # A final comment").execute (); EXPECT_EQ (v.to_string (), std::string ("#17 r90 10,20 [1,2*100;11,22*200]")); }