Subversion Repositories planix.SVN

Rev

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

Rev Author Line No. Line
2 - 1
%{
2
	#include	<u.h>
3
	#include	<libc.h>
4
	#include	<bio.h>
5
 
6
	#define	bsp_max	5000
7
 
8
	Biobuf	*in;
9
	Biobuf	bstdin;
10
	Biobuf	bstdout;
11
	char	cary[1000];
12
	char*	cp = { cary };
13
	char	string[1000];
14
	char*	str = { string };
15
	int	crs = 128;
16
	int	rcrs = 128;	/* reset crs */
17
	int	bindx = 0;
18
	int	lev = 0;
19
	int	ln;
20
	char*	ttp;
21
	char*	ss = "";
22
	int	bstack[10] = { 0 };
23
	char*	numb[15] =
24
	{
25
		" 0", " 1", " 2", " 3", " 4", " 5",
26
		" 6", " 7", " 8", " 9", " 10", " 11",
27
		" 12", " 13", " 14"
28
	};
29
	char*	pre;
30
	char*	post;
31
 
32
	long	peekc = -1;
33
	int	sargc;
34
	int	ifile;
35
	char**	sargv;
36
 
37
	char	*funtab[] =
38
	{
39
		"<1>","<2>","<3>","<4>","<5>",
40
		"<6>","<7>","<8>","<9>","<10>",
41
		"<11>","<12>","<13>","<14>","<15>",
42
		"<16>","<17>","<18>","<19>","<20>",
43
		"<21>","<22>","<23>","<24>","<25>",
44
		"<26>"
45
	};
46
	char	*atab[] =
47
	{
48
		"<221>","<222>","<223>","<224>","<225>",
49
		"<226>","<227>","<228>","<229>","<230>",
50
		"<231>","<232>","<233>","<234>","<235>",
51
		"<236>","<237>","<238>","<239>","<240>",
52
		"<241>","<242>","<243>","<244>","<245>",
53
		"<246>"
54
	};
55
	char*	letr[26] =
56
	{
57
		"a","b","c","d","e","f","g","h","i","j",
58
		"k","l","m","n","o","p","q","r","s","t",
59
		"u","v","w","x","y","z"
60
	};
61
	char*	dot = { "." };
62
	char*	bspace[bsp_max];
63
	char**	bsp_nxt = bspace;
64
	int	bdebug = 0;
65
	int	lflag;
66
	int	cflag;
67
	int	sflag;
68
 
69
	char*	bundle(int, ...);
70
	void	conout(char*, char*);
71
	int	cpeek(int, int, int);
72
	int	getch(void);
73
	char*	geta(char*);
74
	char*	getf(char*);
75
	void	getout(void);
76
	void	output(char*);
77
	void	pp(char*);
78
	void	routput(char*);
79
	void	tp(char*);
80
	void	yyerror(char*, ...);
81
	int	yyparse(void);
82
 
83
	typedef	void*	pointer;
84
	#pragma	varargck	type	"lx"	pointer
85
 
86
%}
87
%union
88
{
89
	char*	cptr;
90
	int	cc;
91
}
92
 
93
%type	<cptr>	pstat stat stat1 def slist dlets e ase nase
94
%type	<cptr>	slist re fprefix cargs eora cons constant lora
95
%type	<cptr>	crs
96
 
97
%token	<cptr>	LETTER EQOP _AUTO DOT
98
%token	<cc>	DIGIT SQRT LENGTH _IF FFF EQ
99
%token	<cc>	_PRINT _WHILE _FOR NE LE GE INCR DECR
100
%token	<cc>	_RETURN _BREAK _DEFINE BASE OBASE SCALE
101
%token	<cc>	QSTR ERROR
102
 
103
%right	'=' EQOP
104
%left	'+' '-'
105
%left	'*' '/' '%'
106
%right	'^'
107
%left	UMINUS
108
 
109
%%
110
start:
111
	start stuff
112
|	stuff
113
 
114
stuff:
115
	pstat tail
116
	{
117
		output($1);
118
	}
119
|	def dargs ')' '{' dlist slist '}'
120
	{
121
		ttp = bundle(6, pre, $6, post , "0", numb[lev], "Q");
122
		conout(ttp, (char*)$1);
123
		rcrs = crs;
124
		output("");
125
		lev = bindx = 0;
126
	}
127
 
128
dlist:
129
	tail
130
|	dlist _AUTO dlets tail
131
 
132
stat:
133
	stat1
