1 #include <fridh/symbol.hpp>
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
)
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
)
30 vector
.push_back(argument
);
32 else if(!left_is_array
&& right_is_array
)
34 vector
= *argument
.array
;
35 vector
.push_back(*this);
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();
60 #define ARITHMETIC_OPERATION(description, operator) \
61 if(is_numeric_type() && argument.is_numeric_type()) \
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); \
68 output.new_signed_integer(signed_integer operator argument.signed_integer); \
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
))
78 if(string_addition(argument
, output
))
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
);
110 output
.new_signed_integer(signed_integer
% argument
.signed_integer
);
113 binary_argument_type_error("Modulo", type
, argument
.type
);
116 void variable::negation(variable
& output
) const
121 case variable_type_identifier::signed_integer
:
122 output
.signed_integer
= - signed_integer
;
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
);
130 case variable_type_identifier::floating_point_value
:
131 output
.floating_point_value
= - floating_point_value
;
135 throw ail::exception("Cannot use unary minus on type " + get_type_string(type
));