Subversion Repositories Kolibri OS

Rev

Rev 7495 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
990 barsuk 1
 
2
 
3
//#include 
4
//#include 
5
//#include 
6
7
// token types
8
 
9
#define VARIABLE 2
10
#define NUMBER 3
11
#define FUNCTION 4
12
#define FINISHED 10
13
14
//#define allocmem(x) malloc(x)
15
 
16
17
double epsilon = 1e-6;
18
 
19
// structure for most parser functions
20
 
21
	char token[80];
22
 
23
	char *prog;
24
25
	int code;    // error code
26
 
27
28
 
29
 
30
struct double_list
31
 
32
	double val;
33
	int code;			// код ошибки
34
	double_list *next;
35
};
36
37
double tg(double d)
38
 
39
	double cosd = cos(d);
40
	if (fabs(cosd) < epsilon)
41
	{
42
		serror(ERR_OVERFLOW);
43
		return 0.0;
44
	}
45
	return sin(d) / cosd;
46
}
47
48
double ctg(double d)
49
 
50
	double sind = sin(d);
51
	if (fabs(sind) < epsilon)
52
	{
53
		serror(ERR_OVERFLOW);
54
		return 0.0;
55
	}
56
	return cos(d) / sind;
57
}
58
59
double exp(double x)
60
 
61
	__asm {
62
		fld	x
63
		FLDL2E
64
		FMUL
65
66
		FLD st(0)
67
 
68
		FLD1
69
 
70
		FXCH
71
 
72
		F2XM1
73
		fadd
74
		FSCALE
75
		FSTP st(1)
76
	}
77
78
}
79
 
80
double log(double x)
81
 
82
	//return 0.0;
83
	if (x <= 0)
84
	{
85
		serror(ERR_OVERFLOW);
86
		//return 0.0;
87
		__asm {
88
			fldz
89
		}
90
	}
91
	__asm {
92
		FLD1
93
		FLD     x
94
		FYL2X
95
		FLDLN2
96
		FMUL
97
	}
98
}
99
100
double sqrt(double x)
101
 
102
	if (x < 0)
103
	{
104
		serror(ERR_BADPARAM);
105
		__asm {
106
			fldz
107
		}
108
	}
109
	__asm {
110
		fld x
111
		fsqrt
112
	}
113
}
114
115
double atan(double x)
116
 
117
	serror(ERR_GENERAL);
118
	return 0.0; // в лом
119
}
120
121
double pow(double x, double y)
122
 
123
	return exp(y * log(x)); //
124
}
125
126
double func_pi()
127
 
128
	return 3.14159265358979;
129
}
130
131
double func_eps()
132
 
133
	return epsilon;
134
}
135
136
double func_if(double_list *p)
137
 
138
	double_list *a, *b, *c;
139
	a = p;
140
	b = a->next;
141
	if (!b)
142
	{
143
		serror(ERR_BADPARAM);
144
		return 0.0;
145
	}
146
	c = b->next;
147
	if (!c || c->next)
148
	{
149
		serror(ERR_BADPARAM);
150
		return 0.0;
151
	}
152
	if (a->val != 0.0)
153
	{
154
		if (b->code)
155
			code = b->code;
156
		return b->val;
157
	}
158
	else
159
	{
160
		if (c->code)
161
			code = c->code;
162
		return c->val;
163
	}
164
}
165
166
double sum(double_list *p)
167
 
168
	double res = 0.0;
169
	while (p)
170
	{
171
		res += p->val;
172
		if (p->code)
173
			code = p->code;
174
		p = p->next;
175
	}
176
	return res;
177
}
178
179
double func_min(double_list *p)
180
 
181
	if (!p)
182
		serror(ERR_BADPARAM);
183
	double res = p->val;
184
	p = p->next;
185
	while (p)
186
	{
187
		if (p->code)
188
			code = p->code;
189
		if (p->val < res)
190
			res = p->val;
191
		p = p->next;
192
	}
193
	return res;
194
}
195
196
double func_max(double_list *p)
197
 
198
	if (!p)
199
		serror(ERR_BADPARAM);
200
	double res = p->val;
201
	p = p->next;
202
	while (p)
203
	{
204
		if (p->code)
205
			code = p->code;
206
		if (p->val > res)
207
			res = p->val;
208
		p = p->next;
209
	}
210
	return res;
211
}
212
213
double avg(double_list *p)
214
 
215
	double res = 0.0;
216
	int count = 0;