134
|	nase
135
	{
136
		if(sflag)
137
			bundle(2, $1, "s.");
138
	}
139
 
140
pstat:
141
	stat1
142
	{
143
		if(sflag)
144
			bundle(2, $1, "0");
145
	}
146
|	nase
147
	{
148
		if(!sflag)
149
			bundle(2, $1, "ps.");
150
	}
151
 
152
stat1:
153
	{
154
		bundle(1, "");
155
	}
156
|	ase
157
	{
158
		bundle(2, $1, "s.");
159
	}
160
|	SCALE '=' e
161
	{
162
		bundle(2, $3, "k");
163
	}
164
|	SCALE EQOP e
165
	{
166
		bundle(4, "K", $3, $2, "k");
167
	}
168
|	BASE '=' e
169
	{
170
		bundle(2, $3, "i");
171
	}
172
|	BASE EQOP e
173
	{
174
		bundle(4, "I", $3, $2, "i");
175
	}
176
|	OBASE '=' e
177
	{
178
		bundle(2, $3, "o");
179
	}
180
|	OBASE EQOP e
181
	{
182
		bundle(4, "O", $3, $2, "o");
183
	}
184
|	QSTR
185
	{
186
		bundle(3, "[", $1, "]P");
187
	}
188
|	_BREAK
189
	{
190
		bundle(2, numb[lev-bstack[bindx-1]], "Q");
191
	}
192
|	_PRINT e
193
	{
194
		bundle(2, $2, "ps.");
195
	}
196
|	_RETURN e
197
	{
198
		bundle(4, $2, post, numb[lev], "Q");
199
	}
200
|	_RETURN
201
	{
202
		bundle(4, "0", post, numb[lev], "Q");
203
	}
204
|	'{' slist '}'
205
	{
206
		$$ = $2;
207
	}
208
|	FFF
209
	{
210
		bundle(1, "fY");
211
	}
212
|	_IF crs BLEV '(' re ')' stat
213
	{
214
		conout($7, $2);
215
		bundle(3, $5, $2, " ");
216
	}
217
|	_WHILE crs '(' re ')' stat BLEV
218
	{
219
		bundle(3, $6, $4, $2);
220
		conout($$, $2);
221
		bundle(3, $4, $2, " ");
222
	}
223
|	fprefix crs re ';' e ')' stat BLEV
224
	{
225
		bundle(5, $7, $5, "s.", $3, $2);
226
		conout($$, $2);
227
		bundle(5, $1, "s.", $3, $2, " ");
228
	}
229
|	'~' LETTER '=' e
230
	{
231
		bundle(3, $4, "S", $2);
232
	}
233
 
234
fprefix:
235
	_FOR '(' e ';'
236
	{
237
		$$ = $3;
238
	}
239
 
240
BLEV:
241
	=
242
	{
243
		--bindx;
244
	}
245
 
246
slist:
247
	stat
248
|	slist tail stat
249
	{
250
		bundle(2, $1, $3);
251
	}
252
 
253
tail:
254
	'\n'
255
	{
256
		ln++;
257
	}
258
|	';'
259
 
260
re:
261
	e EQ e
262
	{
263
		$$ = bundle(3, $1, $3, "=");
264
	}
265
|	e '<' e
266
	{
267
		bundle(3, $1, $3, ">");
268
	}
269
|	e '>' e
270
	{
271
		bundle(3, $1, $3, "<");
272
	}
273
|	e NE e
274
	{
275
		bundle(3, $1, $3, "!=");
276
	}
277
|	e GE e
278
	{
279
		bundle(3, $1, $3, "!>");
280
	}
281
|	e LE e
282
	{
283
		bundle(3, $1, $3, "!<");
284
	}
285
|	e
286
	{
287
		bundle(2, $1, " 0!=");
288
	}
289
 
290
nase:
291
	'(' e ')'
292
	{
293
		$$ = $2;
294
	}
295
|	cons
296
	{
297
		bundle(3, " ", $1, " ");
298
	}
299
|	DOT cons
300
	{
301
		bundle(3, " .", $2, " ");
302
	}
303
|	cons DOT cons
304
	{
305
		bundle(5, " ", $1, ".", $3, " ");
306
	}
307
|	cons DOT
308
	{
309
		bundle(4, " ", $1, ".", " ");
310
	}
311
|	DOT
312
	{
313
		$<cptr>$ = "l.";
314
	}
315
|	LETTER '[' e ']'
316
	{
317
		bundle(3, $3, ";", geta($1));
318
	}
