newer version

This commit is contained in:
ceriel 1986-04-25 10:14:08 +00:00
parent c11efeb1fe
commit f445033fab
14 changed files with 235 additions and 73 deletions

View File

@ -248,8 +248,11 @@ again:
switch (ch) { switch (ch) {
case 'H': case 'H':
Shex: *np++ = '\0'; Shex: *np++ = '\0';
numtype = card_type;
tk->TOK_INT = str2long(&buf[1], 16); tk->TOK_INT = str2long(&buf[1], 16);
if (tk->TOK_INT >= 0 && tk->TOK_INT <= max_int) {
numtype = intorcard_type;
}
else numtype = card_type;
return tk->tk_symb = INTEGER; return tk->tk_symb = INTEGER;
case '8': case '8':
@ -283,11 +286,17 @@ Shex: *np++ = '\0';
PushBack(ch); PushBack(ch);
ch = *--np; ch = *--np;
*np++ = '\0'; *np++ = '\0';
tk->TOK_INT = str2long(&buf[1], 8);
if (ch == 'C') { if (ch == 'C') {
numtype = char_type; numtype = char_type;
if (tk->TOK_INT < 0 || tk->TOK_INT > 255) {
lexwarning("Character constant out of range");
}
}
else if (tk->TOK_INT >= 0 && tk->TOK_INT <= max_int) {
numtype = intorcard_type;
} }
else numtype = card_type; else numtype = card_type;
tk->TOK_INT = str2long(&buf[1], 8);
return tk->tk_symb = INTEGER; return tk->tk_symb = INTEGER;
case 'A': case 'A':

View File

@ -82,7 +82,7 @@ LLlex.o: LLlex.h Lpars.h class.h const.h f_info.h idf.h idfsize.h input.h inputt
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 debug.h errout.h f_info.h input.h inputtype.h main.h node.h error.o: LLlex.h debug.h errout.h f_info.h input.h inputtype.h main.h node.h
main.o: LLlex.h Lpars.h debug.h def.h f_info.h idf.h input.h inputtype.h node.h scope.h standards.h tokenname.h type.h main.o: LLlex.h Lpars.h debug.h def.h f_info.h idf.h input.h inputtype.h ndirs.h node.h scope.h standards.h tokenname.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
@ -97,7 +97,7 @@ typequiv.o: def.h type.h
node.o: LLlex.h debug.h def.h node.h type.h node.o: LLlex.h debug.h def.h node.h type.h
cstoper.o: LLlex.h Lpars.h idf.h node.h standards.h target_sizes.h type.h cstoper.o: LLlex.h Lpars.h idf.h node.h standards.h target_sizes.h type.h
chk_expr.o: LLlex.h Lpars.h const.h debug.h def.h idf.h node.h scope.h standards.h type.h chk_expr.o: LLlex.h Lpars.h const.h debug.h def.h idf.h node.h scope.h standards.h type.h
options.o: idfsize.h type.h options.o: idfsize.h main.h ndir.h type.h
walk.o: LLlex.h Lpars.h debug.h def.h main.h node.h scope.h type.h walk.o: LLlex.h Lpars.h debug.h def.h main.h node.h scope.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 node.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

View File

@ -63,4 +63,8 @@ extern char options[];
but what is a reasonable choice ??? but what is a reasonable choice ???
*/ */
!File: ndir.h
#define NDIRS 16 /* maximum number of directories searched */

View File

@ -35,7 +35,7 @@ chk_expr(expp)
switch(expp->nd_class) { switch(expp->nd_class) {
case Oper: case Oper:
if (expp->nd_symb == '[') { if (expp->nd_symb == '[') {
return chk_designator(expp, DESIGNATOR); return chk_designator(expp, DESIGNATOR|VARIABLE);
} }
return chk_expr(expp->nd_left) && return chk_expr(expp->nd_left) &&
@ -44,7 +44,7 @@ chk_expr(expp)
case Uoper: case Uoper:
if (expp->nd_symb == '^') { if (expp->nd_symb == '^') {
return chk_designator(expp, DESIGNATOR); return chk_designator(expp, DESIGNATOR|VARIABLE);
} }
return chk_expr(expp->nd_right) && return chk_expr(expp->nd_right) &&
@ -66,13 +66,13 @@ chk_expr(expp)
return chk_set(expp); return chk_set(expp);
case Name: case Name:
return chk_designator(expp, DESIGNATOR); return chk_designator(expp, VALUE);
case Call: case Call:
return chk_call(expp); return chk_call(expp);
case Link: case Link:
return chk_designator(expp, DESIGNATOR); return chk_designator(expp, DESIGNATOR|VALUE);
default: default:
assert(0); assert(0);
@ -99,7 +99,7 @@ chk_set(expp)
if (nd = expp->nd_left) { if (nd = expp->nd_left) {
/* A type was given. Check it out /* A type was given. Check it out
*/ */
if (! chk_designator(nd, QUALONLY)) return 0; if (! chk_designator(nd, 0)) return 0;
assert(nd->nd_class == Def); assert(nd->nd_class == Def);
df = nd->nd_def; df = nd->nd_def;
@ -270,12 +270,15 @@ getname(argp, kinds)
return 0; return 0;
} }
argp = argp->nd_right; argp = argp->nd_right;
if (! chk_designator(argp->nd_left, QUALONLY)) return 0; if (! chk_designator(argp->nd_left, 0)) return 0;
assert(argp->nd_left->nd_class == Def); assert(argp->nd_left->nd_class == Def);
if (!(argp->nd_left->nd_def->df_kind & kinds)) { if (!(argp->nd_left->nd_def->df_kind & kinds)) {
node_error(argp, "unexpected type"); node_error(argp, "unexpected type");
return 0; return 0;
} }
return argp; return argp;
} }
@ -294,9 +297,8 @@ chk_call(expp)
*/ */
expp->nd_type = error_type; expp->nd_type = error_type;
left = expp->nd_left; left = expp->nd_left;
if (! chk_designator(left, DESIGNATOR)) return 0; if (! chk_designator(left, 0)) return 0;
if (left->nd_type == error_type) return 0;
if (left->nd_class == Def && if (left->nd_class == Def &&
(left->nd_def->df_kind & (D_HTYPE|D_TYPE|D_HIDDEN))) { (left->nd_def->df_kind & (D_HTYPE|D_TYPE|D_HIDDEN))) {
/* It was a type cast. This is of course not portable. /* It was a type cast. This is of course not portable.
@ -310,7 +312,7 @@ node_error(expp, "only one parameter expected in type cast");
arg = arg->nd_left; arg = arg->nd_left;
if (! chk_expr(arg)) return 0; if (! chk_expr(arg)) return 0;
if (arg->nd_type->tp_size != left->nd_type->tp_size) { if (arg->nd_type->tp_size != left->nd_type->tp_size) {
node_error(expp, "size of type in type cast does not match size of operand"); node_error(expp, "unequal sizes in type cast");
} }
arg->nd_type = left->nd_type; arg->nd_type = left->nd_type;
FreeNode(expp->nd_left); FreeNode(expp->nd_left);
@ -352,30 +354,59 @@ chk_proccall(expp)
register struct node *arg; register struct node *arg;
register struct paramlist *param; register struct paramlist *param;
expp->nd_type = left->nd_type->next;
param = left->nd_type->prc_params;
arg = expp; arg = expp;
arg->nd_type = left->nd_type->next;
param = left->nd_type->prc_params;
while (param) { while (param) {
arg = getarg(arg, 0); if (!(arg = getarg(arg, 0))) return 0;
if (!arg) return 0;
if (param->par_var && if (! TstParCompat(param->par_type,
! TstCompat(param->par_type, arg->nd_left->nd_type)) { arg->nd_left->nd_type,
node_error(arg->nd_left, "type incompatibility in var parameter"); param->par_var)) {
return 0; node_error(arg->nd_left, "type incompatibility in parameter");
}
else
if (!param->par_var &&
!TstAssCompat(param->par_type, arg->nd_left->nd_type)) {
node_error(arg->nd_left, "type incompatibility in value parameter");
return 0; return 0;
} }
param = param->next; param = param->next;
} }
if (arg->nd_right) { if (arg->nd_right) {
node_error(arg->nd_right, "too many parameters supplied"); node_error(arg->nd_right, "too many parameters supplied");
return 0; return 0;
} }
return 1;
}
static int
FlagCheck(expp, df, flag)
struct node *expp;
struct def *df;
{
/* See the routine "chk_designator" for an explanation of
"flag". Here, a definition "df" is checked against it.
*/
if ((flag & VARIABLE) &&
!(df->df_kind & (D_FIELD|D_VARIABLE))) {
node_error(expp, "variable expected");
return 0;
}
if ((flag & HASSELECTORS) &&
( !(df->df_kind & (D_VARIABLE|D_FIELD|D_MODULE)) ||
df->df_type->tp_fund != T_RECORD)) {
node_error(expp, "illegal selection");
return 0;
}
if ((flag & VALUE) &&
( !(df->df_kind & (D_VARIABLE|D_FIELD|D_CONST|D_ENUM)))) {
node_error(expp, "value expected");
return 0;
}
return 1; return 1;
} }
@ -384,7 +415,15 @@ chk_designator(expp, flag)
register struct node *expp; register struct node *expp;
{ {
/* Find the name indicated by "expp", starting from the current /* Find the name indicated by "expp", starting from the current
scope. scope. "flag" indicates the kind of designator we expect:
It contains the flags VARIABLE, indicating that the result must
be something that can be assigned to.
It may also contain the flag VALUE, indicating that a
value is expected. In this case, VARIABLE may not be set.
It also contains the flag DESIGNATOR, indicating that '['
and '^' are allowed for this designator.
Also contained may be the flag HASSELECTORS, indicating that
the result must have selectors.
*/ */
register struct def *df; register struct def *df;
register struct type *tp; register struct type *tp;
@ -403,21 +442,20 @@ chk_designator(expp, flag)
assert(expp->nd_symb == '.'); assert(expp->nd_symb == '.');
assert(expp->nd_right->nd_class == Name); assert(expp->nd_right->nd_class == Name);
if (! chk_designator(expp->nd_left, flag)) return 0; if (! chk_designator(expp->nd_left,
(flag|HASSELECTORS)&DESIGNATOR)) return 0;
tp = expp->nd_left->nd_type; tp = expp->nd_left->nd_type;
if (tp == error_type) return 0;
else if (tp->tp_fund != T_RECORD) { assert(tp->tp_fund == T_RECORD);
/* This is also true for modules */
node_error(expp,"illegal selection"); df = lookup(expp->nd_right->nd_IDF, tp->rec_scope);
return 0;
}
else df = lookup(expp->nd_right->nd_IDF, tp->rec_scope);
if (!df) { if (!df) {
id_not_declared(expp->nd_right); id_not_declared(expp->nd_right);
return 0; return 0;
} }
else if (df != ill_df) { else {
expp->nd_type = df->df_type; expp->nd_type = df->df_type;
if (!(df->df_flags & (D_EXPORTED|D_QEXPORTED))) { if (!(df->df_flags & (D_EXPORTED|D_QEXPORTED))) {
node_error(expp->nd_right, node_error(expp->nd_right,
@ -434,12 +472,16 @@ df->df_idf->id_text);
FreeNode(expp->nd_right); FreeNode(expp->nd_right);
expp->nd_left = expp->nd_right = 0; expp->nd_left = expp->nd_right = 0;
} }
else return 1; else {
return FlagCheck(expp->nd_right, df, flag);
}
} }
if (expp->nd_class == Def) { if (expp->nd_class == Def) {
df = expp->nd_def; df = expp->nd_def;
if (! FlagCheck(expp, df, flag)) return 0;
if (df->df_kind & (D_ENUM | D_CONST)) { if (df->df_kind & (D_ENUM | D_CONST)) {
if (df->df_kind == D_ENUM) { if (df->df_kind == D_ENUM) {
expp->nd_class = Value; expp->nd_class = Value;
@ -455,7 +497,7 @@ df->df_idf->id_text);
return 1; return 1;
} }
if (flag == QUALONLY) { if (! (flag & DESIGNATOR)) {
node_error(expp, "identifier expected"); node_error(expp, "identifier expected");
return 0; return 0;
} }
@ -466,7 +508,7 @@ df->df_idf->id_text);
assert(expp->nd_symb == '['); assert(expp->nd_symb == '[');
if ( if (
!chk_designator(expp->nd_left, DESIGNATOR) !chk_designator(expp->nd_left, DESIGNATOR|VARIABLE)
|| ||
!chk_expr(expp->nd_right) !chk_expr(expp->nd_right)
|| ||
@ -498,7 +540,10 @@ df->df_idf->id_text);
if (expp->nd_class == Uoper) { if (expp->nd_class == Uoper) {
assert(expp->nd_symb == '^'); assert(expp->nd_symb == '^');
if (! chk_designator(expp->nd_right, DESIGNATOR)) return 0; if (! chk_designator(expp->nd_right, DESIGNATOR|VARIABLE)) {
return 0;
}
if (expp->nd_right->nd_type->tp_fund != T_POINTER) { if (expp->nd_right->nd_type->tp_fund != T_POINTER) {
node_error(expp, "illegal operand for unary operator \"%s\"", node_error(expp, "illegal operand for unary operator \"%s\"",
symbol2str(expp->nd_symb)); symbol2str(expp->nd_symb));

View File

@ -17,6 +17,8 @@ static char *RcsId = "$Header$";
#include "misc.h" #include "misc.h"
#include "main.h" #include "main.h"
#include "debug.h"
int proclevel = 0; /* nesting level of procedures */ int proclevel = 0; /* nesting level of procedures */
extern char *sprint(); extern char *sprint();
extern struct def *currentdef; extern struct def *currentdef;
@ -68,6 +70,10 @@ error("inconsistent procedure declaration for \"%s\"", df->df_idf->id_text);
} }
df->df_type = tp; df->df_type = tp;
*pdf = df; *pdf = df;
DO_DEBUG(1, type == D_PROCEDURE &&
(print("proc %s:", df->df_idf->id_text),
DumpType(tp), print("\n")));
} }
; ;
@ -107,9 +113,8 @@ FormalParameters(int doparams;
'(' '('
[ [
FPSection(doparams, pr, parmaddr) FPSection(doparams, pr, parmaddr)
{ pr1 = *pr; }
[ [
{ for (; pr1->next; pr1 = pr1->next) ; } { for (pr1 = *pr; pr1->next; pr1 = pr1->next) ; }
';' FPSection(doparams, &(pr1->next), parmaddr) ';' FPSection(doparams, &(pr1->next), parmaddr)
]* ]*
]? ]?
@ -366,7 +371,7 @@ FieldList(struct scope *scope; arith *cnt; int *palign;)
{ warning("Old fashioned Modula-2 syntax!"); { warning("Old fashioned Modula-2 syntax!");
id = gen_anon_idf(); id = gen_anon_idf();
df = ill_df; df = ill_df;
if (chk_designator(nd, QUALONLY) && if (chk_designator(nd, 0) &&
(nd->nd_class != Def || (nd->nd_class != Def ||
!(nd->nd_def->df_kind & !(nd->nd_def->df_kind &
(D_ERROR|D_TYPE|D_HTYPE|D_HIDDEN)))) { (D_ERROR|D_TYPE|D_HTYPE|D_HIDDEN)))) {

View File

@ -26,7 +26,6 @@ GetFile(name)
/* Try to find a file with basename "name" and extension ".def", /* Try to find a file with basename "name" and extension ".def",
in the directories mentioned in "DEFPATH". in the directories mentioned in "DEFPATH".
*/ */
extern char *DEFPATH[];
char buf[256]; char buf[256];
char *strcpy(), *strcat(); char *strcpy(), *strcat();

View File

@ -43,7 +43,7 @@ qualident(int types; struct def **pdf; char *str; struct node **p;)
{ if (types) { { if (types) {
df = ill_df; df = ill_df;
if (chk_designator(nd, QUALONLY)) { if (chk_designator(nd, 0)) {
if (nd->nd_class != Def) { if (nd->nd_class != Def) {
node_error(nd, "%s expected", str); node_error(nd, "%s expected", str);
} }
@ -83,7 +83,7 @@ ExpList(struct node **pnd;)
',' { *nd = MkNode(Link, NULLNODE, NULLNODE, &dot); ',' { *nd = MkNode(Link, NULLNODE, NULLNODE, &dot);
} }
expression(&(*nd)->nd_left) expression(&(*nd)->nd_left)
{ nd = &((*pnd)->nd_right); } { nd = &((*nd)->nd_right); }
]* ]*
; ;

View File

@ -19,14 +19,14 @@ static char *RcsId = "$Header$";
#include "node.h" #include "node.h"
#include "debug.h" #include "debug.h"
#include "ndir.h"
char options[128]; char options[128];
int DefinitionModule; int DefinitionModule;
int SYSTEMModule = 0; int SYSTEMModule = 0;
char *ProgName; char *ProgName;
extern int err_occurred; extern int err_occurred;
char *DEFPATH[128]; char *DEFPATH[NDIRS+1];
char *getenv();
struct def *Defined; struct def *Defined;
main(argc, argv) main(argc, argv)
@ -67,7 +67,8 @@ Compile(src, dst)
} }
LineNumber = 1; LineNumber = 1;
FileName = src; FileName = src;
init_DEFPATH(); DEFPATH[0] = "";
DEFPATH[NDIRS] = 0;
init_idf(); init_idf();
init_cst(); init_cst();
reserve(tkidf); reserve(tkidf);
@ -181,23 +182,6 @@ add_standards()
df->enm_next = 0; df->enm_next = 0;
} }
init_DEFPATH()
{
register char *p = getenv("M2path");
register int i = 0;
if (p) {
while (*p) {
DEFPATH[i++] = p;
while (*p && *p != ':') p++;
if (*p) *p++ = '\0';
}
}
else DEFPATH[i++] = "";
DEFPATH[i] = 0;
}
do_SYSTEM() do_SYSTEM()
{ {
/* Simulate the reading of the SYSTEM definition module /* Simulate the reading of the SYSTEM definition module

View File

@ -2,17 +2,18 @@
/* $Header$ */ /* $Header$ */
extern char options[]; /* Indicating which options were given */ extern char options[]; /* indicating which options were given */
extern int DefinitionModule; extern int DefinitionModule;
/* Flag indicating that we are reading a definition /* flag indicating that we are reading a definition
module module
*/ */
extern int SYSTEMModule;/* Flag indicating that we are handling the SYSTEM extern int SYSTEMModule;/* flag indicating that we are handling the SYSTEM
module module
*/ */
extern struct def *Defined; extern struct def *Defined;
/* Definition structure of module defined in this /* definition structure of module defined in this
compilation compilation
*/ */
extern char *DEFPATH[]; /* search path for DEFINITION MODULE's */

View File

@ -36,5 +36,8 @@ struct node {
extern struct node *MkNode(); extern struct node *MkNode();
#define NULLNODE ((struct node *) 0) #define NULLNODE ((struct node *) 0)
#define QUALONLY 0
#define DESIGNATOR 1 #define DESIGNATOR 1
#define HASSELECTORS 2
#define VARIABLE 4
#define VALUE 8

View File

@ -6,12 +6,15 @@ static char *RcsId = "$Header$";
#include <em_label.h> #include <em_label.h>
#include "idfsize.h" #include "idfsize.h"
#include "ndir.h"
#include "type.h" #include "type.h"
#include "main.h"
extern char options[];
extern int idfsize; extern int idfsize;
static int ndirs;
do_option(text) do_option(text)
char *text; char *text;
{ {
@ -37,6 +40,13 @@ do_option(text)
options['p'] = 1; options['p'] = 1;
break; break;
case 'I' :
if (++ndirs >= NDIRS) {
fatal("Too many -I options");
}
DEFPATH[ndirs] = text;
break;
case 'V' : /* set object sizes and alignment requirements */ case 'V' : /* set object sizes and alignment requirements */
{ {
arith size; arith size;

View File

@ -436,3 +436,70 @@ lcm(m, n)
*/ */
return m * (n / gcd(m, n)); return m * (n / gcd(m, n));
} }
#ifdef DEBUG
DumpType(tp)
register struct type *tp;
{
print(" a:%d; s:%ld;", tp->tp_align, (long) tp->tp_size);
if (tp->next && tp->tp_fund != T_POINTER) {
/* Avoid printing recursive types!
*/
print(" n:(");
DumpType(tp->next);
print(")");
}
print(" f:");
switch(tp->tp_fund) {
case T_RECORD:
print("RECORD"); break;
case T_ENUMERATION:
print("ENUMERATION; n:%d", tp->enm_ncst); break;
case T_INTEGER:
print("INTEGER"); break;
case T_CARDINAL:
print("CARDINAL"); break;
case T_REAL:
print("REAL"); break;
case T_POINTER:
print("POINTER"); break;
case T_CHAR:
print("CHAR"); break;
case T_WORD:
print("WORD"); break;
case T_SET:
print("SET"); break;
case T_SUBRANGE:
print("SUBRANGE %ld-%ld", (long) tp->sub_lb, (long) tp->sub_ub);
break;
case T_PROCEDURE:
{
register struct paramlist *par = tp->prc_params;
print("PROCEDURE");
if (par) {
print("; p:");
while(par) {
if (par->par_var) print("VAR ");
DumpType(par->par_type);
par = par->next;
}
}
break;
}
case T_ARRAY:
print("ARRAY %ld-%ld", (long) tp->arr_lb, (long) tp->arr_ub);
print("; el:");
DumpType(tp->arr_elem);
break;
case T_STRING:
print("STRING"); break;
case T_INTORCARD:
print("INTORCARD"); break;
default:
assert(0);
}
print(";");
}
#endif

View File

@ -150,3 +150,21 @@ int TstAssCompat(tp1, tp2)
return 0; return 0;
} }
int TstParCompat(formaltype, actualtype, VARflag)
struct type *formaltype, *actualtype;
{
/* Check type compatibility for a parameter in a procedure
call
*/
return
TstCompat(formaltype, actualtype)
||
( !VARflag && TstAssCompat(formaltype, actualtype))
||
( formaltype->tp_fund == T_ARRAY
&& formaltype->next == 0
&& actualtype->tp_fund == T_ARRAY
&& TstTypeEquiv(formaltype->arr_elem, actualtype->arr_elem));
}

View File

@ -181,7 +181,9 @@ WalkStat(nd, lab)
register struct node *right = nd->nd_right; register struct node *right = nd->nd_right;
if (nd->nd_class == Call) { if (nd->nd_class == Call) {
if (chk_call(nd)) {
/* ??? */ /* ??? */
}
return; return;
} }
@ -189,6 +191,8 @@ WalkStat(nd, lab)
switch(nd->nd_symb) { switch(nd->nd_symb) {
case BECOMES: case BECOMES:
WalkExpr(nd->nd_right);
WalkDesignator(nd->nd_left);
/* ??? */ /* ??? */
break; break;
@ -309,6 +313,19 @@ WalkExpr(nd)
} }
} }
WalkDesignator(nd)
struct node *nd;
{
/* Check designator and generate code for it
*/
DO_DEBUG(1, (DumpTree(nd), print("\n")));
if (chk_designator(nd, DESIGNATOR|VARIABLE)) {
/* ??? */
}
}
#ifdef DEBUG #ifdef DEBUG
DumpTree(nd) DumpTree(nd)
struct node *nd; struct node *nd;