code.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <bio.h>
  12. #include "hoc.h"
  13. #include "y.tab.h"
  14. #define NSTACK 256
  15. static Datum stack[NSTACK]; /* the stack */
  16. static Datum *stackp; /* next free spot on stack */
  17. #define NPROG 2000
  18. Inst prog[NPROG]; /* the machine */
  19. Inst *progp; /* next free spot for code generation */
  20. Inst *pc; /* program counter during execution */
  21. Inst *progbase = prog; /* start of current subprogram */
  22. int returning; /* 1 if return stmt seen */
  23. int indef; /* 1 if parsing a func or proc */
  24. typedef struct Frame { /* proc/func call stack frame */
  25. Symbol *sp; /* symbol table entry */
  26. Inst *retpc; /* where to resume after return */
  27. Datum *argn; /* n-th argument on stack */
  28. int nargs; /* number of arguments */
  29. } Frame;
  30. #define NFRAME 100
  31. Frame frame[NFRAME];
  32. Frame *fp; /* frame pointer */
  33. void
  34. initcode(void)
  35. {
  36. progp = progbase;
  37. stackp = stack;
  38. fp = frame;
  39. returning = 0;
  40. indef = 0;
  41. }
  42. void
  43. push(Datum d)
  44. {
  45. if (stackp >= &stack[NSTACK])
  46. execerror("stack too deep", 0);
  47. *stackp++ = d;
  48. }
  49. Datum
  50. pop(void)
  51. {
  52. if (stackp == stack)
  53. execerror("stack underflow", 0);
  54. return *--stackp;
  55. }
  56. void
  57. xpop(void) /* for when no value is wanted */
  58. {
  59. if (stackp == stack)
  60. execerror("stack underflow", (char *)0);
  61. --stackp;
  62. }
  63. void
  64. constpush(void)
  65. {
  66. Datum d;
  67. d.val = ((Symbol *)*pc++)->u.val;
  68. push(d);
  69. }
  70. void
  71. varpush(void)
  72. {
  73. Datum d;
  74. d.sym = (Symbol *)(*pc++);
  75. push(d);
  76. }
  77. void
  78. whilecode(void)
  79. {
  80. Datum d;
  81. Inst *savepc = pc;
  82. execute(savepc+2); /* condition */
  83. d = pop();
  84. while (d.val) {
  85. execute(*((Inst **)(savepc))); /* body */
  86. if (returning)
  87. break;
  88. execute(savepc+2); /* condition */
  89. d = pop();
  90. }
  91. if (!returning)
  92. pc = *((Inst **)(savepc+1)); /* next stmt */
  93. }
  94. void
  95. forcode(void)
  96. {
  97. Datum d;
  98. Inst *savepc = pc;
  99. execute(savepc+4); /* precharge */
  100. pop();
  101. execute(*((Inst **)(savepc))); /* condition */
  102. d = pop();
  103. while (d.val) {
  104. execute(*((Inst **)(savepc+2))); /* body */
  105. if (returning)
  106. break;
  107. execute(*((Inst **)(savepc+1))); /* post loop */
  108. pop();
  109. execute(*((Inst **)(savepc))); /* condition */
  110. d = pop();
  111. }
  112. if (!returning)
  113. pc = *((Inst **)(savepc+3)); /* next stmt */
  114. }
  115. void
  116. ifcode(void)
  117. {
  118. Datum d;
  119. Inst *savepc = pc; /* then part */
  120. execute(savepc+3); /* condition */
  121. d = pop();
  122. if (d.val)
  123. execute(*((Inst **)(savepc)));
  124. else if (*((Inst **)(savepc+1))) /* else part? */
  125. execute(*((Inst **)(savepc+1)));
  126. if (!returning)
  127. pc = *((Inst **)(savepc+2)); /* next stmt */
  128. }
  129. void
  130. define(Symbol* sp, Formal *f) /* put func/proc in symbol table */
  131. {
  132. Fndefn *fd;
  133. int n;
  134. fd = emalloc(sizeof(Fndefn));
  135. fd->code = progbase; /* start of code */
  136. progbase = progp; /* next code starts here */
  137. fd->formals = f;
  138. for(n=0; f; f=f->next)
  139. n++;
  140. fd->nargs = n;
  141. sp->u.defn = fd;
  142. }
  143. void
  144. call(void) /* call a function */
  145. {
  146. Formal *f;
  147. Datum *arg;
  148. Saveval *s;
  149. int i;
  150. Symbol *sp = (Symbol *)pc[0]; /* symbol table entry */
  151. /* for function */
  152. if (fp >= &frame[NFRAME-1])
  153. execerror(sp->name, "call nested too deeply");
  154. fp++;
  155. fp->sp = sp;
  156. fp->nargs = (int)(uintptr)pc[1];
  157. fp->retpc = pc + 2;
  158. fp->argn = stackp - 1; /* last argument */
  159. if(fp->nargs != sp->u.defn->nargs)
  160. execerror(sp->name, "called with wrong number of arguments");
  161. /* bind formals */
  162. f = sp->u.defn->formals;
  163. arg = stackp - fp->nargs;
  164. while(f){
  165. s = emalloc(sizeof(Saveval));
  166. s->val = f->sym->u;
  167. s->type = f->sym->type;
  168. s->next = f->save;
  169. f->save = s;
  170. f->sym->u.val = arg->val;
  171. f->sym->type = VAR;
  172. f = f->next;
  173. arg++;
  174. }
  175. for (i = 0; i < fp->nargs; i++)
  176. pop(); /* pop arguments; no longer needed */
  177. execute(sp->u.defn->code);
  178. returning = 0;
  179. }
  180. void
  181. restore(Symbol *sp) /* restore formals associated with symbol */
  182. {
  183. Formal *f;
  184. Saveval *s;
  185. f = sp->u.defn->formals;
  186. while(f){
  187. s = f->save;
  188. if(s == 0) /* more actuals than formals */
  189. break;
  190. f->sym->u = s->val;
  191. f->sym->type = s->type;
  192. f->save = s->next;
  193. free(s);
  194. f = f->next;
  195. }
  196. }
  197. void
  198. restoreall(void) /* restore all variables in case of error */
  199. {
  200. while(fp>=frame && fp->sp){
  201. restore(fp->sp);
  202. --fp;
  203. }
  204. fp = frame;
  205. }
  206. static void
  207. ret(void) /* common return from func or proc */
  208. {
  209. /* restore formals */
  210. restore(fp->sp);
  211. pc = (Inst *)fp->retpc;
  212. --fp;
  213. returning = 1;
  214. }
  215. void
  216. funcret(void) /* return from a function */
  217. {
  218. Datum d;
  219. if (fp->sp->type == PROCEDURE)
  220. execerror(fp->sp->name, "(proc) returns value");
  221. d = pop(); /* preserve function return value */
  222. ret();
  223. push(d);
  224. }
  225. void
  226. procret(void) /* return from a procedure */
  227. {
  228. if (fp->sp->type == FUNCTION)
  229. execerror(fp->sp->name,
  230. "(func) returns no value");
  231. ret();
  232. }
  233. void
  234. bltin(void)
  235. {
  236. Datum d;
  237. d = pop();
  238. d.val = (*(double (*)(double))*pc++)(d.val);
  239. push(d);
  240. }
  241. void
  242. add(void)
  243. {
  244. Datum d1, d2;
  245. d2 = pop();
  246. d1 = pop();
  247. d1.val += d2.val;
  248. push(d1);
  249. }
  250. void
  251. sub(void)
  252. {
  253. Datum d1, d2;
  254. d2 = pop();
  255. d1 = pop();
  256. d1.val -= d2.val;
  257. push(d1);
  258. }
  259. void
  260. mul(void)
  261. {
  262. Datum d1, d2;
  263. d2 = pop();
  264. d1 = pop();
  265. d1.val *= d2.val;
  266. push(d1);
  267. }
  268. void
  269. div(void)
  270. {
  271. Datum d1, d2;
  272. d2 = pop();
  273. if (d2.val == 0.0)
  274. execerror("division by zero", (char *)0);
  275. d1 = pop();
  276. d1.val /= d2.val;
  277. push(d1);
  278. }
  279. void
  280. mod(void)
  281. {
  282. Datum d1, d2;
  283. d2 = pop();
  284. if (d2.val == 0.0)
  285. execerror("division by zero", (char *)0);
  286. d1 = pop();
  287. /* d1.val %= d2.val; */
  288. d1.val = fmod(d1.val, d2.val);
  289. push(d1);
  290. }
  291. void
  292. negate(void)
  293. {
  294. Datum d;
  295. d = pop();
  296. d.val = -d.val;
  297. push(d);
  298. }
  299. void
  300. verify(Symbol* s)
  301. {
  302. if (s->type != VAR && s->type != UNDEF)
  303. execerror("attempt to evaluate non-variable", s->name);
  304. if (s->type == UNDEF)
  305. execerror("undefined variable", s->name);
  306. }
  307. void
  308. eval(void) /* evaluate variable on stack */
  309. {
  310. Datum d;
  311. d = pop();
  312. verify(d.sym);
  313. d.val = d.sym->u.val;
  314. push(d);
  315. }
  316. void
  317. preinc(void)
  318. {
  319. Datum d;
  320. d.sym = (Symbol *)(*pc++);
  321. verify(d.sym);
  322. d.val = d.sym->u.val += 1.0;
  323. push(d);
  324. }
  325. void
  326. predec(void)
  327. {
  328. Datum d;
  329. d.sym = (Symbol *)(*pc++);
  330. verify(d.sym);
  331. d.val = d.sym->u.val -= 1.0;
  332. push(d);
  333. }
  334. void
  335. postinc(void)
  336. {
  337. Datum d;
  338. double v;
  339. d.sym = (Symbol *)(*pc++);
  340. verify(d.sym);
  341. v = d.sym->u.val;
  342. d.sym->u.val += 1.0;
  343. d.val = v;
  344. push(d);
  345. }
  346. void
  347. postdec(void)
  348. {
  349. Datum d;
  350. double v;
  351. d.sym = (Symbol *)(*pc++);
  352. verify(d.sym);
  353. v = d.sym->u.val;
  354. d.sym->u.val -= 1.0;
  355. d.val = v;
  356. push(d);
  357. }
  358. void
  359. gt(void)
  360. {
  361. Datum d1, d2;
  362. d2 = pop();
  363. d1 = pop();
  364. d1.val = (double)(d1.val > d2.val);
  365. push(d1);
  366. }
  367. void
  368. lt(void)
  369. {
  370. Datum d1, d2;
  371. d2 = pop();
  372. d1 = pop();
  373. d1.val = (double)(d1.val < d2.val);
  374. push(d1);
  375. }
  376. void
  377. ge(void)
  378. {
  379. Datum d1, d2;
  380. d2 = pop();
  381. d1 = pop();
  382. d1.val = (double)(d1.val >= d2.val);
  383. push(d1);
  384. }
  385. void
  386. le(void)
  387. {
  388. Datum d1, d2;
  389. d2 = pop();
  390. d1 = pop();
  391. d1.val = (double)(d1.val <= d2.val);
  392. push(d1);
  393. }
  394. void
  395. eq(void)
  396. {
  397. Datum d1, d2;
  398. d2 = pop();
  399. d1 = pop();
  400. d1.val = (double)(d1.val == d2.val);
  401. push(d1);
  402. }
  403. void
  404. ne(void)
  405. {
  406. Datum d1, d2;
  407. d2 = pop();
  408. d1 = pop();
  409. d1.val = (double)(d1.val != d2.val);
  410. push(d1);
  411. }
  412. void
  413. and(void)
  414. {
  415. Datum d1, d2;
  416. d2 = pop();
  417. d1 = pop();
  418. d1.val = (double)(d1.val != 0.0 && d2.val != 0.0);
  419. push(d1);
  420. }
  421. void
  422. or(void)
  423. {
  424. Datum d1, d2;
  425. d2 = pop();
  426. d1 = pop();
  427. d1.val = (double)(d1.val != 0.0 || d2.val != 0.0);
  428. push(d1);
  429. }
  430. void
  431. not(void)
  432. {
  433. Datum d;
  434. d = pop();
  435. d.val = (double)(d.val == 0.0);
  436. push(d);
  437. }
  438. void
  439. power(void)
  440. {
  441. Datum d1, d2;
  442. d2 = pop();
  443. d1 = pop();
  444. d1.val = Pow(d1.val, d2.val);
  445. push(d1);
  446. }
  447. void
  448. assign(void)
  449. {
  450. Datum d1, d2;
  451. d1 = pop();
  452. d2 = pop();
  453. if (d1.sym->type != VAR && d1.sym->type != UNDEF)
  454. execerror("assignment to non-variable",
  455. d1.sym->name);
  456. d1.sym->u.val = d2.val;
  457. d1.sym->type = VAR;
  458. push(d2);
  459. }
  460. void
  461. addeq(void)
  462. {
  463. Datum d1, d2;
  464. d1 = pop();
  465. d2 = pop();
  466. if (d1.sym->type != VAR && d1.sym->type != UNDEF)
  467. execerror("assignment to non-variable",
  468. d1.sym->name);
  469. d2.val = d1.sym->u.val += d2.val;
  470. d1.sym->type = VAR;
  471. push(d2);
  472. }
  473. void
  474. subeq(void)
  475. {
  476. Datum d1, d2;
  477. d1 = pop();
  478. d2 = pop();
  479. if (d1.sym->type != VAR && d1.sym->type != UNDEF)
  480. execerror("assignment to non-variable",
  481. d1.sym->name);
  482. d2.val = d1.sym->u.val -= d2.val;
  483. d1.sym->type = VAR;
  484. push(d2);
  485. }
  486. void
  487. muleq(void)
  488. {
  489. Datum d1, d2;
  490. d1 = pop();
  491. d2 = pop();
  492. if (d1.sym->type != VAR && d1.sym->type != UNDEF)
  493. execerror("assignment to non-variable",
  494. d1.sym->name);
  495. d2.val = d1.sym->u.val *= d2.val;
  496. d1.sym->type = VAR;
  497. push(d2);
  498. }
  499. void
  500. diveq(void)
  501. {
  502. Datum d1, d2;
  503. d1 = pop();
  504. d2 = pop();
  505. if (d1.sym->type != VAR && d1.sym->type != UNDEF)
  506. execerror("assignment to non-variable",
  507. d1.sym->name);
  508. d2.val = d1.sym->u.val /= d2.val;
  509. d1.sym->type = VAR;
  510. push(d2);
  511. }
  512. void
  513. modeq(void)
  514. {
  515. Datum d1, d2;
  516. int32_t x;
  517. d1 = pop();
  518. d2 = pop();
  519. if (d1.sym->type != VAR && d1.sym->type != UNDEF)
  520. execerror("assignment to non-variable",
  521. d1.sym->name);
  522. /* d2.val = d1.sym->u.val %= d2.val; */
  523. x = d1.sym->u.val;
  524. x %= (int32_t) d2.val;
  525. d2.val = d1.sym->u.val = x;
  526. d1.sym->type = VAR;
  527. push(d2);
  528. }
  529. void
  530. printtop(void) /* pop top value from stack, print it */
  531. {
  532. Datum d;
  533. static Symbol *s; /* last value computed */
  534. if (s == 0)
  535. s = install("_", VAR, 0.0);
  536. d = pop();
  537. print("%.12g\n", d.val);
  538. s->u.val = d.val;
  539. }
  540. void
  541. prexpr(void) /* print numeric value */
  542. {
  543. Datum d;
  544. d = pop();
  545. print("%.12g ", d.val);
  546. }
  547. void
  548. prstr(void) /* print string value */
  549. {
  550. print("%s", (char *) *pc++);
  551. }
  552. void
  553. varread(void) /* read into variable */
  554. {
  555. Datum d;
  556. extern Biobuf *bin;
  557. Symbol *var = (Symbol *) *pc++;
  558. int c;
  559. Again:
  560. do
  561. c = Bgetc(bin);
  562. while(c==' ' || c=='\t' || c=='\n');
  563. if(c == Beof){
  564. Iseof:
  565. if(moreinput())
  566. goto Again;
  567. d.val = var->u.val = 0.0;
  568. goto Return;
  569. }
  570. if(strchr("+-.0123456789", c) == 0)
  571. execerror("non-number read into", var->name);
  572. Bungetc(bin);
  573. if(Bgetd(bin, &var->u.val) == Beof)
  574. goto Iseof;
  575. else
  576. d.val = 1.0;
  577. Return:
  578. var->type = VAR;
  579. push(d);
  580. }
  581. Inst*
  582. code(Inst f) /* install one instruction or operand */
  583. {
  584. Inst *oprogp = progp;
  585. if (progp >= &prog[NPROG])
  586. execerror("program too big", (char *)0);
  587. *progp++ = f;
  588. return oprogp;
  589. }
  590. void
  591. execute(Inst* p)
  592. {
  593. for (pc = p; *pc != STOP && !returning; )
  594. (*((++pc)[-1]))();
  595. }