1 2 /* 3 * Math2 4 * Copyright (c) 2003-2007 by Mattias Hultgren <tilda_o_tize@hotmail.com> 5 * 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; version 2 of the License. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public 17 * License along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21 /* See math2.cpp for news by version info */ 22 23 24 #ifndef MATH2_H_ 25 #define MATH2_H_ 26 27 #include "vartypes.h" 28 #include "utf8_string.h" 29 #include "picture.h" 30 #include "vector.h" 31 #include "integer.h" 32 #include "real.h" 33 #include "complex.h" 34 #include "matrix.h" 35 #include <math.h> 36 37 38 #define MATH2_H_VERSION "v15" 39 #define MATH2_H_DATE "2003-02 - 2006-10" 40 41 namespace math 42 { 43 44 45 // this function must be called before any thing else is called 46 void init(void) throw(error_obj); 47 48 49 // this variable desides whether radians or degree should be used by sin, arg... 50 extern Complex degfix; 51 52 /* priority list 53 priority 54 number 55 56 1 [] // Matrix brackets 57 2 () 58 3 "" 59 4 methods such as set_pixel, get_type... 60 5 functions such as sin,cos,sqrt,ipart,time,++,--... 61 6 ! 62 7 ^ 63 8 * / \ mod 64 9 + - 65 10 == != < > <= >= ~= 66 11 and or xor not 67 12 =, +=, -=, *=, /=, \=, ^= 68 69 */ 70 71 72 class Variable; 73 class VariableList; 74 class CodeLine; 75 class Picture; 76 class CodeBlock; 77 class Array; 78 79 80 81 typedef void * void_ptr; // these typedef's are used to do C++ style castings 82 typedef Complex * Complex_ptr; 83 typedef Variable * Variable_ptr; 84 typedef void (*BuiltinFunctionPtr)(Variable *res, Variable *left, const Variable *right, VariableList *private_varlist); 85 86 void add_function(const utf8_string &name, BuiltinFunctionPtr newfunction,bool needleft,bool needright) throw(error_obj); 87 88 // this function returns true if a file was autoloaded 89 bool autoload_file( const utf8_string &name ) throw(error_obj); 90 91 // this is the directories that will be checked by autoload_file 92 extern Vector<utf8_string> autoload_directories; 93 94 enum argument_types{ type_end, 95 type_complex, type_complex_default, 96 type_floatx, type_floatx_default, 97 type_int64, type_int64_default, 98 type_integer, type_integer_default, 99 type_boolean, type_boolean_default, 100 type_picture, type_picture_default, 101 type_matrix, type_matrix_default, 102 type_string, type_string_default, 103 type_variable, type_variable_default, 104 type_name, type_name_default }; 105 106 void argument_check(const char *function, const Variable *input, ...) throw(error_obj); 107 108 void colorrgb_to_colormatrix(const picture_h::colorrgb &color, Matrix *matr) throw(error_obj); 109 void colormatrix_to_colorrgb(const Matrix &matr, picture_h::colorrgb *color, uint32 index=1) 110 throw(error_obj); 111 void colormatrix_to_colorrgbs(const Matrix &matr, Vector<picture_h::colorrgb> &colors) 112 throw(error_obj); 113 114 void color_list_get_color( const Vector<picture_h::colorrgb> &colors, floatx min, floatx max, 115 floatx value, picture_h::colorrgb *out_color); 116 117 // set this pointer to make the intern functions format numbers the way you want 118 extern Format *intern_format; 119 120 extern VariableList global_varlist; 121 122 123 class Picture 124 { 125 private: 126 floatx left,right,top,bottom; 127 128 public: 129 picture_h::picture pic; 130 131 picture_h::colorrgb bgcolor; 132 133 Picture() throw(error_obj); 134 Picture(const Picture &src) throw(error_obj); 135 136 void operator=(const Picture &src) throw(error_obj); 137 138 bool operator==(const Picture &pict) const; 139 140 void set_size(int32 width,int32 height,floatx newleft,floatx newright,floatx newbottom,floatx newtop) throw(error_obj); 141 142 void set_window(floatx newleft,floatx newright,floatx newbottom,floatx newtop) throw(error_obj); 143 clear(void)144 inline void clear(void) { pic.clear(bgcolor); } 145 146 void line(floatx x1, floatx y1, floatx x2, floatx y2, bool antialiasing = false, 147 const picture_h::colorrgb &color = picture_h::color::BLACK); 148 149 void point(floatx x,floatx y,const picture_h::colorrgb &color = picture_h::color::BLACK); 150 get_left(void)151 inline floatx get_left(void) const { return left; } get_right(void)152 inline floatx get_right(void) const { return right; } get_top(void)153 inline floatx get_top(void) const { return top; } get_bottom(void)154 inline floatx get_bottom(void) const { return bottom; } 155 156 floatx get_x_value(int32 xpixel) const; 157 floatx get_y_value(int32 ypixel) const; 158 159 int32 get_x_pixel(floatx xvalue) const; 160 int32 get_y_pixel(floatx yvalue) const; 161 162 float get_float_x_pixel(floatx xvalue) const; 163 float get_float_y_pixel(floatx yvalue) const; 164 165 166 floatx get_unit_x_pixel(void) const; 167 floatx get_unit_y_pixel(void) const; 168 }; 169 170 171 172 // Variable types 173 enum VariableType { VariableType_Complex, VariableType_Matrix, VariableType_Array, 174 VariableType_String, VariableType_Picture, 175 VariableType_Boolean, VariableType_Void }; 176 177 extern const char *VARIABLE_TYPE_NAMES[]; 178 179 180 181 void check_name_against_reserved(const utf8_string &name) throw(error_obj); 182 183 class Variable 184 { 185 private: 186 VariableType type; 187 188 union{ 189 struct{ 190 bool boolean; 191 char *complex_buf[ sizeof( Complex ) ]; 192 }; 193 Matrix *matr; 194 struct{ 195 CodeLine *code_line; 196 utf8_string *str; 197 }; 198 Array *array; 199 Picture *pic; 200 }; 201 202 utf8_string name; 203 204 void (*change_func)(Variable *ptr); 205 void (*delete_func)(Variable *ptr); 206 207 bool inuse; 208 bool isconstant; 209 bool can_change_type; 210 211 public: 212 213 Variable(); 214 Variable(const Variable &src) throw(error_obj); 215 ~Variable(); 216 217 // if isconstant and can_change_type allows 218 // this function copies the value/Matrix/function/string/list of the Variable 219 // the name of the Variable will not be touched 220 void operator=(const Variable &src) throw(error_obj); 221 222 bool operator==( const Variable &var ) const; 223 inline bool operator!=( const Variable &var ) { return !(*this == var); } 224 get_inuse(void)225 inline bool get_inuse(void) const { return inuse; } 226 227 void set_void(void); is_void(void)228 inline bool is_void(void) const { return ( type == VariableType_Void ); } 229 230 void set_to_constant(void); get_isconstant(void)231 inline bool get_isconstant(void) const { return isconstant; } 232 233 void set_can_change_type(bool boolean) throw(error_obj); get_can_change_type(void)234 inline bool get_can_change_type(void) const { return can_change_type; } 235 set_to_unused(void)236 inline void set_to_unused(void) { inuse = false; } 237 238 239 void set_name(const utf8_string &newname) throw(error_obj); set_name_from(const Variable & src)240 inline void set_name_from(const Variable &src) throw(error_obj) { set_name(src.name); } 241 const utf8_string* get_name(void) const throw(error_obj); 242 get_type(void)243 VariableType get_type(void) const { return type; } 244 has_name(void)245 inline bool has_name(void) const { return (name.get_length() != 0); } 246 247 void signal_changed(void); 248 249 void clear(void) throw(error_obj); 250 251 void set_complex(const Complex &newvalue) throw(error_obj); 252 const Complex* get_complex(void) const throw(error_obj); 253 Complex* get_complex_rw(void) throw(error_obj); 254 255 void set_matrix(const Matrix *newmatrix) throw(error_obj); 256 const Matrix* get_matrix(void) const throw(error_obj); 257 Matrix* get_matrix_rw(void) throw(error_obj); 258 259 260 void set_string(const utf8_string &newstring) throw(error_obj); 261 void set_code_line(const char *new_code_line) throw(error_obj); 262 263 const utf8_string* get_string(void) const throw(error_obj); 264 utf8_string* get_string_rw(void) throw(error_obj); 265 // this will calculate the code_line's value/Matrix/list and return it 266 void calc_code_line( Variable *res ) throw(error_obj); 267 268 269 void set_array(const Array *newarray) throw(error_obj); 270 const Array* get_array(void) const throw(error_obj); 271 Array* get_array_rw(void) throw(error_obj); 272 273 void set_picture(const Picture *newpic) throw(error_obj); 274 const Picture* get_picture(void) const throw(error_obj); 275 Picture* get_picture_rw(void) throw(error_obj); 276 277 void set_boolean(bool newbool) throw(error_obj); 278 bool get_boolean(void) const throw(error_obj); 279 280 // the change-event does only apply to Variable content not the name or flags like isconstant set_change_func(void (* new_func)(Variable * ptr))281 inline void set_change_func(void (*new_func)(Variable *ptr)) 282 { change_func = new_func; } 283 284 // this function is called by the destructor set_delete_func(void (* new_func)(Variable * ptr))285 inline void set_delete_func(void (*new_func)(Variable *ptr)) 286 { delete_func = new_func; } 287 288 void append_to_string( utf8_string &str, const Format &fmt, bool show_name=true ) const 289 throw(error_obj); 290 }; 291 292 class Array 293 { 294 private: 295 uint32 nrofvariables; 296 297 Variable **array; 298 299 // this function increases the size with one, the new pointer is set to zero 300 void increase_size(void) throw(error_obj); 301 302 public: 303 Array(); 304 Array(const Array &src) throw(error_obj); 305 ~Array(); 306 307 void clear(void); 308 309 void set_size( uint32 new_size ) throw(error_obj); 310 get_size(void)311 inline uint32 get_size(void) const { return nrofvariables; } 312 313 const Variable * get_variable(uint32 nr) const throw(error_obj); 314 315 void set_variable( uint32 nr, const Variable &new_var) throw(error_obj); 316 317 // if var == 0 nothing will happen 318 void add_variable(const Variable *var) throw(error_obj); 319 320 // after this call the Array owns the variable 321 void add_this_variable( Variable *var ) throw(error_obj); 322 323 void insert( const Variable *var, uint32 at_pos ) throw(error_obj); 324 void insert_this( Variable *var, uint32 at_pos ) throw(error_obj); 325 326 // if nr isn't existing nothing happens 327 void remove_range( uint32 from_nr, uint32 this_many = 1 ); 328 329 void operator=(const Array &src) throw(error_obj); 330 331 bool operator==(const Array &arr) const; 332 }; 333 334 335 336 337 class VariableList 338 { 339 private: 340 struct intern_variablelist 341 { 342 intern_variablelist *next; 343 344 uint32 idnr; 345 uint32 isdeletable; 346 Variable *var; 347 348 intern_variablelist(); 349 ~intern_variablelist(); // deletes all 'intern_variablelist'-structs linked to *next 350 }*varlist; 351 352 public: 353 VariableList(); 354 VariableList(const VariableList &src) throw(error_obj); 355 ~VariableList(); 356 357 void operator=(const VariableList &src) throw(error_obj); 358 359 // returns the idnr for the variable thats called name (if there is more than one with that name the first found is returned) 360 uint32 get_id(const char *name) const throw(error_obj); 361 362 bool check_for(const utf8_string &name) const; 363 364 // returns the highest idnr in the list 365 uint32 get_highest_idnr(void) const; 366 367 // returns a pointer to the variable determind by idnr 368 const Variable* get_pointer(uint32 idnr) const throw(error_obj); 369 Variable* get_pointer_rw(uint32 idnr) throw(error_obj); 370 371 // creates a new Variable, a pointer to the created Variable is returned... 372 Variable * create(const Variable &newvar, bool isconstant, bool isdeletable, 373 bool can_change_type) throw(error_obj); 374 375 // adds a Variable note that the VariableList will be the owner of Variable newvar after this 376 void add_this(Variable *newvar, bool isconstant, bool isdeletable, bool can_change_type) throw(error_obj); 377 378 void set_all_to_unused(void); 379 380 bool get_deletable(uint32 idnr) const throw(error_obj); 381 382 void make_undeletable(uint32 idnr) throw(error_obj); 383 384 // deletes a Variable, if it's deletable 385 void remove(uint32 idnr) throw(error_obj); 386 387 // removes all Variables in the list, ignoring the isdeletable-flag 388 void clear(void); 389 is_empty(void)390 bool is_empty(void) const { return (varlist) ? false : true; } 391 }; 392 393 394 395 396 class CodeLine 397 { 398 private: 399 class CodeLineNode 400 { 401 public: 402 bool soft_function; 403 BuiltinFunctionPtr function; 404 utf8_string function_name; 405 int32 tmpvariable_index; // this is the result variable 406 407 struct{ 408 int32 tmpvariable_index; 409 bool soft; 410 Variable *ptr; 411 utf8_string name; 412 }left, right; 413 CodeLineNode()414 CodeLineNode() { } throw(error_obj)415 CodeLineNode(const CodeLineNode &src) throw(error_obj) { *this = src; } ~CodeLineNode()416 ~CodeLineNode() { } throw(error_obj)417 void operator=(const CodeLineNode &src) throw(error_obj) 418 { 419 try 420 { 421 soft_function = src.soft_function; 422 function = src.function; 423 function_name = src.function_name; 424 tmpvariable_index = src.tmpvariable_index; 425 left.tmpvariable_index = src.left.tmpvariable_index; 426 left.soft = src.left.soft; 427 left.ptr = src.left.ptr; 428 left.name = src.left.name; 429 right.tmpvariable_index = src.right.tmpvariable_index; 430 right.soft = src.right.soft; 431 right.ptr = src.right.ptr; 432 right.name = src.right.name; 433 } 434 catch(...) { THROW_ERROR( ErrorType_Memory, _("Couldn't get memory.") ); } 435 } 436 437 }; 438 Vector<CodeLineNode> nodes; 439 int32 nroftmpvariables; 440 utf8_string string; 441 VariableList autovarlist; 442 443 // this has a void* because I don't want to make struct Symbol visible in this header 444 // the void* should be a Vector<Symbol>* 445 void create_nodes(void *ptr, int start_at) throw(error_obj); 446 void round_bracket_reducing(void *ptr, int start_at) throw(error_obj); 447 void matrix_bracket_reducing(void *ptr) throw(error_obj); 448 449 void parse_pow_mods(void) throw(error_obj); // this is runned after create_nodes... 450 451 // this function returns the index of the tmp variable which is the matrix... 452 int32 parse_matrix_creation( uint32 col, uint32 row ) throw(error_obj); 453 public: 454 CodeLine(); 455 CodeLine(CodeLine &src) throw(error_obj); 456 ~CodeLine(); 457 458 void operator=(CodeLine &src) throw(error_obj); 459 460 void set_code_line(const char * newstring, bool allow_variable_creation=true, 461 VariableList *private_varlist=0) throw(error_obj); 462 get_code_line(utf8_string * ret_string)463 inline void get_code_line( utf8_string *ret_string ) const throw(error_obj) { *ret_string = string; } 464 465 // calculates the string that has been set by set_code_line/append_code_line 466 void calc( Variable *answer, VariableList *private_varlist=0, Vector<Variable> *tmp_variables=0 ) throw(error_obj); 467 get_nroftmpvariables(void)468 inline int32 get_nroftmpvariables(void) const { return nroftmpvariables; } 469 is_empty(void)470 inline bool is_empty(void) const { return (nodes.get_size() == 0); } 471 }; 472 473 class CodeBlock 474 { 475 private: 476 enum CodeBlock_Type { CodeBlock_Type_Void, CodeBlock_Type_Code, CodeBlock_Type_Start, 477 CodeBlock_Type_Stop }; 478 enum CodeBlock_SubType { CodeBlock_SubType_None, CodeBlock_SubType_While, 479 CodeBlock_SubType_If, CodeBlock_SubType_Else, 480 CodeBlock_SubType_Return, 481 CodeBlock_SubType_Break, CodeBlock_SubType_Continue }; 482 utf8_string filename; 483 484 class CodeBlockLine 485 { 486 public: 487 int line_number; 488 CodeBlock_Type type; 489 CodeBlock_SubType sub_type; 490 491 union{ 492 CodeLine *code; 493 int pair_with; 494 }; 495 496 CodeBlockLine(); 497 CodeBlockLine(const CodeBlockLine &src) throw(error_obj); 498 ~CodeBlockLine(); 499 void operator=(const CodeBlockLine &src) throw(error_obj); 500 }; 501 502 Vector<CodeBlockLine> lines; 503 uint32 inuse; 504 VariableList private_varlist; 505 int32 nroftmpvariables; 506 507 void add_void( CodeBlock_SubType sub_type ) throw(error_obj); 508 509 void add_line(const char *codeline, int linenr, bool allow_variable_creation, 510 CodeBlock_SubType sub_type = CodeBlock_SubType_None) throw(error_obj); 511 void add_curley( CodeBlock_Type type, CodeBlock_SubType sub_type = CodeBlock_SubType_None, 512 int pos = -1 ) throw(error_obj); 513 514 void set_code_intern(char *str, bool allow_variable_creation ) throw(error_obj); 515 bool create_function(char *str, const utf8_string *only_allow_identifier) throw(error_obj); 516 517 // only None, Break, Continue & Return are used 518 void run_block( Vector<Variable> *tmp_variables, VariableList *this_private_varlist, CodeBlock_SubType &ret, 519 Variable *ans, int &start, bool expect_curley_ending = false ) const throw(error_obj); 520 521 void pair_up_curleys(void); 522 void add_automatic_curleys(void) throw(error_obj); 523 524 public: CodeBlock()525 CodeBlock() { inuse = 0; nroftmpvariables = 0; } 526 CodeBlock(const CodeBlock &src) throw(error_obj); 527 ~CodeBlock(); 528 get_inuse(void)529 inline bool get_inuse(void) const { return (inuse != 0); } 530 531 void set_code(const char *newcode) throw(error_obj); 532 void set_code_from_file( const utf8_string &new_filename, 533 const utf8_string *only_allow_identifier = 0 ) throw(error_obj); 534 535 void calc( Variable *answer ) throw(error_obj); 536 537 void clear(void); 538 539 void operator=(const CodeBlock &src) throw(error_obj); 540 541 friend void wrapper_code_block_functions(Variable *res,Variable *left,const Variable *right, 542 const utf8_string &name) throw(error_obj); 543 friend void wrapper_check_argument( int i, int i2, const Variable *right ) throw(error_obj); 544 }; 545 546 547 } // namespace math 548 549 #endif // MATH2_H_ 550