statement.g 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. /* S T A T E M E N T S */
  2. {
  3. #include <alloc.h>
  4. #include <em.h>
  5. #include "LLlex.h"
  6. #include "chk_expr.h"
  7. #include "def.h"
  8. #include "desig.h"
  9. #include "idf.h"
  10. #include "main.h"
  11. #include "node.h"
  12. #include "scope.h"
  13. #include "type.h"
  14. int slevel = 0; /* nesting level of statements */
  15. }
  16. /* ISO section 6.8.3.2, p. 128 */
  17. CompoundStatement:
  18. BEGIN StatementSequence END
  19. ;
  20. /* ISO section 6.8.3.1, p. 128 */
  21. StatementSequence:
  22. Statement
  23. [ %persistent
  24. ';' Statement
  25. ]*
  26. { chk_labels(slevel + 1); }
  27. ;
  28. /* ISO section 6.8.1, p. 126 */
  29. Statement
  30. {
  31. struct node *nd;
  32. } :
  33. {
  34. slevel++;
  35. }
  36. [ Label(&nd) ':'
  37. { if( nd ) DefLabel(nd, slevel); }
  38. ]?
  39. { if( !options['L'] )
  40. C_lin((arith) dot.tk_lineno);
  41. }
  42. [
  43. SimpleStatement
  44. |
  45. StructuredStatement
  46. ]
  47. { slevel--; }
  48. ;
  49. /* ISO section 6.8.2.1, p. 126 */
  50. SimpleStatement
  51. {
  52. struct node *pnd, *expp;
  53. } :
  54. /* This is a changed rule, because the grammar as specified in the
  55. * reference is not LL(1), and this gives conflicts.
  56. * Note : the grammar states : AssignmentStatement |
  57. * ProcedureStatement | ...
  58. */
  59. EmptyStatement
  60. |
  61. GotoStatement
  62. |
  63. /* Evidently this is the beginning of the changed part
  64. */
  65. IDENT { pnd = MkLeaf(Name, &dot); }
  66. [
  67. /* At this point the IDENT can be a FunctionIdentifier in
  68. * which case the VariableAccessTail must be empty.
  69. */
  70. VariableAccessTail(&pnd)
  71. [
  72. BECOMES
  73. |
  74. '=' { error("':=' expected instead of '='"); }
  75. ]
  76. Expression(&expp)
  77. { AssignStat(pnd, expp); }
  78. |
  79. { pnd = MkNode(Call, pnd, NULLNODE, &dot); }
  80. ActualParameterList(&(pnd->nd_right))?
  81. { ProcStat(pnd);
  82. if( !err_occurred )
  83. CodeCall(pnd);
  84. FreeNode(pnd);
  85. }
  86. ]
  87. |
  88. InputOutputStatement
  89. /* end of changed part
  90. */
  91. ;
  92. InputOutputStatement
  93. {
  94. struct node *nd = NULLNODE;
  95. } :
  96. /* This is a new rule because the grammar specified by the standard
  97. * is not exactly LL(1) (see SimpleStatement).
  98. */
  99. [
  100. READ ReadParameterList(&nd) { ChkRead(nd); }
  101. |
  102. READLN ReadParameterList(&nd)? { ChkReadln(nd); }
  103. |
  104. WRITE WriteParameterList(&nd) { ChkWrite(nd); }
  105. |
  106. WRITELN WriteParameterList(&nd)? { ChkWriteln(nd); }
  107. ]
  108. { FreeNode(nd); }
  109. ;
  110. EmptyStatement:
  111. /* empty */
  112. ;
  113. /* ISO section 6.8.3.1, p. 128 */
  114. StructuredStatement:
  115. CompoundStatement
  116. |
  117. ConditionalStatement
  118. |
  119. RepetitiveStatement
  120. |
  121. WithStatement
  122. ;
  123. /* ISO section 6.8.2.4, p. 127 */
  124. GotoStatement
  125. {
  126. struct node *nd;
  127. } :
  128. GOTO Label(&nd)
  129. { if( nd ) TstLabel(nd, slevel); }
  130. ;
  131. /* ISO section 6.8.3.3, p. 128 */
  132. ConditionalStatement:
  133. %default
  134. CaseStatement
  135. |
  136. IfStatement
  137. ;
  138. /* ISO section 6.8.3.6, p. 129 */
  139. RepetitiveStatement:
  140. RepeatStatement
  141. |
  142. WhileStatement
  143. |
  144. ForStatement
  145. ;
  146. /* ISO section 6.8.3.10, p. 132 */
  147. WithStatement
  148. {
  149. struct scopelist *Save = CurrVis;
  150. struct node *nd;
  151. } :
  152. WITH
  153. RecordVariableList(&nd)
  154. DO
  155. Statement { EndWith(Save, nd);
  156. chk_labels(slevel + 1);
  157. }
  158. ;
  159. RecordVariableList(register struct node **pnd;)
  160. {
  161. struct node *nd;
  162. } :
  163. RecordVariable(&nd)
  164. { *pnd = nd = MkNode(Link, nd, NULLNODE, &dot);
  165. nd->nd_symb = ',';
  166. }
  167. [ %persistent
  168. ',' { nd->nd_right = MkLeaf(Link, &dot);
  169. nd = nd->nd_right;
  170. }
  171. RecordVariable(&(nd->nd_left))
  172. ]*
  173. ;
  174. RecordVariable(register struct node **pnd;):
  175. VariableAccess(pnd)
  176. { WithStat(*pnd); }
  177. ;
  178. /* ISO section 6.8.3.4, p. 128 */
  179. IfStatement
  180. {
  181. struct node *nd;
  182. label l1 = ++text_label;
  183. label l2 = ++text_label;
  184. } :
  185. IF
  186. BooleanExpression(&nd)
  187. { struct desig ds;
  188. ds = InitDesig;
  189. if( !err_occurred )
  190. CodeExpr(nd, &ds, l1);
  191. }
  192. THEN
  193. Statement { chk_labels(slevel + 1); }
  194. [ %prefer /* closest matching */
  195. ELSE
  196. { C_bra(l2);
  197. C_df_ilb(l1);
  198. }
  199. Statement
  200. { C_df_ilb(l2);
  201. chk_labels(slevel + 1);
  202. }
  203. |
  204. /* empty */
  205. { C_df_ilb(l1); }
  206. ]
  207. ;
  208. /* ISO section 6.8.3.5, p. 128 */
  209. CaseStatement
  210. {
  211. struct node *casend, *nd;
  212. label exit_label;
  213. } :
  214. /* This is a changed rule, because the grammar as specified in the
  215. * reference states that a semicolon is optional before END,
  216. * and this is not LL(1).
  217. */
  218. CASE { casend = nd = MkLeaf(Link, &dot);
  219. casend->nd_lab = ++text_label;
  220. exit_label = ++text_label;
  221. }
  222. Expression(&(nd->nd_left))
  223. { CaseExpr(casend); }
  224. OF
  225. CaseListElement(&(nd->nd_right), exit_label)
  226. { nd = nd->nd_right; }
  227. CaseListElementTail(&(nd->nd_right), exit_label)
  228. END
  229. { CaseEnd(casend, exit_label); }
  230. ;
  231. CaseListElementTail(register struct node **pnd; label exit_label;):
  232. /* This is a new rule, all because of a silly semicolon
  233. */
  234. /* empty */
  235. |
  236. %default
  237. ';'
  238. [
  239. /* empty */
  240. |
  241. CaseListElement(pnd, exit_label)
  242. CaseListElementTail(&((*pnd)->nd_right), exit_label)
  243. ]
  244. ;
  245. CaseListElement(register struct node **pnd; label exit_label;):
  246. CaseConstantList(pnd)
  247. ':'
  248. { *pnd = MkNode(Link, *pnd, NULLNODE, &dot);
  249. (*pnd)->nd_lab = ++text_label;
  250. C_df_ilb(text_label);
  251. }
  252. Statement { C_bra(exit_label);
  253. chk_labels(slevel + 1);
  254. }
  255. ;
  256. /* ISO section 6.8.3.7, p. 129 */
  257. RepeatStatement
  258. {
  259. struct node *nd;
  260. label repeatlb = ++text_label;
  261. } :
  262. REPEAT
  263. { C_df_ilb(repeatlb); }
  264. StatementSequence
  265. UNTIL
  266. BooleanExpression(&nd)
  267. { struct desig ds;
  268. ds = InitDesig;
  269. if( !err_occurred )
  270. CodeExpr(nd, &ds, repeatlb);
  271. }
  272. ;
  273. /* ISO section 6.8.3.8, p. 129 */
  274. WhileStatement
  275. {
  276. struct node *nd;
  277. label whilelb = ++text_label;
  278. label exitlb = ++text_label;
  279. } :
  280. WHILE
  281. { C_df_ilb(whilelb); }
  282. BooleanExpression(&nd)
  283. { struct desig ds;
  284. ds = InitDesig;
  285. if( !err_occurred )
  286. CodeExpr(nd, &ds, exitlb);
  287. }
  288. DO
  289. Statement
  290. { C_bra(whilelb);
  291. C_df_ilb(exitlb);
  292. chk_labels(slevel + 1);
  293. }
  294. ;
  295. /* ISO section 6.8.3.9, p. 130 */
  296. ForStatement
  297. {
  298. register struct node *nd;
  299. int stepsize;
  300. label l1 = ++text_label;
  301. label l2 = ++text_label;
  302. arith tmp1 = (arith) 0;
  303. arith tmp2 = (arith) 0;
  304. } :
  305. FOR
  306. /* ControlVariable must be an EntireVariable */
  307. IDENT { nd = MkLeaf(Name, &dot); }
  308. BECOMES
  309. Expression(&(nd->nd_left))
  310. [
  311. TO { stepsize = 1; }
  312. |
  313. DOWNTO { stepsize = -1; }
  314. ]
  315. Expression(&(nd->nd_right))
  316. { ChkForStat(nd);
  317. if( !err_occurred ) {
  318. tmp1 = CodeInitFor(nd->nd_left, 0);
  319. tmp2 = CodeInitFor(nd->nd_right, 2);
  320. CodeFor(nd, stepsize, l1, l2, tmp1);
  321. }
  322. }
  323. DO
  324. Statement
  325. { if( !err_occurred )
  326. CodeEndFor(nd, stepsize, l1, l2, tmp2);
  327. chk_labels(slevel + 1);
  328. FreeNode(nd);
  329. if( tmp1 ) FreeInt(tmp1);
  330. if( tmp2 ) FreeInt(tmp2);
  331. }
  332. ;
  333. /* SPECIALSPECIALSPECIALSPECIALSPECIALSPECIALSPECIALSPECIALSPECIALSPECIAL */
  334. /* ISO section 6.9, p. 132-136 */
  335. ReadParameterList(register struct node **pnd;)
  336. {
  337. register struct node *nd;
  338. } :
  339. /* This is a changed rule, because the grammar as specified in the
  340. * reference is not LL(1), and this gives conflicts.
  341. */
  342. '('
  343. VariableAccess(pnd) /* possibly a FileVariable */
  344. { *pnd = nd =
  345. MkNode(Link, *pnd, NULLNODE, &dot);
  346. nd->nd_symb = ',';
  347. }
  348. [ %persistent
  349. ',' { nd->nd_right = MkLeaf(Link, &dot);
  350. nd = nd->nd_right;
  351. }
  352. VariableAccess(&(nd->nd_left))
  353. ]*
  354. ')'
  355. ;
  356. WriteParameterList(register struct node **pnd;)
  357. {
  358. register struct node *nd;
  359. } :
  360. /* This is a changed rule, because the grammar as specified in the
  361. * reference is not LL(1), and this gives conflicts.
  362. */
  363. '('
  364. /* Only the first WriteParameter can be a FileVariable !!
  365. */
  366. WriteParameter(pnd)
  367. { *pnd = nd =
  368. MkNode(Link, *pnd, NULLNODE, &dot);
  369. nd->nd_symb = ',';
  370. }
  371. [ %persistent
  372. ',' { nd->nd_right = MkLeaf(Link, &dot);
  373. nd = nd->nd_right;
  374. }
  375. WriteParameter(&(nd->nd_left))
  376. ]*
  377. ')'
  378. ;
  379. WriteParameter(register struct node **pnd;)
  380. {
  381. register struct node *nd;
  382. } :
  383. Expression(pnd)
  384. { if( !ChkExpression(*pnd) )
  385. (*pnd)->nd_type = error_type;
  386. *pnd = nd =
  387. MkNode(Link, *pnd, NULLNODE, &dot);
  388. nd->nd_symb = ':';
  389. }
  390. [
  391. /* Here the first Expression can't be a FileVariable
  392. */
  393. ':' { nd->nd_right = MkLeaf(Link, &dot);
  394. nd = nd->nd_right;
  395. }
  396. Expression(&(nd->nd_left))
  397. { if( !ChkExpression(nd->nd_left) )
  398. nd->nd_left->nd_type = error_type;
  399. }
  400. [
  401. ':' { nd->nd_right = MkLeaf(Link, &dot);
  402. nd = nd->nd_right;
  403. }
  404. Expression(&(nd->nd_left))
  405. { if( !ChkExpression(nd->nd_left) )
  406. nd->nd_left->nd_type = error_type;
  407. }
  408. ]?
  409. ]?
  410. ;