code.c 9.8 KB

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