217
	while (p)
218
	{
219
		if (p->code)
220
			code = p->code;
221
		res += p->val;
222
		count++;
223
		p = p->next;
224
	}
225
	return res / count;
226
}
227
228
double func_isnull(char *str)
229
 
230
	if (code != 0)
231
		return 0.0;
232
	double tmp = find_var(str);
233
	int c = code;
234
	code = 0;
235
	if (c != 0)
236
		return 1.0;
237
	return 0.0;
238
}
239
240
const double HALF = 0.5;
241
 
242
{
243
	int x;
244
	__asm fld val
245
	__asm fld HALF				// да, криворуко ^_^
246
	__asm fadd
247
	__asm fistp x
248
	__asm fild x
249
}
250
251
double func_round(double val)
252
 
253
	int x;
254
	__asm fld val
255
	__asm fld epsilon
256
	__asm fadd
257
	__asm fistp x
258
	__asm fild x
259
}
260
261
//const double ALMOST_HALF = 0.5 - epsilon;
262
 
1764 clevermous 263
extern void ALMOST_HALF_init(void)
264
{ ALMOST_HALF = 0.5 - epsilon; }
265
double func_floor(double val)
266
{
990 barsuk 267
	int x;
268
	__asm fld val
269
	__asm fld ALMOST_HALF
270
	__asm fsub
271
	__asm fistp x
272
	__asm fild x
273
}
274
275
double logic_xor(double a, double b)
276
 
277
	if (a == 0.0)
278
		if (b == 0.0)
279
			return 0.0;
280
		else
281
			return 1.0;
282
	else
283
		if (b == 0.0)
284
			return 1.0;
285
		else
286
			return 0.0;
287
}
288
289
double logic_and(double a, double b)
290
 
291
	if (a == 0.0)
292
		return 0.0;
293
	else
294
		if (b == 0.0)
295
			return 0.0;
296
		else
297
			return 1.0;
298
}
299
300
double logic_or(double a, double b)
301
 
302
	if (a == 0.0)
303
		if (b == 0.0)
304
			return 0.0;
305
		else
306
			return 1.1;
307
	else
308
		return 1.0;
309
}
310
311
double rand_seed;
312
 
313
{
314
	double q = (257.0 * rand_seed + 739.0);	// числа от балды. надо вставить правильные.
315
	rand_seed = q - 65536.0 * func_floor(q / 65536.0); // для хорошего распределения
316
	return q - max * func_floor(q / max);	 // для модуля
317
}
318
319
/*
320
 
7495 leency 321
{
990 barsuk 322
	if (!p || !p->next)
323
	{
324
		serror(ERR_BADPARAM);
325
		return 0.0;
326
	}
327
	double x = p->val;
328
	int count = (int)p->next->val;
329
	int i, k;
330
331
	double_list *cur = p->next->next;
332
 
333
	for (i = 0; i < count; i++)
334
	{
335
		if (!cur)
336
		{
337
			serror(ERR_BADPARAM);
338
			return 0.0;
339
		}
340
		if (fabs(x - cur->val) < epsilon)
341
		{
342
			if (k != count + 1)
343
			{
344
				serror(ERR_GENERAL);
345
				return 0.0;
346
			}
347
			k = i;
348
		}
349
		cur = cur->next;
350
	}
351
352
	for (i = 0; i < k; i++)
353
 
354
		if (!cur)
355
		{
356
			serror(ERR_BADPARAM);
357
			return 0.0;
358
		}
359
		cur = cur->next;
360
	}
361
	if (!cur)					// проверки бип. достали бип.
362
	{
363
		serror(ERR_BADPARAM);
364
		return 0.0;
365
	}
366
	if (cur->code)
367
		code = cur->code;
368
	return cur->val;
369
}
370
*/
371
7495 leency 372
#define INF_ARGS -1
990 barsuk 373
 
374
375
// represents general mathematical function
376
 
377
typedef double(*matfunc)(double);
378
typedef double(*matfunc2)(double,double);
379
typedef double(*matfunc3)(double,double,double);
380
typedef double(*matfunc_inf)(double_list*);
381
typedef double(*matfunc_str)(char*);
382
383
// used to link function name to the function
384
 
385
{
386
	char name[10];
387
	int args;
388
	void * f;
389
} func;
390
391
// the list of functions
392
 
