bc.y 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989
  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. long 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. void yyerror(char*, ...);
  76. int yyparse(void);
  77. typedef void* pointer;
  78. #pragma varargck type "lx" 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> slist 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. {
  225. --bindx;
  226. }
  227. slist:
  228. stat
  229. | slist tail stat
  230. {
  231. bundle(2, $1, $3);
  232. }
  233. tail:
  234. '\n'
  235. {
  236. ln++;
  237. }
  238. | ';'
  239. re:
  240. e EQ e
  241. {
  242. $$ = bundle(3, $1, $3, "=");
  243. }
  244. | e '<' e
  245. {
  246. bundle(3, $1, $3, ">");
  247. }
  248. | e '>' e
  249. {
  250. bundle(3, $1, $3, "<");
  251. }
  252. | e NE e
  253. {
  254. bundle(3, $1, $3, "!=");
  255. }
  256. | e GE e
  257. {
  258. bundle(3, $1, $3, "!>");
  259. }
  260. | e LE e
  261. {
  262. bundle(3, $1, $3, "!<");
  263. }
  264. | e
  265. {
  266. bundle(2, $1, " 0!=");
  267. }
  268. nase:
  269. '(' e ')'
  270. {
  271. $$ = $2;
  272. }
  273. | cons
  274. {
  275. bundle(3, " ", $1, " ");
  276. }
  277. | DOT cons
  278. {
  279. bundle(3, " .", $2, " ");
  280. }
  281. | cons DOT cons
  282. {
  283. bundle(5, " ", $1, ".", $3, " ");
  284. }
  285. | cons DOT
  286. {
  287. bundle(4, " ", $1, ".", " ");
  288. }
  289. | DOT
  290. {
  291. $<cptr>$ = "l.";
  292. }
  293. | LETTER '[' e ']'
  294. {
  295. bundle(3, $3, ";", geta($1));
  296. }
  297. | LETTER INCR
  298. {
  299. bundle(4, "l", $1, "d1+s", $1);
  300. }
  301. | INCR LETTER
  302. {
  303. bundle(4, "l", $2, "1+ds", $2);
  304. }
  305. | DECR LETTER
  306. {
  307. bundle(4, "l", $2, "1-ds", $2);
  308. }
  309. | LETTER DECR
  310. {
  311. bundle(4, "l", $1, "d1-s", $1);
  312. }
  313. | LETTER '[' e ']' INCR
  314. {
  315. bundle(7, $3, ";", geta($1), "d1+" ,$3, ":" ,geta($1));
  316. }
  317. | INCR LETTER '[' e ']'
  318. {
  319. bundle(7, $4, ";", geta($2), "1+d", $4, ":", geta($2));
  320. }
  321. | LETTER '[' e ']' DECR
  322. {
  323. bundle(7, $3, ";", geta($1), "d1-", $3, ":", geta($1));
  324. }
  325. | DECR LETTER '[' e ']'
  326. {
  327. bundle(7, $4, ";", geta($2), "1-d", $4, ":" ,geta($2));
  328. }
  329. | SCALE INCR
  330. {
  331. bundle(1, "Kd1+k");
  332. }
  333. | INCR SCALE
  334. {
  335. bundle(1, "K1+dk");
  336. }
  337. | SCALE DECR
  338. {
  339. bundle(1, "Kd1-k");
  340. }
  341. | DECR SCALE
  342. {
  343. bundle(1, "K1-dk");
  344. }
  345. | BASE INCR
  346. {
  347. bundle(1, "Id1+i");
  348. }
  349. | INCR BASE
  350. {
  351. bundle(1, "I1+di");
  352. }
  353. | BASE DECR
  354. {
  355. bundle(1, "Id1-i");
  356. }
  357. | DECR BASE
  358. {
  359. bundle(1, "I1-di");
  360. }
  361. | OBASE INCR
  362. {
  363. bundle(1, "Od1+o");
  364. }
  365. | INCR OBASE
  366. {
  367. bundle(1, "O1+do");
  368. }
  369. | OBASE DECR
  370. {
  371. bundle(1, "Od1-o");
  372. }
  373. | DECR OBASE
  374. {
  375. bundle(1, "O1-do");
  376. }
  377. | LETTER '(' cargs ')'
  378. {
  379. bundle(4, $3, "l", getf($1), "x");
  380. }
  381. | LETTER '(' ')'
  382. {
  383. bundle(3, "l", getf($1), "x");
  384. }
  385. | LETTER = {
  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. {
  503. $$ = cp;
  504. *cp++ = '<';
  505. *cp++ = crs/100+'0';
  506. *cp++ = (crs%100)/10+'0';
  507. *cp++ = crs%10+'0';
  508. *cp++ = '>';
  509. *cp++ = '\0';
  510. if(crs++ >= 220) {
  511. yyerror("program too big");
  512. getout();
  513. }
  514. bstack[bindx++] = lev++;
  515. }
  516. def:
  517. _DEFINE LETTER '('
  518. {
  519. $$ = getf($2);
  520. pre = (char*)"";
  521. post = (char*)"";
  522. lev = 1;
  523. bindx = 0;
  524. bstack[bindx] = 0;
  525. }
  526. dargs:
  527. | lora
  528. {
  529. pp((char*)$1);
  530. }
  531. | dargs ',' lora
  532. {
  533. pp((char*)$3);
  534. }
  535. dlets:
  536. lora
  537. {
  538. tp((char*)$1);
  539. }
  540. | dlets ',' lora
  541. {
  542. tp((char*)$3);
  543. }
  544. lora:
  545. LETTER
  546. {
  547. $<cptr>$=$1;
  548. }
  549. | LETTER '[' ']'
  550. {
  551. $$ = geta($1);
  552. }
  553. %%
  554. int
  555. yylex(void)
  556. {
  557. int c, ch;
  558. restart:
  559. c = getch();
  560. peekc = -1;
  561. while(c == ' ' || c == '\t')
  562. c = getch();
  563. if(c == '\\') {
  564. getch();
  565. goto restart;
  566. }
  567. if(c >= 'a' && c <= 'z') {
  568. /* look ahead to look for reserved words */
  569. peekc = getch();
  570. if(peekc >= 'a' && peekc <= 'z') { /* must be reserved word */
  571. if(c=='p' && peekc=='r') {
  572. c = _PRINT;
  573. goto skip;
  574. }
  575. if(c=='i' && peekc=='f') {
  576. c = _IF;
  577. goto skip;
  578. }
  579. if(c=='w' && peekc=='h') {
  580. c = _WHILE;
  581. goto skip;
  582. }
  583. if(c=='f' && peekc=='o') {
  584. c = _FOR;
  585. goto skip;
  586. }
  587. if(c=='s' && peekc=='q') {
  588. c = SQRT;
  589. goto skip;
  590. }
  591. if(c=='r' && peekc=='e') {
  592. c = _RETURN;
  593. goto skip;
  594. }
  595. if(c=='b' && peekc=='r') {
  596. c = _BREAK;
  597. goto skip;
  598. }
  599. if(c=='d' && peekc=='e') {
  600. c = _DEFINE;
  601. goto skip;
  602. }
  603. if(c=='s' && peekc=='c') {
  604. c = SCALE;
  605. goto skip;
  606. }
  607. if(c=='b' && peekc=='a') {
  608. c = BASE;
  609. goto skip;
  610. }
  611. if(c=='i' && peekc=='b') {
  612. c = BASE;
  613. goto skip;
  614. }
  615. if(c=='o' && peekc=='b') {
  616. c = OBASE;
  617. goto skip;
  618. }
  619. if(c=='d' && peekc=='i') {
  620. c = FFF;
  621. goto skip;
  622. }
  623. if(c=='a' && peekc=='u') {
  624. c = _AUTO;
  625. goto skip;
  626. }
  627. if(c=='l' && peekc=='e') {
  628. c = LENGTH;
  629. goto skip;
  630. }
  631. if(c=='q' && peekc=='u')
  632. getout();
  633. /* could not be found */
  634. return ERROR;
  635. skip: /* skip over rest of word */
  636. peekc = -1;
  637. for(;;) {
  638. ch = getch();
  639. if(ch < 'a' || ch > 'z')
  640. break;
  641. }
  642. peekc = ch;
  643. return c;
  644. }
  645. /* usual case; just one single letter */
  646. yylval.cptr = letr[c-'a'];
  647. return LETTER;
  648. }
  649. if((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {
  650. yylval.cc = c;
  651. return DIGIT;
  652. }
  653. switch(c) {
  654. case '.':
  655. return DOT;
  656. case '*':
  657. yylval.cptr = "*";
  658. return cpeek('=', EQOP, c);
  659. case '%':
  660. yylval.cptr = "%%";
  661. return cpeek('=', EQOP, c);
  662. case '^':
  663. yylval.cptr = "^";
  664. return cpeek('=', EQOP, c);
  665. case '+':
  666. ch = cpeek('=', EQOP, c);
  667. if(ch == EQOP) {
  668. yylval.cptr = "+";
  669. return ch;
  670. }
  671. return cpeek('+', INCR, c);
  672. case '-':
  673. ch = cpeek('=', EQOP, c);
  674. if(ch == EQOP) {
  675. yylval.cptr = "-";
  676. return ch;
  677. }
  678. return cpeek('-', DECR, c);
  679. case '=':
  680. return cpeek('=', EQ, '=');
  681. case '<':
  682. return cpeek('=', LE, '<');
  683. case '>':
  684. return cpeek('=', GE, '>');
  685. case '!':
  686. return cpeek('=', NE, '!');
  687. case '/':
  688. ch = cpeek('=', EQOP, c);
  689. if(ch == EQOP) {
  690. yylval.cptr = "/";
  691. return ch;
  692. }
  693. if(peekc == '*') {
  694. peekc = -1;
  695. for(;;) {
  696. ch = getch();
  697. if(ch == '*') {
  698. peekc = getch();
  699. if(peekc == '/') {
  700. peekc = -1;
  701. goto restart;
  702. }
  703. }
  704. }
  705. }
  706. return c;
  707. case '"':
  708. yylval.cptr = str;
  709. while((c=getch()) != '"'){
  710. *str++ = c;
  711. if(str >= &string[999]){
  712. yyerror("string space exceeded");
  713. getout();
  714. }
  715. }
  716. *str++ = 0;
  717. return QSTR;
  718. default:
  719. return c;
  720. }
  721. }
  722. int
  723. cpeek(int c, int yes, int no)
  724. {
  725. peekc = getch();
  726. if(peekc == c) {
  727. peekc = -1;
  728. return yes;
  729. }
  730. return no;
  731. }
  732. int
  733. getch(void)
  734. {
  735. long ch;
  736. loop:
  737. ch = peekc;
  738. if(ch < 0){
  739. if(in == 0)
  740. ch = -1;
  741. else
  742. ch = Bgetc(in);
  743. }
  744. peekc = -1;
  745. if(ch >= 0)
  746. return ch;
  747. ifile++;
  748. if(ifile > sargc) {
  749. if(ifile >= sargc+2)
  750. getout();
  751. in = &bstdin;
  752. Binit(in, 0, OREAD);
  753. ln = 0;
  754. goto loop;
  755. }
  756. if(in)
  757. Bterm(in);
  758. if((in = Bopen(sargv[ifile], OREAD)) != 0){
  759. ln = 0;
  760. ss = sargv[ifile];
  761. goto loop;
  762. }
  763. yyerror("cannot open input file");
  764. return 0; /* shut up ken */
  765. }
  766. char*
  767. bundle(int a, ...)
  768. {
  769. int i;
  770. char **q;
  771. va_list arg;
  772. i = a;
  773. va_start(arg, a);
  774. q = bsp_nxt;
  775. if(bdebug)
  776. fprint(2, "bundle %d elements at %lx\n", i, q);
  777. while(i-- > 0) {
  778. if(bsp_nxt >= &bspace[bsp_max])
  779. yyerror("bundling space exceeded");
  780. *bsp_nxt++ = va_arg(arg, char*);
  781. }
  782. *bsp_nxt++ = 0;
  783. va_end(arg);
  784. yyval.cptr = (char*)q;
  785. return (char*)q;
  786. }
  787. void
  788. routput(char *p)
  789. {
  790. char **pp;
  791. if(bdebug)
  792. fprint(2, "routput(%lx)\n", p);
  793. if((char**)p >= &bspace[0] && (char**)p < &bspace[bsp_max]) {
  794. /* part of a bundle */
  795. pp = (char**)p;
  796. while(*pp != 0)
  797. routput(*pp++);
  798. } else
  799. Bprint(&bstdout, p); /* character string */
  800. }
  801. void
  802. output(char *p)
  803. {
  804. routput(p);
  805. bsp_nxt = &bspace[0];
  806. Bprint(&bstdout, "\n");
  807. Bflush(&bstdout);
  808. cp = cary;
  809. crs = rcrs;
  810. }
  811. void
  812. conout(char *p, char *s)
  813. {
  814. Bprint(&bstdout, "[");
  815. routput(p);
  816. Bprint(&bstdout, "]s%s\n", s);
  817. Bflush(&bstdout);
  818. lev--;
  819. }
  820. void
  821. yyerror(char *s, ...)
  822. {
  823. if(ifile > sargc)
  824. ss = "teletype";
  825. Bprint(&bstdout, "c[%s on line %d, %s]pc\n", s, ln+1, ss);
  826. Bflush(&bstdout);
  827. cp = cary;
  828. crs = rcrs;
  829. bindx = 0;
  830. lev = 0;
  831. bsp_nxt = &bspace[0];
  832. }
  833. void
  834. pp(char *s)
  835. {
  836. /* puts the relevant stuff on pre and post for the letter s */
  837. bundle(3, "S", s, pre);
  838. pre = yyval.cptr;
  839. bundle(4, post, "L", s, "s.");
  840. post = yyval.cptr;
  841. }
  842. void
  843. tp(char *s)
  844. {
  845. /* same as pp, but for temps */
  846. bundle(3, "0S", s, pre);
  847. pre = yyval.cptr;
  848. bundle(4, post, "L", s, "s.");
  849. post = yyval.cptr;
  850. }
  851. void
  852. yyinit(int argc, char **argv)
  853. {
  854. Binit(&bstdout, 1, OWRITE);
  855. sargv = argv;
  856. sargc = argc - 1;
  857. if(sargc == 0) {
  858. in = &bstdin;
  859. Binit(in, 0, OREAD);
  860. } else if((in = Bopen(sargv[1], OREAD)) == 0)
  861. yyerror("cannot open input file");
  862. ifile = 1;
  863. ln = 0;
  864. ss = sargv[1];
  865. }
  866. void
  867. getout(void)
  868. {
  869. Bprint(&bstdout, "q");
  870. Bflush(&bstdout);
  871. exits(0);
  872. }
  873. char*
  874. getf(char *p)
  875. {
  876. return funtab[*p - 'a'];
  877. }
  878. char*
  879. geta(char *p)
  880. {
  881. return atab[*p - 'a'];
  882. }
  883. void
  884. main(int argc, char **argv)
  885. {
  886. int p[2];
  887. while(argc > 1 && *argv[1] == '-') {
  888. switch(argv[1][1]) {
  889. case 'd':
  890. bdebug++;
  891. break;
  892. case 'c':
  893. cflag++;
  894. break;
  895. case 'l':
  896. lflag++;
  897. break;
  898. case 's':
  899. sflag++;
  900. break;
  901. default:
  902. fprint(2, "Usage: bc [-cdls] [file ...]\n");
  903. exits("usage");
  904. }
  905. argc--;
  906. argv++;
  907. }
  908. if(lflag) {
  909. argv--;
  910. argc++;
  911. argv[1] = "/sys/lib/bclib";
  912. }
  913. if(cflag) {
  914. yyinit(argc, argv);
  915. for(;;)
  916. yyparse();
  917. /* not reached */
  918. }
  919. pipe(p);
  920. if(fork() == 0) {
  921. dup(p[1], 1);
  922. close(p[0]);
  923. close(p[1]);
  924. yyinit(argc, argv);
  925. for(;;)
  926. yyparse();
  927. }
  928. dup(p[0], 0);
  929. close(p[0]);
  930. close(p[1]);
  931. execl("/bin/dc", "dc", nil);
  932. }