319
|	LETTER INCR
320
	{
321
		bundle(4, "l", $1, "d1+s", $1);
322
	}
323
|	INCR LETTER
324
	{
325
		bundle(4, "l", $2, "1+ds", $2);
326
	}
327
|	DECR LETTER
328
	{
329
		bundle(4, "l", $2, "1-ds", $2);
330
	}
331
|	LETTER DECR
332
	{
333
		bundle(4, "l", $1, "d1-s", $1);
334
	}
335
|	LETTER '[' e ']' INCR
336
	{
337
		bundle(7, $3, ";", geta($1), "d1+" ,$3, ":" ,geta($1));
338
	}
339
|	INCR LETTER '[' e ']'
340
	{
341
		bundle(7, $4, ";", geta($2), "1+d", $4, ":", geta($2));
342
	}
343
|	LETTER '[' e ']' DECR
344
	{
345
		bundle(7, $3, ";", geta($1), "d1-", $3, ":", geta($1));
346
	}
347
|	DECR LETTER '[' e ']'
348
	{
349
		bundle(7, $4, ";", geta($2), "1-d", $4, ":" ,geta($2));
350
	}
351
|	SCALE INCR
352
	{
353
		bundle(1, "Kd1+k");
354
	}
355
|	INCR SCALE
356
	{
357
		bundle(1, "K1+dk");
358
	}
359
|	SCALE DECR
360
	{
361
		bundle(1, "Kd1-k");
362
	}
363
|	DECR SCALE
364
	{
365
		bundle(1, "K1-dk");
366
	}
367
|	BASE INCR
368
	{
369
		bundle(1, "Id1+i");
370
	}
371
|	INCR BASE
372
	{
373
		bundle(1, "I1+di");
374
	}
375
|	BASE DECR
376
	{
377
		bundle(1, "Id1-i");
378
	}
379
|	DECR BASE
380
	{
381
		bundle(1, "I1-di");
382
	}
383
|	OBASE INCR
384
	{
385
		bundle(1, "Od1+o");
386
	}
387
|	INCR OBASE
388
	{
389
		bundle(1, "O1+do");
390
	}
391
|	OBASE DECR
392
	{
393
		bundle(1, "Od1-o");
394
	}
395
|	DECR OBASE
396
	{
397
		bundle(1, "O1-do");
398
	}
399
|	LETTER '(' cargs ')'
400
	{
401
		bundle(4, $3, "l", getf($1), "x");
402
	}
403
|	LETTER '(' ')'
404
	{
405
		bundle(3, "l", getf($1), "x");
406
	}
407
|	LETTER = {
408
		bundle(2, "l", $1);
409
	}
410
|	LENGTH '(' e ')'
411
	{
412
		bundle(2, $3, "Z");
413
	}
414
|	SCALE '(' e ')'
415
	{
416
		bundle(2, $3, "X");
417
	}
418
|	'?'
419
	{
420
		bundle(1, "?");
421
	}
422
|	SQRT '(' e ')'
423
	{
424
		bundle(2, $3, "v");
425
	}
426
|	'~' LETTER
427
	{
428
		bundle(2, "L", $2);
429
	}
430
|	SCALE
431
	{
432
		bundle(1, "K");
433
	}
434
|	BASE
435
	{
436
		bundle(1, "I");
437
	}
438
|	OBASE
439
	{
440
		bundle(1, "O");
441
	}
442
|	'-' e
443
	{
444
		bundle(3, " 0", $2, "-");
445
	}
446
|	e '+' e
447
	{
448
		bundle(3, $1, $3, "+");
449
	}
450
|	e '-' e
451
	{
452
		bundle(3, $1, $3, "-");
453
	}
454
|	e '*' e
455
	{
456
		bundle(3, $1, $3, "*");
457
	}
458
|	e '/' e
459
	{
460
		bundle(3, $1, $3, "/");
461
	}
462
|	e '%' e
463
	{
464
		bundle(3, $1, $3, "%%");
465
	}
466
|	e '^' e
467
	{
468
		bundle(3, $1, $3, "^");
469
	}
470
 
471
ase:
472
	LETTER '=' e
473
	{
474
		bundle(3, $3, "ds", $1);
475
	}
476
|	LETTER '[' e ']' '=' e
477
	{
478
		bundle(5, $6, "d", $3, ":", geta($1));
479
	}
