ack/lang/m2/comp/declar.g

503 lines
9.5 KiB
Text
Raw Normal View History

1986-03-26 15:11:02 +00:00
/* D E C L A R A T I O N S */
1986-03-20 14:52:03 +00:00
1986-03-26 15:11:02 +00:00
{
1986-03-20 14:52:03 +00:00
static char *RcsId = "$Header$";
1986-03-26 15:11:02 +00:00
#include <em_arith.h>
#include <em_label.h>
1986-04-08 18:15:46 +00:00
#include <alloc.h>
1986-03-26 22:46:48 +00:00
#include <assert.h>
1986-03-26 15:11:02 +00:00
#include "idf.h"
#include "LLlex.h"
#include "def.h"
#include "type.h"
#include "scope.h"
1986-04-06 17:42:56 +00:00
#include "node.h"
#include "misc.h"
1986-03-26 15:11:02 +00:00
}
1986-03-20 14:52:03 +00:00
1986-03-26 15:11:02 +00:00
ProcedureDeclaration
{
1986-03-26 22:46:48 +00:00
struct def *df;
1986-03-26 15:11:02 +00:00
} :
1986-03-26 22:46:48 +00:00
ProcedureHeading(&df, D_PROCEDURE)
1986-03-26 15:11:02 +00:00
';' block IDENT
{ match_id(dot.TOK_IDF, df->df_idf);
1986-04-04 13:47:04 +00:00
df->prc_scope = CurrentScope->sc_scope;
1986-04-12 02:21:24 +00:00
close_scope(SC_CHKFORW);
1986-03-26 15:11:02 +00:00
}
;
1986-03-26 22:46:48 +00:00
ProcedureHeading(struct def **pdf; int type;)
1986-03-26 15:11:02 +00:00
{
1986-04-11 11:57:19 +00:00
struct type *tp = 0;
1986-04-04 13:47:04 +00:00
struct type *tp1 = 0;
1986-03-27 17:37:41 +00:00
struct paramlist *params = 0;
1986-04-04 13:47:04 +00:00
register struct def *df;
1986-03-26 15:11:02 +00:00
} :
PROCEDURE IDENT
1986-03-29 01:04:49 +00:00
{ assert(type & (D_PROCEDURE | D_PROCHEAD));
1986-04-04 13:47:04 +00:00
if (type == D_PROCHEAD) {
df = define(dot.TOK_IDF, CurrentScope, type);
1986-04-12 02:21:24 +00:00
df->for_node = MkNode(Name, NULLNODE, NULLNODE, &dot);
1986-04-04 13:47:04 +00:00
}
else {
df = lookup(dot.TOK_IDF,
CurrentScope->sc_scope);
if (df && df->df_kind == D_PROCHEAD) {
df->df_kind = type;
tp1 = df->df_type;
}
else {
df = define(dot.TOK_IDF,
CurrentScope, type);
}
1986-03-26 22:46:48 +00:00
open_scope(OPENSCOPE, 0);
}
}
1986-04-03 00:44:39 +00:00
FormalParameters(type == D_PROCEDURE, &params, &tp)?
1986-03-29 01:04:49 +00:00
{
1986-04-10 01:08:49 +00:00
df->df_type = tp = construct_type(T_PROCEDURE, tp);
1986-03-29 01:04:49 +00:00
tp->prc_params = params;
1986-04-04 13:47:04 +00:00
if (tp1 && !TstTypeEquiv(tp, tp1)) {
error("inconsistent procedure declaration for \"%s\"", df->df_idf->id_text);
}
*pdf = df;
1986-03-29 01:04:49 +00:00
}
1986-03-20 14:52:03 +00:00
;
block:
declaration* [ BEGIN StatementSequence ]? END
;
declaration:
CONST [ ConstantDeclaration ';' ]*
|
TYPE [ TypeDeclaration ';' ]*
|
VAR [ VariableDeclaration ';' ]*
|
ProcedureDeclaration ';'
|
ModuleDeclaration ';'
;
1986-03-27 17:37:41 +00:00
FormalParameters(int doparams; struct paramlist **pr; struct type **tp;)
{
struct def *df;
register struct paramlist *pr1;
} :
'('
[
1986-03-29 01:04:49 +00:00
FPSection(doparams, pr)
{ pr1 = *pr; }
1986-03-27 17:37:41 +00:00
[
1986-03-29 01:04:49 +00:00
{ for (; pr1->next; pr1 = pr1->next) ; }
1986-03-27 17:37:41 +00:00
';' FPSection(doparams, &(pr1->next))
]*
]?
')'
{ *tp = 0; }
1986-04-11 11:57:19 +00:00
[ ':' qualident(D_TYPE|D_HTYPE|D_HIDDEN, &df, "type", (struct node **) 0)
1986-03-29 01:04:49 +00:00
{ *tp = df->df_type; }
1986-03-26 15:11:02 +00:00
]?
1986-03-20 14:52:03 +00:00
;
1986-03-29 01:04:49 +00:00
/* In the next nonterminal, "doparams" is a flag indicating whether
the identifiers representing the parameters must be added to the
symbol table. We must not do so when reading a Definition Module,
because in this case we only read the header. The Implementation
might contain different identifiers representing the same paramters.
*/
1986-03-27 17:37:41 +00:00
FPSection(int doparams; struct paramlist **ppr;)
1986-03-20 14:52:03 +00:00
{
1986-04-06 17:42:56 +00:00
struct node *FPList;
1986-03-29 01:04:49 +00:00
struct paramlist *ParamList();
struct type *tp;
int VARp = 0;
1986-03-20 14:52:03 +00:00
} :
1986-03-26 15:11:02 +00:00
[
1986-03-29 01:04:49 +00:00
VAR { VARp = 1; }
1986-03-26 15:11:02 +00:00
]?
1986-03-29 01:04:49 +00:00
IdentList(&FPList) ':' FormalType(&tp)
{
if (doparams) {
EnterIdList(FPList, D_VARIABLE, VARp, tp, CurrentScope);
}
1986-04-08 18:15:46 +00:00
*ppr = ParamList(FPList, tp, VARp);
1986-04-06 17:42:56 +00:00
FreeNode(FPList);
1986-03-29 01:04:49 +00:00
}
1986-03-20 14:52:03 +00:00
;
1986-03-29 01:04:49 +00:00
FormalType(struct type **tp;)
1986-03-27 17:37:41 +00:00
{
struct def *df;
int ARRAYflag = 0;
} :
[ ARRAY OF { ARRAYflag = 1; }
]?
1986-04-11 11:57:19 +00:00
qualident(D_TYPE|D_HTYPE|D_HIDDEN, &df, "type", (struct node **) 0)
1986-03-29 01:04:49 +00:00
{ if (ARRAYflag) {
1986-04-10 01:08:49 +00:00
*tp = construct_type(T_ARRAY, NULLTYPE);
1986-03-29 01:04:49 +00:00
(*tp)->arr_elem = df->df_type;
}
else *tp = df->df_type;
}
1986-03-20 14:52:03 +00:00
;
1986-03-26 15:11:02 +00:00
TypeDeclaration
{
1986-03-26 22:46:48 +00:00
struct def *df;
1986-03-27 17:37:41 +00:00
struct type *tp;
1986-03-26 15:11:02 +00:00
}:
1986-03-27 17:37:41 +00:00
IDENT { df = define(dot.TOK_IDF, CurrentScope, D_TYPE); }
'=' type(&tp)
1986-04-02 17:34:21 +00:00
{ df->df_type = tp;
if ((df->df_flags&D_EXPORTED) &&
1986-04-10 01:08:49 +00:00
tp->tp_fund == T_ENUMERATION) {
1986-04-03 00:44:39 +00:00
exprt_literals(tp->enm_enums,
enclosing(CurrentScope));
1986-04-02 17:34:21 +00:00
}
1986-04-03 00:44:39 +00:00
if (df->df_kind == D_HTYPE &&
1986-04-10 01:08:49 +00:00
tp->tp_fund != T_POINTER) {
1986-04-03 00:44:39 +00:00
error("Opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
}
1986-04-08 18:15:46 +00:00
1986-04-02 17:34:21 +00:00
}
1986-03-20 14:52:03 +00:00
;
1986-03-27 17:37:41 +00:00
type(struct type **ptp;):
SimpleType(ptp)
1986-03-20 14:52:03 +00:00
|
1986-03-27 17:37:41 +00:00
ArrayType(ptp)
1986-03-20 14:52:03 +00:00
|
1986-03-27 17:37:41 +00:00
RecordType(ptp)
1986-03-20 14:52:03 +00:00
|
1986-03-27 17:37:41 +00:00
SetType(ptp)
1986-03-20 14:52:03 +00:00
|
1986-03-27 17:37:41 +00:00
PointerType(ptp)
1986-03-20 14:52:03 +00:00
|
1986-03-27 17:37:41 +00:00
ProcedureType(ptp)
1986-03-20 14:52:03 +00:00
;
1986-03-27 17:37:41 +00:00
SimpleType(struct type **ptp;)
{
struct def *df;
} :
1986-04-11 11:57:19 +00:00
qualident(D_TYPE|D_HTYPE|D_HIDDEN, &df, "type", (struct node **) 0)
1986-03-20 14:52:03 +00:00
[
1986-03-29 01:04:49 +00:00
/* nothing */
1986-04-08 18:15:46 +00:00
{ *ptp = df->df_type; }
1986-03-20 14:52:03 +00:00
|
1986-03-27 17:37:41 +00:00
SubrangeType(ptp)
1986-03-29 01:04:49 +00:00
/* The subrange type is given a base type by the
qualident (this is new modula-2).
*/
{
1986-04-08 18:15:46 +00:00
chk_basesubrange(*ptp, df->df_type);
1986-03-29 01:04:49 +00:00
}
1986-03-20 14:52:03 +00:00
]
|
1986-03-27 17:37:41 +00:00
enumeration(ptp)
1986-03-20 14:52:03 +00:00
|
1986-03-27 17:37:41 +00:00
SubrangeType(ptp)
1986-03-20 14:52:03 +00:00
;
1986-03-27 17:37:41 +00:00
enumeration(struct type **ptp;)
1986-03-20 14:52:03 +00:00
{
1986-04-06 17:42:56 +00:00
struct node *EnumList;
1986-03-20 14:52:03 +00:00
} :
'(' IdentList(&EnumList) ')'
1986-04-10 01:08:49 +00:00
{
*ptp = standard_type(T_ENUMERATION,int_align,int_size);
EnterIdList(EnumList, D_ENUM, 0, *ptp, CurrentScope);
FreeNode(EnumList);
}
1986-03-26 22:46:48 +00:00
1986-03-20 14:52:03 +00:00
;
1986-04-06 17:42:56 +00:00
IdentList(struct node **p;)
1986-03-20 14:52:03 +00:00
{
1986-04-06 17:42:56 +00:00
register struct node *q;
1986-03-20 14:52:03 +00:00
} :
1986-04-06 17:42:56 +00:00
IDENT { q = MkNode(Value, NULLNODE, NULLNODE, &dot);
*p = q;
}
1986-03-20 14:52:03 +00:00
[
1986-04-06 17:42:56 +00:00
',' IDENT
{ q->next = MkNode(Value,NULLNODE,NULLNODE,&dot);
q = q->next;
}
1986-03-20 14:52:03 +00:00
]*
1986-04-06 17:42:56 +00:00
{ q->next = 0; }
1986-03-20 14:52:03 +00:00
;
1986-03-27 17:37:41 +00:00
SubrangeType(struct type **ptp;)
{
1986-04-08 23:34:10 +00:00
struct node *nd1, *nd2;
1986-03-27 17:37:41 +00:00
}:
1986-03-20 14:52:03 +00:00
/*
This is not exactly the rule in the new report, but see
the rule for "SimpleType".
*/
1986-04-06 17:42:56 +00:00
'[' ConstExpression(&nd1)
UPTO ConstExpression(&nd2)
1986-03-27 17:37:41 +00:00
']'
1986-04-08 23:34:10 +00:00
{ *ptp = subr_type(nd1, nd2); }
1986-03-20 14:52:03 +00:00
;
1986-03-27 17:37:41 +00:00
ArrayType(struct type **ptp;)
{
struct type *tp;
register struct type *tp2;
} :
ARRAY SimpleType(&tp)
{
1986-04-10 01:08:49 +00:00
*ptp = tp2 = construct_type(T_ARRAY, tp);
1986-03-27 17:37:41 +00:00
}
[
',' SimpleType(&tp)
1986-03-29 01:04:49 +00:00
{ tp2 = tp2->arr_elem =
1986-04-10 01:08:49 +00:00
construct_type(T_ARRAY, tp);
1986-03-27 17:37:41 +00:00
}
]* OF type(&tp)
1986-03-29 01:04:49 +00:00
{ tp2->arr_elem = tp; }
1986-03-20 14:52:03 +00:00
;
1986-03-27 17:37:41 +00:00
RecordType(struct type **ptp;)
{
1986-04-03 00:44:39 +00:00
struct scope scope;
1986-03-27 17:37:41 +00:00
}
:
RECORD
1986-04-03 00:44:39 +00:00
{ scope.sc_scope = uniq_scope();
scope.next = CurrentScope;
}
FieldListSequence(&scope)
1986-04-10 01:08:49 +00:00
{
*ptp = standard_type(T_RECORD, record_align, (arith) 0 /* ???? */);
(*ptp)->rec_scope = scope.sc_scope;
}
1986-03-27 17:37:41 +00:00
END
1986-03-20 14:52:03 +00:00
;
1986-04-03 00:44:39 +00:00
FieldListSequence(struct scope *scope;):
FieldList(scope)
1986-03-27 17:37:41 +00:00
[
1986-04-03 00:44:39 +00:00
';' FieldList(scope)
1986-03-27 17:37:41 +00:00
]*
1986-03-20 14:52:03 +00:00
;
1986-04-03 00:44:39 +00:00
FieldList(struct scope *scope;)
1986-03-20 14:52:03 +00:00
{
1986-04-06 17:42:56 +00:00
struct node *FldList;
1986-03-27 17:37:41 +00:00
struct idf *id;
struct def *df, *df1;
struct type *tp;
1986-04-11 11:57:19 +00:00
struct node *nd;
1986-03-20 14:52:03 +00:00
} :
[
1986-03-27 17:37:41 +00:00
IdentList(&FldList) ':' type(&tp)
1986-04-04 13:47:04 +00:00
{ EnterIdList(FldList, D_FIELD, 0, tp, scope);
1986-04-06 17:42:56 +00:00
FreeNode(FldList);
1986-04-04 13:47:04 +00:00
}
1986-03-20 14:52:03 +00:00
|
1986-03-27 17:37:41 +00:00
CASE
1986-04-11 11:57:19 +00:00
/* Also accept old fashioned Modula-2 syntax, but give a warning
*/
[ qualident(0, &df, (char *) 0, &nd)
[ /* This is good, in both kinds of Modula-2, if
the first qualident is a single identifier.
*/
{
if (nd->nd_class != Name) {
error("illegal variant tag");
id = gen_anon_idf();
}
else id = nd->nd_IDF;
}
':' qualident(D_TYPE|D_HTYPE|D_HIDDEN,
&df, "type", (struct node **) 0)
|
/* Old fashioned! the first qualident now represents
the type
*/
{
warning("Old fashioned Modula-2 syntax!");
id = gen_anon_idf();
findname(nd);
assert(nd->nd_class == Def);
df = nd->nd_def;
if (!(df->df_kind &
(D_ERROR|D_TYPE|D_HTYPE|D_HIDDEN))) {
error("identifier \"%s\" is not a type",
df->df_idf->id_text);
}
FreeNode(nd);
}
]
1986-03-27 17:37:41 +00:00
|
1986-04-11 11:57:19 +00:00
/* Aha, third edition? */
':' qualident(D_TYPE|D_HTYPE|D_HIDDEN,
&df,
"type",
(struct node **) 0)
{
id = gen_anon_idf();
}
]
{
df1 = define(id, scope, D_FIELD);
1986-03-27 17:37:41 +00:00
df1->df_type = df->df_type;
}
1986-04-03 00:44:39 +00:00
OF variant(scope)
1986-03-27 17:37:41 +00:00
[
1986-04-03 00:44:39 +00:00
'|' variant(scope)
1986-03-27 17:37:41 +00:00
]*
1986-04-03 00:44:39 +00:00
[ ELSE FieldListSequence(scope)
1986-03-27 17:37:41 +00:00
]?
1986-03-20 14:52:03 +00:00
END
]?
;
1986-04-03 00:44:39 +00:00
variant(struct scope *scope;):
[ CaseLabelList ':' FieldListSequence(scope) ]?
1986-03-20 14:52:03 +00:00
/* Changed rule in new modula-2 */
;
CaseLabelList:
CaseLabels [ ',' CaseLabels ]*
;
1986-04-06 17:42:56 +00:00
CaseLabels
{
struct node *nd1, *nd2 = 0;
}:
ConstExpression(&nd1) [ UPTO ConstExpression(&nd2) ]?
1986-03-20 14:52:03 +00:00
;
1986-03-27 17:37:41 +00:00
SetType(struct type **ptp;)
{
struct type *tp;
} :
SET OF SimpleType(&tp)
1986-04-08 23:34:10 +00:00
{
*ptp = set_type(tp);
1986-03-27 17:37:41 +00:00
}
1986-03-20 14:52:03 +00:00
;
1986-03-29 01:04:49 +00:00
/* In a pointer type definition, the type pointed at does not
have to be declared yet, so be careful about identifying
type-identifiers
*/
1986-03-27 17:37:41 +00:00
PointerType(struct type **ptp;)
{
struct type *tp;
1986-03-29 01:04:49 +00:00
struct def *df;
1986-03-27 17:37:41 +00:00
struct def *lookfor();
1986-04-08 18:15:46 +00:00
struct node *nd;
1986-03-27 17:37:41 +00:00
} :
POINTER TO
1986-04-03 00:44:39 +00:00
[ %if ( (df = lookup(dot.TOK_IDF, CurrentScope->sc_scope)))
1986-03-29 01:04:49 +00:00
/* Either a Module or a Type, but in both cases defined
in this scope, so this is the correct identification
*/
1986-04-11 11:57:19 +00:00
qualident(D_TYPE|D_HTYPE|D_HIDDEN, &df, "type", (struct node **) 0)
1986-03-27 17:37:41 +00:00
{
if (!df->df_type) {
error("type \"%s\" not declared",
df->df_idf->id_text);
1986-03-29 01:04:49 +00:00
tp = error_type;
1986-03-27 17:37:41 +00:00
}
1986-03-29 01:04:49 +00:00
else tp = df->df_type;
1986-03-27 17:37:41 +00:00
}
1986-04-08 18:15:46 +00:00
| %if ( nd = new_node(), nd->nd_token = dot,
df = lookfor(nd, CurrentScope, 0), free_node(nd),
df->df_kind == D_MODULE)
1986-03-27 17:37:41 +00:00
type(&tp)
|
IDENT
1986-03-29 01:04:49 +00:00
{ tp = NULLTYPE; }
1986-03-27 17:37:41 +00:00
]
1986-03-29 01:04:49 +00:00
{
1986-04-10 01:08:49 +00:00
*ptp = construct_type(T_POINTER, tp);
1986-03-29 01:04:49 +00:00
if (!tp) Forward(&dot, &((*ptp)->next));
}
1986-03-20 14:52:03 +00:00
;
1986-03-29 01:04:49 +00:00
ProcedureType(struct type **ptp;)
{
struct paramlist *pr = 0;
struct type *tp = 0;
} :
PROCEDURE FormalTypeList(&pr, &tp)?
1986-04-10 01:08:49 +00:00
{ *ptp = construct_type(T_PROCEDURE, tp);
1986-03-29 01:04:49 +00:00
(*ptp)->prc_params = pr;
}
1986-03-20 14:52:03 +00:00
;
1986-03-29 01:04:49 +00:00
FormalTypeList(struct paramlist **ppr; struct type **ptp;)
1986-03-27 17:37:41 +00:00
{
struct def *df;
1986-03-29 01:04:49 +00:00
struct type *tp;
struct paramlist *p;
int VARp;
1986-03-27 17:37:41 +00:00
} :
1986-03-29 01:04:49 +00:00
'(' { *ppr = 0; }
[
[ VAR { VARp = 1; }
| { VARp = 0; }
]
FormalType(&tp)
{ *ppr = p = new_paramlist();
p->par_type = tp;
p->par_var = VARp;
}
[
','
[ VAR {VARp = 1; }
| {VARp = 0; }
]
FormalType(&tp)
{ p->next = new_paramlist();
p = p->next;
p->par_type = tp;
p->par_var = VARp;
}
]*
{ p->next = 0; }
]?
')'
1986-04-11 11:57:19 +00:00
[ ':' qualident(D_TYPE|D_HTYPE|D_HIDDEN, &df, "type", (struct node **) 0)
1986-03-29 01:04:49 +00:00
{ *ptp = df->df_type; }
1986-03-27 17:37:41 +00:00
]?
1986-03-20 14:52:03 +00:00
;
1986-03-26 15:11:02 +00:00
ConstantDeclaration
{
1986-03-26 22:46:48 +00:00
struct def *df;
struct idf *id;
1986-04-06 17:42:56 +00:00
struct node *nd;
1986-03-26 15:11:02 +00:00
}:
1986-03-26 22:46:48 +00:00
IDENT { id = dot.TOK_IDF; }
1986-04-06 17:42:56 +00:00
'=' ConstExpression(&nd){ df = define(id, CurrentScope, D_CONST);
1986-04-08 18:15:46 +00:00
df->con_const = nd;
1986-03-26 22:46:48 +00:00
}
1986-03-20 14:52:03 +00:00
;
VariableDeclaration
{
1986-04-06 17:42:56 +00:00
struct node *VarList;
1986-03-27 17:37:41 +00:00
struct type *tp;
1986-04-06 17:42:56 +00:00
struct node *nd = 0;
1986-03-20 14:52:03 +00:00
} :
1986-03-24 17:29:57 +00:00
IdentList(&VarList)
[
1986-04-06 17:42:56 +00:00
ConstExpression(&nd)
1986-03-24 17:29:57 +00:00
]?
1986-03-27 17:37:41 +00:00
':' type(&tp)
{ EnterIdList(VarList, D_VARIABLE, 0, tp, CurrentScope);
1986-04-06 17:42:56 +00:00
FreeNode(VarList);
1986-03-26 22:46:48 +00:00
}
1986-03-20 14:52:03 +00:00
;