newer version, partial parse trees
This commit is contained in:
parent
0e4311490c
commit
376c47c98f
13 changed files with 418 additions and 220 deletions
|
@ -17,7 +17,7 @@ LFLAGS = $(PROFILE)
|
||||||
LOBJ = tokenfile.o program.o declar.o expression.o statement.o
|
LOBJ = tokenfile.o program.o declar.o expression.o statement.o
|
||||||
COBJ = LLlex.o LLmessage.o char.o error.o main.o \
|
COBJ = LLlex.o LLmessage.o char.o error.o main.o \
|
||||||
symbol2str.o tokenname.o idf.o input.o type.o def.o \
|
symbol2str.o tokenname.o idf.o input.o type.o def.o \
|
||||||
scope.o misc.o enter.o defmodule.o typequiv.o
|
scope.o misc.o enter.o defmodule.o typequiv.o node.o
|
||||||
OBJ = $(COBJ) $(LOBJ) Lpars.o
|
OBJ = $(COBJ) $(LOBJ) Lpars.o
|
||||||
GENFILES= tokenfile.c \
|
GENFILES= tokenfile.c \
|
||||||
program.c declar.c expression.c statement.c \
|
program.c declar.c expression.c statement.c \
|
||||||
|
@ -47,6 +47,7 @@ symbol2str.c: tokenname.c make.tokcase
|
||||||
misc.h: misc.H make.allocd
|
misc.h: misc.H make.allocd
|
||||||
def.h: def.H make.allocd
|
def.h: def.H make.allocd
|
||||||
type.h: type.H make.allocd
|
type.h: type.H make.allocd
|
||||||
|
node.h: node.H make.allocd
|
||||||
scope.c: scope.C make.allocd
|
scope.c: scope.C make.allocd
|
||||||
|
|
||||||
char.c: char.tab tab
|
char.c: char.tab tab
|
||||||
|
@ -71,22 +72,23 @@ depend:
|
||||||
LLlex.o: LLlex.h Lpars.h class.h f_info.h idf.h input.h
|
LLlex.o: LLlex.h Lpars.h class.h f_info.h idf.h input.h
|
||||||
LLmessage.o: LLlex.h Lpars.h idf.h
|
LLmessage.o: LLlex.h Lpars.h idf.h
|
||||||
char.o: class.h
|
char.o: class.h
|
||||||
error.o: LLlex.h f_info.h input.h main.h
|
error.o: LLlex.h f_info.h input.h main.h node.h
|
||||||
main.o: LLlex.h Lpars.h debug.h def.h f_info.h idf.h input.h main.h scope.h standards.h type.h
|
main.o: LLlex.h Lpars.h debug.h def.h f_info.h idf.h input.h main.h scope.h standards.h type.h
|
||||||
symbol2str.o: Lpars.h
|
symbol2str.o: Lpars.h
|
||||||
tokenname.o: Lpars.h idf.h tokenname.h
|
tokenname.o: Lpars.h idf.h tokenname.h
|
||||||
idf.o: idf.h
|
idf.o: idf.h
|
||||||
input.o: f_info.h input.h
|
input.o: f_info.h input.h
|
||||||
type.o: Lpars.h def.h def_sizes.h idf.h misc.h type.h
|
type.o: LLlex.h Lpars.h def.h def_sizes.h idf.h node.h type.h
|
||||||
def.o: Lpars.h debug.h def.h idf.h main.h misc.h scope.h type.h
|
def.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h type.h
|
||||||
scope.o: LLlex.h debug.h def.h idf.h scope.h type.h
|
scope.o: LLlex.h debug.h def.h idf.h scope.h type.h
|
||||||
misc.o: LLlex.h f_info.h idf.h misc.h
|
misc.o: LLlex.h f_info.h idf.h misc.h
|
||||||
enter.o: def.h idf.h misc.h scope.h type.h
|
enter.o: LLlex.h def.h idf.h node.h scope.h type.h
|
||||||
defmodule.o: LLlex.h def.h f_info.h idf.h input.h scope.h
|
defmodule.o: LLlex.h def.h f_info.h idf.h input.h scope.h
|
||||||
typequiv.o: Lpars.h def.h type.h
|
typequiv.o: Lpars.h def.h type.h
|
||||||
|
node.o: LLlex.h def.h node.h type.h
|
||||||
tokenfile.o: Lpars.h
|
tokenfile.o: Lpars.h
|
||||||
program.o: LLlex.h Lpars.h debug.h def.h idf.h main.h misc.h scope.h type.h
|
program.o: LLlex.h Lpars.h debug.h def.h idf.h main.h node.h scope.h type.h
|
||||||
declar.o: LLlex.h Lpars.h def.h idf.h misc.h scope.h type.h
|
declar.o: LLlex.h Lpars.h def.h idf.h misc.h node.h scope.h type.h
|
||||||
expression.o: LLlex.h Lpars.h def.h idf.h scope.h
|
expression.o: LLlex.h Lpars.h def.h idf.h node.h scope.h
|
||||||
statement.o: Lpars.h
|
statement.o: Lpars.h
|
||||||
Lpars.o: Lpars.h
|
Lpars.o: Lpars.h
|
||||||
|
|
|
@ -7,11 +7,12 @@ static char *RcsId = "$Header$";
|
||||||
#include <em_label.h>
|
#include <em_label.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "misc.h"
|
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
|
#include "node.h"
|
||||||
|
#include "misc.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcedureDeclaration
|
ProcedureDeclaration
|
||||||
|
@ -95,7 +96,7 @@ FormalParameters(int doparams; struct paramlist **pr; struct type **tp;)
|
||||||
]?
|
]?
|
||||||
')'
|
')'
|
||||||
{ *tp = 0; }
|
{ *tp = 0; }
|
||||||
[ ':' qualident(D_TYPE | D_HTYPE, &df, "type")
|
[ ':' qualident(D_TYPE | D_HTYPE, &df, "type", (struct node **) 0)
|
||||||
{ *tp = df->df_type; }
|
{ *tp = df->df_type; }
|
||||||
]?
|
]?
|
||||||
;
|
;
|
||||||
|
@ -108,7 +109,7 @@ FormalParameters(int doparams; struct paramlist **pr; struct type **tp;)
|
||||||
*/
|
*/
|
||||||
FPSection(int doparams; struct paramlist **ppr;)
|
FPSection(int doparams; struct paramlist **ppr;)
|
||||||
{
|
{
|
||||||
struct id_list *FPList;
|
struct node *FPList;
|
||||||
struct paramlist *ParamList();
|
struct paramlist *ParamList();
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
int VARp = 0;
|
int VARp = 0;
|
||||||
|
@ -122,7 +123,7 @@ FPSection(int doparams; struct paramlist **ppr;)
|
||||||
EnterIdList(FPList, D_VARIABLE, VARp, tp, CurrentScope);
|
EnterIdList(FPList, D_VARIABLE, VARp, tp, CurrentScope);
|
||||||
}
|
}
|
||||||
*ppr = ParamList(FPList, tp);
|
*ppr = ParamList(FPList, tp);
|
||||||
FreeIdList(FPList);
|
FreeNode(FPList);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -133,7 +134,7 @@ FormalType(struct type **tp;)
|
||||||
} :
|
} :
|
||||||
[ ARRAY OF { ARRAYflag = 1; }
|
[ ARRAY OF { ARRAYflag = 1; }
|
||||||
]?
|
]?
|
||||||
qualident(D_TYPE | D_HTYPE, &df, "type")
|
qualident(D_TYPE | D_HTYPE, &df, "type", (struct node **) 0)
|
||||||
{ if (ARRAYflag) {
|
{ if (ARRAYflag) {
|
||||||
*tp = construct_type(ARRAY, NULLTYPE);
|
*tp = construct_type(ARRAY, NULLTYPE);
|
||||||
(*tp)->arr_elem = df->df_type;
|
(*tp)->arr_elem = df->df_type;
|
||||||
|
@ -182,7 +183,7 @@ SimpleType(struct type **ptp;)
|
||||||
struct def *df;
|
struct def *df;
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
} :
|
} :
|
||||||
qualident(D_TYPE | D_HTYPE, &df, "type")
|
qualident(D_TYPE | D_HTYPE, &df, "type", (struct node **) 0)
|
||||||
[
|
[
|
||||||
/* nothing */
|
/* nothing */
|
||||||
|
|
|
|
||||||
|
@ -202,41 +203,44 @@ SimpleType(struct type **ptp;)
|
||||||
|
|
||||||
enumeration(struct type **ptp;)
|
enumeration(struct type **ptp;)
|
||||||
{
|
{
|
||||||
struct id_list *EnumList;
|
struct node *EnumList;
|
||||||
} :
|
} :
|
||||||
'(' IdentList(&EnumList) ')'
|
'(' IdentList(&EnumList) ')'
|
||||||
{
|
{
|
||||||
*ptp = standard_type(ENUMERATION,int_align,int_size);
|
*ptp = standard_type(ENUMERATION,int_align,int_size);
|
||||||
EnterIdList(EnumList, D_ENUM, 0, *ptp, CurrentScope);
|
EnterIdList(EnumList, D_ENUM, 0, *ptp, CurrentScope);
|
||||||
FreeIdList(EnumList);
|
FreeNode(EnumList);
|
||||||
}
|
}
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
IdentList(struct id_list **p;)
|
IdentList(struct node **p;)
|
||||||
{
|
{
|
||||||
register struct id_list *q = new_id_list();
|
register struct node *q;
|
||||||
} :
|
} :
|
||||||
IDENT { q->id_ptr = dot.TOK_IDF; *p = q;}
|
IDENT { q = MkNode(Value, NULLNODE, NULLNODE, &dot);
|
||||||
|
*p = q;
|
||||||
|
}
|
||||||
[
|
[
|
||||||
',' IDENT { q->next = new_id_list();
|
',' IDENT
|
||||||
q = q->next;
|
{ q->next = MkNode(Value,NULLNODE,NULLNODE,&dot);
|
||||||
q->id_ptr = dot.TOK_IDF;
|
q = q->next;
|
||||||
}
|
}
|
||||||
]*
|
]*
|
||||||
{ q->next = 0; }
|
{ q->next = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
SubrangeType(struct type **ptp;)
|
SubrangeType(struct type **ptp;)
|
||||||
{
|
{
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
|
struct node *nd1 = 0, *nd2 = 0;
|
||||||
}:
|
}:
|
||||||
/*
|
/*
|
||||||
This is not exactly the rule in the new report, but see
|
This is not exactly the rule in the new report, but see
|
||||||
the rule for "SimpleType".
|
the rule for "SimpleType".
|
||||||
*/
|
*/
|
||||||
'[' ConstExpression
|
'[' ConstExpression(&nd1)
|
||||||
UPTO ConstExpression
|
UPTO ConstExpression(&nd2)
|
||||||
']'
|
']'
|
||||||
/*
|
/*
|
||||||
Evaluate the expressions. Check that they are indeed constant.
|
Evaluate the expressions. Check that they are indeed constant.
|
||||||
|
@ -295,7 +299,7 @@ FieldListSequence(struct scope *scope;):
|
||||||
|
|
||||||
FieldList(struct scope *scope;)
|
FieldList(struct scope *scope;)
|
||||||
{
|
{
|
||||||
struct id_list *FldList;
|
struct node *FldList;
|
||||||
struct idf *id;
|
struct idf *id;
|
||||||
struct def *df, *df1;
|
struct def *df, *df1;
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
|
@ -303,7 +307,7 @@ FieldList(struct scope *scope;)
|
||||||
[
|
[
|
||||||
IdentList(&FldList) ':' type(&tp)
|
IdentList(&FldList) ':' type(&tp)
|
||||||
{ EnterIdList(FldList, D_FIELD, 0, tp, scope);
|
{ EnterIdList(FldList, D_FIELD, 0, tp, scope);
|
||||||
FreeIdList(FldList);
|
FreeNode(FldList);
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
CASE
|
CASE
|
||||||
|
@ -312,7 +316,7 @@ FieldList(struct scope *scope;)
|
||||||
|
|
|
|
||||||
{ id = gen_anon_idf(); }
|
{ id = gen_anon_idf(); }
|
||||||
] /* Changed rule in new modula-2 */
|
] /* Changed rule in new modula-2 */
|
||||||
':' qualident(D_TYPE|D_HTYPE, &df, "type")
|
':' qualident(D_TYPE|D_HTYPE, &df, "type", (struct node **) 0)
|
||||||
{ df1 = define(id, scope, D_FIELD);
|
{ df1 = define(id, scope, D_FIELD);
|
||||||
df1->df_type = df->df_type;
|
df1->df_type = df->df_type;
|
||||||
}
|
}
|
||||||
|
@ -335,8 +339,11 @@ CaseLabelList:
|
||||||
CaseLabels [ ',' CaseLabels ]*
|
CaseLabels [ ',' CaseLabels ]*
|
||||||
;
|
;
|
||||||
|
|
||||||
CaseLabels:
|
CaseLabels
|
||||||
ConstExpression [ UPTO ConstExpression ]?
|
{
|
||||||
|
struct node *nd1, *nd2 = 0;
|
||||||
|
}:
|
||||||
|
ConstExpression(&nd1) [ UPTO ConstExpression(&nd2) ]?
|
||||||
;
|
;
|
||||||
|
|
||||||
SetType(struct type **ptp;)
|
SetType(struct type **ptp;)
|
||||||
|
@ -364,7 +371,7 @@ PointerType(struct type **ptp;)
|
||||||
/* Either a Module or a Type, but in both cases defined
|
/* Either a Module or a Type, but in both cases defined
|
||||||
in this scope, so this is the correct identification
|
in this scope, so this is the correct identification
|
||||||
*/
|
*/
|
||||||
qualident(D_TYPE|D_HTYPE, &df, "type")
|
qualident(D_TYPE|D_HTYPE, &df, "type", (struct node **) 0)
|
||||||
{
|
{
|
||||||
if (!df->df_type) {
|
if (!df->df_type) {
|
||||||
error("type \"%s\" not declared",
|
error("type \"%s\" not declared",
|
||||||
|
@ -429,7 +436,7 @@ FormalTypeList(struct paramlist **ppr; struct type **ptp;)
|
||||||
{ p->next = 0; }
|
{ p->next = 0; }
|
||||||
]?
|
]?
|
||||||
')'
|
')'
|
||||||
[ ':' qualident(D_TYPE|D_HTYPE, &df, "type")
|
[ ':' qualident(D_TYPE|D_HTYPE, &df, "type", (struct node **) 0)
|
||||||
{ *ptp = df->df_type; }
|
{ *ptp = df->df_type; }
|
||||||
]?
|
]?
|
||||||
;
|
;
|
||||||
|
@ -438,24 +445,26 @@ ConstantDeclaration
|
||||||
{
|
{
|
||||||
struct def *df;
|
struct def *df;
|
||||||
struct idf *id;
|
struct idf *id;
|
||||||
|
struct node *nd;
|
||||||
}:
|
}:
|
||||||
IDENT { id = dot.TOK_IDF; }
|
IDENT { id = dot.TOK_IDF; }
|
||||||
'=' ConstExpression { df = define(id, CurrentScope, D_CONST);
|
'=' ConstExpression(&nd){ df = define(id, CurrentScope, D_CONST);
|
||||||
/* ???? */
|
/* ???? */
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
VariableDeclaration
|
VariableDeclaration
|
||||||
{
|
{
|
||||||
struct id_list *VarList;
|
struct node *VarList;
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
|
struct node *nd = 0;
|
||||||
} :
|
} :
|
||||||
IdentList(&VarList)
|
IdentList(&VarList)
|
||||||
[
|
[
|
||||||
ConstExpression
|
ConstExpression(&nd)
|
||||||
]?
|
]?
|
||||||
':' type(&tp)
|
':' type(&tp)
|
||||||
{ EnterIdList(VarList, D_VARIABLE, 0, tp, CurrentScope);
|
{ EnterIdList(VarList, D_VARIABLE, 0, tp, CurrentScope);
|
||||||
FreeIdList(VarList);
|
FreeNode(VarList);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
|
@ -10,9 +10,10 @@ static char *RcsId = "$Header$";
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "misc.h"
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
|
#include "LLlex.h"
|
||||||
|
#include "node.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
struct def *h_def; /* Pointer to free list of def structures */
|
struct def *h_def; /* Pointer to free list of def structures */
|
||||||
|
@ -63,7 +64,7 @@ define(id, scope, kind)
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
if (kind != D_ERROR) {
|
if (kind != D_ERROR) {
|
||||||
error("identifier \"%s\" already declared", id->id_text);
|
error("identifier \"%s\" already declared", id->id_text);
|
||||||
}
|
}
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +116,7 @@ lookup(id, scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
Export(ids, qualified)
|
Export(ids, qualified)
|
||||||
register struct id_list *ids;
|
register struct node *ids;
|
||||||
{
|
{
|
||||||
/* From the current scope, the list of identifiers "ids" is
|
/* From the current scope, the list of identifiers "ids" is
|
||||||
exported. Note this fact. If the export is not qualified, make
|
exported. Note this fact. If the export is not qualified, make
|
||||||
|
@ -125,36 +126,38 @@ Export(ids, qualified)
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
|
|
||||||
while (ids) {
|
while (ids) {
|
||||||
df = define(ids->id_ptr, CurrentScope, D_ISEXPORTED);
|
df = define(ids->nd_IDF, CurrentScope, D_ISEXPORTED);
|
||||||
if (qualified) {
|
if (qualified) {
|
||||||
df->df_flags |= D_QEXPORTED;
|
df->df_flags |= D_QEXPORTED;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
df->df_flags |= D_EXPORTED;
|
df->df_flags |= D_EXPORTED;
|
||||||
df = define(ids->id_ptr, enclosing(CurrentScope),
|
df = define(ids->nd_IDF, enclosing(CurrentScope),
|
||||||
D_IMPORT);
|
D_IMPORT);
|
||||||
}
|
}
|
||||||
ids = ids->next;
|
ids = ids->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Import(ids, id, local)
|
Import(ids, idn, local)
|
||||||
register struct id_list *ids;
|
register struct node *ids;
|
||||||
struct idf *id;
|
struct node *idn;
|
||||||
{
|
{
|
||||||
/* "ids" is a list of imported identifiers.
|
/* "ids" is a list of imported identifiers.
|
||||||
If "id" is a null-pointer, the identifiers are imported from the
|
If "idn" is a null-pointer, the identifiers are imported from
|
||||||
enclosing scope. Otherwise they are imported from the module
|
the enclosing scope. Otherwise they are imported from the module
|
||||||
indicated by "id", which must be visible in the enclosing scope.
|
indicated by "idn", which must be visible in the enclosing
|
||||||
An exception must be made for imports of the Compilation Unit.
|
scope. An exception must be made for imports of the
|
||||||
|
Compilation Unit.
|
||||||
This case is indicated by the value 0 of the flag "local".
|
This case is indicated by the value 0 of the flag "local".
|
||||||
In this case, if "id" is a null pointer, the "ids" identifiers
|
In this case, if "idn" is a null pointer, the "ids" identifiers
|
||||||
are all module identifiers. Their Definition Modules must be
|
are all module identifiers. Their Definition Modules must be
|
||||||
read. Otherwise "id" is a module identifier whose Definition
|
read. Otherwise "idn" is a module identifier whose Definition
|
||||||
Module must be read. "ids" then represents a list of
|
Module must be read. "ids" then represents a list of
|
||||||
identifiers defined in this module.
|
identifiers defined in this module.
|
||||||
*/
|
*/
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
|
register struct idf *id = 0;
|
||||||
int scope;
|
int scope;
|
||||||
int kind;
|
int kind;
|
||||||
int imp_kind;
|
int imp_kind;
|
||||||
|
@ -162,6 +165,7 @@ Import(ids, id, local)
|
||||||
#define FROM_ENCLOSING 1
|
#define FROM_ENCLOSING 1
|
||||||
struct def *lookfor(), *GetDefinitionModule();
|
struct def *lookfor(), *GetDefinitionModule();
|
||||||
|
|
||||||
|
if (idn) id = idn->nd_IDF;
|
||||||
kind = D_IMPORT;
|
kind = D_IMPORT;
|
||||||
scope = enclosing(CurrentScope)->sc_scope;
|
scope = enclosing(CurrentScope)->sc_scope;
|
||||||
if (!id) imp_kind = FROM_ENCLOSING;
|
if (!id) imp_kind = FROM_ENCLOSING;
|
||||||
|
@ -173,35 +177,35 @@ Import(ids, id, local)
|
||||||
/* enter all "ids" with type D_ERROR */
|
/* enter all "ids" with type D_ERROR */
|
||||||
kind = D_ERROR;
|
kind = D_ERROR;
|
||||||
if (df->df_kind != D_ERROR) {
|
if (df->df_kind != D_ERROR) {
|
||||||
error("identifier \"%s\" does not represent a module", id->id_text);
|
node_error(idn, "identifier \"%s\" does not represent a module", id->id_text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else scope = df->mod_scope;
|
else scope = df->mod_scope;
|
||||||
}
|
}
|
||||||
while (ids) {
|
while (ids) {
|
||||||
if (imp_kind == FROM_MODULE) {
|
if (imp_kind == FROM_MODULE) {
|
||||||
if (!(df = lookup(ids->id_ptr, scope))) {
|
if (!(df = lookup(ids->nd_IDF, scope))) {
|
||||||
error("identifier \"%s\" not declared in qualifying module",
|
node_error(ids, "identifier \"%s\" not declared in qualifying module",
|
||||||
ids->id_ptr->id_text);
|
ids->nd_IDF->id_text);
|
||||||
df = ill_df;
|
df = ill_df;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (!(df->df_flags&(D_EXPORTED|D_QEXPORTED))) {
|
if (!(df->df_flags&(D_EXPORTED|D_QEXPORTED))) {
|
||||||
error("identifier \"%s\" not exported from qualifying module",
|
node_error(ids,"identifier \"%s\" not exported from qualifying module",
|
||||||
ids->id_ptr->id_text);
|
ids->nd_IDF->id_text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (local) {
|
if (local) {
|
||||||
df = lookfor(ids->id_ptr,
|
df = lookfor(ids->nd_IDF,
|
||||||
enclosing(CurrentScope), 0);
|
enclosing(CurrentScope), 0);
|
||||||
} else df = GetDefinitionModule(ids->id_ptr);
|
} else df = GetDefinitionModule(ids->nd_IDF);
|
||||||
if (df->df_kind == D_ERROR) {
|
if (df->df_kind == D_ERROR) {
|
||||||
error("identifier \"%s\" not visible in enclosing scope",
|
node_error(ids, "identifier \"%s\" not visible in enclosing scope",
|
||||||
ids->id_ptr->id_text);
|
ids->nd_IDF->id_text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
define(ids->id_ptr, CurrentScope, kind)->imp_def = df;
|
define(ids->nd_IDF, CurrentScope, kind)->imp_def = df;
|
||||||
if (df->df_kind == D_TYPE &&
|
if (df->df_kind == D_TYPE &&
|
||||||
df->df_type->tp_fund == ENUMERATION) {
|
df->df_type->tp_fund == ENUMERATION) {
|
||||||
/* Also import all enumeration literals */
|
/* Also import all enumeration literals */
|
||||||
|
|
|
@ -9,7 +9,8 @@ static char *RcsId = "$Header$";
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "misc.h"
|
#include "LLlex.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
struct def *
|
struct def *
|
||||||
Enter(name, kind, type, pnam)
|
Enter(name, kind, type, pnam)
|
||||||
|
@ -30,7 +31,7 @@ Enter(name, kind, type, pnam)
|
||||||
}
|
}
|
||||||
|
|
||||||
EnterIdList(idlist, kind, flags, type, scope)
|
EnterIdList(idlist, kind, flags, type, scope)
|
||||||
register struct id_list *idlist;
|
register struct node *idlist;
|
||||||
struct type *type;
|
struct type *type;
|
||||||
struct scope *scope;
|
struct scope *scope;
|
||||||
{
|
{
|
||||||
|
@ -39,7 +40,7 @@ EnterIdList(idlist, kind, flags, type, scope)
|
||||||
int assval = 0;
|
int assval = 0;
|
||||||
|
|
||||||
while (idlist) {
|
while (idlist) {
|
||||||
df = define(idlist->id_ptr, scope, kind);
|
df = define(idlist->nd_IDF, scope, kind);
|
||||||
df->df_type = type;
|
df->df_type = type;
|
||||||
df->df_flags = flags;
|
df->df_flags = flags;
|
||||||
if (kind == D_ENUM) {
|
if (kind == D_ENUM) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ static char *RcsId = "$Header$";
|
||||||
#include "f_info.h"
|
#include "f_info.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
#define MAXERR_LINE 5 /* Number of error messages on one line ... */
|
#define MAXERR_LINE 5 /* Number of error messages on one line ... */
|
||||||
#define ERROUT STDERR
|
#define ERROUT STDERR
|
||||||
|
@ -28,8 +29,6 @@ static char *RcsId = "$Header$";
|
||||||
#define VDEBUG 7
|
#define VDEBUG 7
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NILEXPR ((struct expr *) 0)
|
|
||||||
|
|
||||||
int err_occurred;
|
int err_occurred;
|
||||||
|
|
||||||
extern char *symbol2str();
|
extern char *symbol2str();
|
||||||
|
@ -37,12 +36,12 @@ extern char *symbol2str();
|
||||||
/* There are three general error-message functions:
|
/* There are three general error-message functions:
|
||||||
lexerror() lexical and pre-processor error messages
|
lexerror() lexical and pre-processor error messages
|
||||||
error() syntactic and semantic error messages
|
error() syntactic and semantic error messages
|
||||||
expr_error() errors in expressions
|
node_error() errors in nodes
|
||||||
The difference lies in the place where the file name and line
|
The difference lies in the place where the file name and line
|
||||||
number come from.
|
number come from.
|
||||||
Lexical errors report from the global variables LineNumber and
|
Lexical errors report from the global variables LineNumber and
|
||||||
FileName, expression errors get their information from the
|
FileName, node errors get their information from the
|
||||||
expression, whereas other errors use the information in the token.
|
node, whereas other errors use the information in the token.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -50,7 +49,7 @@ extern char *symbol2str();
|
||||||
debug(level, fmt, args)
|
debug(level, fmt, args)
|
||||||
char *fmt;
|
char *fmt;
|
||||||
{
|
{
|
||||||
if (level <= options['D']) _error(VDEBUG, NILEXPR, fmt, &args);
|
if (level <= options['D']) _error(VDEBUG, NULLNODE, fmt, &args);
|
||||||
}
|
}
|
||||||
#endif DEBUG
|
#endif DEBUG
|
||||||
|
|
||||||
|
@ -58,44 +57,44 @@ debug(level, fmt, args)
|
||||||
error(fmt, args)
|
error(fmt, args)
|
||||||
char *fmt;
|
char *fmt;
|
||||||
{
|
{
|
||||||
_error(ERROR, NILEXPR, fmt, &args);
|
_error(ERROR, NULLNODE, fmt, &args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS2*/
|
/*VARARGS2*/
|
||||||
expr_error(expr, fmt, args)
|
node_error(node, fmt, args)
|
||||||
struct expr *expr;
|
struct node *node;
|
||||||
char *fmt;
|
char *fmt;
|
||||||
{
|
{
|
||||||
_error(ERROR, expr, fmt, &args);
|
_error(ERROR, node, fmt, &args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS1*/
|
/*VARARGS1*/
|
||||||
warning(fmt, args)
|
warning(fmt, args)
|
||||||
char *fmt;
|
char *fmt;
|
||||||
{
|
{
|
||||||
_error(WARNING, NILEXPR, fmt, &args);
|
_error(WARNING, NULLNODE, fmt, &args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS2*/
|
/*VARARGS2*/
|
||||||
expr_warning(expr, fmt, args)
|
node_warning(node, fmt, args)
|
||||||
struct expr *expr;
|
struct node *node;
|
||||||
char *fmt;
|
char *fmt;
|
||||||
{
|
{
|
||||||
_error(WARNING, expr, fmt, &args);
|
_error(WARNING, node, fmt, &args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS1*/
|
/*VARARGS1*/
|
||||||
lexerror(fmt, args)
|
lexerror(fmt, args)
|
||||||
char *fmt;
|
char *fmt;
|
||||||
{
|
{
|
||||||
_error(LEXERROR, NILEXPR, fmt, &args);
|
_error(LEXERROR, NULLNODE, fmt, &args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS1*/
|
/*VARARGS1*/
|
||||||
lexwarning(fmt, args)
|
lexwarning(fmt, args)
|
||||||
char *fmt;
|
char *fmt;
|
||||||
{
|
{
|
||||||
_error(LEXWARNING, NILEXPR, fmt, &args);
|
_error(LEXWARNING, NULLNODE, fmt, &args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS1*/
|
/*VARARGS1*/
|
||||||
|
@ -104,13 +103,13 @@ fatal(fmt, args)
|
||||||
int args;
|
int args;
|
||||||
{
|
{
|
||||||
|
|
||||||
_error(FATAL, NILEXPR, fmt, &args);
|
_error(FATAL, NULLNODE, fmt, &args);
|
||||||
sys_stop(S_EXIT);
|
sys_stop(S_EXIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
_error(class, expr, fmt, argv)
|
_error(class, node, fmt, argv)
|
||||||
int class;
|
int class;
|
||||||
struct expr *expr;
|
struct node *node;
|
||||||
char *fmt;
|
char *fmt;
|
||||||
int argv[];
|
int argv[];
|
||||||
{
|
{
|
||||||
|
@ -118,8 +117,10 @@ _error(class, expr, fmt, argv)
|
||||||
for a given line to MAXERR_LINE.
|
for a given line to MAXERR_LINE.
|
||||||
*/
|
*/
|
||||||
static unsigned int last_ln = 0;
|
static unsigned int last_ln = 0;
|
||||||
static int e_seen = 0;
|
|
||||||
unsigned int ln = 0;
|
unsigned int ln = 0;
|
||||||
|
static char * last_fn = 0;
|
||||||
|
char *fn = 0;
|
||||||
|
static int e_seen = 0;
|
||||||
char *remark = 0;
|
char *remark = 0;
|
||||||
|
|
||||||
/* Since name and number are gathered from different places
|
/* Since name and number are gathered from different places
|
||||||
|
@ -158,13 +159,19 @@ _error(class, expr, fmt, argv)
|
||||||
case FATAL:
|
case FATAL:
|
||||||
remark = "fatal error --";
|
remark = "fatal error --";
|
||||||
break;
|
break;
|
||||||
|
#ifdef DEBUG
|
||||||
|
case VDEBUG:
|
||||||
|
remark = "(debug)";
|
||||||
|
break;
|
||||||
|
#endif DEBUG
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the place */
|
/* the place */
|
||||||
switch (class) {
|
switch (class) {
|
||||||
case WARNING:
|
case WARNING:
|
||||||
case ERROR:
|
case ERROR:
|
||||||
ln = /* ???? expr ? expr->ex_line : */ dot.tk_lineno;
|
fn = node ? node->nd_filename : dot.tk_filename;
|
||||||
|
ln = node ? node->nd_lineno : dot.tk_lineno;
|
||||||
break;
|
break;
|
||||||
case LEXWARNING:
|
case LEXWARNING:
|
||||||
case LEXERROR:
|
case LEXERROR:
|
||||||
|
@ -174,13 +181,14 @@ _error(class, expr, fmt, argv)
|
||||||
case VDEBUG:
|
case VDEBUG:
|
||||||
#endif DEBUG
|
#endif DEBUG
|
||||||
ln = LineNumber;
|
ln = LineNumber;
|
||||||
|
fn = FileName;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (class != VDEBUG) {
|
if (class != VDEBUG) {
|
||||||
#endif
|
#endif
|
||||||
if (ln == last_ln) {
|
if (fn == last_fn && ln == last_ln) {
|
||||||
/* we've seen this place before */
|
/* we've seen this place before */
|
||||||
e_seen++;
|
e_seen++;
|
||||||
if (e_seen == MAXERR_LINE) fmt = "etc ...";
|
if (e_seen == MAXERR_LINE) fmt = "etc ...";
|
||||||
|
@ -192,13 +200,14 @@ _error(class, expr, fmt, argv)
|
||||||
else {
|
else {
|
||||||
/* brand new place */
|
/* brand new place */
|
||||||
last_ln = ln;
|
last_ln = ln;
|
||||||
|
last_fn = fn;
|
||||||
e_seen = 0;
|
e_seen = 0;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
}
|
}
|
||||||
#endif DEBUG
|
#endif DEBUG
|
||||||
|
|
||||||
if (FileName) fprint(ERROUT, "\"%s\", line %u: ", FileName, ln);
|
if (fn) fprint(ERROUT, "\"%s\", line %u: ", fn, ln);
|
||||||
|
|
||||||
if (remark) fprint(ERROUT, "%s ", remark);
|
if (remark) fprint(ERROUT, "%s ", remark);
|
||||||
|
|
||||||
|
|
|
@ -10,15 +10,18 @@ static char *RcsId = "$Header$";
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
|
#include "node.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
number:
|
number(struct node **p;):
|
||||||
|
[
|
||||||
INTEGER
|
INTEGER
|
||||||
|
|
|
|
||||||
REAL
|
REAL
|
||||||
|
] { *p = MkNode(Value, NULLNODE, NULLNODE, dot); }
|
||||||
;
|
;
|
||||||
|
|
||||||
qualident(int types; struct def **pdf; char *str;)
|
qualident(int types; struct def **pdf; char *str; struct node **p;)
|
||||||
{
|
{
|
||||||
int scope;
|
int scope;
|
||||||
int module;
|
int module;
|
||||||
|
@ -30,6 +33,9 @@ qualident(int types; struct def **pdf; char *str;)
|
||||||
*pdf = df;
|
*pdf = df;
|
||||||
if (df->df_kind == D_ERROR) types = 0;
|
if (df->df_kind == D_ERROR) types = 0;
|
||||||
}
|
}
|
||||||
|
if (p) {
|
||||||
|
*p = MkNode(Value, NULLNODE, NULLNODE,&dot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
[
|
[
|
||||||
{ if (types &&!(scope = has_selectors(df))) {
|
{ if (types &&!(scope = has_selectors(df))) {
|
||||||
|
@ -38,8 +44,13 @@ qualident(int types; struct def **pdf; char *str;)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* selector */
|
/* selector */
|
||||||
'.' IDENT
|
'.' { if (p) *p = MkNode(Link, *p, NULLNODE, &dot); }
|
||||||
{ if (types) {
|
IDENT
|
||||||
|
{ if (p) {
|
||||||
|
p = &((*p)->nd_right);
|
||||||
|
*p = MkNode(Value, NULLNODE, NULLNODE,&dot);
|
||||||
|
}
|
||||||
|
if (types) {
|
||||||
module = (df->df_kind == D_MODULE);
|
module = (df->df_kind == D_MODULE);
|
||||||
df = lookup(dot.TOK_IDF, scope);
|
df = lookup(dot.TOK_IDF, scope);
|
||||||
if (!df) {
|
if (!df) {
|
||||||
|
@ -62,99 +73,179 @@ qualident(int types; struct def **pdf; char *str;)
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
/* Inline substituted wherever it occurred
|
||||||
selector:
|
selector:
|
||||||
'.' /* field */ IDENT
|
'.' IDENT
|
||||||
|
;
|
||||||
|
*/
|
||||||
|
|
||||||
|
ExpList(struct node **pnd;)
|
||||||
|
{
|
||||||
|
struct node **nd;
|
||||||
|
} :
|
||||||
|
expression(pnd) { nd = pnd; }
|
||||||
|
[
|
||||||
|
',' { *nd = MkNode(Link, *nd, NULLNODE, &dot);
|
||||||
|
nd = &(*nd)->nd_right;
|
||||||
|
}
|
||||||
|
expression(nd)
|
||||||
|
]*
|
||||||
;
|
;
|
||||||
|
|
||||||
ExpList:
|
ConstExpression(struct node **pnd;):
|
||||||
expression [ ',' expression ]*
|
expression(pnd)
|
||||||
;
|
|
||||||
|
|
||||||
ConstExpression:
|
|
||||||
expression
|
|
||||||
/*
|
/*
|
||||||
* Changed rule in new Modula-2.
|
* Changed rule in new Modula-2.
|
||||||
* Check that the expression is a constant expression and evaluate!
|
* Check that the expression is a constant expression and evaluate!
|
||||||
*/
|
*/
|
||||||
;
|
;
|
||||||
|
|
||||||
expression:
|
expression(struct node **pnd;)
|
||||||
SimpleExpression [ relation SimpleExpression ]?
|
{
|
||||||
|
struct node *nd;
|
||||||
|
} :
|
||||||
|
SimpleExpression(&nd)
|
||||||
|
[
|
||||||
|
/* relation */
|
||||||
|
[ '=' | '#' | UNEQUAL | '<' | LESSEQUAL | '>' |
|
||||||
|
GREATEREQUAL | IN
|
||||||
|
]
|
||||||
|
{ nd = MkNode(Oper, nd, NULLNODE, &dot); }
|
||||||
|
SimpleExpression(&(nd->nd_right))
|
||||||
|
]?
|
||||||
|
{ *pnd = nd; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
/* Inline in expression
|
||||||
relation:
|
relation:
|
||||||
'=' | '#' | UNEQUAL | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN
|
'=' | '#' | UNEQUAL | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN
|
||||||
;
|
;
|
||||||
|
*/
|
||||||
|
|
||||||
SimpleExpression:
|
SimpleExpression(struct node **pnd;)
|
||||||
[ '+' | '-' ]? term [ AddOperator term ]*
|
|
||||||
;
|
|
||||||
|
|
||||||
AddOperator:
|
|
||||||
'+' | '-' | OR
|
|
||||||
;
|
|
||||||
|
|
||||||
term:
|
|
||||||
factor [ MulOperator factor ]*
|
|
||||||
;
|
|
||||||
|
|
||||||
MulOperator:
|
|
||||||
'*' | '/' | DIV | MOD | AND | '&'
|
|
||||||
;
|
|
||||||
|
|
||||||
factor
|
|
||||||
{
|
{
|
||||||
struct def *df;
|
register struct node *nd;
|
||||||
} :
|
} :
|
||||||
qualident(0, &df, (char *) 0)
|
[ '+' | '-' ]?
|
||||||
|
term(pnd) { nd = *pnd; }
|
||||||
[
|
[
|
||||||
designator_tail? ActualParameters?
|
/* AddOperator */
|
||||||
|
|
[ '+' | '-' | OR ]
|
||||||
bare_set
|
{ *pnd = nd = MkNode(Oper, nd, NULLNODE, &dot); }
|
||||||
]
|
term(&(nd->nd_right))
|
||||||
|
|
|
||||||
bare_set
|
|
||||||
| %default
|
|
||||||
number
|
|
||||||
|
|
|
||||||
STRING
|
|
||||||
|
|
|
||||||
'(' expression ')'
|
|
||||||
|
|
|
||||||
NOT factor
|
|
||||||
;
|
|
||||||
|
|
||||||
bare_set:
|
|
||||||
'{' [ element [ ',' element ]* ]? '}'
|
|
||||||
;
|
|
||||||
|
|
||||||
ActualParameters:
|
|
||||||
'(' ExpList? ')'
|
|
||||||
;
|
|
||||||
|
|
||||||
element:
|
|
||||||
expression [ UPTO expression ]?
|
|
||||||
;
|
|
||||||
|
|
||||||
designator
|
|
||||||
{
|
|
||||||
struct def *df;
|
|
||||||
} :
|
|
||||||
qualident(0, &df, (char *) 0)
|
|
||||||
designator_tail?
|
|
||||||
;
|
|
||||||
|
|
||||||
designator_tail:
|
|
||||||
visible_designator_tail
|
|
||||||
[
|
|
||||||
selector
|
|
||||||
|
|
|
||||||
visible_designator_tail
|
|
||||||
]*
|
]*
|
||||||
;
|
;
|
||||||
|
|
||||||
visible_designator_tail:
|
/* Inline in "SimpleExpression"
|
||||||
'[' ExpList ']'
|
AddOperator:
|
||||||
|
|
'+' | '-' | OR
|
||||||
'^'
|
;
|
||||||
|
*/
|
||||||
|
|
||||||
|
term(struct node **pnd;)
|
||||||
|
{
|
||||||
|
register struct node *nd;
|
||||||
|
}:
|
||||||
|
factor(pnd) { nd = *pnd; }
|
||||||
|
[
|
||||||
|
/* MulOperator */
|
||||||
|
[ '*' | '/' | DIV | MOD | AND | '&' ]
|
||||||
|
{ *pnd = nd = MkNode(Oper, nd, NULLNODE, &dot); }
|
||||||
|
factor(&(nd->nd_right))
|
||||||
|
]*
|
||||||
|
;
|
||||||
|
|
||||||
|
/* inline in "term"
|
||||||
|
MulOperator:
|
||||||
|
'*' | '/' | DIV | MOD | AND | '&'
|
||||||
|
;
|
||||||
|
*/
|
||||||
|
|
||||||
|
factor(struct node **p;)
|
||||||
|
{
|
||||||
|
struct def *df;
|
||||||
|
} :
|
||||||
|
qualident(0, &df, (char *) 0, p)
|
||||||
|
[
|
||||||
|
designator_tail(p)?
|
||||||
|
[
|
||||||
|
{ *p = MkNode(Call, p, NULLNODE, &dot); }
|
||||||
|
ActualParameters(&((*p)->nd_right))
|
||||||
|
]?
|
||||||
|
| { *p = MkNode(Call, p, NULLNODE, &dot); }
|
||||||
|
bare_set(&((*p)->nd_right))
|
||||||
|
]
|
||||||
|
|
|
||||||
|
bare_set(p)
|
||||||
|
| %default
|
||||||
|
number(p)
|
||||||
|
|
|
||||||
|
STRING { *p = MkNode(Value, NULLNODE, NULLNODE, &dot); }
|
||||||
|
|
|
||||||
|
'(' expression(p) ')'
|
||||||
|
|
|
||||||
|
NOT { *p = MkNode(Uoper, NULLNODE, NULLNODE, &dot); }
|
||||||
|
factor(&((*p)->nd_left))
|
||||||
|
;
|
||||||
|
|
||||||
|
bare_set(struct node **pnd;)
|
||||||
|
{
|
||||||
|
struct node **nd;
|
||||||
|
} :
|
||||||
|
'{' {
|
||||||
|
dot.tk_symb = SET;
|
||||||
|
*pnd = MkNode(Link, NULLNODE, NULLNODE, &dot);
|
||||||
|
nd = &((*pnd)->nd_left);
|
||||||
|
}
|
||||||
|
[
|
||||||
|
element(nd)
|
||||||
|
[
|
||||||
|
',' { *nd = MkNode(Link, *nd, NULLNODE, &dot);
|
||||||
|
nd = &((*nd)->nd_right);
|
||||||
|
}
|
||||||
|
element(nd)
|
||||||
|
]*
|
||||||
|
]?
|
||||||
|
'}'
|
||||||
|
;
|
||||||
|
|
||||||
|
ActualParameters(struct node **pnd;):
|
||||||
|
'(' ExpList(pnd)? ')'
|
||||||
|
;
|
||||||
|
|
||||||
|
element(struct node **pnd;):
|
||||||
|
expression(pnd)
|
||||||
|
[
|
||||||
|
UPTO { *pnd = MkNode(Link, *pnd, NULLNODE, &dot);}
|
||||||
|
expression(&((*pnd)->nd_right))
|
||||||
|
]?
|
||||||
|
;
|
||||||
|
|
||||||
|
designator(struct node **pnd;)
|
||||||
|
{
|
||||||
|
struct def *df;
|
||||||
|
} :
|
||||||
|
qualident(0, &df, (char *) 0, pnd)
|
||||||
|
designator_tail(pnd)?
|
||||||
|
;
|
||||||
|
|
||||||
|
designator_tail(struct node **pnd;):
|
||||||
|
visible_designator_tail(pnd)
|
||||||
|
[
|
||||||
|
/* selector */
|
||||||
|
'.' { *pnd = MkNode(Oper, *pnd, NULLNODE, &dot); }
|
||||||
|
IDENT { (*pnd)->nd_right =
|
||||||
|
MkNode(Value, NULLNODE, NULLNODE, &dot);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
visible_designator_tail(pnd)
|
||||||
|
]*
|
||||||
|
;
|
||||||
|
|
||||||
|
visible_designator_tail(struct node **pnd;):
|
||||||
|
'[' { *pnd = MkNode(Oper, *pnd, NULLNODE, &dot); }
|
||||||
|
ExpList(&((*pnd)->nd_right))
|
||||||
|
']'
|
||||||
|
|
|
||||||
|
'^' { *pnd = MkNode(Oper, *pnd, NULLNODE, &dot); }
|
||||||
;
|
;
|
||||||
|
|
|
@ -2,13 +2,6 @@
|
||||||
|
|
||||||
/* $Header$ */
|
/* $Header$ */
|
||||||
|
|
||||||
/* Structure to link idf structures together
|
|
||||||
*/
|
|
||||||
struct id_list {
|
|
||||||
struct id_list *next;
|
|
||||||
struct idf *id_ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ALLOCDEF "id_list" */
|
/* ALLOCDEF "id_list" */
|
||||||
|
|
||||||
#define is_anon_idf(x) ((x)->id_text[0] == '#')
|
#define is_anon_idf(x) ((x)->id_text[0] == '#')
|
||||||
|
|
|
@ -24,22 +24,6 @@ match_id(id1, id2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct id_list *h_id_list; /* Header of free list of id_list structures */
|
|
||||||
|
|
||||||
/* FreeIdList: take a list of id_list structures and put them
|
|
||||||
on the free list of id_list structures
|
|
||||||
*/
|
|
||||||
FreeIdList(p)
|
|
||||||
struct id_list *p;
|
|
||||||
{
|
|
||||||
register struct id_list *q;
|
|
||||||
|
|
||||||
while (q = p) {
|
|
||||||
p = p->next;
|
|
||||||
free_id_list(q);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct idf *
|
struct idf *
|
||||||
gen_anon_idf()
|
gen_anon_idf()
|
||||||
{
|
{
|
||||||
|
|
31
lang/m2/comp/node.H
Normal file
31
lang/m2/comp/node.H
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/* N O D E O F A N A B S T R A C T P A R S E T R E E */
|
||||||
|
|
||||||
|
/* $Header$ */
|
||||||
|
|
||||||
|
struct node {
|
||||||
|
struct node *next;
|
||||||
|
#define nd_left next
|
||||||
|
struct node *nd_right;
|
||||||
|
int nd_class; /* kind of node */
|
||||||
|
#define Value 1 /* idf or constant */
|
||||||
|
#define Oper 2 /* binary operator */
|
||||||
|
#define Uoper 3 /* unary operator */
|
||||||
|
#define Call 4 /* cast or procedure - or function call */
|
||||||
|
#define Link 5
|
||||||
|
struct type *nd_type; /* type of this node */
|
||||||
|
struct token nd_token;
|
||||||
|
#define nd_symb nd_token.tk_symb
|
||||||
|
#define nd_lineno nd_token.tk_lineno
|
||||||
|
#define nd_filename nd_token.tk_filename
|
||||||
|
#define nd_IDF nd_token.TOK_IDF
|
||||||
|
#define nd_STR nd_token.TOK_STR
|
||||||
|
#define nd_SLE nd_token.TOK_SLE
|
||||||
|
#define nd_INT nd_token.TOK_INT
|
||||||
|
#define nd_REL nd_token.TOK_REL
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ALLOCDEF "node" */
|
||||||
|
|
||||||
|
extern struct node *MkNode();
|
||||||
|
|
||||||
|
#define NULLNODE ((struct node *) 0)
|
41
lang/m2/comp/node.c
Normal file
41
lang/m2/comp/node.c
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/* N O D E O F A N A B S T R A C T P A R S E T R E E */
|
||||||
|
|
||||||
|
static char *RcsId = "$Header$";
|
||||||
|
|
||||||
|
#include <em_label.h>
|
||||||
|
#include <em_arith.h>
|
||||||
|
#include <alloc.h>
|
||||||
|
#include "def.h"
|
||||||
|
#include "type.h"
|
||||||
|
#include "LLlex.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
struct node *h_node; /* header of free list */
|
||||||
|
|
||||||
|
struct node *
|
||||||
|
MkNode(class, left, right, token)
|
||||||
|
struct node *left, *right;
|
||||||
|
struct token *token;
|
||||||
|
{
|
||||||
|
/* Create a node and initialize it with the given parameters
|
||||||
|
*/
|
||||||
|
register struct node *nd = new_node();
|
||||||
|
|
||||||
|
nd->nd_left = left;
|
||||||
|
nd->nd_right = right;
|
||||||
|
nd->nd_token = *token;
|
||||||
|
nd->nd_class = class;
|
||||||
|
nd->nd_type = NULLTYPE;
|
||||||
|
return nd;
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeNode(nd)
|
||||||
|
register struct node *nd;
|
||||||
|
{
|
||||||
|
/* Put nodes that are no longer needed back onto the free
|
||||||
|
list
|
||||||
|
*/
|
||||||
|
if (nd->nd_left) FreeNode(nd->nd_left);
|
||||||
|
if (nd->nd_right) FreeNode(nd->nd_right);
|
||||||
|
free_node(nd);
|
||||||
|
}
|
|
@ -7,12 +7,12 @@ static char *RcsId = "$Header$";
|
||||||
#include <em_arith.h>
|
#include <em_arith.h>
|
||||||
#include <em_label.h>
|
#include <em_label.h>
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "misc.h"
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
#include "node.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
static struct idf *impl_name = 0;
|
static struct idf *impl_name = 0;
|
||||||
|
@ -57,13 +57,16 @@ ModuleDeclaration
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
priority:
|
priority
|
||||||
'[' ConstExpression ']'
|
{
|
||||||
|
struct node *nd;
|
||||||
|
}:
|
||||||
|
'[' ConstExpression(&nd) ']'
|
||||||
;
|
;
|
||||||
|
|
||||||
export(int def;)
|
export(int def;)
|
||||||
{
|
{
|
||||||
struct id_list *ExportList;
|
struct node *ExportList;
|
||||||
int QUALflag = 0;
|
int QUALflag = 0;
|
||||||
} :
|
} :
|
||||||
EXPORT
|
EXPORT
|
||||||
|
@ -74,17 +77,17 @@ export(int def;)
|
||||||
{
|
{
|
||||||
if (!def) Export(ExportList, QUALflag);
|
if (!def) Export(ExportList, QUALflag);
|
||||||
else warning("export list in definition module ignored");
|
else warning("export list in definition module ignored");
|
||||||
FreeIdList(ExportList);
|
FreeNode(ExportList);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
import(int local;)
|
import(int local;)
|
||||||
{
|
{
|
||||||
struct id_list *ImportList;
|
struct node *ImportList;
|
||||||
struct idf *id = 0;
|
struct node *id = 0;
|
||||||
} :
|
} :
|
||||||
[ FROM
|
[ FROM
|
||||||
IDENT { id = dot.TOK_IDF; }
|
IDENT { id = MkNode(Value, NULLNODE, NULLNODE, &dot); }
|
||||||
]?
|
]?
|
||||||
IMPORT IdentList(&ImportList) ';'
|
IMPORT IdentList(&ImportList) ';'
|
||||||
/*
|
/*
|
||||||
|
@ -95,7 +98,8 @@ import(int local;)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
Import(ImportList, id, local);
|
Import(ImportList, id, local);
|
||||||
FreeIdList(ImportList);
|
FreeNode(ImportList);
|
||||||
|
if (id) FreeNode(id);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -2,20 +2,27 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
static char *RcsId = "$Header$";
|
static char *RcsId = "$Header$";
|
||||||
|
|
||||||
|
#include <em_arith.h>
|
||||||
|
#include "LLlex.h"
|
||||||
|
#include "node.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
statement:
|
statement
|
||||||
|
{
|
||||||
|
struct node *nd1, *nd2;
|
||||||
|
} :
|
||||||
[
|
[
|
||||||
/*
|
/*
|
||||||
* This part is not in the reference grammar. The reference grammar
|
* This part is not in the reference grammar. The reference grammar
|
||||||
* states : assignment | ProcedureCall | ...
|
* states : assignment | ProcedureCall | ...
|
||||||
* but this gives LL(1) conflicts
|
* but this gives LL(1) conflicts
|
||||||
*/
|
*/
|
||||||
designator
|
designator(&nd1)
|
||||||
[
|
[
|
||||||
ActualParameters?
|
ActualParameters(&nd2)?
|
||||||
|
|
|
|
||||||
BECOMES expression
|
BECOMES expression(&nd2)
|
||||||
]
|
]
|
||||||
/*
|
/*
|
||||||
* end of changed part
|
* end of changed part
|
||||||
|
@ -37,7 +44,10 @@ statement:
|
||||||
|
|
|
|
||||||
EXIT
|
EXIT
|
||||||
|
|
|
|
||||||
RETURN expression?
|
RETURN
|
||||||
|
[
|
||||||
|
expression(&nd1)
|
||||||
|
]?
|
||||||
]?
|
]?
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -57,15 +67,21 @@ StatementSequence:
|
||||||
statement [ ';' statement ]*
|
statement [ ';' statement ]*
|
||||||
;
|
;
|
||||||
|
|
||||||
IfStatement:
|
IfStatement
|
||||||
IF expression THEN StatementSequence
|
{
|
||||||
[ ELSIF expression THEN StatementSequence ]*
|
struct node *nd1;
|
||||||
|
} :
|
||||||
|
IF expression(&nd1) THEN StatementSequence
|
||||||
|
[ ELSIF expression(&nd1) THEN StatementSequence ]*
|
||||||
[ ELSE StatementSequence ]?
|
[ ELSE StatementSequence ]?
|
||||||
END
|
END
|
||||||
;
|
;
|
||||||
|
|
||||||
CaseStatement:
|
CaseStatement
|
||||||
CASE expression OF case [ '|' case ]*
|
{
|
||||||
|
struct node *nd;
|
||||||
|
} :
|
||||||
|
CASE expression(&nd) OF case [ '|' case ]*
|
||||||
[ ELSE StatementSequence ]?
|
[ ELSE StatementSequence ]?
|
||||||
END
|
END
|
||||||
;
|
;
|
||||||
|
@ -75,19 +91,28 @@ case:
|
||||||
/* This rule is changed in new modula-2 */
|
/* This rule is changed in new modula-2 */
|
||||||
;
|
;
|
||||||
|
|
||||||
WhileStatement:
|
WhileStatement
|
||||||
WHILE expression DO StatementSequence END
|
{
|
||||||
|
struct node *nd;
|
||||||
|
}:
|
||||||
|
WHILE expression(&nd) DO StatementSequence END
|
||||||
;
|
;
|
||||||
|
|
||||||
RepeatStatement:
|
RepeatStatement
|
||||||
REPEAT StatementSequence UNTIL expression
|
{
|
||||||
|
struct node *nd;
|
||||||
|
}:
|
||||||
|
REPEAT StatementSequence UNTIL expression(&nd)
|
||||||
;
|
;
|
||||||
|
|
||||||
ForStatement:
|
ForStatement
|
||||||
|
{
|
||||||
|
struct node *nd1, *nd2, *nd3;
|
||||||
|
}:
|
||||||
FOR IDENT
|
FOR IDENT
|
||||||
BECOMES expression
|
BECOMES expression(&nd1)
|
||||||
TO expression
|
TO expression(&nd2)
|
||||||
[ BY ConstExpression ]?
|
[ BY ConstExpression(&nd3) ]?
|
||||||
DO StatementSequence END
|
DO StatementSequence END
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -95,6 +120,9 @@ LoopStatement:
|
||||||
LOOP StatementSequence END
|
LOOP StatementSequence END
|
||||||
;
|
;
|
||||||
|
|
||||||
WithStatement:
|
WithStatement
|
||||||
WITH designator DO StatementSequence END
|
{
|
||||||
|
struct node *nd;
|
||||||
|
}:
|
||||||
|
WITH designator(&nd) DO StatementSequence END
|
||||||
;
|
;
|
||||||
|
|
|
@ -11,7 +11,8 @@ static char *RcsId = "$Header$";
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "misc.h"
|
#include "LLlex.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
/* To be created dynamically in main() from defaults or from command
|
/* To be created dynamically in main() from defaults or from command
|
||||||
line parameters.
|
line parameters.
|
||||||
|
@ -164,7 +165,7 @@ has_selectors(df)
|
||||||
*/
|
*/
|
||||||
struct paramlist *
|
struct paramlist *
|
||||||
ParamList(ids, tp, VARp)
|
ParamList(ids, tp, VARp)
|
||||||
register struct id_list *ids;
|
register struct node *ids;
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
{
|
{
|
||||||
register struct paramlist *pr;
|
register struct paramlist *pr;
|
||||||
|
|
Loading…
Reference in a new issue