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".
5 * Author: Ceriel J.H. Jacobs
8 /* D E C L A R A T I O N S */
10 /* $Id: declar.g,v 1.82 1994/06/24 12:40:18 ceriel Exp $ */
20 #include "strict3rd.h"
33 int proclevel = 0; /* nesting level of procedures */
34 int return_occurred; /* set if a return occurs in a block */
36 extern t_node *EmptyStatement;
38 #define needs_static_link() (proclevel > 1)
41 /* inline in declaration: need space
42 * ProcedureDeclaration
47 * ProcedureHeading(&df, D_PROCEDURE)
48 * ';' block(&(df->prc_body))
50 * { EndProc(df, dot.TOK_IDF);
56 ProcedureHeading(t_def **pdf; int type;)
59 arith parmaddr = needs_static_link() ? pointer_size : 0;
63 { *pdf = DeclProc(type, dot.TOK_IDF); }
67 FPSection(&pr, &parmaddr)
69 ';' FPSection(&pr, &parmaddr)
79 { CheckWithDef(*pdf, proc_type(tp, pr, parmaddr));
81 if (tp && IsConstructed(tp)) {
82 warning(W_STRICT, "procedure \"%s\" has a constructed result type",
83 (*pdf)->df_idf->id_text);
89 block(t_node **pnd;) :
93 { return_occurred = 0; }
96 StatementSequence(pnd)
98 { *pnd = EmptyStatement; }
107 CONST [ ConstantDeclaration ';' ]*
109 TYPE [ TypeDeclaration ';' ]*
111 VAR [ VariableDeclaration ';' ]*
114 ProcedureHeading(&df, D_PROCEDURE)
118 block(&(df->prc_body))
121 EndProc(df, dot.TOK_IDF);
126 ModuleDeclaration ';'
129 /* inline in procedureheading: need space
130 * FormalParameters(t_param **ppr; arith *parmaddr; t_type **ptp;):
133 * FPSection(ppr, parmaddr)
135 * ';' FPSection(ppr, parmaddr)
140 * [ ':' qualtype(ptp)
146 FPSection(t_param **ppr; arith *parmaddr;)
152 var(&VARp) IdentList(&FPList) ':' FormalType(&tp)
153 { EnterParamList(ppr, FPList, tp, VARp, parmaddr); }
156 FormalType(t_type **ptp;)
157 /* index type of conformant array is "CARDINAL".
158 Recognize a conformant array by size 0.
160 { register t_type *tp;
163 { tp = construct_type(T_ARRAY, card_type); }
164 qualtype(&(tp->arr_elem))
178 IDENT { df = define(dot.TOK_IDF, CurrentScope, D_TYPE);
182 { DeclareType(nd, df, tp);
187 type(register t_type **ptp;):
188 %default SimpleType(ptp)
201 SimpleType(register t_type **ptp;) :
207 /* The subrange type is given a base type by the
208 qualident (this is new modula-2).
213 | { *ptp = 0; /* no qualification */ }
217 enumeration(t_type **ptp;)
221 '(' IdentList(&EnumList) ')'
222 { *ptp = enum_type(EnumList); }
225 IdentList(t_node **p;)
229 IDENT { *p = q = dot2leaf(Select); }
232 { q->nd_NEXT = dot2leaf(Select);
238 SubrangeType(t_type **ptp;)
243 This is not exactly the rule in the new report, but see
244 the rule for "SimpleType".
246 '[' ConstExpression(&nd1)
247 UPTO ConstExpression(&nd2)
249 { *ptp = subr_type(nd1, nd2, *ptp);
255 ArrayType(t_type **ptp;)
258 register t_type *tp1, *tp2;
260 ARRAY SimpleType(&tp)
261 { tp1 = tp2 = construct_type(T_ARRAY, tp); }
264 { tp2->arr_elem = construct_type(T_ARRAY, tp);
268 { tp2->arr_elem = tp;
274 RecordType(t_type **ptp;)
276 register t_scope *scope;
278 int xalign = struct_align;
282 { scope = open_and_close_scope(OPENSCOPE); }
283 FieldListSequence(scope, &size, &xalign)
285 warning(W_ORDINARY, "empty record declaration");
288 *ptp = standard_type(T_RECORD, xalign, align(size, xalign));
289 (*ptp)->rec_scope = scope;
290 Reverse(&(scope->sc_def));
295 FieldListSequence(t_scope *scope; arith *cnt; int *palign;):
296 FieldList(scope, cnt, palign)
298 ';' FieldList(scope, cnt, palign)
302 FieldList(t_scope *scope; arith *cnt; int *palign;)
311 IdentList(&FldList) ':' type(&tp)
313 *palign = lcm(*palign, tp->tp_align);
314 EnterFieldList(FldList, tp, scope, cnt);
318 /* Also accept old fashioned Modula-2 syntax, but give a warning.
319 Sorry for the complicated code.
323 /* This is correct, in both kinds of Modula-2, if
324 the first qualident is a single identifier.
326 { if (nd->nd_class != Name) {
327 error("illegal variant tag");
330 df = define(nd->nd_IDF, scope, D_FIELD);
331 *palign = lcm(*palign, tp->tp_align);
332 if (!(tp->tp_fund & T_DISCRETE)) {
333 error("illegal type in variant");
336 df->fld_off = align(*cnt, tp->tp_align);
337 *cnt = df->fld_off + tp->tp_size;
338 df->df_flags |= D_QEXPORTED;
342 | /* Old fashioned! the first qualident now represents
346 #ifndef STRICT_3RD_ED
347 if (! options['3']) warning(W_OLDFASHIONED,
348 "old fashioned Modula-2 syntax; ':' missing");
351 error("':' missing");
352 tp = qualified_type(&nd);
356 /* Aha, third edition. Well done! */
359 OF variant(scope, &tcnt, tp, palign)
360 { max = tcnt; tcnt = *cnt; }
362 '|' variant(scope, &tcnt, tp, palign)
363 { if (tcnt > max) max = tcnt; tcnt = *cnt; }
365 [ ELSE FieldListSequence(scope, &tcnt, palign)
366 { if (tcnt > max) max = tcnt; }
375 variant(t_scope *scope; arith *cnt; t_type *tp; int *palign;)
380 CaseLabelList(&tp, &nd)
381 { /* Ignore the cases for the time being.
382 Maybe a checking version will be supplied
387 ':' FieldListSequence(scope, cnt, palign)
390 /* Changed rule in new modula-2 */
393 CaseLabelList(t_type **ptp; t_node **pnd;):
396 { *pnd = dot2node(Link, *pnd, NULLNODE); }
397 ',' CaseLabels(ptp, &((*pnd)->nd_RIGHT))
398 { pnd = &((*pnd)->nd_RIGHT); }
402 CaseLabels(t_type **ptp; register t_node **pnd;)
409 t_type *tp = intorcard(*ptp,
410 BaseType((*pnd)->nd_type));
412 ChkCompat(pnd, *ptp, "case label");
415 nd->nd_type = BaseType(nd->nd_type); /* ??? */
416 if (! (nd->nd_type->tp_fund & T_DISCRETE) ||
417 nd->nd_type->tp_size > word_size) {
418 node_error(nd, "illegal type in case label");
422 UPTO { *pnd = nd = dot2node(Link,nd,NULLNODE);
423 nd->nd_type = nd->nd_LEFT->nd_type;
425 ConstExpression(&(*pnd)->nd_RIGHT)
426 { if (!ChkCompat(&((*pnd)->nd_RIGHT), nd->nd_type,
428 nd->nd_type = error_type;
430 else if (! chk_bounds(nd->nd_LEFT->nd_INT,
431 nd->nd_RIGHT->nd_INT,
432 nd->nd_type->tp_fund)) {
434 "lower bound exceeds upper bound in case label range");
445 SetType(t_type **ptp;)
448 SET OF SimpleType(&tp)
449 { *ptp = set_type(tp); }
452 /* In a pointer type definition, the type pointed at does not
453 have to be declared yet, so be careful about identifying
456 PointerType(register t_type **ptp;)
457 { register t_type *tp;
459 { tp = construct_type(T_POINTER, NULLTYPE); }
461 [ %if (type_or_forward(tp))
469 qualtype(t_type **ptp;)
474 { *ptp = qualified_type(&nd); }
477 ProcedureType(t_type **ptp;)
485 FormalTypeList(&pr, &parmaddr, &tp)
488 { *ptp = proc_type(tp, pr, parmaddr); }
491 FormalTypeList(t_param **ppr; arith *pparmaddr; t_type **ptp;) :
494 VarFormalType(ppr, pparmaddr)
496 ',' VarFormalType(ppr, pparmaddr)
506 VarFormalType(t_param **ppr; arith *pparmaddr;)
513 { EnterParamList(ppr,NULLNODE,tp,isvar,pparmaddr); }
518 VAR { *VARp = D_VARPAR; }
520 /* empty */ { *VARp = D_VALPAR; }
530 IDENT { id = dot.TOK_IDF; }
531 '=' ConstExpression(&nd)
532 { df = define(id,CurrentScope,D_CONST);
533 df->con_const = nd->nd_token;
534 df->df_type = nd->nd_type;
548 ',' IdentAddr(&(nd->nd_RIGHT))
549 { nd = nd->nd_RIGHT; }
552 { EnterVarList(VarList, tp, proclevel > 0); }
555 IdentAddr(t_node **pnd;)
559 IDENT { nd = dot2leaf(Name);
560 *pnd = dot2node(Link, nd, NULLNODE);
563 ConstExpression(&(nd->nd_NEXT))