expr.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. /* $Header$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. #include "symtab.h"
  7. #include "sizes.h"
  8. #include "expr.h"
  9. #include "Lpars.h"
  10. static void rvalue(), assignable(), inputable(), outputable(), subscriptable();
  11. static void assigned();
  12. /* The new_* functions make use of the used() and assinged() functions to
  13. * make known what is done to a variable.
  14. */
  15. struct expr *new_node(op, left, right, byte)
  16. int op;
  17. register struct expr *left, *right;
  18. int byte;
  19. /* Makes a new node with given operator, left and right operand.
  20. * Constant folding is done if possible.
  21. */
  22. {
  23. if (op!=FOR && constant(left) && (right==nil || constant(right))) {
  24. register long lc, rc;
  25. lc=left->u.const;
  26. rc=right->u.const;
  27. switch (op) {
  28. case '+': lc+=rc; break;
  29. case '-': lc-=rc; break;
  30. case '*': lc*=rc; break;
  31. case '/': if (rc==0L)
  32. report("division by zero");
  33. else
  34. lc/=rc;
  35. break;
  36. case BS: lc%=rc; break;
  37. case '<': lc= lc<rc ? -1L : 0L; break;
  38. case '>': lc= lc>rc ? -1L : 0L; break;
  39. case LE: lc= lc<=rc ? -1L : 0L; break;
  40. case GE: lc= lc>=rc ? -1L : 0L; break;
  41. case NE: lc= lc!=rc ? -1L : 0L; break;
  42. case '=': lc= lc==rc ? -1L : 0L; break;
  43. case AFTER: lc= (lc-rc)>0 ? -1L : 0L; break;
  44. case BA: lc&=rc; break;
  45. case BO: lc|=rc; break;
  46. case BX: lc^=rc; break;
  47. case AND: lc= lc&&rc ? -1L : 0L; break;
  48. case OR: lc= lc||rc ? -1L : 0L; break;
  49. case LS: lc<<=rc; break;
  50. case RS: lc>>=rc; break;
  51. case '~': lc= -lc; break;
  52. case NOT: lc= ~lc; break;
  53. default:
  54. report("illegal operator on constants");
  55. }
  56. destroy(right);
  57. left->u.const=lc;
  58. return left;
  59. } else {
  60. register struct expr *pe;
  61. int type=0, arr_siz=1;
  62. switch (op) {
  63. case '+': case '-': case '*': case '/':
  64. case BS: case '<': case '>': case LE:
  65. case GE: case NE: case '=': case AFTER:
  66. case BA: case BO: case BX: case AND:
  67. case OR: case LS: case RS:
  68. rvalue(left);
  69. rvalue(right);
  70. type=T_VALUE;
  71. break;
  72. case '~':
  73. case NOT:
  74. rvalue(left);
  75. type=T_VALUE;
  76. break;
  77. case AS:
  78. assignable(left, right);
  79. type=T_VOID;
  80. break;
  81. case '[':
  82. subscriptable(left, right, byte, &type, &arr_siz);
  83. break;
  84. }
  85. pe= (struct expr *) malloc(sizeof *pe);
  86. pe->kind=E_NODE;
  87. pe->type=type;
  88. pe->arr_siz=arr_siz;
  89. pe->u.node.op=op;
  90. pe->u.node.left=left;
  91. pe->u.node.right=right;
  92. return pe;
  93. }
  94. }
  95. struct expr *new_var(var)
  96. register struct symbol *var;
  97. /* Given a variable an expression node is constructed. Note the changes in
  98. * type! T_VAR becomes T_VALUE with flag T_LVALUE.
  99. */
  100. {
  101. register struct expr *pe;
  102. pe= (struct expr *) malloc(sizeof *pe);
  103. pe->kind=E_VAR;
  104. if ((var->type&T_TYPE)==T_VAR || var->type&T_NOTDECL) {
  105. pe->type=(var->type&(~T_TYPE));
  106. pe->type|=T_VALUE|T_LVALUE;
  107. } else
  108. pe->type=var->type;
  109. pe->arr_siz=var->arr_siz;
  110. pe->u.var=var;
  111. return pe;
  112. }
  113. struct expr *new_const(const)
  114. long const;
  115. /* Make a constant, which is a VALUE, of course. */
  116. {
  117. register struct expr *pe;
  118. pe= (struct expr *) malloc(sizeof *pe);
  119. pe->kind=E_CONST;
  120. pe->type=T_VALUE;
  121. pe->u.const=const;
  122. return pe;
  123. }
  124. struct expr *new_table(kind, tab)
  125. register kind;
  126. register struct table *tab;
  127. /* One table is being made, it is no doubt a VALUEd ARRay, but maybe even a
  128. * BYTE array. A label is reserved for it and the individual elements are
  129. * rommified.
  130. */
  131. {
  132. register struct expr *pe;
  133. pe= (struct expr *) malloc(sizeof *pe);
  134. pe->kind=kind;
  135. pe->type=T_VALUE|T_ARR;
  136. if (kind==E_BTAB) pe->type|=T_BYTE;
  137. dot_label(new_dot_label(&pe->u.tab));
  138. pe->arr_siz=0;
  139. while (tab!=nil) {
  140. register struct table *junk=tab;
  141. rom(kind==E_BTAB ? 1 : vz, tab->val);
  142. tab=tab->next;
  143. pe->arr_siz++;
  144. free(junk);
  145. }
  146. return pe;
  147. }
  148. struct expr *copy_const(e) struct expr *e;
  149. /* If you double it up, you've got one you can throw away. (Or do something
  150. * useful with).
  151. */
  152. {
  153. register struct expr *c;
  154. c= (struct expr *) malloc(sizeof *c);
  155. *c= *e;
  156. return c;
  157. }
  158. struct expr *new_now()
  159. /* Now is the time to make a VALUE cell for the clock. */
  160. {
  161. register struct expr *pe;
  162. pe= (struct expr *) malloc(sizeof *pe);
  163. pe->kind=E_NOW;
  164. pe->type=T_VALUE;
  165. return pe;
  166. }
  167. struct expr *new_io(out, chan, args)
  168. int out;
  169. register struct expr *chan;
  170. struct expr_list *args;
  171. /* Either c ? v0; v1; v2; ... (out=0) or c ! e0; e1; e2; ... (out=1). */
  172. {
  173. register struct expr *pe;
  174. if ( ( (chan->type&T_TYPE) != T_CHAN || (chan->type&T_ARR) )
  175. && ! (chan->type&T_NOTDECL)
  176. )
  177. report("channel variable expected");
  178. used(chan);
  179. pe= (struct expr *) malloc(sizeof *pe);
  180. pe->kind=E_IO;
  181. pe->type=T_VOID;
  182. pe->u.io.out=out;
  183. pe->u.io.chan=chan;
  184. pe->u.io.args=args;
  185. return pe;
  186. }
  187. struct expr *new_call(proc, args)
  188. struct expr *proc;
  189. struct expr_list *args;
  190. /* Dial proc(arg1, arg2, ...) and you'll hear the tone of this function.
  191. * Dialing yourself is not allowed, but it will work if you ignore the
  192. * compiler generated noise.
  193. */
  194. {
  195. register struct expr *pe;
  196. pe= (struct expr *) malloc(sizeof *pe);
  197. used(proc);
  198. check_recursion(proc);
  199. pe->kind=E_CALL;
  200. pe->type=T_VOID;
  201. pe->u.call.proc=proc;
  202. pe->u.call.args=args;
  203. return pe;
  204. }
  205. void table_add(aapt, val) register struct table ***aapt; long val;
  206. /* Adds a value to a table using a hook to a hook. */
  207. {
  208. register struct table *pt;
  209. pt= (struct table *) malloc(sizeof *pt);
  210. pt->val=val;
  211. pt->next= **aapt;
  212. **aapt=pt;
  213. *aapt= &pt->next;
  214. }
  215. void expr_list_add(aaelp, arg)
  216. register struct expr_list ***aaelp;
  217. struct expr *arg;
  218. /* Another add, this time for actual arguments and the like. */
  219. {
  220. register struct expr_list *elp;
  221. elp= (struct expr_list *) malloc(sizeof *elp);
  222. elp->arg=arg;
  223. elp->next= **aaelp;
  224. **aaelp=elp;
  225. *aaelp= &elp->next;
  226. }
  227. void check_io(out, arg) int out; struct expr *arg;
  228. {
  229. if (out)
  230. outputable(arg);
  231. else
  232. inputable(arg);
  233. }
  234. void check_wait(e) struct expr *e;
  235. {
  236. if ((e->type&T_TYPE)!=T_VALUE)
  237. report("WAIT process needs valued operand");
  238. }
  239. static void assigned(e) register struct expr *e;
  240. /* Tries to tell e that it is assigned to. */
  241. {
  242. if (e->kind==E_VAR || (e->kind==E_NODE && e->u.node.op=='['
  243. && (e=e->u.node.left)->kind==E_VAR)
  244. ) {
  245. register struct symbol *var;
  246. if ((var=e->u.var)->type&T_REP) {
  247. warning("replicator index %s may not be assigned",
  248. var->name);
  249. var->type&= ~T_REP;
  250. }
  251. var->type|=T_ASSIGNED;
  252. }
  253. }
  254. void used(e) register struct expr *e;
  255. {
  256. if (e->kind==E_VAR || (e->kind==E_NODE && e->u.node.op=='['
  257. && (e=e->u.node.left)->kind==E_VAR)
  258. ) {
  259. register struct symbol *var;
  260. if ( ! ( (var=e->u.var)->type&(T_ASSIGNED|T_BUILTIN))
  261. && (var->type&T_TYPE)==T_VAR
  262. && var->info.vc.st.level==curr_level)
  263. warning("%s used before assigned", var->name);
  264. var->type|=(T_USED|T_ASSIGNED);
  265. }
  266. }
  267. static void rvalue(e) register struct expr *e;
  268. {
  269. if ((e->type&T_TYPE)!=T_VALUE || e->type&T_ARR)
  270. report("illegal operand of arithmetic operator");
  271. used(e);
  272. }
  273. static void assignable(l, r) register struct expr *l, *r;
  274. /* See if l can be assigned r. */
  275. {
  276. if ( ! ( (l->type&T_LVALUE && (r->type&T_TYPE)==T_VALUE
  277. && (l->type&T_ARR)==(r->type&T_ARR))
  278. || (l->type|r->type)&T_NOTDECL
  279. ))
  280. report("operands of assignment are not conformable");
  281. else
  282. if (l->type&T_ARR && ! ( (l->type|r->type)&T_NOTDECL ) ) {
  283. register lsiz=l->arr_siz, rsiz=r->arr_siz;
  284. if (lsiz!=0 && rsiz!=0 && lsiz!=rsiz)
  285. report("arrays have incompatible sizes");
  286. }
  287. used(r);
  288. assigned(l);
  289. }
  290. static void inputable(e) struct expr *e;
  291. {
  292. if ( ! (e->type&T_LVALUE) )
  293. report("operand of input process can't be assigned");
  294. assigned(e);
  295. }
  296. static void outputable(e) struct expr *e;
  297. {
  298. if ( ! ( (e->type&T_TYPE)==T_VALUE ) )
  299. report("operand of output process has no value");
  300. used(e);
  301. }
  302. static void subscriptable(l, r, byte, atype, arr_siz)
  303. register struct expr *l, *r;
  304. register byte;
  305. int *atype, *arr_siz;
  306. /* Tries to subscript l by r, returning type and array size for slices. */
  307. {
  308. register type= (l->type&T_TYPE)|byte;
  309. if ( !(l->type&(T_ARR|T_NOTDECL) ) )
  310. report("indexing on a non-array");
  311. else
  312. if ( ! ( (r->type&T_TYPE)==T_VALUE
  313. || (r->kind==E_NODE && r->u.node.op==FOR)
  314. ) )
  315. report("index is not computable");
  316. type|=(l->type&T_LVALUE);
  317. if (r->kind==E_NODE && r->u.node.op==FOR) {
  318. type|=T_ARR;
  319. if (r->u.node.right->kind!=E_CONST)
  320. report("slice must be of constant size");
  321. else
  322. *arr_siz=r->u.node.right->u.const;
  323. used(r->u.node.left);
  324. } else
  325. used(r);
  326. *atype=type;
  327. }
  328. void check_param(aform, act, err)
  329. struct par_list **aform;
  330. register struct expr *act;
  331. int *err;
  332. /* Test if formal parameter *aform corresponds with actual act. Err returns
  333. * error status. The aform hook is set to the next formal after the check.
  334. */
  335. {
  336. register struct par_list *form= *aform;
  337. register struct expr *left;
  338. register struct symbol *var;
  339. static char NONCORR[]="actual and formal parameter don't correspond";
  340. if (form==nil) {
  341. if (! *err) {
  342. report("too many actual parameters");
  343. *err=1;
  344. }
  345. return;
  346. }
  347. if ((form->type&T_ARR)!=(act->type&T_ARR) && !(act->type&T_NOTDECL) ) {
  348. report(NONCORR);
  349. } else {
  350. switch (form->type&T_TYPE) {
  351. case T_VAR:
  352. if ( ! (
  353. (act->type&T_TYPE)==T_VALUE
  354. && act->type&T_LVALUE
  355. && !(act->type&T_BYTE)
  356. ))
  357. report(NONCORR);
  358. assigned(act);
  359. used(act);
  360. break;
  361. case T_CHAN:
  362. if((act->type&T_TYPE)!=T_CHAN && !(act->type&T_NOTDECL))
  363. report(NONCORR);
  364. used(act);
  365. break;
  366. case T_VALUE:
  367. if ((act->type&T_TYPE)!=T_VALUE)
  368. report(NONCORR);
  369. used(act);
  370. break;
  371. }
  372. }
  373. *aform= form->next;
  374. }
  375. void destroy(e) register struct expr *e;
  376. /* Opposite of making. */
  377. {
  378. if (e!=nil) {
  379. switch (e->kind) {
  380. case E_NODE:
  381. destroy(e->u.node.left);
  382. destroy(e->u.node.right);
  383. break;
  384. case E_IO:
  385. case E_CALL:
  386. destroy(e->kind==E_IO ? e->u.io.chan : e->u.call.proc);
  387. {
  388. register struct expr_list *elp, *junk;
  389. elp= e->kind==E_IO ? e->u.io.args : e->u.call.args;
  390. while (elp!=nil) {
  391. destroy(elp->arg);
  392. junk=elp;
  393. elp=elp->next;
  394. free(junk);
  395. }
  396. }
  397. break;
  398. }
  399. free(e);
  400. }
  401. }