3#include <cgv/utils/convert.h>
4#include <cgv/utils/tokenizer.h>
5#include <cgv/utils/file.h>
6#include <cgv/utils/dir.h>
17 func_type::func_type(
unsigned _i,
unsigned _j, ph_processor* _ph_proc, namespace_info* _ns)
18 : block_begin(_i), block_end(_j), ph_proc(_ph_proc), ns(_ns)
23 variant::variant() : vt(UNDEF_VALUE), reference_value(0) {}
30 case BOOL_VALUE: bool_value = v.bool_value;
break;
31 case INT_VALUE: int_value = v.int_value;
break;
32 case DOUBLE_VALUE: dbl_value = v.dbl_value;
break;
33 case STRING_VALUE: string_value =
new std::string(*v.string_value);
break;
34 case REFERENCE_VALUE: reference_value = v.reference_value;
break;
35 case NAME_VALUE: name_value =
new std::string(*v.name_value);
break;
36 case LIST_VALUE: list_value =
new list_type(*v.list_value);
break;
37 case MAP_VALUE: map_value =
new map_type(*v.map_value);
break;
38 case FUNC_VALUE: func_value =
new func_type(*v.func_value);
break;
46 variant::variant(
const std::string& v) : vt(STRING_VALUE), string_value(new std::string(v)) {}
52 name_value =
new std::string(v);
69 case STRING_VALUE:
delete string_value; string_value = 0;
break;
70 case REFERENCE_VALUE: reference_value = 0;
break;
71 case NAME_VALUE:
delete name_value; name_value = 0;
break;
72 case LIST_VALUE:
delete list_value; list_value = 0;
break;
73 case MAP_VALUE:
delete map_value; map_value = 0;
break;
74 case FUNC_VALUE:
delete func_value; func_value = 0;
break;
88 case BOOL_VALUE: bool_value = v.bool_value;
break;
89 case INT_VALUE: int_value = v.int_value;
break;
90 case DOUBLE_VALUE: dbl_value = v.dbl_value;
break;
91 case STRING_VALUE: string_value =
new std::string(*v.string_value);
break;
92 case REFERENCE_VALUE: reference_value = v.reference_value;
break;
93 case NAME_VALUE: name_value =
new std::string(*v.name_value);
break;
94 case LIST_VALUE: list_value =
new list_type(*v.list_value);
break;
95 case MAP_VALUE: map_value =
new map_type(*v.map_value);
break;
96 case FUNC_VALUE: func_value =
new func_type(*v.func_value);
break;
102 bool variant::is_unary_applicable(OperatorType ot)
123 bool variant::unary_check_defined(OperatorType ot)
137 void variant::apply_unary(OperatorType ot)
144 set_int((
int)
get_str().size());
152 set_bool(cgv::utils::file::exists(
get_str()) || cgv::utils::dir::exists(
get_str()));
168 set_str(to_lower(*
ref_value().string_value));
178 namespace_info* cns = get_current_namespace();
179 namespace_info* ns = cns;
180 while (ns->environment_ns)
181 ns = ns->environment_ns;
182 set_current_namespace(ns);
187 set_current_namespace(cns);
197 if (has_child_namespace()) {
198 goto_child_namespace();
203 goto_parent_namespace();
210 bool variant::is_binary_applicable(OperatorType ot,
const variant& v2)
234 return !
is_str() && !
is_list() && !
is_map() && !v2.is_str() && !v2.is_list() && !v2.is_map();
236 return !
is_list() && !
is_map() && !v2.is_list() && !v2.is_map();
240 case OT_UNEQUAL_TYPE:
243 case OT_LESS_OR_EQUAL:
244 case OT_GREATER_OR_EQUAL:
247 return !
is_list() && !
is_map() && !v2.is_list() && !v2.is_map();
250 return !
is_map() && !v2.is_list() && !v2.is_map() && (!v2.is_str() ||
is_str());
253 (
is_str() && (v2.is_bool() || v2.is_int() || v2.is_double() || v2.is_str())) ||
257 (
is_map() && v2.is_list());
259 return is_map() && (v2.is_name() || v2.is_str());
265 bool variant::binary_check_defined(OperatorType ot,
const variant& v2)
272 if (ot == OT_EQUAL_TYPE || ot == OT_UNEQUAL_TYPE)
274 if (ot == OT_BINARY_MAP)
276 if (v2.is_undefined())
278 if (ot >= OT_ASSIGN && ot <= OT_ASSIGN_RSH)
283 void variant::apply_binary(OperatorType ot,
const variant& v2)
299 ref_value().ref_double() += v2.get_double();
305 ref_value().ref_double() -= v2.get_double();
311 ref_value().ref_double() *= v2.get_double();
317 ref_value().ref_double() /= v2.get_double();
340 set_bool(
get_bool() || v2.get_bool());
343 set_bool(
get_bool() && v2.get_bool());
346 if (
is_int() && v2.is_int())
347 set_int(
get_int() | v2.get_int());
349 set_bool(
get_bool() || v2.get_bool());
352 if (
is_int() && v2.is_int())
353 set_int(
get_int() & v2.get_int());
355 set_bool(
get_bool() && v2.get_bool());
358 if (
is_int() && v2.is_int())
359 set_int(
get_int() ^ v2.get_int());
361 set_bool(
get_bool() ^ v2.get_bool());
364 set_int(
get_int() << v2.get_int());
367 set_int(
get_int() >> v2.get_int());
372 for (
unsigned int i = 0; i < v2.get_size(); ++i) {
374 if (tmp.is_binary_applicable(OT_EQUAL, v2.get_element(i))) {
375 tmp.apply_binary(OT_EQUAL, v2.get_element(i));
376 if (tmp.get_bool()) {
388 case DOUBLE_VALUE: set_bool(
get_double() < v2.get_double());
break;
389 case STRING_VALUE: set_bool(
get_str() < v2.get_str());
break;
398 case DOUBLE_VALUE: set_bool(
get_double() > v2.get_double());
break;
399 case STRING_VALUE: set_bool(
get_str() > v2.get_str());
break;
403 case OT_LESS_OR_EQUAL:
407 case DOUBLE_VALUE: set_bool(
get_double() <= v2.get_double());
break;
408 case STRING_VALUE: set_bool(
get_str() <= v2.get_str());
break;
412 case OT_GREATER_OR_EQUAL:
416 case DOUBLE_VALUE: set_bool(
get_double() >= v2.get_double());
break;
417 case STRING_VALUE: set_bool(
get_str() >= v2.get_str());
break;
425 case DOUBLE_VALUE: set_bool(
get_double() == v2.get_double());
break;
426 case STRING_VALUE: set_bool(
get_str() == v2.get_str());
break;
434 case DOUBLE_VALUE: set_bool(
get_double() != v2.get_double());
break;
435 case STRING_VALUE: set_bool(
get_str() != v2.get_str());
break;
442 case OT_UNEQUAL_TYPE:
448 std::size_t p =
get_str().find_first_of(v2.get_str());
449 if (p != std::string::npos)
453 int idx = v2.get_int();
454 if (idx >= (
int)
get_str().size())
457 set_str(
get_str().substr(v2.get_int()));
461 int idx = v2.get_int();
465 std::vector<variant> l =
get_list();
466 l.erase(l.begin(), l.begin() + idx);
474 set_int(
get_int() + v2.get_int());
480 std::size_t p =
get_str().find_last_of(v2.get_str());
481 if (p != std::string::npos)
482 set_str(
get_str().substr(0, p));
485 int idx = v2.get_int();
486 if (idx >= (
int)
get_str().size())
493 int idx = v2.get_int();
497 std::vector<variant> l =
get_list();
498 for (
int i = 0; i < idx; ++i)
507 set_int(
get_int() - v2.get_int());
512 std::string arg = v2.get_str();
513 if (arg.size() > 3) {
514 std::vector<token> toks;
516 if (toks.size() > 0) {
535 set_int(
get_int() * v2.get_int());
542 set_int(
get_int() / v2.get_int());
545 set_int(
get_int() % v2.get_int());
551 list_type l = v2.get_list();
555 m[l[0].get_str()] = l[1].get_value();
559 for (
unsigned int i = 0; i < l.size(); ++i) {
562 m[l[i].ref_element((
unsigned int)0).get_str()] = l[i].get_element((
unsigned int)1).get_value();
573 set_str(
get_str() + v2.get_str());
576 list_type l = v2.get_list();
583 std::vector<variant> l =
get_list();
584 unsigned int n = v2.get_size();
585 for (
unsigned int i = 0; i < n; ++i)
586 l.push_back(v2.get_element(i).get_value());
591 std::vector<variant> l =
get_list();
592 l.push_back(v2.get_value());
722 return atoi(
get_str().c_str());
737 return get_value().bool_value ? 1.0 : 0.0;
743 return atof(
get_str().c_str());
770 for (
unsigned int i = 0; i < v.
get_size(); ++i) {
788 std::cerr <<
"attemt to access name of non name variant value" << std::endl;
789 static std::string dummy;
793 void variant::set_bool(
bool v)
798 void variant::set_int(
int v)
803 void variant::set_double(
double v)
808 void variant::set_str(
const std::string& v)
813 void variant::set_name(
const std::string& v)
815 *
this =
variant(NAME_VALUE, v);
818 void variant::set_list()
823 void variant::set_list(
const list_type& l)
828 void variant::set_map()
833 void variant::set_map(
const map_type& m)
841 return reference_value;
851 bool& variant::ref_bool()
856 int& variant::ref_int()
861 double& variant::ref_double()
866 std::string& variant::ref_str()
871 variant::list_type& variant::ref_list()
891 if (
vt == DOUBLE_VALUE || v2.
get_type() == DOUBLE_VALUE) {
892 if (
vt != DOUBLE_VALUE)
901 variant::map_type& variant::ref_map()
934 case STRING_VALUE:
return (
unsigned int)
get_value().string_value->size();
935 case LIST_VALUE:
return (
unsigned int)
get_list().size();
936 case MAP_VALUE:
return (
unsigned int)
get_map().size();
949 unsigned N = 0, n = (unsigned)L.size();
950 for (
unsigned i = 0; i < n; ++i)
958 for (map_type::const_iterator i = M.begin(); i != M.end(); ++i)
959 N += i->second.get_total_nr_elements();
971 map_type::iterator mi = ref_map().begin();
972 for (
unsigned int j = 0; j < i; ++j)
976 return ref_list()[i];
982 map_type::const_iterator mi =
get_map().begin();
983 for (
unsigned int j = 0; j < i; ++j)
990 void variant::append_to_list(
const variant& v)
992 ref_list().push_back(v);
995 void variant::prepend_to_list(
const variant& v)
997 ref_list().insert(ref_list().begin(), v);
1000 void variant::pop_back_from_list()
1002 ref_list().pop_back();
1005 void variant::pop_front_from_list()
1007 ref_list().erase(ref_list().begin());
1013 return ref_map()[name];
1014 std::cerr <<
"attemt to get_element of non map variant by name" << std::endl;
1022 map_type& M = ref_map();
1025 std::cerr <<
"attemt to ref_element of non map variant by name" << std::endl;
1033 map_type::const_iterator mi =
get_map().begin();
1034 for (
unsigned int j = 0; j < i; ++j)
1041 ref_map()[name] = v;
1045 std::ostream& operator << (std::ostream& os,
const variant& v)
1047 static unsigned tab = 0;
1050 return os <<
">UNDEF<";
1051 case REFERENCE_VALUE:
1054 return os <<
"<" << v.
get_name() <<
">";
1063 for (
unsigned int i = 0; i < n; ++i) {
1067 os <<
"\n" << std::string(tab,
' ');
1074 os <<
"\n" << std::string(tab,
' ');
1079 return os << v.
get_str().c_str();
std::string get_str() const
lookup names and follow references and convert to string
ValueType get_value_type() const
lookup names and follow references and return value type
unsigned get_total_nr_elements() const
return total number of elements in a list or map summing over all elements recursively
const map_type & get_map() const
constant access to map value
const variant & get_value() const
lookup names and follow references and return the reached variant
double get_double() const
lookup names and follow references and convert to double: undef ... -1, bool ... 0 or 1,...
variant()
construct undefined value
const std::string & get_element_name(unsigned int i) const
return the name of the i-th element in a map
bool is_int() const
lookup names and follow references and return whether variant is int
const list_type & get_list() const
constant access to list value
int get_int() const
lookup names and follow references and convert to int: undef ... -1, bool ... 0 or 1,...
ValueType get_type() const
return the variant type
const std::string & get_name() const
return the name of a name value
ValueType vt
store type of value
func_type & ref_func()
access to func value
variant & operator=(const variant &v)
assignment operator
bool is_reference() const
name and reference type return true
unsigned int get_size() const
return number of elements in a list or map
variant & ref_element(unsigned int i)
return a reference to the i-th element in a list or map
bool is_name() const
only a name returns true
bool is_func() const
lookup names and follow references and return whether variant is func
variant * get_reference() const
return the pointer of a reference
bool get_bool() const
lookup names and follow references and convert to bool: undef ... false, int ... compares unequal zer...
bool is_bool() const
lookup names and follow references and return whether variant is bool
void ensure_int_type()
convert to int type
bool is_undefined() const
lookup names and follow references and return whether variant is undefined
variant & ref_value()
lookup names and follow references and return reference to the reached variant
void insert(const std::string &name, const variant &v)
insert a new entry to the map
bool match_number_type(const variant &v2)
convert to int or double such that result of binary operators can be stored in this variant without l...
const variant & get_element(unsigned int i) const
return a const reference to the i-th element in a list or map
bool is_list() const
lookup names and follow references and return whether variant is list
bool is_str() const
lookup names and follow references and return whether variant is string
bool is_double() const
lookup names and follow references and return whether variant is double
bool is_map() const
lookup names and follow references and return whether variant is map
void clear()
remove all elements from a list or map and set to undefined type
the tokenizer allows to split text into tokens in a convenient way.
tokenizer & set_ws(const std::string &ws)
set the list of white spaces, that separate tokens and are skipped
namespace that holds tools that dont fit any other namespace
unsigned int replace(std::string &s, char c1, char c2)
replace char c1 with c2 in the given string _s and return number of replacements
std::string to_string(const std::string &v, unsigned int w, unsigned int p, bool)
specialization of conversion from string to strings
char to_upper(char c)
convert char to upper case
Helper functions to process strings.