480
|	LETTER EQOP e
481
	{
482
		bundle(6, "l", $1, $3, $2, "ds", $1);
483
	}
484
|	LETTER '[' e ']' EQOP e
485
	{
486
		bundle(9, $3, ";", geta($1), $6, $5, "d", $3, ":", geta($1));
487
	}
488
 
489
e:
490
	ase
491
|	nase
492
 
493
cargs:
494
	eora
495
|	cargs ',' eora
496
	{
497
		bundle(2, $1, $3);
498
	}
499
 
500
eora:
501
	e
502
|	LETTER '[' ']'
503
	{
504
		bundle(2, "l", geta($1));
505
	}
506
 
507
cons:
508
	constant
509
	{
510
		*cp++ = 0;
511
	}
512
 
513
constant:
514
	'_'
515
	{
516
		$<cptr>$ = cp;
517
		*cp++ = '_';
518
	}
519
|	DIGIT
520
	{
521
		$<cptr>$ = cp;
522
		*cp++ = $1;
523
	}
524
|	constant DIGIT
525
	{
526
		*cp++ = $2;
527
	}
528
 
529
crs:
530
	=
531
	{
532
		$$ = cp;
533
		*cp++ = '<';
534
		*cp++ = crs/100+'0';
535
		*cp++ = (crs%100)/10+'0';
536
		*cp++ = crs%10+'0';
537
		*cp++ = '>';
538
		*cp++ = '\0';
539
		if(crs++ >= 220) {
540
			yyerror("program too big");
541
			getout();
542
		}
543
		bstack[bindx++] = lev++;
544
	}
545
 
546
def:
547
	_DEFINE LETTER '('
548
	{
549
		$$ = getf($2);
550
		pre = (char*)"";
551
		post = (char*)"";
552
		lev = 1;
553
		bindx = 0;
554
		bstack[bindx] = 0;
555
	}
556
 
557
dargs:
558
|	lora
559
	{
560
		pp((char*)$1);
561
	}
562
|	dargs ',' lora
563
	{
564
		pp((char*)$3);
565
	}
566
 
567
dlets:
568
	lora
569
	{
570
		tp((char*)$1);
571
	}
572
|	dlets ',' lora
573
	{
574
		tp((char*)$3);
575
	}
576
 
577
lora:
578
	LETTER
579
	{
580
		$<cptr>$=$1;
581
	}
582
|	LETTER '[' ']'
583
	{
584
		$$ = geta($1);
585
	}
586
 
587
%%
588
 