393
func functions[max_func] =
7495 leency 394
{
990 barsuk 395
	"", 1, NULL,								// не помню, с какой целью
396
	"sin", 1, &sin,
397
	"cos", 1, &cos,
398
	"exp", 1, &exp,
399
	"sqrt", 1, &sqrt,
400
	"log", 1, &log,
401
	"tg", 1, &tg,
402
	"ctg", 1, &ctg,
403
	"arcsin", 1, &asin,
404
	"arccos", 1, &acos,
405
	"arctg", 1, &atan,							// не реализовано. возвращает ошибку ERR_GENERAL
406
	"abs", 1, &fabs,
407
	"pow", 2, &pow,
408
	"if", INF_ARGS, &func_if,
409
	"sum",INF_ARGS,&sum,
410
	"isnull",STR_ARG,&func_isnull,				// слегка ч/ж
411
	"min",INF_ARGS,&func_min,
412
	"max",INF_ARGS,&func_max,
413
	"avg",INF_ARGS,&avg,
414
	"ceil",1,&func_ceil,
415
	"round",1,&func_round,
416
	"floor",1,&func_floor,
417
	"and",2,&logic_and,
418
	"or",2,&logic_or,
419
	"xor",2,&logic_xor,
420
	"rand",1,&func_rand,
421
	//"case",INF_ARGS,&func_case,
422
	"pi",0,&func_pi,
7495 leency 423
	"eps",0,&func_eps
990 barsuk 424
};
425
426
// all delimiters
427
 
428
const char delim[MAXDELIM]="+-*^/%=;(),><#! ";		// not bad words
429
430
431
 
432
 
433
	//return strchr(delim, c) != 0;
434
	for (int i = 0; i < MAXDELIM; i++)
435
		if (c == delim[i])
436
			return 1;
437
	return 0;
438
}
439
440
int isdigit(char c)
441
 
442
	return (c >= '0' && c <= '9');
443
}
444
445
int isalpha2(char c)
446
 
447
	return ((c >= 'a' && c <= 'z')
448
		|| (c >= 'A' && c <= 'Z') || (c=='$'));
449
}
450
451
int iswhite(char c)
452
 
453
	return (c==' ' || c=='\t');
454
}
455
456
457
 
458
 
459
	if (acode != 0)
460
		code = acode;
461
}
462
463
void set_exp(char *exp)
464
 
465
	prog = exp;
466
}
467
468
int get_token()
469
 
470
	int tok;
471
	char *temp;
472
	(token_type) = 0;
473
	tok = 0;
474
	temp = (token);
475
476
	if (*(prog) == '\0')
477
 
478
		*(token) = 0;
479
		tok = FINISHED;
480
		return ((token_type) = DELIMITER);
481
	}
482
	while (iswhite(*(prog))) ++(prog);
483
	if (isdelim(*(prog)))
484
	{
485
		char t=*temp = *(prog);
486
		(prog)++;
487
		temp++;
488
		if ((t == '>' || t == '<' || t == '!') && (*prog) && (*prog == '='))
489
		{
490
			*temp = *(prog);
491
			(prog)++;
492
			temp++;
493
		}
494
		*temp = 0;
495
		return ((token_type) = DELIMITER);
496
	}
497
	if (isdigit(*(prog)))
498
	{
499
		while (!isdelim(*(prog)))
500
			*temp++=*(prog)++;
501
		*temp = '\0';
502
		return ((token_type) = NUMBER);
503
	}
504
	if (isalpha2(*(prog)))
505
	{
506
		while (!isdelim(*(prog)))
507
			*temp++=*(prog)++;
508
		(token_type) = VARIABLE;
509
	}
510
	*temp = '\0';
511
	if ((token_type) == VARIABLE)
512
	{
513
		tok = look_up((token));
514
		if (tok)
515
			(token_type) = FUNCTION;
516
	}
517
	return (token_type);
518
}
519
520
double sign(double d)
521
 
522
  if (d > 0.0)
523
    return 1.0;
524
  if (d < 0.0)
525
    return -1.0;
526
  return 0.0;
527
}
528
529
void putback()
530
 
531
	char *t;
532
	t = (token);
533
	for (;*t;t++)
534
		(prog)--;
535
}
536
537
int get_exp(double *hold)
538
 
539
	code = 0;
540
541
	get_token();
542
 
543
	{
544
		return 0;
545
	}
546
	level1( hold);
547
	putback();
548
  return code==0;
549
}
550
551
void level1(double *hold)
552
 
553
	char op[2];
554
	double h;
