Subversion Repositories Kolibri OS

Rev

Rev 7495 | Go to most recent revision | Details | 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
 
263
{
264
	int x;
265
	__asm fld val
266
	__asm fld ALMOST_HALF
267
	__asm fsub
268
	__asm fistp x
269
	__asm fild x
270
}
271
272
double logic_xor(double a, double b)
273
 
274
	if (a == 0.0)
275
		if (b == 0.0)
276
			return 0.0;
277
		else
278
			return 1.0;
279
	else
280
		if (b == 0.0)
281
			return 1.0;
282
		else
283
			return 0.0;
284
}
285
286
double logic_and(double a, double b)
287
 
288
	if (a == 0.0)
289
		return 0.0;
290
	else
291
		if (b == 0.0)
292
			return 0.0;
293
		else
294
			return 1.0;
295
}
296
297
double logic_or(double a, double b)
298
 
299
	if (a == 0.0)
300
		if (b == 0.0)
301
			return 0.0;
302
		else
303
			return 1.1;
304
	else
305
		return 1.0;
306
}
307
308
double rand_seed;
309
 
310
{
311
	double q = (257.0 * rand_seed + 739.0);	// числа от балды. надо вставить правильные.
312
	rand_seed = q - 65536.0 * func_floor(q / 65536.0); // для хорошего распределения
313
	return q - max * func_floor(q / max);	 // для модуля
314
}
315
316
double func_case(double_list *p)
317
 
318
	if (!p || !p->next)
319
	{
320
		serror(ERR_BADPARAM);
321
		return 0.0;
322
	}
323
	double x = p->val;
324
	int count = (int)p->next->val;
325
	int i, k;
326
327
	double_list *cur = p->next->next;
328
 
329
	for (i = 0; i < count; i++)
330
	{
331
		if (!cur)
332
		{
333
			serror(ERR_BADPARAM);
334
			return 0.0;
335
		}
336
		if (fabs(x - cur->val) < epsilon)
337
		{
338
			if (k != count + 1)
339
			{
340
				serror(ERR_GENERAL);
341
				return 0.0;
342
			}
343
			k = i;
344
		}
345
		cur = cur->next;
346
	}
347
348
	for (i = 0; i < k; i++)
349
 
350
		if (!cur)
351
		{
352
			serror(ERR_BADPARAM);
353
			return 0.0;
354
		}
355
		cur = cur->next;
356
	}
357
	if (!cur)					// проверки бип. достали бип.
358
	{
359
		serror(ERR_BADPARAM);
360
		return 0.0;
361
	}
362
	if (cur->code)
363
		code = cur->code;
364
	return cur->val;
365
}
366
367
#define INF_ARGS -1
368
 
369
370
// represents general mathematical function
371
 
372
typedef double(*matfunc)(double);
373
typedef double(*matfunc2)(double,double);
374
typedef double(*matfunc3)(double,double,double);
375
typedef double(*matfunc_inf)(double_list*);
376
typedef double(*matfunc_str)(char*);
377
378
// used to link function name to the function
379
 
380
{
381
	char name[10];
382
	int args;
383
	void * f;
384
} func;
385
386
// the list of functions
387
 
388
func functions[max_func] =
389
{
390
	"", 1, NULL,								// не помню, с какой целью
391
	"sin", 1, &sin,
392
	"cos", 1, &cos,
393
	"exp", 1, &exp,
394
	"sqrt", 1, &sqrt,
395
	"log", 1, &log,
396
	"tg", 1, &tg,
397
	"ctg", 1, &ctg,
398
	"arcsin", 1, &asin,
399
	"arccos", 1, &acos,
400
	"arctg", 1, &atan,							// не реализовано. возвращает ошибку ERR_GENERAL
401
	"abs", 1, &fabs,
402
	"pow", 2, &pow,
403
	"if", INF_ARGS, &func_if,
404
	"sum",INF_ARGS,&sum,
405
	"isnull",STR_ARG,&func_isnull,				// слегка ч/ж
406
	"min",INF_ARGS,&func_min,
407
	"max",INF_ARGS,&func_max,
408
	"avg",INF_ARGS,&avg,
409
	"ceil",1,&func_ceil,
410
	"round",1,&func_round,
411
	"floor",1,&func_floor,
412
	"and",2,&logic_and,
413
	"or",2,&logic_or,
414
	"xor",2,&logic_xor,
415
	"rand",1,&func_rand,
416
	"case",INF_ARGS,&func_case,
417
	"pi",0,&func_pi,
418
	"eps",0,&func_eps
419
};
420
421
// all delimiters
422
 