589
int
590
yylex(void)
591
{
592
	int c, ch;
593
 
594
restart:
595
	c = getch();
596
	peekc = -1;
597
	while(c == ' ' || c == '\t')
598
		c = getch();
599
	if(c == '\\') {
600
		getch();
601
		goto restart;
602
	}
603
	if(c >= 'a' && c <= 'z') {
604
		/* look ahead to look for reserved words */
605
		peekc = getch();
606
		if(peekc >= 'a' && peekc <= 'z') { /* must be reserved word */
607
			if(c=='p' && peekc=='r') {
608
				c = _PRINT;
609
				goto skip;
610
			}
611
			if(c=='i' && peekc=='f') {
612
				c = _IF;
613
				goto skip;
614
			}
615
			if(c=='w' && peekc=='h') {
616
				c = _WHILE;
617
				goto skip;
618
			}
619
			if(c=='f' && peekc=='o') {
620
				c = _FOR;
621
				goto skip;
622
			}
623
			if(c=='s' && peekc=='q') {
624
				c = SQRT;
625
				goto skip;
626
			}
627
			if(c=='r' && peekc=='e') {
628
				c = _RETURN;
629
				goto skip;
630
			}
631
			if(c=='b' && peekc=='r') {
632
				c = _BREAK;
633
				goto skip;
634
			}
635
			if(c=='d' && peekc=='e') {
636
				c = _DEFINE;
637
				goto skip;
638
			}
639
			if(c=='s' && peekc=='c') {
640
				c = SCALE;
641
				goto skip;
642
			}
643
			if(c=='b' && peekc=='a') {
644
				c = BASE;
645
				goto skip;
646
			}
647
			if(c=='i' && peekc=='b') {
648
				c = BASE;
649
				goto skip;
650
			}
651
			if(c=='o' && peekc=='b') {
652
				c = OBASE;
653
				goto skip;
654
			}
655
			if(c=='d' && peekc=='i') {
656
				c = FFF;
657
				goto skip;
658
			}
659
			if(c=='a' && peekc=='u') {
660
				c = _AUTO;
661
				goto skip;
662
			}
663
			if(c=='l' && peekc=='e') {
664
				c = LENGTH;
665
				goto skip;
666
			}
667
			if(c=='q' && peekc=='u')
668
				getout();
669
			/* could not be found */
670
			return ERROR;
671
 
672
		skip:	/* skip over rest of word */
673
			peekc = -1;
674
			for(;;) {
675
				ch = getch();
676
				if(ch < 'a' || ch > 'z')
677
					break;
678
			}
679
			peekc = ch;
680
			return c;
681
		}
682
 
683
		/* usual case; just one single letter */
684
		yylval.cptr = letr[c-'a'];
685
		return LETTER;
686
	}
687
	if((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {
688
		yylval.cc = c;
689
		return DIGIT;
690
	}
691
	switch(c) {
692
	case '.':
693
		return DOT;
694
	case '*':
695
		yylval.cptr = "*";
696
		return cpeek('=', EQOP, c);
697
	case '%':
698
		yylval.cptr = "%%";
699
		return cpeek('=', EQOP, c);
700
	case '^':
701
		yylval.cptr = "^";
702
		return cpeek('=', EQOP, c);
703
	case '+':
704
		ch = cpeek('=', EQOP, c);
705
		if(ch == EQOP) {
706
			yylval.cptr = "+";
707
			return ch;
708
		}
709
		return cpeek('+', INCR, c);
710
	case '-':
711
		ch = cpeek('=', EQOP, c);
712
		if(ch == EQOP) {
713
			yylval.cptr = "-";
714
			return ch;
715
		}
716
		return cpeek('-', DECR, c);
717
	case '=':
718
		return cpeek('=', EQ, '=');
719
	case '<':
720
		return cpeek('=', LE, '<');
721
	case '>':
722
		return cpeek('=', GE, '>');
723
	case '!':
724
		return cpeek('=', NE, '!');
725
	case '/':
726
		ch = cpeek('=', EQOP, c);
727
		if(ch == EQOP) {
728
			yylval.cptr = "/";
729
			return ch;
730
		}
731
		if(peekc == '*') {
732
			peekc = -1;
733
			for(;;) {
734
				ch = getch();
735
				if(ch == '*') {
736
					peekc = getch();
737
					if(peekc == '/') {
738
						peekc = -1;
739
						goto restart;
740
					}
741
				}
742
			}
743
		}
744
		return c;
745
	case '"':
746
		yylval.cptr = str;
747
		while((c=getch()) != '"'){
748
			*str++ = c;
749
			if(str >= &string[999]){
750
				yyerror("string space exceeded");
751
				getout();
752
			}
753
		}
754
		*str++ = 0;
755
		return QSTR;
756
	default:
757
		return c;
758
	}
759
}
760
 
761
int
762
cpeek(int c, int yes, int no)
763
{
764
 
765
	peekc = getch();
766
	if(peekc == c) {
767
		peekc = -1;
768
		return yes;
769
	}
770
	return no;
771
}
772
 
773
int
774
getch(void)
775
{
776
	long ch;
777
 
778
loop:
779
	ch = peekc;
780
	if(ch < 0){
781
		if(in == 0)
782
			ch = -1;
783
		else
784
			ch = Bgetc(in);
785
	}
786
	peekc = -1;
787
	if(ch >= 0)
788
		return ch;
789
	ifile++;
790
	if(ifile > sargc) {
791
		if(ifile >= sargc+2)
792
			getout();
793
		in = &bstdin;
794
		Binit(in, 0, OREAD);
795
		ln = 0;
796
		goto loop;
797
	}
798
	if(in)
799
		Bterm(in);
800
	if((in = Bopen(sargv[ifile], OREAD)) != 0){
801
		ln = 0;
802
		ss = sargv[ifile];
803
		goto loop;
804
	}
805
	yyerror("cannot open input file");
806
	return 0;		/* shut up ken */
807
}
808
 
809
char*
810
bundle(int a, ...)
811
{
812
	int i;
813
	char **q;
814
	va_list arg;
815
 
816
	i = a;
817
	va_start(arg, a);
818
	q = bsp_nxt;
819
	if(bdebug)
820
		fprint(2, "bundle %d elements at %lx\n", i, q);
821
	while(i-- > 0) {
822
		if(bsp_nxt >= &bspace[bsp_max])
823
			yyerror("bundling space exceeded");
824
		*bsp_nxt++ = va_arg(arg, char*);
825
	}
826
	*bsp_nxt++ = 0;
827
	va_end(arg);
828
	yyval.cptr = (char*)q;
829
	return (char*)q;
830
}
831
 
832
void
833
routput(char *p)
834
{
835
	char **pp;
836
 
837
	if(bdebug)
838
		fprint(2, "routput(%lx)\n", p);
839
	if((char**)p >= &bspace[0] && (char**)p < &bspace[bsp_max]) {
840
		/* part of a bundle */
841
		pp = (char**)p;
842
		while(*pp != 0)
843
			routput(*pp++);
844
	} else
845
		Bprint(&bstdout, p);	/* character string */
846
}
847
 
848
void
849
output(char *p)
850
{
851
	routput(p);
852
	bsp_nxt = &bspace[0];
853
	Bprint(&bstdout, "\n");
854
	Bflush(&bstdout);
855
	cp = cary;
856
	crs = rcrs;
857
}
858
 
859
void
860
conout(char *p, char *s)
861
{
862
	Bprint(&bstdout, "[");
863
	routput(p);
864
	Bprint(&bstdout, "]s%s\n", s);
865
	Bflush(&bstdout);
866
	lev--;
867
}
868
 
869
void
870
yyerror(char *s, ...)
871
{
872
	if(ifile > sargc)
873
		ss = "stdin";
874
	Bprint(&bstdout, "c[%s:%d %s]pc\n", ss, ln+1, s);
875
	Bflush(&bstdout);
876
	cp = cary;
877
	crs = rcrs;
878
	bindx = 0;
879
	lev = 0;
880
	bsp_nxt = &bspace[0];
881
}
882
 
883
void
884
pp(char *s)
885
{
886
	/* puts the relevant stuff on pre and post for the letter s */
887
	bundle(3, "S", s, pre);
888
	pre = yyval.cptr;
889
	bundle(4, post, "L", s, "s.");
890
	post = yyval.cptr;
891
}
892
 
893
void
894
tp(char *s)
895
{
896
	/* same as pp, but for temps */
897
	bundle(3, "0S", s, pre);
898
	pre = yyval.cptr;
899
	bundle(4, post, "L", s, "s.");
900
	post = yyval.cptr;
901
}
902
 
903
void
904
yyinit(int argc, char **argv)
905
{
906
	Binit(&bstdout, 1, OWRITE);
907
	sargv = argv;
908
	sargc = argc - 1;
909
	if(sargc == 0) {
910
		in = &bstdin;
911
		Binit(in, 0, OREAD);
912
	} else if((in = Bopen(sargv[1], OREAD)) == 0)
913
		yyerror("cannot open input file");
914
	ifile = 1;
915
	ln = 0;
916
	ss = sargv[1];
917
}
918
 
919
void
920
getout(void)
921
{
922
	Bprint(&bstdout, "q");
923
	Bflush(&bstdout);
924
	exits(0);
925
}
926
 
927
char*
928
getf(char *p)
929
{
930
	return funtab[*p - 'a'];
931
}
932
 
933
char*
934
geta(char *p)
935
{
936
	return atab[*p - 'a'];
937
}
938
 
939
void
940
main(int argc, char **argv)
941
{
942
	int p[2];
943
 
944
	while(argc > 1 && *argv[1] == '-') {
945
		switch(argv[1][1]) {
946
		case 'd':
947
			bdebug++;
948
			break;
949
		case 'c':
950
			cflag++;
951
			break;
952
		case 'l':
953
			lflag++;
954
			break;
955
		case 's':
956
			sflag++;
957
			break;
958
		default:
959
			fprint(2, "Usage: bc [-cdls] [file ...]\n");
960
			exits("usage");
961
		}
962
		argc--;
963
		argv++;
964
	}
965
	if(lflag) {
966
		argv--;
967
		argc++;
968
		argv[1] = "/sys/lib/bclib";
969
	}
970
	if(cflag) {
971
		yyinit(argc, argv);
972
		for(;;)
973
			yyparse();
974
		/* not reached */
975
	}
976
	pipe(p);
977
	if(fork() == 0) {
978
		dup(p[1], 1);
979
		close(p[0]);
980
		close(p[1]);
981
		yyinit(argc, argv);
982
		for(;;)
983
			yyparse();
984
	}
985
	dup(p[0], 0);
986
	close(p[0]);
987
	close(p[1]);
988
	execl("/bin/dc", "dc", nil);
989
}