expression.g 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. *
  5. * Author: Ceriel J.H. Jacobs
  6. */
  7. /* E X P R E S S I O N S */
  8. /* $Id$ */
  9. {
  10. #include "debug.h"
  11. #include <alloc.h>
  12. #include <em_arith.h>
  13. #include <em_label.h>
  14. #include <assert.h>
  15. #include "LLlex.h"
  16. #include "idf.h"
  17. #include "def.h"
  18. #include "node.h"
  19. #include "type.h"
  20. #include "chk_expr.h"
  21. #include "warning.h"
  22. extern char options[];
  23. }
  24. /* inline, we need room for pdp/11
  25. number(t_node **p;) :
  26. [
  27. %default
  28. INTEGER
  29. |
  30. REAL
  31. ] { *p = dot2leaf(Value);
  32. (*p)->nd_type = toktype;
  33. }
  34. ;
  35. */
  36. qualident(t_node **p;)
  37. {
  38. } :
  39. IDENT { *p = dot2leaf(Name); }
  40. [
  41. selector(p)
  42. ]*
  43. ;
  44. selector(register t_node **pnd;)
  45. { t_node *nd;
  46. } :
  47. '.' { nd = dot2leaf(Select); nd->nd_NEXT = *pnd; *pnd = nd; }
  48. IDENT { (*pnd)->nd_IDF = dot.TOK_IDF; }
  49. ;
  50. ExpList(t_node **pnd;)
  51. {
  52. register t_node *nd;
  53. } :
  54. expression(pnd) { *pnd = nd = dot2node(Link,*pnd,NULLNODE);
  55. nd->nd_symb = ',';
  56. }
  57. [
  58. ',' { nd->nd_RIGHT = dot2leaf(Link);
  59. nd = nd->nd_RIGHT;
  60. }
  61. expression(&(nd->nd_LEFT))
  62. ]*
  63. ;
  64. ConstExpression(register t_node **pnd;)
  65. {
  66. }:
  67. expression(pnd)
  68. /*
  69. * Changed rule in new Modula-2.
  70. * Check that the expression is a constant expression and evaluate!
  71. */
  72. {
  73. DO_DEBUG(options['C'], print("CONSTANT EXPRESSION\n"));
  74. DO_DEBUG(options['C'], PrNode(*pnd, 0));
  75. if (ChkExpression(pnd) &&
  76. (*pnd)->nd_class != Set &&
  77. (*pnd)->nd_class != Value &&
  78. ! (options['l'] && (*pnd)->nd_class == Def && IsProc((*pnd)))) {
  79. error("constant expression expected");
  80. }
  81. DO_DEBUG(options['C'], print("RESULTS IN\n"));
  82. DO_DEBUG(options['C'], PrNode(*pnd, 0));
  83. }
  84. ;
  85. expression(register t_node **pnd;)
  86. {
  87. } :
  88. SimpleExpression(pnd)
  89. [
  90. /* relation */
  91. [ '=' | '#' | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN ]
  92. { *pnd = dot2node(Oper, *pnd, NULLNODE); }
  93. SimpleExpression(&((*pnd)->nd_RIGHT))
  94. |
  95. ]
  96. ;
  97. /* Inline in expression
  98. relation:
  99. '=' | '#' | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN
  100. ;
  101. */
  102. SimpleExpression(register t_node **pnd;)
  103. {
  104. register t_node *nd = 0;
  105. } :
  106. [
  107. [ '+' | '-' ]
  108. { nd = dot2leaf(Uoper);
  109. /* priority of unary operator ??? */
  110. }
  111. |
  112. ]
  113. term(pnd)
  114. { if (nd) {
  115. nd->nd_RIGHT = *pnd;
  116. *pnd = nd;
  117. }
  118. nd = *pnd;
  119. }
  120. [
  121. /* AddOperator */
  122. [ '+' | '-' | OR ]
  123. { nd = dot2node(Oper, nd, NULLNODE); }
  124. term(&(nd->nd_RIGHT))
  125. ]*
  126. { *pnd = nd; }
  127. ;
  128. /* Inline in "SimpleExpression"
  129. AddOperator:
  130. '+' | '-' | OR
  131. ;
  132. */
  133. term(t_node **pnd;)
  134. {
  135. register t_node *nd;
  136. }:
  137. factor(pnd) { nd = *pnd; }
  138. [
  139. /* MulOperator */
  140. [ '*' | '/' | DIV | MOD | AND ]
  141. { nd = dot2node(Oper, nd, NULLNODE); }
  142. factor(&(nd->nd_RIGHT))
  143. ]*
  144. { *pnd = nd; }
  145. ;
  146. /* inline in "term"
  147. MulOperator:
  148. '*' | '/' | DIV | MOD | AND
  149. ;
  150. */
  151. factor(register t_node **p;)
  152. {
  153. register t_node *nd;
  154. t_node *nd1;
  155. } :
  156. qualident(p)
  157. [
  158. designator_tail(p)
  159. [
  160. { *p = dot2node(Call, *p, NULLNODE); }
  161. ActualParameters(&((*p)->nd_RIGHT))
  162. |
  163. ]
  164. |
  165. bare_set(&nd1)
  166. { nd = nd1; nd->nd_LEFT = *p; *p = nd; }
  167. ]
  168. |
  169. bare_set(p)
  170. | %default
  171. [
  172. %default
  173. INTEGER
  174. |
  175. REAL
  176. |
  177. STRING
  178. ] { *p = dot2leaf(Value);
  179. (*p)->nd_type = toktype;
  180. }
  181. |
  182. '(' { nd = dot2leaf(Uoper); }
  183. expression(p)
  184. { /* In some cases we must leave the '(' as an unary
  185. operator, because otherwise we cannot see that the
  186. factor was not a designator
  187. */
  188. register int class = (*p)->nd_class;
  189. if (class == Arrsel ||
  190. class == Arrow ||
  191. class == Name ||
  192. class == Select) {
  193. nd->nd_RIGHT = *p;
  194. *p = nd;
  195. }
  196. else FreeNode(nd);
  197. }
  198. ')'
  199. |
  200. NOT { *p = dot2leaf(Uoper); }
  201. factor(&((*p)->nd_RIGHT))
  202. ;
  203. bare_set(t_node **pnd;)
  204. {
  205. register t_node *nd;
  206. } :
  207. '{' { DOT = SET;
  208. *pnd = nd = dot2leaf(Xset);
  209. nd->nd_type = bitset_type;
  210. }
  211. [
  212. element(nd)
  213. [ { nd = nd->nd_RIGHT; }
  214. ',' element(nd)
  215. ]*
  216. |
  217. ]
  218. '}'
  219. ;
  220. ActualParameters(t_node **pnd;):
  221. '(' ExpList(pnd)? ')'
  222. ;
  223. element(register t_node *nd;) :
  224. expression(&(nd->nd_RIGHT))
  225. [
  226. UPTO
  227. { nd->nd_RIGHT = dot2node(Link, nd->nd_RIGHT, NULLNODE);}
  228. expression(&(nd->nd_RIGHT->nd_RIGHT))
  229. |
  230. ]
  231. { nd->nd_RIGHT = dot2node(Link, nd->nd_RIGHT, NULLNODE);
  232. nd->nd_RIGHT->nd_symb = ',';
  233. }
  234. ;
  235. designator(t_node **pnd;)
  236. :
  237. qualident(pnd)
  238. designator_tail(pnd)
  239. ;
  240. designator_tail(register t_node **pnd;):
  241. visible_designator_tail(pnd)
  242. [ %persistent
  243. %default
  244. selector(pnd)
  245. |
  246. visible_designator_tail(pnd)
  247. ]*
  248. |
  249. ;
  250. visible_designator_tail(t_node **pnd;)
  251. {
  252. register t_node *nd = *pnd;
  253. }:
  254. '[' { nd = dot2node(Arrsel, nd, NULLNODE); }
  255. expression(&(nd->nd_RIGHT))
  256. [
  257. ','
  258. { nd = dot2node(Arrsel, nd, NULLNODE);
  259. }
  260. expression(&(nd->nd_RIGHT))
  261. ]*
  262. ']'
  263. { *pnd = nd; }
  264. |
  265. '^' { *pnd = dot2node(Arrow, NULLNODE, nd); }
  266. ;