Subversion Repositories Kolibri OS

Rev

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