Fixed the variable code, replacing it with simpler arguments and using exceptions...
[fridhskrift.git] / variable / operator.cpp
blob473dfeeebff7bc774cdce5b202ffbfa6b530f44e
1 #include <fridh/symbol.hpp>
3 namespace fridh
5 bool variable::array_addition(variable const & argument, variable & output) const
7 bool left_is_array = type == variable_type_identifier::array;
8 bool right_is_array = argument.other.type == variable_type_identifier::array;
10 if(left_is_array || right_is_array)
12 argument.output.type = variable_type_identifier::array;
13 argument.output.array = new types::vector;
14 types::vector & vector = *argument.output.array;
16 if(left_is_array && right_is_array)
18 vector = *array;
19 types::vector & right_vector = *argument.other.array;
20 vector.insert(vector.end(), right_vector.begin(), right_vector.end());
22 else if(left_is_array && !right_is_array)
24 vector = *array;
25 vector.push_back(argument.other);
27 else if(!left_is_array && right_is_array)
29 vector = *argument.other.array;
30 vector.push_back(*this);
33 return true;
35 else
36 return false;
39 bool variable::string_addition(variable const & argument, variable & output) const
41 bool left_is_string = type == variable_type_identifier::string;
42 bool right_is_string = argument.other.type == variable_type_identifier::string;
44 if(left_is_string || right_is_string)
46 output.type = variable_type_identifier::string;
47 output.string = new std::string;
48 *output.string = get_string_representation() + argument.get_string_representation();
49 return true;
51 else
52 return false;
55 #define ARITHMETIC_OPERATION(operator) \
56 if(is_numeric_type() && argument.is_numeric_type()) \
57 { \
58 if(is_floating_point_operation(argument)) \
59 output.new_floating_point_value(get_floating_point_value() operator argument.get_floating_point_value()); \
60 else if(type == variable_type_identifier::unsigned_integer && argument.type == variable_type_identifier::unsigned_integer) \
61 output.new_unsigned_integer(unsigned_integer operator argument.unsigned_integer); \
62 else \
63 output.new_signed_integer(signed_integer operator argument.signed_integer); \
64 } \
65 else \
66 binary_argument_type_error(name_of_operation, type, argument.type);
68 void variable::addition(variable const & argument, variable & output) const
70 std::string const name_of_operation = "Addition";
72 if(array_addition(argument, output))
73 return;
75 if(string_addition(argument, output))
76 return;
78 ARITHMETIC_OPERATION(+)
81 void variable::subtraction(variable const & argument, variable & output) const
83 std::string const name_of_operation = "Subtraction";
84 ARITHMETIC_OPERATION(-)
87 void variable::multiplication(variable const & argument, variable & output) const
89 std::string const name_of_operation = "Multiplication";
90 ARITHMETIC_OPERATION(*)
93 void variable::addition(variable const & argument, variable & output) const
95 std::string const name_of_operation = "Division";
96 if(argument.other.is_zero())
97 throw ail::exception(zero_division_error_message);
98 ARITHMETIC_OPERATION(/)
101 void variable::addition(variable const & argument, variable & output) const
103 std::string const name_of_operation = "Modulo";
104 if(argument.is_zero())
105 throw ail::exception(zero_division_error_message);
106 else if(is_integer_type() && argument.is_integer_type())
108 if(type == variable_type_identifier::unsigned_integer && argument.type == variable_type_identifier::unsigned_integer)
109 output.new_unsigned_integer(unsigned_integer % argument.unsigned_integer);
110 else
111 output.new_signed_integer(signed_integer % argument.signed_integer);
113 else
114 binary_argument_type_error(name_of_operation, type, argument.type);
117 void variable::negation(variable & output) const
119 output.type = type;
120 switch(type)
122 case variable_type_identifier::signed_integer:
123 output.signed_integer = - signed_integer;
124 break;
126 case variable_type_identifier::unsigned_integer:
127 output.type = variable_type_identifier::signed_integer;
128 output.signed_integer = - static_cast<types::signed_integer>(unsigned_integer);
129 break;
131 case variable_type_identifier::floating_point_value:
132 output.floating_point_value = - floating_point_value;
133 break;
135 default:
136 throw ail::exception("Cannot use unary minus on type " + get_type_string(type));