423
const char delim[MAXDELIM]="+-*^/%=;(),><#! ";		// not bad words
424
425
426
 
427
 
428
	//return strchr(delim, c) != 0;
429
	for (int i = 0; i < MAXDELIM; i++)
430
		if (c == delim[i])
431
			return 1;
432
	return 0;
433
}
434
435
int isdigit(char c)
436
 
437
	return (c >= '0' && c <= '9');
438
}
439
440
int isalpha2(char c)
441
 
442
	return ((c >= 'a' && c <= 'z')
443
		|| (c >= 'A' && c <= 'Z') || (c=='$'));
444
}
445
446
int iswhite(char c)
447
 
448
	return (c==' ' || c=='\t');
449
}
450
451
452
 
453
 
454
	if (acode != 0)
455
		code = acode;
456
}
457
458
void set_exp(char *exp)
459
 
460
	prog = exp;
461
}
462
463
int get_token()
464
 
465
	int tok;
466
	char *temp;
467
	(token_type) = 0;
468
	tok = 0;
469
	temp = (token);
470
471
	if (*(prog) == '\0')
472
 
473
		*(token) = 0;
474
		tok = FINISHED;
475
		return ((token_type) = DELIMITER);
476
	}
477
	while (iswhite(*(prog))) ++(prog);
478
	if (isdelim(*(prog)))
479
	{
480
		char t=*temp = *(prog);
481
		(prog)++;
482
		temp++;
483
		if ((t == '>' || t == '<' || t == '!') && (*prog) && (*prog == '='))
484
		{
485
			*temp = *(prog);
486
			(prog)++;
487
			temp++;
488
		}
489
		*temp = 0;
490
		return ((token_type) = DELIMITER);
491
	}
492
	if (isdigit(*(prog)))
493
	{
494
		while (!isdelim(*(prog)))
495
			*temp++=*(prog)++;
496
		*temp = '\0';
497
		return ((token_type) = NUMBER);
498
	}
499
	if (isalpha2(*(prog)))
500
	{
501
		while (!isdelim(*(prog)))
502
			*temp++=*(prog)++;
503
		(token_type) = VARIABLE;
504
	}
505
	*temp = '\0';
506
	if ((token_type) == VARIABLE)
507
	{
508
		tok = look_up((token));
509
		if (tok)
510
			(token_type) = FUNCTION;
511
	}
512
	return (token_type);
513
}
514
515
double sign(double d)
516
 
517
  if (d > 0.0)
518
    return 1.0;
519
  if (d < 0.0)
520
    return -1.0;
521
  return 0.0;
522
}
523
524
void putback()
525
 
526
	char *t;
527
	t = (token);
528
	for (;*t;t++)
529
		(prog)--;
530
}
531
532
int get_exp(double *hold)
533
 
534
	code = 0;
535
536
	get_token();
537
 
538
	{
539
		return 0;
540
	}
541
	level1( hold);
542
	putback();
543
  return code==0;
544
}
545
546
void level1(double *hold)
547
 
548
	char op[2];
549
	double h;
550
551
	level1_5( hold);
552
 
553
		*op == '<' || *op == '>' || *op == '=' || *op == '#' || *op == '!')
554
	{
555
		get_token();
556
		level1_5( &h);
557
		logic(op, hold, &h);
558
	}
559
}
560
561
void level1_5(double *hold)
562
 
563
	char op;
564
565
	op = 0;
566
 
567
	{
568
		op = *(token);
569
		get_token();
570
	}
571
	level2( hold);
572
573
	if (op)
