bc.y 13 KB

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