bc.y 13 KB

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