574
 
575
		if (*hold == 0.0)
576
			*hold = 1.0;
577
		else
578
			*hold = 0.0;
579
	}
580
}
581
582
void level2(double *hold)
583
 
584
	char op;
585
	double h;
586
587
	level3( hold);
588
 
589
	{
590
		get_token();
591
		level3( &h);
592
		arith(op, hold, &h);
593
	}
594
}
595
596
void level3(double *hold)
597
 
598
	char op;
599
	double h;
600
601
	level4( hold);
602
 
603
	{
604
		get_token();
605
		level4( &h);
606
		arith( op, hold, &h);
607
	}
608
}
609
610
void level4(double *hold)
611
 
612
	double h;
613
	level5( hold);
614
615
	if (*(token) == '^')
616
 
617
		get_token();
618
		level5( &h);
619
		arith( '^', hold, &h);
620
	}
621
}
622
623
void level5(double *hold)
624
 
625
	char op;
626
627
	op = 0;
628
 
629
	{
630
		op = *(token);
631
		get_token();
632
	}
633
	level6( hold);
634
635
	if (op)
636
 
637
}
638
639
void level6(double *hold)
640
 
641
	if ((*(token) == '(') && ((token_type) == DELIMITER))
642
	{
643
		get_token();
644
		level1( hold);
645
		if (*(token) != ')')
646
			  serror( ERR_NOBRACKET);
647
		get_token();
648
	}
649
	else
650
		primitive( hold);
651
}
652
653
void calc_function(double *hold)
654
 
655
  double_list *args = NULL, *last = NULL, *t;
656
  double d;
657
	int i,argc=0,save_code;
658
659
	save_code = code;
660
 
661
	i = look_up(token);
662
663
	if (i == 0)
664
 
665
666
	get_token();
667
 
668
		serror(ERR_NOBRACKET);	// error
669
	//get_token();
670
	if (functions[i].args == STR_ARG)
671
	{
672
		get_token();
673
		d = ((matfunc_str)(functions[i].f))(token);
674
		*hold = d;
675
		get_token();
676
		if (save_code)
677
			code = save_code;
678
		return;
679
	}
680
681
	//last = args = (double_list*)malloc(sizeof(double_list));
682
 
683
	//level1(&args->val);
684
	//get_token();
685
	argc=0;
686
	do
687
	{
688
		get_token();
689
		if (*token == ')')
690
			break;
691
		t = (double_list*)allocmem(sizeof(double_list));
692
		code = 0;
693
		level1(&t->val);
694
		t->code = code;
695
		t->next = NULL;
696
		if (last)
697
			last->next = t;
698
		else
699
			args = t;
700
		last = t;
701
		argc++;
702
	} while (*token == ',');
703
704
	code = save_code;
705
 
706
	if (argc != functions[i].args && functions[i].args >= 0)
707
 
708
		serror(ERR_BADPARAM);
709
	}
710
	else
711
	{
712
		switch (functions[i].args)
713
		{
714
			case 0:
715
				d = ((matfunc0)(functions[i].f))();
716
				break;
717
			case 1:
718
				d = ((matfunc)(functions[i].f))(args->val);
719
				break;
720
			case 2:
721
				d = ((matfunc2)(functions[i].f))(args->val,args->next->val);
722
				break;
723
			case 3:
724
				d = ((matfunc3)(functions[i].f))(args->val,args->next->val,args->next->next->val);
725
				break;
726
			case INF_ARGS:
727
				d = ((matfunc_inf)(functions[i].f))(args);
728
				break;
729
		}
730
	}
731
732
	t = args;
733
 
734
	{
735
		args = t->next;
736
		freemem(t);
737
		t = args;
738
	}
739
740
  *hold = d;
741
 
742
//    serror( ERR_OVERFLOW);
743
744
}
745
 
746
void primitive(double *hold)
747
 
748
	switch (token_type)
