1 #include <fridh/symbol.hpp>
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
)
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
)
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);
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();
55 #define ARITHMETIC_OPERATION(operator) \
56 if(is_numeric_type() && argument.is_numeric_type()) \
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); \
63 output.new_signed_integer(signed_integer operator argument.signed_integer); \
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
))
75 if(string_addition(argument
, output
))
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
);
111 output
.new_signed_integer(signed_integer
% argument
.signed_integer
);
114 binary_argument_type_error(name_of_operation
, type
, argument
.type
);
117 void variable::negation(variable
& output
) const
122 case variable_type_identifier::signed_integer
:
123 output
.signed_integer
= - signed_integer
;
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
);
131 case variable_type_identifier::floating_point_value
:
132 output
.floating_point_value
= - floating_point_value
;
136 throw ail::exception("Cannot use unary minus on type " + get_type_string(type
));