Fixed bracket/array parsing, empty calls and empty arrays are now permitted
[fridhskrift.git] / variable / operator.cpp
blobedd095fc179e4682043ddc264e305749066928d5
1 #include <fridh/symbol.hpp>
3 namespace fridh
5 namespace
7 std::string const zero_division_error_message = "Zero division error";
10 bool variable::array_addition(variable const & argument, variable & output) const
12 bool left_is_array = type == variable_type_identifier::array;
13 bool right_is_array = argument.type == variable_type_identifier::array;
15 if(left_is_array || right_is_array)
17 output.type = variable_type_identifier::array;
18 output.array = new types::vector;
19 types::vector & vector = *output.array;
21 if(left_is_array && right_is_array)
23 vector = *array;
24 types::vector & right_vector = *argument.array;
25 vector.insert(vector.end(), right_vector.begin(), right_vector.end());
27 else if(left_is_array && !right_is_array)
29 vector = *array;
30 vector.push_back(argument);
32 else if(!left_is_array && right_is_array)
34 vector = *argument.array;
35 vector.push_back(*this);
38 return true;
40 else
41 return false;
44 bool variable::string_addition(variable const & argument, variable & output) const
46 bool left_is_string = type == variable_type_identifier::string;
47 bool right_is_string = argument.type == variable_type_identifier::string;
49 if(left_is_string || right_is_string)
51 output.type = variable_type_identifier::string;
52 output.string = new std::string;
53 *output.string = get_string_representation() + argument.get_string_representation();
54 return true;
56 else
57 return false;
60 #define ARITHMETIC_OPERATION(description, operator) \
61 if(is_numeric_type() && argument.is_numeric_type()) \
62 { \
63 if(is_floating_point_operation(argument)) \
64 output.new_floating_point_value(get_floating_point_value() operator argument.get_floating_point_value()); \
65 else if(type == variable_type_identifier::unsigned_integer && argument.type == variable_type_identifier::unsigned_integer) \
66 output.new_unsigned_integer(unsigned_integer operator argument.unsigned_integer); \
67 else \
68 output.new_signed_integer(signed_integer operator argument.signed_integer); \
69 } \
70 else \
71 binary_argument_type_error(description, type, argument.type);
73 void variable::addition(variable const & argument, variable & output) const
75 if(array_addition(argument, output))
76 return;
78 if(string_addition(argument, output))
79 return;
81 ARITHMETIC_OPERATION("Addition", +)
84 void variable::subtraction(variable const & argument, variable & output) const
86 ARITHMETIC_OPERATION("Subtraction", -)
89 void variable::multiplication(variable const & argument, variable & output) const
91 ARITHMETIC_OPERATION("Multiplication", *)
94 void variable::division(variable const & argument, variable & output) const
96 if(argument.is_zero())
97 throw ail::exception(zero_division_error_message);
98 ARITHMETIC_OPERATION("Division", /)
101 void variable::modulo(variable const & argument, variable & output) const
103 if(argument.is_zero())
104 throw ail::exception(zero_division_error_message);
105 else if(is_integer_type() && argument.is_integer_type())
107 if(type == variable_type_identifier::unsigned_integer && argument.type == variable_type_identifier::unsigned_integer)
108 output.new_unsigned_integer(unsigned_integer % argument.unsigned_integer);
109 else
110 output.new_signed_integer(signed_integer % argument.signed_integer);
112 else
113 binary_argument_type_error("Modulo", type, argument.type);
116 void variable::negation(variable & output) const
118 output.type = type;
119 switch(type)
121 case variable_type_identifier::signed_integer:
122 output.signed_integer = - signed_integer;
123 break;
125 case variable_type_identifier::unsigned_integer:
126 output.type = variable_type_identifier::signed_integer;
127 output.signed_integer = - static_cast<types::signed_integer>(unsigned_integer);
128 break;
130 case variable_type_identifier::floating_point_value:
131 output.floating_point_value = - floating_point_value;
132 break;
134 default:
135 throw ail::exception("Cannot use unary minus on type " + get_type_string(type));