749
	{
750
	case VARIABLE:
751
		*hold = find_var(token);
752
		get_token();
753
		return;
754
	case NUMBER:
755
    //
756
		*hold = atof((token));
757
    //if (sscanf(token, "%lf", hold) != 1)
758
	*hold = convert(token);
759
	if (convert_error == ERROR)
760
      serror( ERR_BADNUMER);
761
		get_token();
762
		return;
763
	case FUNCTION:
764
		calc_function( hold);
765
		if (*token != ')')
766
			serror(ERR_NOBRACKET);
767
		get_token();
768
		return;
769
	default:	// error
770
		return;
771
	}
772
}
773
774
void arith(char op, double *r, double *h)
775
 
776
	double t;
777
	switch(op)
778
	{
779
	case '-':
780
		*r = *r - *h;
781
		break;
782
	case '+':
783
		*r = *r + *h;
784
		break;
785
	case '*':
786
		*r = *r * *h;
787
		break;
788
	case '/':
789
	    if (fabs(*h) < epsilon)
790
			serror( ERR_OVERFLOW);
791
		else
792
		  *r = (*r) / (*h);
793
		break;
794
	case '%':
795
	    if (fabs(*h) < epsilon)
796
			serror( ERR_OVERFLOW);
797
		else
798
		{
799
			t = func_floor ((*r) / (*h));
800
			*r = *r - (t * (*h));
801
		}
802
		break;
803
	case '^':
804
		*r = pow(*r, *h);
805
		break;
806
	}
807
}
808
809
void logic(char *op, double *r, double *h)
810
 
811
	double t;
812
	switch (*op)
813
	{
814
	case '<':
815
		if (*(op+1) && *(op+1) == '=')
816
			t = *r <= *h + epsilon ? 1.0 : 0.0;
817
		else
818
			t = *r < *h - epsilon? 1.0 : 0.0;
819
		break;
820
	case '>':
821
		if (*(op+1) && *(op+1) == '=')
822
			t = *r >= *h - epsilon ? 1.0 : 0.0;
823
		else
824
			t = *r > *h + epsilon ? 1.0 : 0.0;
825
		break;
826
	case '=':
827
		t = fabs(*r - *h) <= epsilon ? 1.0 : 0.0;
828
		break;
829
	case '#':
830
		t = fabs(*r - *h) > epsilon ? 1.0 : 0.0;
831
		break;
832
	case '!':
833
		if (*(op+1) && *(op+1) == '=')
834
			t = fabs(*r - *h) > epsilon ? 1.0 : 0.0;
835
		else
836
			serror(ERR_GENERAL);
837
		break;
838
	}
839
	*r = t;
840
}
841
842
843
 
844
 
845
	if (op == '-')
846
		*r = -(*r);
847
}
848
849
bool strcmp(char *s1, char *s2)
850
 
851
	int i;
852
853
	if (s1 == NULL)
854
 
855
			return 0;
856
		else
857
			return 1;
858
	else
859
		if (s2 == NULL)
860
			return 1;
861
862
	for (i = 0;;i++)
863
 
864
		if (s1[i] == '\0')
865
			if (s2[i] == '\0')
866
				return 0;
867
			else
868
				return 1;
869
		else
870
			if (s2[i] == '\0')
871
				return 1;
872
			else
873
			{
874
				if (s1[i] != s2[i])
875
					return 1;
876
			}
877
	}
878
	return 0;
879
}
880
881
882
 
883
 
884
	int i;
885
886
	if (s1 == NULL)
887
 
888
			return 0;
889
		else
890
			return 1;
891
	else
892
		if (s2 == NULL)
893
			return 1;
894
895
	for (i = 0;i
896
 
897
		if (s1[i] == '\0')
898
			if (s2[i] == '\0')
899
				return 0;
900
			else
901
				return 1;
902
		else
903
			if (s2[i] == '\0')
904
				return 1;
905
			else
906
			{
907
				if (s1[i] != s2[i])
908
					return 1;
909
			}
910
	}
911
	return 0;
912
}
913
914
int look_up(char *s)
915
 
916
	int i;
917
918
	for (i = 0; i < max_func; i++)
919
 
920
			return i;
921
	return 0;	// search command/function name
922
}
923
>
924
>
925