555
556
	level1_5( hold);
557
 
558
		*op == '<' || *op == '>' || *op == '=' || *op == '#' || *op == '!')
559
	{
560
		get_token();
561
		level1_5( &h);
562
		logic(op, hold, &h);
563
	}
564
}
565
566
void level1_5(double *hold)
567
 
568
	char op;
569
570
	op = 0;
571
 
572
	{
573
		op = *(token);
574
		get_token();
575
	}
576
	level2( hold);
577
578
	if (op)
579
 
580
		if (*hold == 0.0)
581
			*hold = 1.0;
582
		else
583
			*hold = 0.0;
584
	}
585
}
586
587
void level2(double *hold)
588
 
589
	char op;
590
	double h;
591
592
	level3( hold);
593
 
594
	{
595
		get_token();
596
		level3( &h);
597
		arith(op, hold, &h);
598
	}
599
}
600
601
void level3(double *hold)
602
 
603
	char op;
604
	double h;
605
606
	level4( hold);
607
 
608
	{
609
		get_token();
610
		level4( &h);
611
		arith( op, hold, &h);
612
	}
613
}
614
615
void level4(double *hold)
616
 
617
	double h;
618
	level5( hold);
619
620
	if (*(token) == '^')
621
 
622
		get_token();
623
		level5( &h);
624
		arith( '^', hold, &h);
625
	}
626
}
627
628
void level5(double *hold)
629
 
630
	char op;
631
632
	op = 0;
633
 
634
	{
635
		op = *(token);
636
		get_token();
637
	}
638
	level6( hold);
639
640
	if (op)
641
 
642
}
643
644
void level6(double *hold)
645
 
646
	if ((*(token) == '(') && ((token_type) == DELIMITER))
647
	{
648
		get_token();
649
		level1( hold);
650
		if (*(token) != ')')
651
			  serror( ERR_NOBRACKET);
652
		get_token();
653
	}
654
	else
655
		primitive( hold);
656
}
657
658
void calc_function(double *hold)
659
 
660
  double_list *args = NULL, *last = NULL, *t;
661
  double d;
662
	int i,argc=0,save_code;
663
664
	save_code = code;
665
 
666
	i = look_up(token);
667
668
	if (i == 0)
669
 
670
671
	get_token();
672
 
673
		serror(ERR_NOBRACKET);	// error
674
	//get_token();
675
	if (functions[i].args == STR_ARG)
676
	{
677
		get_token();
678
		d = ((matfunc_str)(functions[i].f))(token);
679
		*hold = d;
680
		get_token();
681
		if (save_code)
682
			code = save_code;
683
		return;
684
	}
685
686
	//last = args = (double_list*)malloc(sizeof(double_list));
687
 
688
	//level1(&args->val);
689
	//get_token();
690
	argc=0;
691
	do
692
	{
693
		get_token();
694
		if (*token == ')')
695
			break;
696
		t = (double_list*)allocmem(sizeof(double_list));
697
		code = 0;
698
		level1(&t->val);
699
		t->code = code;
700
		t->next = NULL;
701
		if (last)
702
			last->next = t;
703
		else
704
			args = t;
705
		last = t;
706
		argc++;
707
	} while (*token == ',');
708
709
	code = save_code;
710
 
711
	if (argc != functions[i].args && functions[i].args >= 0)
712
 
713
		serror(ERR_BADPARAM);
714
	}
715
	else
716
	{
717
		switch (functions[i].args)
718
		{
719
			case 0:
720
				d = ((matfunc0)(functions[i].f))();
721
				break;
722
			case 1:
723
				d = ((matfunc)(functions[i].f))(args->val);
724
				break;
725
			case 2:
726
				d = ((matfunc2)(functions[i].f))(args->val,args->next->val);
727
				break;
728
			case 3:
729
				d = ((matfunc3)(functions[i].f))(args->val,args->next->val,args->next->next->val);
730
				break;
731
			case INF_ARGS:
732
				d = ((matfunc_inf)(functions[i].f))(args);
733
				break;
734
		}
735
	}
736
737
	t = args;
738
 
739
	{
740
		args = t->next;
741
		freemem(t);
742
		t = args;
743
	}
744
745
  *hold = d;
746
 
747
//    serror( ERR_OVERFLOW);
748
749
}
750
 
751
void primitive(double *hold)
752
 
753
	switch (token_type)
