1
2 /*
3 * Math2
4 * Copyright (c) 2003-2007 by Mattias Hultgren <tilda_o_tize@hotmail.com>
5 *
6 * See math2.h
7 */
8
9
10
11 #include "math2.h"
12 #include "math2.intern.h"
13 #include "keyfile.h"
14 #include <stdarg.h>
15 #include <time.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 namespace math
21 {
22
23 VariableList global_varlist;
24 Format *intern_format = 0;
25
26 Vector<utf8_string> autoload_directories;
27
28 Complex degfix( 1.0 );
29
30 const char *VARIABLE_TYPE_NAMES[] = {
31 "Complex",
32 "Matrix",
33 "Array",
34 "String",
35 "Picture",
36 "Boolean",
37 "Void",
38 0
39 };
40
41
init(void)42 void init(void) throw(error_obj)
43 {
44 static bool already_inited = false;
45 Variable tmpvar;
46
47 if(!already_inited)
48 {
49 already_inited = true;
50 srand(time(0));
51
52 tmpvar.set_boolean( false );
53 tmpvar.set_name( "false" );
54 global_varlist.create( tmpvar, true, false, false); // constant
55 tmpvar.set_boolean( true );
56 tmpvar.set_name( "true" );
57 global_varlist.create( tmpvar, true,false,false); // constant
58
59 tmpvar.set_complex( Complex( PI ) );
60 tmpvar.set_name( "pi" );
61 global_varlist.create( tmpvar , true,false,false); // constant
62 tmpvar.set_complex( Complex(0, 1) );
63 tmpvar.set_name( "i" );
64 global_varlist.create( tmpvar , true,false,false); // constant
65 tmpvar.set_complex( Complex( E ) );
66 tmpvar.set_name( "e" );
67 global_varlist.create( tmpvar , true,false,false); // constant
68
69 tmpvar.set_complex( Complex( 0 ) );
70 tmpvar.set_name( "x" );
71 global_varlist.create( tmpvar , false,false,true);
72 tmpvar.set_name( "y" );
73 global_varlist.create( tmpvar , false,false,true);
74
75 tmpvar.set_void();
76 tmpvar.set_name( "void" );
77 global_varlist.create( tmpvar, true, false, false);
78
79 function_list.add_function( "append", builtin_append, 15, true, true );
80 function_list.add_function( "(array_of_two)", builtin_array_of_two, 15, true, true );
81 function_list.add_function( "axes", builtin_axes, 15, true, true );
82 function_list.add_function( "circle", builtin_circle, 15, true, true );
83 function_list.add_function( "(eval)", builtin_round_eval, 15, true, true );
84 function_list.add_function( "[get]", builtin_hook_get, 15, true, true );
85 function_list.add_function( "get_bottom", builtin_get_bottom, 15, true, false );
86 function_list.add_function( "get_col", builtin_get_col, 15, true, true );
87 function_list.add_function( "get_height", builtin_get_height, 15, true, false );
88 function_list.add_function( "get_left", builtin_get_left, 15, true, false );
89 function_list.add_function( "get_right", builtin_get_right, 15, true, false );
90 function_list.add_function( "get_row", builtin_get_row, 15, true, true );
91 function_list.add_function( "get_top", builtin_get_top, 15, true, false );
92 function_list.add_function( "get_type", builtin_get_type, 15, true, false );
93 function_list.add_function( "get_width", builtin_get_width, 15, true, false );
94 function_list.add_function( "grid", builtin_grid, 15, true, true );
95 function_list.add_function( "insert", builtin_insert, 15, true, true );
96 function_list.add_function( "line", builtin_line, 15, true, true );
97 function_list.add_function( "merge", builtin_merge, 15, true, true );
98 function_list.add_function( "pixel_circle", builtin_pixel_circle, 15, true, true );
99 function_list.add_function( "pixel_line", builtin_pixel_line, 15, true, true );
100 function_list.add_function( "plot", builtin_plot, 15, true, true );
101 function_list.add_function( "(powMod)", builtin_pow_mod, 15, true, true );
102 function_list.add_function( "remove", builtin_remove, 15, true, true );
103 function_list.add_function( "[set]", builtin_hook_set, 15, true, true );
104 function_list.add_function( "[set_next]", builtin_hook_set_next, 15, true, true );
105 function_list.add_function( "set_pixel", builtin_set_pixel, 15, true, true );
106 function_list.add_function( "set_point", builtin_set_point, 15, true, true );
107 function_list.add_function( "set_window", builtin_set_window, 15, true, true );
108
109
110 function_list.add_function( "abs", builtin_abs, 14, false, true );
111 function_list.add_function( "acos", builtin_acos, 14, false, true );
112 function_list.add_function( "acosh", builtin_acosh, 14, false, true );
113 function_list.add_function( "adj", builtin_adj, 14, false, true );
114 function_list.add_function( "arg", builtin_arg, 14, false, true );
115 function_list.add_function( "array", builtin_array, 14, false, true );
116 function_list.add_function( "asin", builtin_asin, 14, false, true );
117 function_list.add_function( "asinh", builtin_asinh, 14, false, true );
118 function_list.add_function( "atan", builtin_atan, 14, false, true );
119 function_list.add_function( "atanh", builtin_atanh, 14, false, true );
120 function_list.add_function( "clear", builtin_clear, 14, false, true );
121 function_list.add_function( "comb", builtin_comb, 14, false, true );
122 function_list.add_function( "cos", builtin_cos, 14, false, true );
123 function_list.add_function( "cosh", builtin_cosh, 14, false, true );
124 function_list.add_function( "dec", builtin_dec, 14, false, true );
125 function_list.add_function( "delete", builtin_delete, 14, false, true );
126 function_list.add_function( "det", builtin_det, 14, false, true );
127 function_list.add_function( "error", builtin_error, 14, false, true );
128 function_list.add_function( "frac", builtin_frac, 14, false, true );
129 function_list.add_function( "fPart", builtin_fpart, 14, false, true );
130 function_list.add_function( "im", builtin_im, 14, false, true );
131 function_list.add_function( "iPart", builtin_ipart, 14, false, true );
132 function_list.add_function( "iSqrt", builtin_isqrt, 14, false, true );
133 function_list.add_function( "log", builtin_log, 14, false, true );
134 function_list.add_function( "log2", builtin_log2, 14, false, true );
135 function_list.add_function( "ln", builtin_ln, 14, false, true );
136 function_list.add_function( "make_constant", builtin_make_constant, 14, false, true );
137 function_list.add_function( "make_type_locked", builtin_make_type_locked, 14, false, true );
138 function_list.add_function( "make_undeletable", builtin_make_undeletable, 14, false, true );
139 function_list.add_function( "matrix", builtin_matrix, 14, false, true );
140 function_list.add_function( "nDeriv", builtin_nderiv, 14, false, true );
141 function_list.add_function( "nInt", builtin_nint, 14, false, true );
142 function_list.add_function( "nSolve", builtin_nsolve, 14, false, true );
143 function_list.add_function( "perm", builtin_perm, 14, false, true );
144 function_list.add_function( "picture", builtin_picture, 14, false, true );
145 function_list.add_function( "polyreg", builtin_polyreg, 14, false, true );
146 function_list.add_function( "rand", builtin_rand, 14, false, false );
147 function_list.add_function( "re", builtin_re, 14, false, true );
148 function_list.add_function( "shade", builtin_shade, 14, false, true );
149 function_list.add_function( "sin", builtin_sin, 14, false, true );
150 function_list.add_function( "sinh", builtin_sinh, 14, false, true );
151 function_list.add_function( "sum", builtin_sum, 14, false, true );
152 function_list.add_function( "sqrt", builtin_sqrt, 14, false, true );
153 function_list.add_function( "table", builtin_table, 14, false, true );
154 function_list.add_function( "table2d", builtin_table2d, 14, false, true );
155 function_list.add_function( "tan", builtin_tan, 14, false, true );
156 function_list.add_function( "tanh", builtin_tanh, 14, false, true );
157 function_list.add_function( "time", builtin_time, 14, false, false );
158 function_list.add_function( "++", builtin_inc, 14, true, false );
159 function_list.add_function( "--", builtin_decrement, 14, true, false );
160 function_list.add_function( "-(neg)", builtin_neg, 14, false, true );
161
162 function_list.add_function( "!", builtin_faculty, 13, true, false );
163
164 function_list.add_function( "^", builtin_pow, 12, true, true );
165
166 function_list.add_function( "*", builtin_mul, 11, true, true );
167 function_list.add_function( "/", builtin_div, 11, true, true );
168 function_list.add_function( "mod", builtin_modulo, 11, true, true );
169 function_list.add_function( "\\", builtin_intdiv, 11, true, true );
170
171 function_list.add_function( "+", builtin_plus, 10, true, true );
172 function_list.add_function( "-", builtin_minus, 10, true, true );
173
174 function_list.add_function( "==", builtin_equal, 9, true, true );
175 function_list.add_function( "!=", builtin_notequal, 9, true, true );
176 function_list.add_function( ">", builtin_greater, 9, true, true );
177 function_list.add_function( "<", builtin_smaller, 9, true, true );
178 function_list.add_function( ">=", builtin_greater_eq, 9, true, true );
179 function_list.add_function( "<=", builtin_smaller_eq, 9, true, true );
180 function_list.add_function( "~=", builtin_almost_eq, 9, true, true );
181
182 function_list.add_function( "and", builtin_and, 8, true, true );
183 function_list.add_function( "or", builtin_or, 8, true, true );
184 function_list.add_function( "xor", builtin_xor, 8, true, true );
185 function_list.add_function( "not", builtin_not, 8, false, true );
186
187 function_list.add_function( "=", builtin_set, 7, true, true );
188 function_list.add_function( "+=", builtin_set_add, 7, true, true );
189 function_list.add_function( "-=", builtin_set_sub, 7, true, true );
190 function_list.add_function( "*=", builtin_set_mul, 7, true, true );
191 function_list.add_function( "/=", builtin_set_div, 7, true, true );
192 function_list.add_function( "\\=", builtin_set_intdiv, 7, true, true );
193 function_list.add_function( "^=", builtin_set_pow, 7, true, true );
194 }
195 }
196
197
add_function(const utf8_string & name,BuiltinFunctionPtr newfunction,bool needleft,bool needright)198 void add_function( const utf8_string &name, BuiltinFunctionPtr newfunction, bool needleft,
199 bool needright ) throw(error_obj)
200 {
201 function_list.add_function( name, newfunction, 14, needleft, needright );
202 }
203
204
argument_check(const char * function,const Variable * input,...)205 void argument_check(const char *function, const Variable *input, ...) throw(error_obj)
206 {
207 va_list ap;
208 argument_types type;
209 const Variable *var = 0;
210 const Array *array;
211 Array tmparray;
212 Complex tmp;
213
214 Complex *out_complex;
215 floatx *out_floatx;
216 int64 *out_int64;
217 Integer *out_integer;
218 bool *out_boolean;
219 Picture *out_picture;
220 Matrix *out_matrix;
221 utf8_string *out_string;
222 Variable *out_variable;
223
224 va_start(ap,input);
225
226 try
227 {
228 switch(input->get_type())
229 {
230 case VariableType_Array:
231 array = input->get_array();
232 argument_check_do_the_check:
233 for(uint32 i=0;i<array->get_size();)
234 {
235 type = argument_types( va_arg(ap, int) );
236 if(type == type_end)
237 {
238 char tmp_err[ERROR_OBJ_MSG_LEN];
239 snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Argument list doesn't match for %s"), function );
240 THROW_ERROR( ErrorType_General, tmp_err );
241 }
242
243 if(var == 0)
244 var = array->get_variable(i);
245 switch(type)
246 {
247 case type_complex:
248 case type_complex_default:
249 out_complex = va_arg(ap, Complex *);
250 if(var->get_type() == VariableType_Complex)
251 {
252 *out_complex = *(var->get_complex());
253 var = 0;
254 }
255 else
256 {
257 if(type == type_complex)
258 {
259 char tmp_err[ERROR_OBJ_MSG_LEN];
260 snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Argument list doesn't match for %s"), function );
261 THROW_ERROR( ErrorType_General, tmp_err );
262 }
263 }
264 break;
265
266 case type_floatx:
267 case type_floatx_default:
268 out_floatx = va_arg(ap, floatx *);
269 if(var->get_type() == VariableType_Complex)
270 {
271 tmp = *(var->get_complex());
272 if(floatx(tmp.imaginary) != 0.0)
273 THROW_ERROR( ErrorType_Domain, _("Domain error: Imaginary part must be zero.") );
274
275 *out_floatx = floatx(tmp.real);
276 var = 0;
277 }
278 else
279 {
280 if(type == type_floatx)
281 {
282 char tmp_err[ERROR_OBJ_MSG_LEN];
283 snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Argument list doesn't match for %s"), function );
284 THROW_ERROR( ErrorType_General, tmp_err );
285 }
286 }
287 break;
288
289 case type_int64:
290 case type_int64_default:
291 out_int64 = va_arg(ap, int64 *);
292 if(var->get_type() == VariableType_Complex)
293 {
294 tmp = *(var->get_complex());
295
296 if(floatx(tmp.imaginary) != 0.0)
297 THROW_ERROR( ErrorType_Domain, _("Domain error: Imaginary part must be zero.") );
298 if(ipart(tmp.real) != tmp.real)
299 THROW_ERROR( ErrorType_Domain, _("Domain error: The number must be an integer.") );
300
301 if(floatx(tmp.real) >= int64_max) {
302 THROW_ERROR( ErrorType_Domain, _("Domain error: The number must be below 2^64.") );
303 } else if(floatx(tmp.real) <= int64_min) {
304 THROW_ERROR( ErrorType_Domain, _("Domain error: The number must be above -2^64.") );
305 } else
306 *out_int64 = int64(floatx(tmp.real));
307 var = 0;
308 }
309 else
310 {
311 if(type == type_int64)
312 {
313 char tmp_err[ERROR_OBJ_MSG_LEN];
314 snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Argument list doesn't match for %s"), function );
315 THROW_ERROR( ErrorType_General, tmp_err );
316 }
317 }
318 break;
319
320 case type_integer:
321 case type_integer_default:
322 out_integer = va_arg(ap, Integer *);
323 if(var->get_type() == VariableType_Complex)
324 {
325 tmp = *(var->get_complex());
326
327 if(floatx(tmp.imaginary) != 0.0)
328 THROW_ERROR( ErrorType_Domain, _("Domain error: Imaginary part must be zero.") );
329 if( !tmp.real.isInteger() )
330 THROW_ERROR( ErrorType_Domain, _("Domain error: The number must be an integer.") );
331
332 tmp.real.get_top( out_integer );
333 var = 0;
334 }
335 else
336 {
337 if(type == type_integer)
338 {
339 char tmp_err[ERROR_OBJ_MSG_LEN];
340 snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Argument list doesn't match for %s"), function );
341 THROW_ERROR( ErrorType_General, tmp_err );
342 }
343 }
344 break;
345
346 case type_boolean:
347 case type_boolean_default:
348 out_boolean = va_arg(ap, bool *);
349 if(var->get_type() == VariableType_Boolean)
350 {
351 *out_boolean = var->get_boolean();
352 var = 0;
353 }
354 else
355 {
356 if(type == type_boolean)
357 {
358 char tmp_err[ERROR_OBJ_MSG_LEN];
359 snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Argument list doesn't match for %s"), function );
360 THROW_ERROR( ErrorType_General, tmp_err );
361 }
362 }
363 break;
364
365 case type_picture:
366 case type_picture_default:
367 out_picture = va_arg(ap, Picture *);
368 if(var->get_type() == VariableType_Picture)
369 {
370 *out_picture = *(var->get_picture());
371 var = 0;
372 }
373 else
374 {
375 if(type == type_picture)
376 {
377 char tmp_err[ERROR_OBJ_MSG_LEN];
378 snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Argument list doesn't match for %s"), function );
379 THROW_ERROR( ErrorType_General, tmp_err );
380 }
381 }
382 break;
383
384 case type_matrix:
385 case type_matrix_default:
386 out_matrix = va_arg(ap, Matrix *);
387 if(var->get_type() == VariableType_Matrix)
388 {
389 *out_matrix = *(var->get_matrix());
390 var = 0;
391 }
392 else
393 {
394 if(type == type_matrix)
395 {
396 char tmp_err[ERROR_OBJ_MSG_LEN];
397 snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Argument list doesn't match for %s"), function );
398 THROW_ERROR( ErrorType_General, tmp_err );
399 }
400 }
401 break;
402
403 case type_string:
404 case type_string_default:
405 out_string = va_arg(ap, utf8_string *);
406 if(var->get_type() == VariableType_String)
407 {
408 *out_string = *(var->get_string());
409 var = 0;
410 }
411 else
412 {
413 if(type == type_string)
414 {
415 char tmp_err[ERROR_OBJ_MSG_LEN];
416 snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Argument list doesn't match for %s"), function );
417 THROW_ERROR( ErrorType_General, tmp_err );
418 }
419 }
420 break;
421
422 case type_name:
423 case type_name_default:
424 out_string = va_arg(ap, utf8_string *);
425 if(var->has_name())
426 {
427 *out_string = *(var->get_name());
428 var = 0;
429 }
430 else
431 {
432 if(type == type_name)
433 {
434 char tmp_err[ERROR_OBJ_MSG_LEN];
435 snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Argument list doesn't match for %s"), function );
436 THROW_ERROR( ErrorType_General, tmp_err );
437 }
438 }
439 break;
440
441 case type_variable:
442 case type_variable_default:
443 out_variable = va_arg(ap, Variable *);
444
445 *out_variable = *var;
446 var = 0;
447 break;
448
449 default:
450 printf("argument_check was called in an unsupported way\n\n");
451 exit(-1);
452 }
453 if(var == 0)
454 i++;
455 }
456 break;
457
458 default:
459 tmparray.clear();
460 tmparray.add_variable( input );
461 array = &tmparray;
462 goto argument_check_do_the_check;
463 }
464
465
466 bool loop=true;
467 do{
468 switch(argument_types( va_arg(ap, int) ))
469 {
470 case type_end:
471 loop = false;
472 break;
473
474 case type_complex_default:
475 case type_floatx_default:
476 case type_int64_default:
477 case type_integer_default:
478 case type_boolean_default:
479 case type_picture_default:
480 case type_matrix_default:
481 case type_string_default:
482 case type_name_default:
483 case type_variable_default:
484 break;
485
486 default:
487 {
488 char tmp_err[ERROR_OBJ_MSG_LEN];
489 snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Argument list doesn't match for %s"), function );
490 THROW_ERROR( ErrorType_General, tmp_err );
491 }
492 }
493 out_complex = va_arg(ap, Complex *); // this is not always a legal pointer, but all pointers are
494 }while(loop); // equal in size so the code is OK
495 }
496 catch(error_obj error)
497 {
498 va_end(ap);
499 throw;
500 }
501 catch(...)
502 {
503 va_end(ap);
504 THROW_ERROR( ErrorType_Memory, _("Couldn't get memory.") );
505 }
506 va_end(ap);
507 }
508
colorrgb_to_colormatrix(const picture_h::colorrgb & color,Matrix * matr)509 void colorrgb_to_colormatrix(const picture_h::colorrgb &color, Matrix *matr) throw(error_obj)
510 {
511 Complex tmp;
512
513 if(matr == 0)
514 THROW_ERROR( ErrorType_General, _("Invalid matrix width") );
515
516 matr->set_size( 3, 1 );
517
518 tmp.imaginary = Real(0);
519
520 tmp.real = Real( int64(color.red), 255 );
521 matr->set_complex(1,1,tmp);
522
523 tmp.real = Real( int64(color.green), 255 );
524 matr->set_complex(2,1,tmp);
525
526 tmp.real = Real( int64(color.blue), 255 );
527 matr->set_complex(3,1,tmp);
528 }
colormatrix_to_colorrgb(const Matrix & matr,picture_h::colorrgb * color,uint32 index)529 void colormatrix_to_colorrgb(const Matrix &matr, picture_h::colorrgb *color, uint32 index)
530 throw(error_obj)
531 {
532 Complex tmp;
533
534 if( index == 0 )
535 THROW_ERROR( ErrorType_General, _("colormatrix_to_colorrgb: Index mustn't be zero.") );
536
537 if( matr.get_width() != 3 || matr.get_height() < index )
538 THROW_ERROR( ErrorType_General, _("Invalid matrix width") );
539
540 tmp = matr.get_complex( 1, index );
541 tmp.real = floatx(tmp.real) * 255.0 + 0.5;
542 if( floatx(tmp.real) > 255.0 )
543 color->red = 255;
544 else if( floatx(tmp.real) < 0.0 )
545 color->red = 0;
546 else
547 color->red = uint8(floatx(tmp.real));
548
549 tmp = matr.get_complex( 2, index );
550 tmp.real = floatx(tmp.real) * 255.0 + 0.5;
551 if( floatx(tmp.real) > 255.0 )
552 color->green = 255;
553 else if( floatx(tmp.real) < 0.0 )
554 color->green = 0;
555 else
556 color->green = uint8(floatx(tmp.real));
557
558 tmp = matr.get_complex( 3, index );
559 tmp.real = floatx(tmp.real) * 255.0 + 0.5;
560 if( floatx(tmp.real) > 255.0 )
561 color->blue = 255;
562 else if( floatx(tmp.real) < 0.0 )
563 color->blue = 0;
564 else
565 color->blue = uint8(floatx(tmp.real));
566 }
567
colormatrix_to_colorrgbs(const Matrix & matr,Vector<picture_h::colorrgb> & colors)568 void colormatrix_to_colorrgbs(const Matrix &matr, Vector<picture_h::colorrgb> &colors)
569 throw(error_obj)
570 {
571 colors.set_size_filled( int(matr.get_height()) );
572
573 for( uint32 i=1; i<=matr.get_height(); i++ )
574 colormatrix_to_colorrgb( matr, colors[i-1], i );
575 }
576
color_list_get_color(const Vector<picture_h::colorrgb> & colors,floatx min,floatx max,floatx value,picture_h::colorrgb * out_color)577 void color_list_get_color( const Vector<picture_h::colorrgb> &colors, floatx min, floatx max,
578 floatx value, picture_h::colorrgb *out_color)
579 {
580 int base;
581
582 if( min >= max || colors.get_size() == 0 )
583 return;
584 if( value < min )
585 value = min;
586 if( value > max )
587 value = max;
588
589 value = (value - min ) / (max - min );
590 value = value * floatx(colors.get_size()-1);
591 base = int(value);
592 value -= truncx( value );
593
594 if( base >= (colors.get_size()-1) )
595 *out_color = *colors[base];
596 else
597 {
598 out_color->red = uint8( floatx(colors[base]->red)*(1.0-value) +
599 floatx(colors[base+1]->red)*value );
600 out_color->green = uint8( floatx(colors[base]->green)*(1.0-value) +
601 floatx(colors[base+1]->green)*value );
602 out_color->blue = uint8( floatx(colors[base]->blue)*(1.0-value) +
603 floatx(colors[base+1]->blue)*value );
604 }
605 }
606
autoload_file(const utf8_string & name)607 bool autoload_file( const utf8_string &name ) throw(error_obj)
608 {
609 utf8_string filename;
610 FILE *fp;
611 CodeBlock code;
612
613 for( int i=0; i<autoload_directories.get_size(); i++ )
614 {
615 filename = *autoload_directories[i];
616 filename.append( "/" );
617 filename.append( name );
618 filename.append( ".ump" );
619
620 fp = fopen( filename.c_str(), "r" );
621 if( fp != 0 )
622 {
623 fclose(fp);
624
625 code.set_code_from_file( filename, &name );
626
627 return true;
628 }
629 }
630
631 return false;
632 }
633
parse_create_symbol_vector(const utf8_string & string,Vector<utf8_string> * symbols)634 void parse_create_symbol_vector( const utf8_string &string, Vector<utf8_string> *symbols) throw(error_obj)
635 {
636 utf8_string tmp;
637 int start;
638
639 try
640 {
641 for( int i=0; string.c_str_from( i )[0] != '\0'; i++ )
642 {
643 if( string.test_character( i, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_" ) )
644 {
645 start = i;
646
647 for( i++; string.test_character( i,
648 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789" ); i++ )
649 ;
650 tmp.assign( string, start, i-start );
651 symbols->append( tmp );
652 i--;
653 }
654 else if( string.test_character( i, "0123456789" ) ||
655 ( string.test_character( i, "." ) && string.test_character( i+1, "0123456789" ) ))
656 {
657 start = i;
658
659 for( i++; string.test_character( i, "0123456789." ); i++ )
660 ;
661 tmp.assign( string, start, i-start );
662 symbols->append( tmp );
663 i--;
664 }
665 else if( string.test_character( i, "\"" ) )
666 {
667 start = i;
668
669 for( i++; !string.test_character( i, "\"" ); i++ )
670 {
671 if( string.test_character( i, "\\" ) )
672 {
673 if( string.c_str_from(i)[0] == '\0' )
674 THROW_ERROR( ErrorType_General, _("Expected closing \" but found line break or end of file.") );
675 if( string.test_character( i, "\"\\" ) )
676 i++;
677 }
678 if( string.c_str_from(i)[0] == '\0' || string.test_character( i, "\0\n\r" ) )
679 THROW_ERROR( ErrorType_General, _("Expected closing \" but found line break or end of file.") );
680 }
681 tmp.assign( string, start, i-start+1 );
682 tmp.remove_escape_sequences();
683 symbols->append( tmp );
684 }
685 else if( !string.test_character( i, " \t\n\r" ) )
686 {
687 int len=1;
688 const char *tmp_c_str = string.c_str_from( i );
689
690 if( (tmp_c_str[0] == '+' && tmp_c_str[1] == '+') || (tmp_c_str[0] == '+' && tmp_c_str[1] == '=') ||
691 (tmp_c_str[0] == '-' && tmp_c_str[1] == '-') || (tmp_c_str[0] == '-' && tmp_c_str[1] == '=') ||
692 (tmp_c_str[0] == '*' && tmp_c_str[1] == '=') || (tmp_c_str[0] == '/' && tmp_c_str[1] == '=') ||
693 (tmp_c_str[0] == '\\' && tmp_c_str[1] == '=') || (tmp_c_str[0] == '^' && tmp_c_str[1] == '=') ||
694 (tmp_c_str[0] == '=' && tmp_c_str[1] == '=') || (tmp_c_str[0] == '~' && tmp_c_str[1] == '=') ||
695 (tmp_c_str[0] == '<' && tmp_c_str[1] == '=') || (tmp_c_str[0] == '>' && tmp_c_str[1] == '=') ||
696 (tmp_c_str[0] == '!' && tmp_c_str[1] == '=') )
697 len = 2;
698
699 tmp.assign( string, i, len );
700 symbols->append( tmp );
701 i += (len-1);
702 }
703 }
704 }
705 catch( error_obj error ) { throw error; }
706 catch(...) { THROW_ERROR( ErrorType_Memory, _("Couldn't get memory.") ); }
707 }
708
709 } // namespace math
710