754
	{
755
	case VARIABLE:
756
		*hold = find_var(token);
757
		get_token();
758
		return;
759
	case NUMBER:
760
    //
761
		*hold = atof((token));
762
    //if (sscanf(token, "%lf", hold) != 1)
763
	*hold = convert(token);
764
	if (convert_error == ERROR)
765
      serror( ERR_BADNUMER);
766
		get_token();
767
		return;
768
	case FUNCTION:
769
		calc_function( hold);
770
		if (*token != ')')
771
			serror(ERR_NOBRACKET);
772
		get_token();
773
		return;
774
	default:	// error
775
		return;
776
	}
777
}
778
779
void arith(char op, double *r, double *h)
780
 
781
	double t;
782
	switch(op)
783
	{
784
	case '-':
785
		*r = *r - *h;
786
		break;
787
	case '+':
788
		*r = *r + *h;
789
		break;
790
	case '*':
791
		*r = *r * *h;
792
		break;
793
	case '/':
794
	    if (fabs(*h) < epsilon)
795
			serror( ERR_OVERFLOW);
796
		else
797
		  *r = (*r) / (*h);
798
		break;
799
	case '%':
800
	    if (fabs(*h) < epsilon)
801
			serror( ERR_OVERFLOW);
802
		else
803
		{
804
			t = func_floor ((*r) / (*h));
805
			*r = *r - (t * (*h));
806
		}
807
		break;
808
	case '^':
809
		*r = pow(*r, *h);
810
		break;
811
	}
812
}
813
814
void logic(char *op, double *r, double *h)
815
 
816
	double t;
817
	switch (*op)
818
	{
819
	case '<':
820
		if (*(op+1) && *(op+1) == '=')
821
			t = *r <= *h + epsilon ? 1.0 : 0.0;
822
		else
823
			t = *r < *h - epsilon? 1.0 : 0.0;
824
		break;
825
	case '>':
826
		if (*(op+1) && *(op+1) == '=')
827
			t = *r >= *h - epsilon ? 1.0 : 0.0;
828
		else
829
			t = *r > *h + epsilon ? 1.0 : 0.0;
830
		break;
831
	case '=':
832
		t = fabs(*r - *h) <= epsilon ? 1.0 : 0.0;
833
		break;
834
	case '#':
835
		t = fabs(*r - *h) > epsilon ? 1.0 : 0.0;
836
		break;
837
	case '!':
838
		if (*(op+1) && *(op+1) == '=')
839
			t = fabs(*r - *h) > epsilon ? 1.0 : 0.0;
840
		else
841
			serror(ERR_GENERAL);
842
		break;
843
	}
844
	*r = t;
845
}
846
847
848
 
849
 
850
	if (op == '-')
851
		*r = -(*r);
852
}
853
854
bool strcmp(char *s1, char *s2)
855
 
856
	int i;
857
858
	if (s1 == NULL)
859
 
860
			return 0;
861
		else
862
			return 1;
863
	else
864
		if (s2 == NULL)
865
			return 1;
866
867
	for (i = 0;;i++)
868
 
869
		if (s1[i] == '\0')
870
			if (s2[i] == '\0')
871
				return 0;
872
			else
873
				return 1;
874
		else
875
			if (s2[i] == '\0')
876
				return 1;
877
			else
878
			{
879
				if (s1[i] != s2[i])
880
					return 1;
881
			}
882
	}
883
	return 0;
884
}
885
886
887
 
888
 
889
	int i;
890
891
	if (s1 == NULL)
892
 
893
			return 0;
894
		else
895
			return 1;
896
	else
897
		if (s2 == NULL)
898
			return 1;
899
900
	for (i = 0;i
901
 
902
		if (s1[i] == '\0')
903
			if (s2[i] == '\0')
904
				return 0;
905
			else
906
				return 1;
907
		else
908
			if (s2[i] == '\0')
909
				return 1;
910
			else
911
			{
912
				if (s1[i] != s2[i])
913
					return 1;
914
			}
915
	}
916
	return 0;
917
}
918
919
int look_up(char *s)
920
 
921
	int i;
922
923
	for (i = 0; i < max_func; i++)
924
 
925
			return i;
926
	return 0;	// search command/function name
927
}
928
929
unsigned int chrnum(char* text, char symbol)
930
 
7516 leency 931
	int num = 0;
932
	int i = 0;
933
	while(text[i])
934
	{
935
		if (text[i] == symbol) num++;
936
		i++;
937
	}
938
	return num;
939
}
940
>
941
>
942