newer version
This commit is contained in:
parent
441ba991fa
commit
6382054ae5
23 changed files with 671 additions and 196 deletions
|
@ -182,10 +182,6 @@ again:
|
||||||
if (nch == '=') {
|
if (nch == '=') {
|
||||||
return tk->tk_symb = LESSEQUAL;
|
return tk->tk_symb = LESSEQUAL;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
if (nch == '>') {
|
|
||||||
return tk->tk_symb = '#';
|
|
||||||
}
|
|
||||||
PushBack(nch);
|
PushBack(nch);
|
||||||
return tk->tk_symb = ch;
|
return tk->tk_symb = ch;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,12 @@
|
||||||
static char *RcsId = "$Header$";
|
static char *RcsId = "$Header$";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Defines the LLmessage routine. LLgen-generated parsers require the
|
||||||
|
existence of a routine of that name.
|
||||||
|
The routine must do syntax-error reporting and must be able to
|
||||||
|
insert tokens in the token stream.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <alloc.h>
|
#include <alloc.h>
|
||||||
#include <em_arith.h>
|
#include <em_arith.h>
|
||||||
#include <em_label.h>
|
#include <em_label.h>
|
||||||
|
@ -12,15 +18,18 @@ static char *RcsId = "$Header$";
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
|
|
||||||
extern char *symbol2str();
|
extern char *symbol2str();
|
||||||
extern struct idf *gen_anon_idf();
|
extern struct idf *gen_anon_idf();
|
||||||
int err_occurred = 0;
|
int err_occurred = 0;
|
||||||
|
|
||||||
LLmessage(tk)
|
LLmessage(tk)
|
||||||
int tk;
|
int tk;
|
||||||
{
|
{
|
||||||
++err_occurred;
|
++err_occurred;
|
||||||
if (tk) {
|
if (tk) {
|
||||||
|
/* if (tk != 0), it represents the token to be inserted.
|
||||||
|
otherwize, the current token is deleted
|
||||||
|
*/
|
||||||
error("%s missing", symbol2str(tk));
|
error("%s missing", symbol2str(tk));
|
||||||
insert_token(tk);
|
insert_token(tk);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ LSRC = tokenfile.g program.g declar.g expression.g statement.g
|
||||||
CC = cc
|
CC = cc
|
||||||
GEN = LLgen
|
GEN = LLgen
|
||||||
GENOPTIONS =
|
GENOPTIONS =
|
||||||
PROFILE =
|
PROFILE =
|
||||||
CFLAGS = $(PROFILE) $(INCLUDES)
|
CFLAGS = $(PROFILE) $(INCLUDES)
|
||||||
LFLAGS = $(PROFILE)
|
LFLAGS = $(PROFILE)
|
||||||
LOBJ = tokenfile.o program.o declar.o expression.o statement.o
|
LOBJ = tokenfile.o program.o declar.o expression.o statement.o
|
||||||
|
@ -91,7 +91,7 @@ tokenname.o: Lpars.h idf.h tokenname.h
|
||||||
idf.o: idf.h
|
idf.o: idf.h
|
||||||
input.o: f_info.h input.h inputtype.h
|
input.o: f_info.h input.h inputtype.h
|
||||||
type.o: LLlex.h const.h debug.h def.h idf.h maxset.h node.h target_sizes.h type.h
|
type.o: LLlex.h const.h debug.h def.h idf.h maxset.h node.h target_sizes.h type.h
|
||||||
def.o: LLlex.h debug.h def.h idf.h main.h node.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 node.h scope.h type.h
|
scope.o: LLlex.h debug.h def.h idf.h node.h scope.h type.h
|
||||||
misc.o: LLlex.h f_info.h idf.h misc.h node.h
|
misc.o: LLlex.h f_info.h idf.h misc.h node.h
|
||||||
enter.o: LLlex.h debug.h def.h idf.h main.h node.h scope.h type.h
|
enter.o: LLlex.h debug.h def.h idf.h main.h node.h scope.h type.h
|
||||||
|
@ -101,10 +101,11 @@ node.o: LLlex.h debug.h def.h node.h type.h
|
||||||
cstoper.o: LLlex.h Lpars.h debug.h idf.h node.h standards.h target_sizes.h type.h
|
cstoper.o: LLlex.h Lpars.h debug.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 main.h ndir.h type.h
|
options.o: idfsize.h main.h ndir.h type.h
|
||||||
walk.o: LLlex.h Lpars.h debug.h def.h desig.h main.h node.h scope.h type.h
|
walk.o: LLlex.h Lpars.h debug.h def.h desig.h f_info.h idf.h main.h node.h scope.h type.h
|
||||||
casestat.o: LLlex.h Lpars.h debug.h density.h desig.h node.h type.h
|
casestat.o: LLlex.h Lpars.h debug.h density.h desig.h node.h type.h
|
||||||
desig.o: LLlex.h debug.h def.h desig.h node.h scope.h type.h
|
desig.o: LLlex.h debug.h def.h desig.h node.h scope.h type.h
|
||||||
code.o: LLlex.h Lpars.h debug.h def.h desig.h node.h scope.h type.h
|
code.o: LLlex.h Lpars.h debug.h def.h desig.h node.h scope.h type.h
|
||||||
|
tmpvar.o: debug.h def.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
|
||||||
declar.o: LLlex.h Lpars.h debug.h def.h idf.h main.h misc.h node.h scope.h type.h
|
declar.o: LLlex.h Lpars.h debug.h def.h idf.h main.h misc.h node.h scope.h type.h
|
||||||
|
|
|
@ -63,15 +63,12 @@ CaseCode(nd, exitlabel)
|
||||||
register arith val;
|
register arith val;
|
||||||
label tablabel;
|
label tablabel;
|
||||||
|
|
||||||
assert(nd->nd_class == Stat && nd->nd_symb == CASE);
|
assert(pnode->nd_class == Stat && pnode->nd_symb == CASE);
|
||||||
|
|
||||||
WalkExpr(nd->nd_left, NO_LABEL, NO_LABEL);
|
clear((char *) sh, sizeof(*sh));
|
||||||
sh->sh_type = nd->nd_left->nd_type;
|
WalkExpr(pnode->nd_left, NO_LABEL, NO_LABEL);
|
||||||
|
sh->sh_type = pnode->nd_left->nd_type;
|
||||||
sh->sh_break = text_label();
|
sh->sh_break = text_label();
|
||||||
sh->sh_default = 0;
|
|
||||||
sh->sh_nrofentries = 0;
|
|
||||||
sh->sh_lowerbd = sh->sh_upperbd = (arith)0; /* immaterial ??? */
|
|
||||||
sh->sh_entries = (struct case_entry *) 0; /* case-entry list */
|
|
||||||
|
|
||||||
/* Now, create case label list
|
/* Now, create case label list
|
||||||
*/
|
*/
|
||||||
|
@ -189,6 +186,7 @@ AddCases(sh, node, lbl)
|
||||||
if (node->nd_symb == UPTO) {
|
if (node->nd_symb == UPTO) {
|
||||||
assert(node->nd_left->nd_class == Value);
|
assert(node->nd_left->nd_class == Value);
|
||||||
assert(node->nd_right->nd_class == Value);
|
assert(node->nd_right->nd_class == Value);
|
||||||
|
|
||||||
v2 = node->nd_right->nd_INT;
|
v2 = node->nd_right->nd_INT;
|
||||||
node->nd_type = node->nd_left->nd_type;
|
node->nd_type = node->nd_left->nd_type;
|
||||||
for (v1 = node->nd_left->nd_INT; v1 <= v2; v1++) {
|
for (v1 = node->nd_left->nd_INT; v1 <= v2; v1++) {
|
||||||
|
@ -233,9 +231,12 @@ AddOneCase(sh, node, lbl)
|
||||||
/* second etc. case entry */
|
/* second etc. case entry */
|
||||||
/* find the proper place to put ce into the list */
|
/* find the proper place to put ce into the list */
|
||||||
|
|
||||||
if (ce->ce_value < sh->sh_lowerbd) sh->sh_lowerbd = ce->ce_value;
|
if (ce->ce_value < sh->sh_lowerbd) {
|
||||||
else
|
sh->sh_lowerbd = ce->ce_value;
|
||||||
if (ce->ce_value > sh->sh_upperbd) sh->sh_upperbd = ce->ce_value;
|
}
|
||||||
|
else if (ce->ce_value > sh->sh_upperbd) {
|
||||||
|
sh->sh_upperbd = ce->ce_value;
|
||||||
|
}
|
||||||
while (c1 && c1->ce_value < ce->ce_value) {
|
while (c1 && c1->ce_value < ce->ce_value) {
|
||||||
c2 = c1;
|
c2 = c1;
|
||||||
c1 = c1->next;
|
c1 = c1->next;
|
||||||
|
|
|
@ -38,7 +38,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|VARIABLE);
|
return chk_designator(expp, DESIGNATOR|VARIABLE, D_NOREG|D_USED);
|
||||||
}
|
}
|
||||||
|
|
||||||
return chk_expr(expp->nd_left) &&
|
return chk_expr(expp->nd_left) &&
|
||||||
|
@ -47,7 +47,7 @@ chk_expr(expp)
|
||||||
|
|
||||||
case Uoper:
|
case Uoper:
|
||||||
if (expp->nd_symb == '^') {
|
if (expp->nd_symb == '^') {
|
||||||
return chk_designator(expp, DESIGNATOR|VARIABLE);
|
return chk_designator(expp, DESIGNATOR|VARIABLE, D_USED);
|
||||||
}
|
}
|
||||||
|
|
||||||
return chk_expr(expp->nd_right) &&
|
return chk_expr(expp->nd_right) &&
|
||||||
|
@ -69,13 +69,13 @@ chk_expr(expp)
|
||||||
return chk_set(expp);
|
return chk_set(expp);
|
||||||
|
|
||||||
case Name:
|
case Name:
|
||||||
return chk_designator(expp, VALUE);
|
return chk_designator(expp, VALUE, D_USED);
|
||||||
|
|
||||||
case Call:
|
case Call:
|
||||||
return chk_call(expp);
|
return chk_call(expp);
|
||||||
|
|
||||||
case Link:
|
case Link:
|
||||||
return chk_designator(expp, DESIGNATOR|VALUE);
|
return chk_designator(expp, DESIGNATOR|VALUE, D_USED|D_NOREG);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
|
@ -94,6 +94,7 @@ chk_set(expp)
|
||||||
struct def *df;
|
struct def *df;
|
||||||
register struct node *nd;
|
register struct node *nd;
|
||||||
arith *set;
|
arith *set;
|
||||||
|
unsigned size;
|
||||||
|
|
||||||
assert(expp->nd_symb == SET);
|
assert(expp->nd_symb == SET);
|
||||||
|
|
||||||
|
@ -102,7 +103,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, 0)) return 0;
|
if (! chk_designator(nd, 0, D_USED)) return 0;
|
||||||
|
|
||||||
assert(nd->nd_class == Def);
|
assert(nd->nd_class == Def);
|
||||||
df = nd->nd_def;
|
df = nd->nd_def;
|
||||||
|
@ -117,16 +118,26 @@ chk_set(expp)
|
||||||
expp->nd_left = 0;
|
expp->nd_left = 0;
|
||||||
}
|
}
|
||||||
else tp = bitset_type;
|
else tp = bitset_type;
|
||||||
|
expp->nd_type = tp;
|
||||||
|
|
||||||
|
nd = expp->nd_right;
|
||||||
|
|
||||||
/* Now check the elements given, and try to compute a constant set.
|
/* Now check the elements given, and try to compute a constant set.
|
||||||
First allocate room for the set
|
First allocate room for the set, but only if it is'nt empty.
|
||||||
*/
|
*/
|
||||||
set = (arith *)
|
if (! nd) {
|
||||||
Malloc((unsigned) (tp->tp_size * sizeof(arith) / word_size));
|
/* The resulting set IS empty, so we just return
|
||||||
|
*/
|
||||||
|
expp->nd_class = Set;
|
||||||
|
expp->nd_set = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
size = tp->tp_size * (sizeof(arith) / word_size);
|
||||||
|
set = (arith *) Malloc(size);
|
||||||
|
clear((char *) set, size);
|
||||||
|
|
||||||
/* Now check the elements, one by one
|
/* Now check the elements, one by one
|
||||||
*/
|
*/
|
||||||
nd = expp->nd_right;
|
|
||||||
while (nd) {
|
while (nd) {
|
||||||
assert(nd->nd_class == Link && nd->nd_symb == ',');
|
assert(nd->nd_class == Link && nd->nd_symb == ',');
|
||||||
|
|
||||||
|
@ -134,8 +145,6 @@ chk_set(expp)
|
||||||
nd = nd->nd_right;
|
nd = nd->nd_right;
|
||||||
}
|
}
|
||||||
|
|
||||||
expp->nd_type = tp;
|
|
||||||
|
|
||||||
if (set) {
|
if (set) {
|
||||||
/* Yes, it was a constant set, and we managed to compute it!
|
/* Yes, it was a constant set, and we managed to compute it!
|
||||||
Notice that at the moment there is no such thing as
|
Notice that at the moment there is no such thing as
|
||||||
|
@ -255,7 +264,7 @@ getarg(argp, bases, designator)
|
||||||
}
|
}
|
||||||
argp = argp->nd_right;
|
argp = argp->nd_right;
|
||||||
if ((!designator && !chk_expr(argp->nd_left)) ||
|
if ((!designator && !chk_expr(argp->nd_left)) ||
|
||||||
(designator && !chk_designator(argp->nd_left, DESIGNATOR))) {
|
(designator && !chk_designator(argp->nd_left, DESIGNATOR, D_REFERRED))) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
tp = argp->nd_left->nd_type;
|
tp = argp->nd_left->nd_type;
|
||||||
|
@ -276,7 +285,7 @@ getname(argp, kinds)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
argp = argp->nd_right;
|
argp = argp->nd_right;
|
||||||
if (! chk_designator(argp->nd_left, 0)) return 0;
|
if (! chk_designator(argp->nd_left, 0, D_REFERRED)) return 0;
|
||||||
|
|
||||||
assert(argp->nd_left->nd_class == Def);
|
assert(argp->nd_left->nd_class == Def);
|
||||||
|
|
||||||
|
@ -303,10 +312,9 @@ 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, 0)) return 0;
|
if (! chk_designator(left, 0, D_USED)) return 0;
|
||||||
|
|
||||||
if (left->nd_class == Def &&
|
if (left->nd_class == Def && is_type(left->nd_def)) {
|
||||||
(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.
|
||||||
*/
|
*/
|
||||||
arg = expp->nd_right;
|
arg = expp->nd_right;
|
||||||
|
@ -359,10 +367,21 @@ chk_proccall(expp)
|
||||||
{
|
{
|
||||||
/* Check a procedure call
|
/* Check a procedure call
|
||||||
*/
|
*/
|
||||||
register struct node *left = expp->nd_left;
|
register struct node *left;
|
||||||
register struct node *arg;
|
register struct node *arg;
|
||||||
register struct paramlist *param;
|
register struct paramlist *param;
|
||||||
|
|
||||||
|
left = 0;
|
||||||
|
arg = expp->nd_right;
|
||||||
|
/* First, reverse the order in the argument list */
|
||||||
|
while (arg) {
|
||||||
|
expp->nd_right = arg;
|
||||||
|
arg = arg->nd_right;
|
||||||
|
expp->nd_right->nd_right = left;
|
||||||
|
left = expp->nd_right;
|
||||||
|
}
|
||||||
|
|
||||||
|
left = expp->nd_left;
|
||||||
arg = expp;
|
arg = expp;
|
||||||
arg->nd_type = left->nd_type->next;
|
arg->nd_type = left->nd_type->next;
|
||||||
param = left->nd_type->prc_params;
|
param = left->nd_type->prc_params;
|
||||||
|
@ -376,6 +395,9 @@ chk_proccall(expp)
|
||||||
node_error(arg->nd_left, "type incompatibility in parameter");
|
node_error(arg->nd_left, "type incompatibility in parameter");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (param->par_var && arg->nd_left->nd_class == Def) {
|
||||||
|
arg->nd_left->nd_def->df_flags |= D_NOREG;
|
||||||
|
}
|
||||||
|
|
||||||
param = param->next;
|
param = param->next;
|
||||||
}
|
}
|
||||||
|
@ -422,7 +444,7 @@ FlagCheck(expp, df, flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
chk_designator(expp, flag)
|
chk_designator(expp, flag, dflags)
|
||||||
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
|
||||||
|
@ -435,6 +457,8 @@ chk_designator(expp, flag)
|
||||||
and '^' are allowed for this designator.
|
and '^' are allowed for this designator.
|
||||||
Also contained may be the flag HASSELECTORS, indicating that
|
Also contained may be the flag HASSELECTORS, indicating that
|
||||||
the result must have selectors.
|
the result must have selectors.
|
||||||
|
"dflags" contains some flags that must be set at the definition
|
||||||
|
found.
|
||||||
*/
|
*/
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
register struct type *tp;
|
register struct type *tp;
|
||||||
|
@ -454,7 +478,8 @@ chk_designator(expp, flag)
|
||||||
assert(expp->nd_right->nd_class == Name);
|
assert(expp->nd_right->nd_class == Name);
|
||||||
|
|
||||||
if (! chk_designator(expp->nd_left,
|
if (! chk_designator(expp->nd_left,
|
||||||
(flag|HASSELECTORS))) return 0;
|
flag|HASSELECTORS,
|
||||||
|
dflags|D_NOREG)) return 0;
|
||||||
|
|
||||||
tp = expp->nd_left->nd_type;
|
tp = expp->nd_left->nd_type;
|
||||||
|
|
||||||
|
@ -512,6 +537,8 @@ df->df_idf->id_text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
df->df_flags |= dflags;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,7 +553,7 @@ df->df_idf->id_text);
|
||||||
assert(expp->nd_symb == '[');
|
assert(expp->nd_symb == '[');
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!chk_designator(expp->nd_left, DESIGNATOR|VARIABLE)
|
!chk_designator(expp->nd_left, DESIGNATOR|VARIABLE, dflags|D_NOREG)
|
||||||
||
|
||
|
||||||
!chk_expr(expp->nd_right)
|
!chk_expr(expp->nd_right)
|
||||||
||
|
||
|
||||||
|
@ -558,7 +585,7 @@ 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|VARIABLE)) {
|
if (! chk_designator(expp->nd_right, DESIGNATOR|VARIABLE, dflags)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -703,7 +730,6 @@ node_error(expp, "IN operator: type of LHS not compatible with element type of R
|
||||||
|
|
||||||
case '=':
|
case '=':
|
||||||
case '#':
|
case '#':
|
||||||
case UNEQUAL:
|
|
||||||
case GREATEREQUAL:
|
case GREATEREQUAL:
|
||||||
case LESSEQUAL:
|
case LESSEQUAL:
|
||||||
case '<':
|
case '<':
|
||||||
|
@ -732,7 +758,6 @@ node_error(expp, "IN operator: type of LHS not compatible with element type of R
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
if (chk_address(tpl, tpr) ||
|
if (chk_address(tpl, tpr) ||
|
||||||
expp->nd_symb == '=' ||
|
expp->nd_symb == '=' ||
|
||||||
expp->nd_symb == UNEQUAL ||
|
|
||||||
expp->nd_symb == '#') return 1;
|
expp->nd_symb == '#') return 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -790,6 +815,7 @@ chk_uoper(expp)
|
||||||
case '+':
|
case '+':
|
||||||
if (tpr->tp_fund & T_NUMERIC) {
|
if (tpr->tp_fund & T_NUMERIC) {
|
||||||
expp->nd_token = right->nd_token;
|
expp->nd_token = right->nd_token;
|
||||||
|
expp->nd_class = right->nd_class;
|
||||||
FreeNode(right);
|
FreeNode(right);
|
||||||
expp->nd_right = 0;
|
expp->nd_right = 0;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -809,10 +835,14 @@ chk_uoper(expp)
|
||||||
else if (tpr->tp_fund == T_REAL) {
|
else if (tpr->tp_fund == T_REAL) {
|
||||||
if (right->nd_class == Value) {
|
if (right->nd_class == Value) {
|
||||||
expp->nd_token = right->nd_token;
|
expp->nd_token = right->nd_token;
|
||||||
|
expp->nd_class = Value;
|
||||||
if (*(expp->nd_REL) == '-') {
|
if (*(expp->nd_REL) == '-') {
|
||||||
expp->nd_REL++;
|
expp->nd_REL++;
|
||||||
}
|
}
|
||||||
else expp->nd_REL--;
|
else {
|
||||||
|
expp->nd_REL--;
|
||||||
|
*(expp->nd_REL) = '-';
|
||||||
|
}
|
||||||
FreeNode(right);
|
FreeNode(right);
|
||||||
expp->nd_right = 0;
|
expp->nd_right = 0;
|
||||||
}
|
}
|
||||||
|
@ -853,7 +883,7 @@ getvariable(arg)
|
||||||
|
|
||||||
left = arg->nd_left;
|
left = arg->nd_left;
|
||||||
|
|
||||||
if (! chk_designator(left, DESIGNATOR)) return 0;
|
if (! chk_designator(left, DESIGNATOR, D_REFERRED)) return 0;
|
||||||
if (left->nd_class == Oper || left->nd_class == Uoper) {
|
if (left->nd_class == Oper || left->nd_class == Uoper) {
|
||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
|
@ -941,7 +971,7 @@ left->nd_def->df_idf->id_text, left->nd_def->df_value.df_stdname));
|
||||||
case S_TSIZE: /* ??? */
|
case S_TSIZE: /* ??? */
|
||||||
case S_SIZE:
|
case S_SIZE:
|
||||||
expp->nd_type = intorcard_type;
|
expp->nd_type = intorcard_type;
|
||||||
arg = getname(arg, D_FIELD|D_VARIABLE|D_TYPE|D_HIDDEN|D_HTYPE);
|
arg = getname(arg, D_FIELD|D_VARIABLE|D_ISTYPE);
|
||||||
if (!arg) return 0;
|
if (!arg) return 0;
|
||||||
cstcall(expp, S_SIZE);
|
cstcall(expp, S_SIZE);
|
||||||
break;
|
break;
|
||||||
|
@ -955,7 +985,7 @@ left->nd_def->df_idf->id_text, left->nd_def->df_value.df_stdname));
|
||||||
{
|
{
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
|
|
||||||
if (!(arg = getname(arg, D_HIDDEN|D_HTYPE|D_TYPE))) return 0;
|
if (!(arg = getname(arg, D_ISTYPE))) return 0;
|
||||||
tp = arg->nd_left->nd_def->df_type;
|
tp = arg->nd_left->nd_def->df_type;
|
||||||
if (tp->tp_fund == T_SUBRANGE) tp = tp->next;
|
if (tp->tp_fund == T_SUBRANGE) tp = tp->next;
|
||||||
if (!(tp->tp_fund & T_DISCRETE)) {
|
if (!(tp->tp_fund & T_DISCRETE)) {
|
||||||
|
|
|
@ -52,14 +52,14 @@ CodeString(nd)
|
||||||
struct node *nd;
|
struct node *nd;
|
||||||
{
|
{
|
||||||
label lab;
|
label lab;
|
||||||
|
|
||||||
if (nd->nd_type == charc_type) {
|
if (nd->nd_type == charc_type) {
|
||||||
C_loc(nd->nd_INT);
|
C_loc(nd->nd_INT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
C_df_dlb(lab = data_label());
|
C_df_dlb(lab = data_label());
|
||||||
C_rom_scon(nd->nd_STR, nd->nd_SLE);
|
C_rom_scon(nd->nd_STR, nd->nd_SLE);
|
||||||
C_lae_dlb(lab);
|
C_lae_dlb(lab, (arith) 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeReal(nd)
|
CodeReal(nd)
|
||||||
|
@ -69,7 +69,7 @@ CodeReal(nd)
|
||||||
|
|
||||||
C_df_dlb(lab = data_label());
|
C_df_dlb(lab = data_label());
|
||||||
C_rom_fcon(nd->nd_REL, nd->nd_type->tp_size);
|
C_rom_fcon(nd->nd_REL, nd->nd_type->tp_size);
|
||||||
C_lae_dlb(lab);
|
C_lae_dlb(lab, (arith) 0);
|
||||||
C_loi(nd->nd_type->tp_size);
|
C_loi(nd->nd_type->tp_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,12 +139,16 @@ CodeExpr(nd, ds, true_label, false_label)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
st = nd->nd_set;
|
st = nd->nd_set;
|
||||||
for (i = nd->nd_type->tp_size / word_size, st = nd->nd_set + i;
|
ds->dsg_kind = DSG_LOADED;
|
||||||
|
if (!st) {
|
||||||
|
C_zer(nd->nd_type->tp_size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (i = nd->nd_type->tp_size / word_size, st += i;
|
||||||
i > 0;
|
i > 0;
|
||||||
i--) {
|
i--) {
|
||||||
C_loc(*--st);
|
C_loc(*--st);
|
||||||
}
|
}
|
||||||
ds->dsg_kind = DSG_LOADED;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -166,9 +170,97 @@ CodeExpr(nd, ds, true_label, false_label)
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeCoercion(t1, t2)
|
CodeCoercion(t1, t2)
|
||||||
struct type *t1, *t2;
|
register struct type *t1, *t2;
|
||||||
{
|
{
|
||||||
/* ??? */
|
int fund1, fund2;
|
||||||
|
|
||||||
|
if (t1 == t2) return;
|
||||||
|
if (t1->tp_fund == T_SUBRANGE) t1 = t1->next;
|
||||||
|
if (t2->tp_fund == T_SUBRANGE) t2 = t2->next;
|
||||||
|
if ((fund1 = t1->tp_fund) == T_WORD) fund1 = T_INTEGER;
|
||||||
|
if ((fund2 = t2->tp_fund) == T_WORD) fund2 = T_INTEGER;
|
||||||
|
switch(fund1) {
|
||||||
|
case T_INTEGER:
|
||||||
|
switch(fund2) {
|
||||||
|
case T_INTEGER:
|
||||||
|
if (t2->tp_size != t1->tp_size) {
|
||||||
|
C_loc(t1->tp_size);
|
||||||
|
C_loc(t2->tp_size);
|
||||||
|
C_cii();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case T_ENUMERATION:
|
||||||
|
case T_CHAR:
|
||||||
|
case T_CARDINAL:
|
||||||
|
if (t1->tp_size != word_size) {
|
||||||
|
C_loc(t1->tp_size);
|
||||||
|
C_loc(word_size);
|
||||||
|
C_ciu();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case T_REAL:
|
||||||
|
C_loc(t1->tp_size);
|
||||||
|
C_loc(t2->tp_size);
|
||||||
|
C_cif();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
crash("Funny integer conversion");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_CHAR:
|
||||||
|
case T_ENUMERATION:
|
||||||
|
case T_CARDINAL:
|
||||||
|
switch(fund2) {
|
||||||
|
case T_ENUMERATION:
|
||||||
|
case T_CHAR:
|
||||||
|
case T_CARDINAL:
|
||||||
|
case T_POINTER:
|
||||||
|
if (t2->tp_size > word_size) {
|
||||||
|
C_loc(word_size);
|
||||||
|
C_loc(t2->tp_size);
|
||||||
|
C_cuu();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case T_INTEGER:
|
||||||
|
C_loc(t1->tp_size);
|
||||||
|
C_loc(t2->tp_size);
|
||||||
|
C_cui();
|
||||||
|
break;
|
||||||
|
case T_REAL:
|
||||||
|
C_loc(t1->tp_size);
|
||||||
|
C_loc(t2->tp_size);
|
||||||
|
C_cuf();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
crash("Funny cardinal conversion");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_REAL:
|
||||||
|
switch(fund2) {
|
||||||
|
case T_REAL:
|
||||||
|
if (t2->tp_size != t1->tp_size) {
|
||||||
|
C_loc(t1->tp_size);
|
||||||
|
C_loc(t2->tp_size);
|
||||||
|
C_cff();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case T_INTEGER:
|
||||||
|
C_loc(t1->tp_size);
|
||||||
|
C_loc(t2->tp_size);
|
||||||
|
C_cfi();
|
||||||
|
break;
|
||||||
|
case T_CARDINAL:
|
||||||
|
C_loc(t1->tp_size);
|
||||||
|
C_loc(t2->tp_size);
|
||||||
|
C_cfu();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
crash("Funny REAL conversion");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeCall(nd)
|
CodeCall(nd)
|
||||||
|
@ -190,13 +282,12 @@ CodeCall(nd)
|
||||||
}
|
}
|
||||||
tp = left->nd_type;
|
tp = left->nd_type;
|
||||||
|
|
||||||
if (left->nd_class == Def &&
|
if (left->nd_class == Def && is_type(left->nd_def)) {
|
||||||
(left->nd_def->df_kind & (D_TYPE|D_HTYPE|D_HIDDEN))) {
|
|
||||||
/* it was just a cast. Simply ignore it
|
/* it was just a cast. Simply ignore it
|
||||||
*/
|
*/
|
||||||
Des = InitDesig;
|
Des = InitDesig;
|
||||||
CodeExpr(nd->nd_right->nd_left, &Des, NO_LABEL, NO_LABEL);
|
CodeExpr(nd->nd_right->nd_left, &Des, NO_LABEL, NO_LABEL);
|
||||||
CodeValue(&Des);
|
CodeValue(&Des, tp->tp_size);
|
||||||
*nd = *(nd->nd_right->nd_left);
|
*nd = *(nd->nd_right->nd_left);
|
||||||
nd->nd_type = left->nd_def->df_type;
|
nd->nd_type = left->nd_def->df_type;
|
||||||
return;
|
return;
|
||||||
|
@ -216,6 +307,7 @@ CodeCall(nd)
|
||||||
else {
|
else {
|
||||||
CodeExpr(arg->nd_left, &Des, NO_LABEL, NO_LABEL);
|
CodeExpr(arg->nd_left, &Des, NO_LABEL, NO_LABEL);
|
||||||
CodeValue(&Des, arg->nd_left->nd_type->tp_size);
|
CodeValue(&Des, arg->nd_left->nd_type->tp_size);
|
||||||
|
CheckAssign(arg->nd_left->nd_type, param->par_type);
|
||||||
pushed += align(arg->nd_left->nd_type->tp_size, word_align);
|
pushed += align(arg->nd_left->nd_type->tp_size, word_align);
|
||||||
}
|
}
|
||||||
/* ??? Conformant arrays */
|
/* ??? Conformant arrays */
|
||||||
|
@ -249,16 +341,55 @@ CodeStd(nd)
|
||||||
/* ??? */
|
/* ??? */
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeAssign(nd, dst, dss)
|
CodeAssign(nd, dss, dst)
|
||||||
struct node *nd;
|
struct node *nd;
|
||||||
struct desig *dst, *dss;
|
struct desig *dst, *dss;
|
||||||
{
|
{
|
||||||
/* Generate code for an assignment. Testing of type
|
/* Generate code for an assignment. Testing of type
|
||||||
compatibility and the like is already done.
|
compatibility and the like is already done.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CodeCoercion(nd->nd_right->nd_type, nd->nd_left->nd_type);
|
if (dss->dsg_kind == DSG_LOADED) {
|
||||||
/* ??? */
|
CodeStore(dst, nd->nd_left->nd_type->tp_size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CodeAddress(dst);
|
||||||
|
C_blm(nd->nd_left->nd_type->tp_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckAssign(tpl, tpr)
|
||||||
|
register struct type *tpl, *tpr;
|
||||||
|
{
|
||||||
|
/* Generate a range check if neccessary
|
||||||
|
*/
|
||||||
|
|
||||||
|
arith llo, lhi, rlo, rhi;
|
||||||
|
label l = 0;
|
||||||
|
extern label getrck();
|
||||||
|
|
||||||
|
if (bounded(tpl)) {
|
||||||
|
/* in this case we might need a range check */
|
||||||
|
if (!bounded(tpr)) {
|
||||||
|
/* yes, we need one */
|
||||||
|
l = getrck(tpl);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* both types are restricted. check the bounds
|
||||||
|
to see wether we need a range check
|
||||||
|
*/
|
||||||
|
getbounds(tpl, &llo, &lhi);
|
||||||
|
getbounds(tpr, &rlo, &rhi);
|
||||||
|
if (llo > rlo || lhi < rhi) {
|
||||||
|
l = getrck(tpl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l) {
|
||||||
|
C_lae_dlb(l, (arith) 0);
|
||||||
|
C_rck(word_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Operands(leftop, rightop)
|
Operands(leftop, rightop)
|
||||||
|
@ -415,29 +546,44 @@ CodeOper(expr, true_label, false_label)
|
||||||
case '>':
|
case '>':
|
||||||
case GREATEREQUAL:
|
case GREATEREQUAL:
|
||||||
case '=':
|
case '=':
|
||||||
case UNEQUAL:
|
|
||||||
case '#':
|
case '#':
|
||||||
Operands(leftop, rightop);
|
Operands(leftop, rightop);
|
||||||
CodeCoercion(rightop->nd_type, leftop->nd_type);
|
CodeCoercion(rightop->nd_type, leftop->nd_type);
|
||||||
|
tp = leftop->nd_type; /* Not the result type! */
|
||||||
|
if (tp->tp_fund == T_SUBRANGE) tp = tp->next;
|
||||||
switch (tp->tp_fund) {
|
switch (tp->tp_fund) {
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
C_cmi(leftop->nd_type->tp_size);
|
C_cmi(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
C_cmp();
|
C_cmp();
|
||||||
break;
|
break;
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
C_cmu(leftop->nd_type->tp_size);
|
C_cmu(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_ENUMERATION:
|
case T_ENUMERATION:
|
||||||
case T_CHAR:
|
case T_CHAR:
|
||||||
C_cmu(word_size);
|
C_cmu(word_size);
|
||||||
break;
|
break;
|
||||||
case T_REAL:
|
case T_REAL:
|
||||||
C_cmf(leftop->nd_type->tp_size);
|
C_cmf(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_SET:
|
case T_SET:
|
||||||
C_cms(leftop->nd_type->tp_size);
|
if (oper == GREATEREQUAL) {
|
||||||
|
/* A >= B is the same as A equals A + B
|
||||||
|
*/
|
||||||
|
C_dup(2*tp->tp_size);
|
||||||
|
C_asp(tp->tp_size);
|
||||||
|
C_zer(tp->tp_size);
|
||||||
|
}
|
||||||
|
else if (oper == LESSEQUAL) {
|
||||||
|
/* A <= B is the same as A - B = {}
|
||||||
|
*/
|
||||||
|
C_com(tp->tp_size);
|
||||||
|
C_and(tp->tp_size);
|
||||||
|
C_ior(tp->tp_size);
|
||||||
|
}
|
||||||
|
C_cms(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
crash("bad type COMPARE");
|
crash("bad type COMPARE");
|
||||||
|
@ -451,9 +597,13 @@ CodeOper(expr, true_label, false_label)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IN:
|
case IN:
|
||||||
Operands(leftop, rightop);
|
/* In this case, evaluate right hand side first! The
|
||||||
CodeCoercion(rightop->nd_type, word_type);
|
INN instruction expects the bit number on top of the
|
||||||
C_inn(leftop->nd_type->tp_size);
|
stack
|
||||||
|
*/
|
||||||
|
Operands(rightop, leftop);
|
||||||
|
CodeCoercion(leftop->nd_type, word_type);
|
||||||
|
C_inn(rightop->nd_type->tp_size);
|
||||||
break;
|
break;
|
||||||
case AND:
|
case AND:
|
||||||
case '&':
|
case '&':
|
||||||
|
@ -544,7 +694,6 @@ compare(relop, lbl)
|
||||||
case '=':
|
case '=':
|
||||||
C_zeq(lbl);
|
C_zeq(lbl);
|
||||||
break;
|
break;
|
||||||
case UNEQUAL:
|
|
||||||
case '#':
|
case '#':
|
||||||
C_zne(lbl);
|
C_zne(lbl);
|
||||||
break;
|
break;
|
||||||
|
@ -573,7 +722,6 @@ truthvalue(relop)
|
||||||
case '=':
|
case '=':
|
||||||
C_teq();
|
C_teq();
|
||||||
break;
|
break;
|
||||||
case UNEQUAL:
|
|
||||||
case '#':
|
case '#':
|
||||||
C_tne();
|
C_tne();
|
||||||
break;
|
break;
|
||||||
|
@ -643,7 +791,7 @@ CodeEl(nd, tp)
|
||||||
|
|
||||||
Des = InitDesig;
|
Des = InitDesig;
|
||||||
CodeExpr(nd, &Des, NO_LABEL, NO_LABEL);
|
CodeExpr(nd, &Des, NO_LABEL, NO_LABEL);
|
||||||
CodeValue(nd, word_size);
|
CodeValue(&Des, word_size);
|
||||||
C_set(tp->tp_size);
|
C_set(tp->tp_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ cstunary(expp)
|
||||||
o1 = !o1;
|
o1 = !o1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
crash("(cstunary)");
|
||||||
}
|
}
|
||||||
expp->nd_class = Value;
|
expp->nd_class = Value;
|
||||||
expp->nd_token = expp->nd_right->nd_token;
|
expp->nd_token = expp->nd_right->nd_token;
|
||||||
|
@ -159,7 +159,7 @@ cstbin(expp)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
o1 = o1 < o2;
|
o1 = (o1 < o2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '>':
|
case '>':
|
||||||
|
@ -170,7 +170,7 @@ cstbin(expp)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
o1 = o1 > o2;
|
o1 = (o1 > o2);
|
||||||
break;
|
break;
|
||||||
case LESSEQUAL:
|
case LESSEQUAL:
|
||||||
if (uns) {
|
if (uns) {
|
||||||
|
@ -180,7 +180,7 @@ cstbin(expp)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
o1 = o1 <= o2;
|
o1 = (o1 <= o2);
|
||||||
break;
|
break;
|
||||||
case GREATEREQUAL:
|
case GREATEREQUAL:
|
||||||
if (uns) {
|
if (uns) {
|
||||||
|
@ -190,27 +190,27 @@ cstbin(expp)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
o1 = o1 >= o2;
|
o1 = (o1 >= o2);
|
||||||
break;
|
break;
|
||||||
case '=':
|
case '=':
|
||||||
o1 = o1 == o2;
|
o1 = (o1 == o2);
|
||||||
break;
|
break;
|
||||||
case '#':
|
case '#':
|
||||||
case UNEQUAL:
|
o1 = (o1 != o2);
|
||||||
o1 = o1 != o2;
|
|
||||||
break;
|
break;
|
||||||
case AND:
|
case AND:
|
||||||
case '&':
|
case '&':
|
||||||
o1 = o1 && o2;
|
o1 = (o1 && o2);
|
||||||
break;
|
break;
|
||||||
case OR:
|
case OR:
|
||||||
o1 = o1 || o2;
|
o1 = (o1 || o2);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
crash("(cstbin)");
|
||||||
}
|
}
|
||||||
expp->nd_class = Value;
|
expp->nd_class = Value;
|
||||||
expp->nd_token = expp->nd_right->nd_token;
|
expp->nd_token = expp->nd_right->nd_token;
|
||||||
|
if (expp->nd_type == bool_type) expp->nd_symb = INTEGER;
|
||||||
expp->nd_INT = o1;
|
expp->nd_INT = o1;
|
||||||
CutSize(expp);
|
CutSize(expp);
|
||||||
FreeNode(expp->nd_left);
|
FreeNode(expp->nd_left);
|
||||||
|
@ -222,6 +222,7 @@ cstset(expp)
|
||||||
register struct node *expp;
|
register struct node *expp;
|
||||||
{
|
{
|
||||||
register arith *set1 = 0, *set2;
|
register arith *set1 = 0, *set2;
|
||||||
|
arith *resultset = 0;
|
||||||
register int setsize, j;
|
register int setsize, j;
|
||||||
|
|
||||||
assert(expp->nd_right->nd_class == Set);
|
assert(expp->nd_right->nd_class == Set);
|
||||||
|
@ -233,32 +234,59 @@ cstset(expp)
|
||||||
arith i;
|
arith i;
|
||||||
|
|
||||||
assert(expp->nd_left->nd_class == Value);
|
assert(expp->nd_left->nd_class == Value);
|
||||||
|
|
||||||
i = expp->nd_left->nd_INT;
|
i = expp->nd_left->nd_INT;
|
||||||
expp->nd_INT = (i >= 0 &&
|
expp->nd_INT = (i >= 0 && set2 != 0 &&
|
||||||
i < setsize * wrd_bits &&
|
i < setsize * wrd_bits &&
|
||||||
(set2[i / wrd_bits] & (1 << (i % wrd_bits))));
|
(set2[i / wrd_bits] & (1 << (i % wrd_bits))));
|
||||||
free((char *) set2);
|
if (set2) free((char *) set2);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
set1 = expp->nd_left->nd_set;
|
set1 = expp->nd_left->nd_set;
|
||||||
|
resultset = set1;
|
||||||
|
expp->nd_left->nd_set = 0;
|
||||||
switch(expp->nd_symb) {
|
switch(expp->nd_symb) {
|
||||||
case '+':
|
case '+':
|
||||||
for (j = 0; j < setsize; j++) {
|
if (!set1) {
|
||||||
|
resultset = set2;
|
||||||
|
expp->nd_right->nd_set = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (set2) for (j = 0; j < setsize; j++) {
|
||||||
*set1++ |= *set2++;
|
*set1++ |= *set2++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
|
if (!set1 || !set2) {
|
||||||
|
/* The set from which something is substracted
|
||||||
|
is already empty, or the set that is
|
||||||
|
substracted is empty
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
for (j = 0; j < setsize; j++) {
|
for (j = 0; j < setsize; j++) {
|
||||||
*set1++ &= ~*set2++;
|
*set1++ &= ~*set2++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '*':
|
case '*':
|
||||||
|
if (!set1) break;
|
||||||
|
if (!set2) {
|
||||||
|
resultset = set2;
|
||||||
|
expp->nd_right->nd_set = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
for (j = 0; j < setsize; j++) {
|
for (j = 0; j < setsize; j++) {
|
||||||
*set1++ &= *set2++;
|
*set1++ &= *set2++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '/':
|
case '/':
|
||||||
for (j = 0; j < setsize; j++) {
|
if (!set1) {
|
||||||
|
resultset = set2;
|
||||||
|
expp->nd_right->nd_set = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (set2) for (j = 0; j < setsize; j++) {
|
||||||
*set1++ ^= *set2++;
|
*set1++ ^= *set2++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -266,42 +294,62 @@ cstset(expp)
|
||||||
case LESSEQUAL:
|
case LESSEQUAL:
|
||||||
case '=':
|
case '=':
|
||||||
case '#':
|
case '#':
|
||||||
case UNEQUAL:
|
|
||||||
/* Clumsy, but who cares? Nobody writes these things! */
|
/* Clumsy, but who cares? Nobody writes these things! */
|
||||||
|
expp->nd_left->nd_set = set1;
|
||||||
for (j = 0; j < setsize; j++) {
|
for (j = 0; j < setsize; j++) {
|
||||||
switch(expp->nd_symb) {
|
switch(expp->nd_symb) {
|
||||||
case GREATEREQUAL:
|
case GREATEREQUAL:
|
||||||
|
if (!set2) {j = setsize; break; }
|
||||||
|
if (!set1) break;
|
||||||
if ((*set1 | *set2++) != *set1) break;
|
if ((*set1 | *set2++) != *set1) break;
|
||||||
set1++;
|
set1++;
|
||||||
continue;
|
continue;
|
||||||
case LESSEQUAL:
|
case LESSEQUAL:
|
||||||
|
if (!set1) {j = setsize; break; }
|
||||||
|
if (!set2) break;
|
||||||
if ((*set2 | *set1++) != *set2) break;
|
if ((*set2 | *set1++) != *set2) break;
|
||||||
set2++;
|
set2++;
|
||||||
continue;
|
continue;
|
||||||
case '=':
|
case '=':
|
||||||
case '#':
|
case '#':
|
||||||
case UNEQUAL:
|
if (!set1 && !set2) {
|
||||||
|
j = setsize; break;
|
||||||
|
}
|
||||||
|
if (!set1 || !set2) break;
|
||||||
if (*set1++ != *set2++) break;
|
if (*set1++ != *set2++) break;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
expp->nd_INT = expp->nd_symb != '=';
|
if (j < setsize) {
|
||||||
|
expp->nd_INT = expp->nd_symb == '#';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
expp->nd_INT = expp->nd_symb != '#';
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (j == setsize) expp->nd_INT = expp->nd_symb == '=';
|
|
||||||
expp->nd_class = Value;
|
expp->nd_class = Value;
|
||||||
expp->nd_symb = INTEGER;
|
expp->nd_symb = INTEGER;
|
||||||
free((char *) expp->nd_left->nd_set);
|
if (expp->nd_left->nd_set) {
|
||||||
free((char *) expp->nd_right->nd_set);
|
free((char *) expp->nd_left->nd_set);
|
||||||
|
}
|
||||||
|
if (expp->nd_right->nd_set) {
|
||||||
|
free((char *) expp->nd_right->nd_set);
|
||||||
|
}
|
||||||
FreeNode(expp->nd_left);
|
FreeNode(expp->nd_left);
|
||||||
FreeNode(expp->nd_right);
|
FreeNode(expp->nd_right);
|
||||||
expp->nd_left = expp->nd_right = 0;
|
expp->nd_left = expp->nd_right = 0;
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
crash("(cstset)");
|
||||||
|
}
|
||||||
|
if (expp->nd_right->nd_set) {
|
||||||
|
free((char *) expp->nd_right->nd_set);
|
||||||
|
}
|
||||||
|
if (expp->nd_left->nd_set) {
|
||||||
|
free((char *) expp->nd_left->nd_set);
|
||||||
}
|
}
|
||||||
free((char *) expp->nd_right->nd_set);
|
|
||||||
expp->nd_class = Set;
|
expp->nd_class = Set;
|
||||||
expp->nd_set = expp->nd_left->nd_set;
|
expp->nd_set = resultset;
|
||||||
}
|
}
|
||||||
FreeNode(expp->nd_left);
|
FreeNode(expp->nd_left);
|
||||||
FreeNode(expp->nd_right);
|
FreeNode(expp->nd_right);
|
||||||
|
@ -405,7 +453,7 @@ cstcall(expp, call)
|
||||||
else CutSize(expp);
|
else CutSize(expp);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
crash("(cstcall)");
|
||||||
}
|
}
|
||||||
FreeNode(expr);
|
FreeNode(expr);
|
||||||
FreeNode(expp->nd_left);
|
FreeNode(expp->nd_left);
|
||||||
|
|
|
@ -128,8 +128,7 @@ FormalParameters(int doparams;
|
||||||
]?
|
]?
|
||||||
')'
|
')'
|
||||||
{ *tp = 0; }
|
{ *tp = 0; }
|
||||||
[ ':' qualident(D_TYPE|D_HTYPE|D_HIDDEN, &df, "type",
|
[ ':' qualident(D_ISTYPE, &df, "type", (struct node **) 0)
|
||||||
(struct node **) 0)
|
|
||||||
{ *tp = df->df_type;
|
{ *tp = df->df_type;
|
||||||
}
|
}
|
||||||
]?
|
]?
|
||||||
|
@ -169,7 +168,7 @@ FormalType(struct type **tp;)
|
||||||
} :
|
} :
|
||||||
[ ARRAY OF { ARRAYflag = 1; }
|
[ ARRAY OF { ARRAYflag = 1; }
|
||||||
]?
|
]?
|
||||||
qualident(D_TYPE|D_HTYPE|D_HIDDEN, &df, "type", (struct node **) 0)
|
qualident(D_ISTYPE, &df, "type", (struct node **) 0)
|
||||||
{ if (ARRAYflag) {
|
{ if (ARRAYflag) {
|
||||||
*tp = construct_type(T_ARRAY, NULLTYPE);
|
*tp = construct_type(T_ARRAY, NULLTYPE);
|
||||||
(*tp)->arr_elem = df->df_type;
|
(*tp)->arr_elem = df->df_type;
|
||||||
|
@ -186,14 +185,19 @@ TypeDeclaration
|
||||||
struct def *df;
|
struct def *df;
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
}:
|
}:
|
||||||
IDENT { df = define(dot.TOK_IDF, CurrentScope, D_TYPE); }
|
IDENT { df = lookup(dot.TOK_IDF, CurrentScope);
|
||||||
|
if (!df) df = define( dot.TOK_IDF,
|
||||||
|
CurrentScope,
|
||||||
|
D_TYPE);
|
||||||
|
}
|
||||||
'=' type(&tp)
|
'=' type(&tp)
|
||||||
{ if (df->df_type) free_type(df->df_type);
|
{ if (df->df_type) free_type(df->df_type); /* ??? */
|
||||||
df->df_type = tp;
|
df->df_type = tp;
|
||||||
if (df->df_kind == D_HTYPE &&
|
if (df->df_kind == D_HIDDEN &&
|
||||||
tp->tp_fund != T_POINTER) {
|
tp->tp_fund != T_POINTER) {
|
||||||
error("opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
|
error("opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
|
||||||
}
|
}
|
||||||
|
df->df_kind = D_TYPE;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -215,7 +219,7 @@ SimpleType(struct type **ptp;)
|
||||||
{
|
{
|
||||||
struct def *df;
|
struct def *df;
|
||||||
} :
|
} :
|
||||||
qualident(D_TYPE|D_HTYPE|D_HIDDEN, &df, "type", (struct node **) 0)
|
qualident(D_ISTYPE, &df, "type", (struct node **) 0)
|
||||||
[
|
[
|
||||||
/* nothing */
|
/* nothing */
|
||||||
{ *ptp = df->df_type; }
|
{ *ptp = df->df_type; }
|
||||||
|
@ -237,22 +241,16 @@ SimpleType(struct type **ptp;)
|
||||||
enumeration(struct type **ptp;)
|
enumeration(struct type **ptp;)
|
||||||
{
|
{
|
||||||
struct node *EnumList;
|
struct node *EnumList;
|
||||||
|
register struct type *tp;
|
||||||
} :
|
} :
|
||||||
'(' IdentList(&EnumList) ')'
|
'(' IdentList(&EnumList) ')'
|
||||||
{
|
{
|
||||||
*ptp = standard_type(T_ENUMERATION, 1, (arith) 1);
|
*ptp = tp = standard_type(T_ENUMERATION, 1, (arith) 1);
|
||||||
EnterIdList(EnumList, D_ENUM, 0, *ptp,
|
EnterIdList(EnumList, D_ENUM, 0, tp,
|
||||||
CurrentScope, (arith *) 0);
|
CurrentScope, (arith *) 0);
|
||||||
FreeNode(EnumList);
|
FreeNode(EnumList);
|
||||||
if ((*ptp)->enm_ncst > 256) {
|
if (tp->enm_ncst > 256) {
|
||||||
if (word_size == 1) {
|
error("Too many enumeration literals");
|
||||||
error("Too many enumeration literals");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* ??? This is crummy */
|
|
||||||
(*ptp)->tp_size = word_size;
|
|
||||||
(*ptp)->tp_align = word_align;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -284,7 +282,8 @@ SubrangeType(struct type **ptp;)
|
||||||
'[' ConstExpression(&nd1)
|
'[' ConstExpression(&nd1)
|
||||||
UPTO ConstExpression(&nd2)
|
UPTO ConstExpression(&nd2)
|
||||||
']'
|
']'
|
||||||
{ *ptp = subr_type(nd1, nd2); }
|
{ *ptp = subr_type(nd1, nd2);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
ArrayType(struct type **ptp;)
|
ArrayType(struct type **ptp;)
|
||||||
|
@ -298,8 +297,8 @@ ArrayType(struct type **ptp;)
|
||||||
}
|
}
|
||||||
[
|
[
|
||||||
',' SimpleType(&tp)
|
',' SimpleType(&tp)
|
||||||
{ tp2 = tp2->arr_elem =
|
{ tp2->arr_elem = construct_type(T_ARRAY, tp);
|
||||||
construct_type(T_ARRAY, tp);
|
tp2 = tp2->arr_elem;
|
||||||
}
|
}
|
||||||
]* OF type(&tp)
|
]* OF type(&tp)
|
||||||
{ tp2->arr_elem = tp;
|
{ tp2->arr_elem = tp;
|
||||||
|
@ -365,8 +364,7 @@ FieldList(struct scope *scope; arith *cnt; int *palign;)
|
||||||
}
|
}
|
||||||
else id = nd->nd_IDF;
|
else id = nd->nd_IDF;
|
||||||
}
|
}
|
||||||
':' qualident(D_TYPE|D_HTYPE|D_HIDDEN,
|
':' qualident(D_ISTYPE, &df, "type", (struct node **) 0)
|
||||||
&df, "type", (struct node **) 0)
|
|
||||||
|
|
|
|
||||||
/* Old fashioned! the first qualident now represents
|
/* Old fashioned! the first qualident now represents
|
||||||
the type
|
the type
|
||||||
|
@ -374,10 +372,10 @@ 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, 0) &&
|
if (chk_designator(nd, 0, D_REFERRED) &&
|
||||||
(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_ISTYPE)))) {
|
||||||
node_error(nd, "type expected");
|
node_error(nd, "type expected");
|
||||||
}
|
}
|
||||||
else df = nd->nd_def;
|
else df = nd->nd_def;
|
||||||
|
@ -386,7 +384,7 @@ FieldList(struct scope *scope; arith *cnt; int *palign;)
|
||||||
]
|
]
|
||||||
|
|
|
|
||||||
/* Aha, third edition? */
|
/* Aha, third edition? */
|
||||||
':' qualident(D_TYPE|D_HTYPE|D_HIDDEN, &df, "type", (struct node **) 0)
|
':' qualident(D_ISTYPE, &df, "type", (struct node **) 0)
|
||||||
{ id = gen_anon_idf(); }
|
{ id = gen_anon_idf(); }
|
||||||
]
|
]
|
||||||
{ tp = df->df_type;
|
{ tp = df->df_type;
|
||||||
|
@ -489,7 +487,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|D_HIDDEN, &df, "type", (struct node **) 0)
|
qualident(D_ISTYPE, &df, "type", (struct node **) 0)
|
||||||
{
|
{
|
||||||
if (!df->df_type) {
|
if (!df->df_type) {
|
||||||
error("type \"%s\" not declared",
|
error("type \"%s\" not declared",
|
||||||
|
@ -555,7 +553,7 @@ FormalTypeList(struct paramlist **ppr; struct type **ptp;)
|
||||||
{ p->next = 0; }
|
{ p->next = 0; }
|
||||||
]?
|
]?
|
||||||
')'
|
')'
|
||||||
[ ':' qualident(D_TYPE|D_HTYPE|D_HIDDEN, &df, "type", (struct node **) 0)
|
[ ':' qualident(D_TYPE, &df, "type", (struct node **) 0)
|
||||||
{ *ptp = df->df_type; }
|
{ *ptp = df->df_type; }
|
||||||
]?
|
]?
|
||||||
;
|
;
|
||||||
|
|
|
@ -81,19 +81,21 @@ struct def { /* list of definitions for a name */
|
||||||
#define D_IMPORT 0x0080 /* an imported definition */
|
#define D_IMPORT 0x0080 /* an imported definition */
|
||||||
#define D_PROCHEAD 0x0100 /* a procedure heading in a definition module */
|
#define D_PROCHEAD 0x0100 /* a procedure heading in a definition module */
|
||||||
#define D_HIDDEN 0x0200 /* a hidden type */
|
#define D_HIDDEN 0x0200 /* a hidden type */
|
||||||
#define D_HTYPE 0x0400 /* definition of a hidden type seen */
|
|
||||||
#define D_FORWARD 0x0800 /* not yet defined */
|
#define D_FORWARD 0x0800 /* not yet defined */
|
||||||
#define D_UNDEF_IMPORT 0x1000 /* imported from an undefined name */
|
#define D_UNDEF_IMPORT 0x1000 /* imported from an undefined name */
|
||||||
#define D_FORWMODULE 0x2000 /* module must be declared later */
|
#define D_FORWMODULE 0x2000 /* module must be declared later */
|
||||||
#define D_ERROR 0x4000 /* a compiler generated definition for an
|
#define D_ERROR 0x4000 /* a compiler generated definition for an
|
||||||
undefined variable
|
undefined variable
|
||||||
*/
|
*/
|
||||||
|
#define D_ISTYPE (D_HIDDEN|D_TYPE)
|
||||||
|
#define is_type(dfx) ((dfx)->df_kind & D_ISTYPE)
|
||||||
char df_flags;
|
char df_flags;
|
||||||
#define D_ADDRESS 0x01 /* set if address was taken */
|
#define D_NOREG 0x01 /* set if it may not reside in a register */
|
||||||
#define D_USED 0x02 /* set if used */
|
#define D_USED 0x02 /* set if used */
|
||||||
#define D_DEFINED 0x04 /* set if it is assigned a value */
|
#define D_DEFINED 0x04 /* set if it is assigned a value */
|
||||||
#define D_VARPAR 0x08 /* set if it is a VAR parameter */
|
#define D_REFERRED 0x08 /* set if it is referred to */
|
||||||
#define D_VALPAR 0x10 /* set if it is a value parameter */
|
#define D_VARPAR 0x10 /* set if it is a VAR parameter */
|
||||||
|
#define D_VALPAR 0x20 /* set if it is a value parameter */
|
||||||
#define D_EXPORTED 0x40 /* set if exported */
|
#define D_EXPORTED 0x40 /* set if exported */
|
||||||
#define D_QEXPORTED 0x80 /* set if qualified exported */
|
#define D_QEXPORTED 0x80 /* set if qualified exported */
|
||||||
struct type *df_type;
|
struct type *df_type;
|
||||||
|
|
|
@ -18,6 +18,7 @@ static char *RcsId = "$Header$";
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
#include "Lpars.h"
|
||||||
|
|
||||||
struct def *h_def; /* Pointer to free list of def structures */
|
struct def *h_def; /* Pointer to free list of def structures */
|
||||||
|
|
||||||
|
@ -80,7 +81,7 @@ define(id, scope, kind)
|
||||||
switch(df->df_kind) {
|
switch(df->df_kind) {
|
||||||
case D_HIDDEN:
|
case D_HIDDEN:
|
||||||
if (kind == D_TYPE && !DefinitionModule) {
|
if (kind == D_TYPE && !DefinitionModule) {
|
||||||
df->df_kind = D_HTYPE;
|
df->df_kind = D_TYPE;
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -94,6 +95,7 @@ define(id, scope, kind)
|
||||||
FreeNode(df->for_node);
|
FreeNode(df->for_node);
|
||||||
df->mod_vis = df->for_vis;
|
df->mod_vis = df->for_vis;
|
||||||
df->df_kind = kind;
|
df->df_kind = kind;
|
||||||
|
DefInFront(df);
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -241,9 +243,9 @@ df->df_idf->id_text);
|
||||||
else if (df1 && df1->df_kind == D_HIDDEN) {
|
else if (df1 && df1->df_kind == D_HIDDEN) {
|
||||||
if (df->df_kind == D_TYPE) {
|
if (df->df_kind == D_TYPE) {
|
||||||
if (df->df_type->tp_fund != T_POINTER) {
|
if (df->df_type->tp_fund != T_POINTER) {
|
||||||
error("Opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
|
error("opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
|
||||||
}
|
}
|
||||||
df->df_kind = D_HTYPE;
|
df->df_kind = D_TYPE;
|
||||||
df1->df_kind = D_IMPORT;
|
df1->df_kind = D_IMPORT;
|
||||||
df1->imp_def = df;
|
df1->imp_def = df;
|
||||||
continue;
|
continue;
|
||||||
|
@ -436,8 +438,10 @@ DeclProc(type)
|
||||||
module. Create a def structure for it (if neccessary)
|
module. Create a def structure for it (if neccessary)
|
||||||
*/
|
*/
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
extern char *sprint(), *Malloc(), *strcpy();
|
|
||||||
static int nmcount = 0;
|
static int nmcount = 0;
|
||||||
|
extern char *Malloc();
|
||||||
|
extern char *strcpy();
|
||||||
|
extern char *sprint();
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
|
||||||
assert(type & (D_PROCEDURE | D_PROCHEAD));
|
assert(type & (D_PROCEDURE | D_PROCHEAD));
|
||||||
|
@ -462,6 +466,7 @@ DeclProc(type)
|
||||||
open_scope(OPENSCOPE);
|
open_scope(OPENSCOPE);
|
||||||
CurrentScope->sc_name = df->for_name;
|
CurrentScope->sc_name = df->for_name;
|
||||||
df->prc_vis = CurrVis;
|
df->prc_vis = CurrVis;
|
||||||
|
DefInFront(df);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
df = define(dot.TOK_IDF, CurrentScope, type);
|
df = define(dot.TOK_IDF, CurrentScope, type);
|
||||||
|
@ -492,6 +497,46 @@ InitProc(nd, df)
|
||||||
/* Keep it this way, or really create a procedure out of it??? */
|
/* Keep it this way, or really create a procedure out of it??? */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddModule(id)
|
||||||
|
struct idf *id;
|
||||||
|
{
|
||||||
|
/* Add the name of a module to the Module list. This list is
|
||||||
|
maintained to create the initialization routine of the
|
||||||
|
program/implementation module currently defined.
|
||||||
|
*/
|
||||||
|
static struct node *nd_end; /* to remember end of list */
|
||||||
|
register struct node *n;
|
||||||
|
extern struct node *Modules;
|
||||||
|
|
||||||
|
n = MkNode(Name, NULLNODE, NULLNODE, &dot);
|
||||||
|
n->nd_IDF = id;
|
||||||
|
n->nd_symb = IDENT;
|
||||||
|
if (nd_end) nd_end->next = n;
|
||||||
|
nd_end = n;
|
||||||
|
if (!Modules) Modules = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
DefInFront(df)
|
||||||
|
register struct def *df;
|
||||||
|
{
|
||||||
|
/* Put definition "df" in front of the list of definitions
|
||||||
|
in its scope.
|
||||||
|
This is neccessary because in some cases the order in this
|
||||||
|
list is important.
|
||||||
|
*/
|
||||||
|
register struct def *df1;
|
||||||
|
|
||||||
|
if (df->df_scope->sc_def != df) {
|
||||||
|
df1 = df->df_scope->sc_def;
|
||||||
|
while (df1 && df1->df_nextinscope != df) {
|
||||||
|
df1 = df1->df_nextinscope;
|
||||||
|
}
|
||||||
|
if (df1) df1->df_nextinscope = df->df_nextinscope;
|
||||||
|
df->df_nextinscope = df->df_scope->sc_def;
|
||||||
|
df->df_scope->sc_def = df;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PrDef(df)
|
PrDef(df)
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
|
|
|
@ -52,7 +52,9 @@ GetDefinitionModule(id)
|
||||||
We may have to read the definition module itself.
|
We may have to read the definition module itself.
|
||||||
*/
|
*/
|
||||||
struct def *df;
|
struct def *df;
|
||||||
|
static int level;
|
||||||
|
|
||||||
|
level++;
|
||||||
df = lookup(id, GlobalScope);
|
df = lookup(id, GlobalScope);
|
||||||
if (!df) {
|
if (!df) {
|
||||||
/* Read definition module. Make an exception for SYSTEM.
|
/* Read definition module. Make an exception for SYSTEM.
|
||||||
|
@ -63,10 +65,19 @@ GetDefinitionModule(id)
|
||||||
else {
|
else {
|
||||||
GetFile(id->id_text);
|
GetFile(id->id_text);
|
||||||
DefModule();
|
DefModule();
|
||||||
|
if (level == 1) {
|
||||||
|
/* The module is directly imported by the
|
||||||
|
currently defined module, so we have to
|
||||||
|
remember its name because we have to call
|
||||||
|
its initialization routine
|
||||||
|
*/
|
||||||
|
AddModule(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
df = lookup(id, GlobalScope);
|
df = lookup(id, GlobalScope);
|
||||||
}
|
}
|
||||||
assert(df != 0 && df->df_kind == D_MODULE);
|
assert(df != 0 && df->df_kind == D_MODULE);
|
||||||
|
level--;
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -232,6 +232,7 @@ CodeVarDesig(df, ds)
|
||||||
CodeConst(df->var_off, pointer_size);
|
CodeConst(df->var_off, pointer_size);
|
||||||
ds->dsg_kind = DSG_PLOADED;
|
ds->dsg_kind = DSG_PLOADED;
|
||||||
ds->dsg_offset = 0;
|
ds->dsg_offset = 0;
|
||||||
|
df->df_flags |= D_NOREG;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,6 +243,7 @@ CodeVarDesig(df, ds)
|
||||||
ds->dsg_name = df->var_name;
|
ds->dsg_name = df->var_name;
|
||||||
ds->dsg_offset = 0;
|
ds->dsg_offset = 0;
|
||||||
ds->dsg_kind = DSG_FIXED;
|
ds->dsg_kind = DSG_FIXED;
|
||||||
|
df->df_flags |= D_NOREG;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,6 +256,7 @@ CodeVarDesig(df, ds)
|
||||||
ds->dsg_name = &(sc->sc_name[1]);
|
ds->dsg_name = &(sc->sc_name[1]);
|
||||||
ds->dsg_offset = df->var_off;
|
ds->dsg_offset = df->var_off;
|
||||||
ds->dsg_kind = DSG_FIXED;
|
ds->dsg_kind = DSG_FIXED;
|
||||||
|
df->df_flags |= D_NOREG;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,6 +281,7 @@ CodeVarDesig(df, ds)
|
||||||
else C_lxl((arith) (proclevel - sc->sc_level));
|
else C_lxl((arith) (proclevel - sc->sc_level));
|
||||||
ds->dsg_kind = DSG_PLOADED;
|
ds->dsg_kind = DSG_PLOADED;
|
||||||
ds->dsg_offset = df->var_off;
|
ds->dsg_offset = df->var_off;
|
||||||
|
df->df_flags |= D_NOREG;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,6 +308,7 @@ CodeDesig(nd, ds)
|
||||||
case Def: {
|
case Def: {
|
||||||
register struct def *df = nd->nd_def;
|
register struct def *df = nd->nd_def;
|
||||||
|
|
||||||
|
df->df_flags |= D_USED;
|
||||||
switch(df->df_kind) {
|
switch(df->df_kind) {
|
||||||
case D_FIELD:
|
case D_FIELD:
|
||||||
CodeFieldDesig(df, ds);
|
CodeFieldDesig(df, ds);
|
||||||
|
@ -335,14 +340,16 @@ CodeDesig(nd, ds)
|
||||||
*ds = InitDesig;
|
*ds = InitDesig;
|
||||||
CodeExpr(nd->nd_right, ds, NO_LABEL, NO_LABEL);
|
CodeExpr(nd->nd_right, ds, NO_LABEL, NO_LABEL);
|
||||||
CodeValue(ds, nd->nd_right->nd_type->tp_size);
|
CodeValue(ds, nd->nd_right->nd_type->tp_size);
|
||||||
CodeCoercion(nd->nd_right->nd_type, int_type);
|
if (nd->nd_right->nd_type->tp_size > word_size) {
|
||||||
|
CodeCoercion(nd->nd_right->nd_type, int_type);
|
||||||
|
}
|
||||||
if (IsConformantArray(nd->nd_left->nd_type)) {
|
if (IsConformantArray(nd->nd_left->nd_type)) {
|
||||||
/* ??? */
|
/* ??? */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* load address of descriptor
|
/* load address of descriptor
|
||||||
*/
|
*/
|
||||||
/* ??? */
|
C_lae_dlb(nd->nd_left->nd_type->arr_descr, (arith) 0);
|
||||||
}
|
}
|
||||||
ds->dsg_kind = DSG_INDEXED;
|
ds->dsg_kind = DSG_INDEXED;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -67,27 +67,23 @@ EnterIdList(idlist, kind, flags, type, scope, addr)
|
||||||
int xalign = type->tp_align;
|
int xalign = type->tp_align;
|
||||||
|
|
||||||
if (xalign < word_align && kind != D_FIELD) {
|
if (xalign < word_align && kind != D_FIELD) {
|
||||||
|
/* variables are at least word aligned
|
||||||
|
*/
|
||||||
xalign = word_align;
|
xalign = word_align;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*addr >= 0) {
|
if (*addr >= 0) {
|
||||||
if (scope->sc_level) {
|
if (scope->sc_level && kind != D_FIELD) {
|
||||||
/* alignment of parameters is on
|
/* alignment of parameters is on
|
||||||
word boundaries. We cannot do any
|
word boundaries. We cannot do any
|
||||||
better, because we don't know the
|
better, because we don't know the
|
||||||
alignment of the stack pointer when
|
alignment of the stack pointer when
|
||||||
starting to push parameters
|
starting to push parameters
|
||||||
*/
|
*/
|
||||||
off = *addr;
|
xalign = word_align;
|
||||||
*addr = align(off, word_align);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* for global variables we can honour
|
|
||||||
the alignment requirements totally.
|
|
||||||
*/
|
|
||||||
off = align(*addr, xalign);
|
|
||||||
*addr = off + type->tp_size;
|
|
||||||
}
|
}
|
||||||
|
off = align(*addr, xalign);
|
||||||
|
*addr = off + type->tp_size;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
off = -align(-*addr-type->tp_size, xalign);
|
off = -align(-*addr-type->tp_size, xalign);
|
||||||
|
|
|
@ -25,6 +25,7 @@ number(struct node **p;)
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
} :
|
} :
|
||||||
[
|
[
|
||||||
|
%default
|
||||||
INTEGER { tp = numtype; }
|
INTEGER { tp = numtype; }
|
||||||
|
|
|
|
||||||
REAL { tp = real_type; }
|
REAL { tp = real_type; }
|
||||||
|
@ -46,7 +47,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, 0)) {
|
if (chk_designator(nd, 0, D_REFERRED)) {
|
||||||
if (nd->nd_class != Def) {
|
if (nd->nd_class != Def) {
|
||||||
node_error(nd, "%s expected", str);
|
node_error(nd, "%s expected", str);
|
||||||
}
|
}
|
||||||
|
@ -113,9 +114,7 @@ expression(struct node **pnd;)
|
||||||
SimpleExpression(pnd)
|
SimpleExpression(pnd)
|
||||||
[
|
[
|
||||||
/* relation */
|
/* relation */
|
||||||
[ '=' | '#' | UNEQUAL | '<' | LESSEQUAL | '>' |
|
[ '=' | '#' | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN ]
|
||||||
GREATEREQUAL | IN
|
|
||||||
]
|
|
||||||
{ *pnd = MkNode(Oper, *pnd, NULLNODE, &dot); }
|
{ *pnd = MkNode(Oper, *pnd, NULLNODE, &dot); }
|
||||||
SimpleExpression(&((*pnd)->nd_right))
|
SimpleExpression(&((*pnd)->nd_right))
|
||||||
]?
|
]?
|
||||||
|
@ -123,7 +122,7 @@ expression(struct node **pnd;)
|
||||||
|
|
||||||
/* Inline in expression
|
/* Inline in expression
|
||||||
relation:
|
relation:
|
||||||
'=' | '#' | UNEQUAL | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN
|
'=' | '#' | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN
|
||||||
;
|
;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -184,9 +183,7 @@ factor(struct node **p;)
|
||||||
]?
|
]?
|
||||||
|
|
|
|
||||||
bare_set(&nd)
|
bare_set(&nd)
|
||||||
{ nd->nd_left = *p;
|
{ nd->nd_left = *p; *p = nd; }
|
||||||
*p = nd;
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
|
|
|
|
||||||
bare_set(p)
|
bare_set(p)
|
||||||
|
@ -200,9 +197,9 @@ factor(struct node **p;)
|
||||||
|
|
||||||
tp = charc_type;
|
tp = charc_type;
|
||||||
i = *(dot.TOK_STR) & 0377;
|
i = *(dot.TOK_STR) & 0377;
|
||||||
free((char *) dot.tk_data.tk_str);
|
|
||||||
free(dot.TOK_STR);
|
free(dot.TOK_STR);
|
||||||
dot.TOK_INT = i;
|
free((char *) dot.tk_data.tk_str);
|
||||||
|
(*p)->nd_INT = i;
|
||||||
}
|
}
|
||||||
else tp = standard_type(T_STRING, 1, dot.TOK_SLE);
|
else tp = standard_type(T_STRING, 1, dot.TOK_SLE);
|
||||||
(*p)->nd_type = tp;
|
(*p)->nd_type = tp;
|
||||||
|
|
|
@ -23,13 +23,14 @@ static char *RcsId = "$Header$";
|
||||||
#include "tokenname.h"
|
#include "tokenname.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
|
||||||
|
int state; /* either IMPLEMENTATION or PROGRAM */
|
||||||
char options[128];
|
char options[128];
|
||||||
int DefinitionModule;
|
int DefinitionModule;
|
||||||
int SYSTEMModule = 0;
|
int SYSTEMModule = 0;
|
||||||
char *ProgName;
|
char *ProgName;
|
||||||
extern int err_occurred;
|
|
||||||
char *DEFPATH[NDIRS+1];
|
char *DEFPATH[NDIRS+1];
|
||||||
struct def *Defined;
|
struct def *Defined;
|
||||||
|
extern int err_occurred;
|
||||||
|
|
||||||
main(argc, argv)
|
main(argc, argv)
|
||||||
char *argv[];
|
char *argv[];
|
||||||
|
@ -93,6 +94,7 @@ Compile(src, dst)
|
||||||
C_magic();
|
C_magic();
|
||||||
C_ms_emx(word_size, pointer_size);
|
C_ms_emx(word_size, pointer_size);
|
||||||
CompUnit();
|
CompUnit();
|
||||||
|
close_scope(SC_REVERSE);
|
||||||
if (err_occurred) {
|
if (err_occurred) {
|
||||||
C_close();
|
C_close();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -17,3 +17,4 @@ extern struct def *Defined;
|
||||||
compilation
|
compilation
|
||||||
*/
|
*/
|
||||||
extern char *DEFPATH[]; /* search path for DEFINITION MODULE's */
|
extern char *DEFPATH[]; /* search path for DEFINITION MODULE's */
|
||||||
|
extern int state; /* either IMPLEMENTATION or PROGRAM */
|
||||||
|
|
|
@ -31,7 +31,7 @@ MkNode(class, left, right, token)
|
||||||
nd->nd_right = right;
|
nd->nd_right = right;
|
||||||
nd->nd_token = *token;
|
nd->nd_token = *token;
|
||||||
nd->nd_class = class;
|
nd->nd_class = class;
|
||||||
nd->nd_type = NULLTYPE;
|
nd->nd_type = error_type;
|
||||||
DO_DEBUG(4,(debug("Create node:"), PrNode(nd)));
|
DO_DEBUG(4,(debug("Create node:"), PrNode(nd)));
|
||||||
return nd;
|
return nd;
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,7 +231,7 @@ Semicolon:
|
||||||
{ warning("; expected"); }
|
{ warning("; expected"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
ProgramModule(int state;)
|
ProgramModule
|
||||||
{
|
{
|
||||||
struct idf *id;
|
struct idf *id;
|
||||||
struct def *GetDefinitionModule();
|
struct def *GetDefinitionModule();
|
||||||
|
@ -267,16 +267,15 @@ ProgramModule(int state;)
|
||||||
'.'
|
'.'
|
||||||
;
|
;
|
||||||
|
|
||||||
Module
|
Module:
|
||||||
{
|
|
||||||
int state = PROGRAM;
|
|
||||||
} :
|
|
||||||
DefinitionModule
|
DefinitionModule
|
||||||
|
|
|
|
||||||
[
|
[
|
||||||
IMPLEMENTATION { state = IMPLEMENTATION; }
|
IMPLEMENTATION { state = IMPLEMENTATION; }
|
||||||
]?
|
|
|
||||||
ProgramModule(state)
|
{ state = PROGRAM; }
|
||||||
|
]
|
||||||
|
ProgramModule
|
||||||
;
|
;
|
||||||
|
|
||||||
CompilationUnit:
|
CompilationUnit:
|
||||||
|
|
|
@ -166,7 +166,7 @@ rem_forwards(fo)
|
||||||
|
|
||||||
while (f = fo) {
|
while (f = fo) {
|
||||||
df = lookfor(&(f->fo_tok), CurrVis, 1);
|
df = lookfor(&(f->fo_tok), CurrVis, 1);
|
||||||
if (!(df->df_kind & (D_TYPE|D_HTYPE|D_ERROR))) {
|
if (!(df->df_kind & (D_TYPE|D_ERROR))) {
|
||||||
node_error(&(f->fo_tok), "identifier \"%s\" not a type",
|
node_error(&(f->fo_tok), "identifier \"%s\" not a type",
|
||||||
df->df_idf->id_text);
|
df->df_idf->id_text);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ struct tokenname tkspec[] = { /* the names of the special tokens */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tokenname tkcomp[] = { /* names of the composite tokens */
|
struct tokenname tkcomp[] = { /* names of the composite tokens */
|
||||||
{UNEQUAL, "<>"},
|
|
||||||
{LESSEQUAL, "<="},
|
{LESSEQUAL, "<="},
|
||||||
{GREATEREQUAL, ">="},
|
{GREATEREQUAL, ">="},
|
||||||
{UPTO, ".."},
|
{UPTO, ".."},
|
||||||
|
|
|
@ -16,7 +16,7 @@ struct enume {
|
||||||
label en_rck; /* Label of range check descriptor */
|
label en_rck; /* Label of range check descriptor */
|
||||||
#define enm_enums tp_value.tp_enum.en_enums
|
#define enm_enums tp_value.tp_enum.en_enums
|
||||||
#define enm_ncst tp_value.tp_enum.en_ncst
|
#define enm_ncst tp_value.tp_enum.en_ncst
|
||||||
#define enm_rck tp_value.tp_enum.enm_rck
|
#define enm_rck tp_value.tp_enum.en_rck
|
||||||
};
|
};
|
||||||
|
|
||||||
struct subrange {
|
struct subrange {
|
||||||
|
@ -68,9 +68,10 @@ struct type {
|
||||||
#define T_ARRAY 0x2000
|
#define T_ARRAY 0x2000
|
||||||
#define T_STRING 0x4000
|
#define T_STRING 0x4000
|
||||||
#define T_INTORCARD (T_INTEGER|T_CARDINAL)
|
#define T_INTORCARD (T_INTEGER|T_CARDINAL)
|
||||||
#define T_DISCRETE (T_ENUMERATION|T_INTORCARD|T_CHAR)
|
|
||||||
#define T_NUMERIC (T_INTORCARD|T_REAL)
|
#define T_NUMERIC (T_INTORCARD|T_REAL)
|
||||||
#define T_INDEX (T_ENUMERATION|T_CHAR|T_SUBRANGE)
|
#define T_INDEX (T_ENUMERATION|T_CHAR|T_SUBRANGE)
|
||||||
|
#define T_DISCRETE (T_INDEX|T_INTORCARD)
|
||||||
|
#define T_PRCRESULT (T_DISCRETE|T_REAL|T_POINTER|T_WORD)
|
||||||
int tp_align; /* alignment requirement of this type */
|
int tp_align; /* alignment requirement of this type */
|
||||||
arith tp_size; /* size of this type */
|
arith tp_size; /* size of this type */
|
||||||
union {
|
union {
|
||||||
|
@ -131,3 +132,7 @@ struct type
|
||||||
#define NULLTYPE ((struct type *) 0)
|
#define NULLTYPE ((struct type *) 0)
|
||||||
|
|
||||||
#define IsConformantArray(tpx) ((tpx)->tp_fund == T_ARRAY && (tpx)->next == 0)
|
#define IsConformantArray(tpx) ((tpx)->tp_fund == T_ARRAY && (tpx)->next == 0)
|
||||||
|
#define bounded(tpx) ((tpx)->tp_fund & T_INDEX)
|
||||||
|
#define complex(tpx) ((tpx)->tp_fund & (T_RECORD|T_ARRAY))
|
||||||
|
#define returntype(tpx) (((tpx)->tp_fund & T_PRCRESULT) ||\
|
||||||
|
((tpx)->tp_fund == T_SET && (tpx)->tp_size <= dword_size))
|
||||||
|
|
|
@ -61,6 +61,8 @@ struct paramlist *h_paramlist;
|
||||||
|
|
||||||
struct type *h_type;
|
struct type *h_type;
|
||||||
|
|
||||||
|
extern label data_label();
|
||||||
|
|
||||||
struct type *
|
struct type *
|
||||||
create_type(fund)
|
create_type(fund)
|
||||||
register int fund;
|
register int fund;
|
||||||
|
@ -117,7 +119,7 @@ construct_type(fund, tp)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
crash("funny type constructor");
|
||||||
}
|
}
|
||||||
|
|
||||||
return dtp;
|
return dtp;
|
||||||
|
@ -325,6 +327,52 @@ subr_type(lb, ub)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label
|
||||||
|
getrck(tp)
|
||||||
|
register struct type *tp;
|
||||||
|
{
|
||||||
|
/* generate a range check descriptor for type "tp" when
|
||||||
|
neccessary. Return its label
|
||||||
|
*/
|
||||||
|
|
||||||
|
assert(bounded(tp));
|
||||||
|
|
||||||
|
if (tp->tp_fund == T_SUBRANGE) {
|
||||||
|
if (tp->sub_rck == (label) 0) {
|
||||||
|
tp->sub_rck = data_label();
|
||||||
|
C_df_dlb(tp->sub_rck);
|
||||||
|
C_rom_cst(tp->sub_lb);
|
||||||
|
C_rom_cst(tp->sub_ub);
|
||||||
|
}
|
||||||
|
return tp->sub_rck;
|
||||||
|
}
|
||||||
|
if (tp->enm_rck == (label) 0) {
|
||||||
|
tp->enm_rck = data_label();
|
||||||
|
C_df_dlb(tp->enm_rck);
|
||||||
|
C_rom_cst((arith) 0);
|
||||||
|
C_rom_cst((arith) (tp->enm_ncst - 1));
|
||||||
|
}
|
||||||
|
return tp->enm_rck;
|
||||||
|
}
|
||||||
|
|
||||||
|
getbounds(tp, plo, phi)
|
||||||
|
register struct type *tp;
|
||||||
|
arith *plo, *phi;
|
||||||
|
{
|
||||||
|
/* Get the bounds of a bounded type
|
||||||
|
*/
|
||||||
|
|
||||||
|
assert(bounded(tp));
|
||||||
|
|
||||||
|
if (tp->tp_fund == T_SUBRANGE) {
|
||||||
|
*plo = tp->sub_lb;
|
||||||
|
*phi = tp->sub_ub;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*plo = 0;
|
||||||
|
*phi = tp->enm_ncst - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
struct type *
|
struct type *
|
||||||
set_type(tp)
|
set_type(tp)
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
|
@ -385,18 +433,30 @@ ArraySizes(tp)
|
||||||
|
|
||||||
/* find out HIGH, LOW and size of ARRAY
|
/* find out HIGH, LOW and size of ARRAY
|
||||||
*/
|
*/
|
||||||
|
tp->arr_descr = data_label();
|
||||||
|
C_df_dlb(tp->arr_descr);
|
||||||
|
|
||||||
switch(index_type->tp_fund) {
|
switch(index_type->tp_fund) {
|
||||||
case T_SUBRANGE:
|
case T_SUBRANGE:
|
||||||
tp->tp_size = elem_size *
|
tp->tp_size = elem_size *
|
||||||
(index_type->sub_ub - index_type->sub_lb + 1);
|
(index_type->sub_ub - index_type->sub_lb + 1);
|
||||||
|
C_rom_cst(index_type->sub_lb);
|
||||||
|
C_rom_cst(index_type->sub_ub - index_type->sub_lb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_CHAR:
|
case T_CHAR:
|
||||||
case T_ENUMERATION:
|
case T_ENUMERATION:
|
||||||
tp->tp_size = elem_size * index_type->enm_ncst;
|
tp->tp_size = elem_size * index_type->enm_ncst;
|
||||||
|
C_rom_cst((arith) 0);
|
||||||
|
C_rom_cst((arith) (index_type->enm_ncst - 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
crash("Funny index type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
C_rom_cst(elem_size);
|
||||||
|
|
||||||
/* ??? overflow checking ???
|
/* ??? overflow checking ???
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,14 +23,17 @@ static char *RcsId = "$Header$";
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
#include "desig.h"
|
#include "desig.h"
|
||||||
#include "f_info.h"
|
#include "f_info.h"
|
||||||
|
#include "idf.h"
|
||||||
|
|
||||||
extern arith align();
|
extern arith align();
|
||||||
extern arith NewPtr();
|
extern arith NewPtr();
|
||||||
|
extern arith NewInt();
|
||||||
extern int proclevel;
|
extern int proclevel;
|
||||||
static label instructionlabel;
|
static label instructionlabel;
|
||||||
static char return_expr_occurred;
|
static char return_expr_occurred;
|
||||||
static struct type *func_type;
|
static struct type *func_type;
|
||||||
struct withdesig *WithDesigs;
|
struct withdesig *WithDesigs;
|
||||||
|
struct node *Modules;
|
||||||
|
|
||||||
label
|
label
|
||||||
text_label()
|
text_label()
|
||||||
|
@ -88,7 +91,9 @@ WalkModule(module)
|
||||||
/* WHY ??? because we generated an INA for it ??? */
|
/* WHY ??? because we generated an INA for it ??? */
|
||||||
|
|
||||||
C_df_dnam(&(sc->sc_name[1]));
|
C_df_dnam(&(sc->sc_name[1]));
|
||||||
|
size = align(size, word_align);
|
||||||
C_bss_cst(size, (arith) 0, 0);
|
C_bss_cst(size, (arith) 0, 0);
|
||||||
|
C_exp(sc->sc_name);
|
||||||
}
|
}
|
||||||
else if (CurrVis == Defined->mod_vis) {
|
else if (CurrVis == Defined->mod_vis) {
|
||||||
/* This module is the module currently being compiled.
|
/* This module is the module currently being compiled.
|
||||||
|
@ -98,10 +103,14 @@ WalkModule(module)
|
||||||
while (df) {
|
while (df) {
|
||||||
if (df->df_kind == D_VARIABLE) {
|
if (df->df_kind == D_VARIABLE) {
|
||||||
C_df_dnam(df->var_name);
|
C_df_dnam(df->var_name);
|
||||||
C_bss_cst(df->df_type->tp_size, (arith) 0, 0);
|
C_bss_cst(
|
||||||
|
align(df->df_type->tp_size, word_align),
|
||||||
|
(arith) 0, 0);
|
||||||
}
|
}
|
||||||
df = df->df_nextinscope;
|
df = df->df_nextinscope;
|
||||||
}
|
}
|
||||||
|
if (state == PROGRAM) C_exp("main");
|
||||||
|
else C_exp(sc->sc_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now, walk through it's local definitions
|
/* Now, walk through it's local definitions
|
||||||
|
@ -115,26 +124,55 @@ WalkModule(module)
|
||||||
sc->sc_off = 0;
|
sc->sc_off = 0;
|
||||||
instructionlabel = 2;
|
instructionlabel = 2;
|
||||||
func_type = 0;
|
func_type = 0;
|
||||||
C_pro_narg(sc->sc_name);
|
C_pro_narg(state == PROGRAM ? "main" : sc->sc_name);
|
||||||
DoProfil();
|
DoProfil();
|
||||||
|
if (CurrVis == Defined->mod_vis) {
|
||||||
|
/* Body of implementation or program module.
|
||||||
|
Call initialization routines of imported modules.
|
||||||
|
Also prevent recursive calls of this one.
|
||||||
|
*/
|
||||||
|
label l1 = data_label(), l2 = text_label();
|
||||||
|
struct node *nd;
|
||||||
|
|
||||||
|
/* we don't actually prevent recursive calls, but do nothing
|
||||||
|
if called recursively
|
||||||
|
*/
|
||||||
|
C_df_dlb(l1);
|
||||||
|
C_bss_cst(word_size, (arith) 0, 1);
|
||||||
|
C_loe_dlb(l1, (arith) 0);
|
||||||
|
C_zeq(l2);
|
||||||
|
C_ret((arith) 0);
|
||||||
|
C_df_ilb(l2);
|
||||||
|
C_loc((arith) 1);
|
||||||
|
C_ste_dlb(l1, (arith) 0);
|
||||||
|
|
||||||
|
nd = Modules;
|
||||||
|
while (nd) {
|
||||||
|
C_cal(nd->nd_IDF->id_text);
|
||||||
|
nd = nd->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
MkCalls(sc->sc_def);
|
MkCalls(sc->sc_def);
|
||||||
|
proclevel++;
|
||||||
WalkNode(module->mod_body, (label) 0);
|
WalkNode(module->mod_body, (label) 0);
|
||||||
C_df_ilb((label) 1);
|
C_df_ilb((label) 1);
|
||||||
C_ret(0);
|
C_ret((arith) 0);
|
||||||
C_end(-sc->sc_off);
|
C_end(-sc->sc_off);
|
||||||
|
proclevel--;
|
||||||
TmpClose();
|
TmpClose();
|
||||||
|
|
||||||
CurrVis = vis;
|
CurrVis = vis;
|
||||||
}
|
}
|
||||||
|
|
||||||
WalkProcedure(procedure)
|
WalkProcedure(procedure)
|
||||||
struct def *procedure;
|
register struct def *procedure;
|
||||||
{
|
{
|
||||||
/* Walk through the definition of a procedure and all its
|
/* Walk through the definition of a procedure and all its
|
||||||
local definitions
|
local definitions
|
||||||
*/
|
*/
|
||||||
struct scopelist *vis = CurrVis;
|
struct scopelist *vis = CurrVis;
|
||||||
register struct scope *sc;
|
register struct scope *sc;
|
||||||
|
register struct type *res_type;
|
||||||
|
|
||||||
proclevel++;
|
proclevel++;
|
||||||
CurrVis = procedure->prc_vis;
|
CurrVis = procedure->prc_vis;
|
||||||
|
@ -152,16 +190,19 @@ WalkProcedure(procedure)
|
||||||
MkCalls(sc->sc_def);
|
MkCalls(sc->sc_def);
|
||||||
return_expr_occurred = 0;
|
return_expr_occurred = 0;
|
||||||
instructionlabel = 2;
|
instructionlabel = 2;
|
||||||
func_type = procedure->df_type->next;
|
func_type = res_type = procedure->df_type->next;
|
||||||
|
if (! returntype(res_type)) {
|
||||||
|
node_error(procedure->prc_body, "illegal result type");
|
||||||
|
}
|
||||||
WalkNode(procedure->prc_body, (label) 0);
|
WalkNode(procedure->prc_body, (label) 0);
|
||||||
C_df_ilb((label) 1);
|
C_df_ilb((label) 1);
|
||||||
if (func_type) {
|
if (res_type) {
|
||||||
if (! return_expr_occurred) {
|
if (! return_expr_occurred) {
|
||||||
node_error(procedure->prc_body,"function procedure does not return a value");
|
node_error(procedure->prc_body,"function procedure does not return a value");
|
||||||
}
|
}
|
||||||
C_ret((int) align(func_type->tp_size, word_align));
|
C_ret(align(res_type->tp_size, word_align));
|
||||||
}
|
}
|
||||||
else C_ret(0);
|
else C_ret((arith) 0);
|
||||||
C_end(-sc->sc_off);
|
C_end(-sc->sc_off);
|
||||||
TmpClose();
|
TmpClose();
|
||||||
CurrVis = vis;
|
CurrVis = vis;
|
||||||
|
@ -195,6 +236,7 @@ MkCalls(df)
|
||||||
if (df->df_kind == D_MODULE) {
|
if (df->df_kind == D_MODULE) {
|
||||||
C_lxl((arith) 0);
|
C_lxl((arith) 0);
|
||||||
C_cal(df->mod_vis->sc_scope->sc_name);
|
C_cal(df->mod_vis->sc_scope->sc_name);
|
||||||
|
C_asp(pointer_size);
|
||||||
}
|
}
|
||||||
df = df->df_nextinscope;
|
df = df->df_nextinscope;
|
||||||
}
|
}
|
||||||
|
@ -246,20 +288,8 @@ WalkStat(nd, lab)
|
||||||
assert(nd->nd_class == Stat);
|
assert(nd->nd_class == Stat);
|
||||||
|
|
||||||
switch(nd->nd_symb) {
|
switch(nd->nd_symb) {
|
||||||
case BECOMES: {
|
case BECOMES:
|
||||||
struct desig ds;
|
DoAssign(nd, left, right, 0);
|
||||||
|
|
||||||
WalkExpr(right, NO_LABEL, NO_LABEL);
|
|
||||||
ds = Desig;
|
|
||||||
WalkDesignator(left); /* May we do it in this order??? */
|
|
||||||
|
|
||||||
if (! TstAssCompat(left->nd_type, right->nd_type)) {
|
|
||||||
node_error(nd, "type incompatibility in assignment");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
CodeAssign(nd, &ds, pds);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IF:
|
case IF:
|
||||||
|
@ -327,8 +357,61 @@ WalkStat(nd, lab)
|
||||||
}
|
}
|
||||||
|
|
||||||
case FOR:
|
case FOR:
|
||||||
/* ??? */
|
{
|
||||||
WalkNode(right, lab);
|
arith tmp = 0;
|
||||||
|
struct node *fnd;
|
||||||
|
label l1 = instructionlabel++;
|
||||||
|
label l2 = instructionlabel++;
|
||||||
|
arith incr = 1;
|
||||||
|
arith size;
|
||||||
|
|
||||||
|
assert(left->nd_symb == TO);
|
||||||
|
assert(left->nd_left->nd_symb == BECOMES);
|
||||||
|
|
||||||
|
DoAssign(left->nd_left,
|
||||||
|
left->nd_left->nd_left,
|
||||||
|
left->nd_left->nd_right, 1);
|
||||||
|
fnd = left->nd_right;
|
||||||
|
if (fnd->nd_symb == BY) {
|
||||||
|
incr = fnd->nd_left->nd_INT;
|
||||||
|
fnd = fnd->nd_right;
|
||||||
|
}
|
||||||
|
if (! chk_expr(fnd)) return;
|
||||||
|
size = fnd->nd_type->tp_size;
|
||||||
|
if (fnd->nd_class != Value) {
|
||||||
|
*pds = InitDesig;
|
||||||
|
CodeExpr(fnd, pds, NO_LABEL, NO_LABEL);
|
||||||
|
CodeValue(pds, size);
|
||||||
|
tmp = NewInt();
|
||||||
|
C_stl(tmp);
|
||||||
|
}
|
||||||
|
if (!TstCompat(left->nd_left->nd_left->nd_type,
|
||||||
|
fnd->nd_type)) {
|
||||||
|
node_error(fnd, "type incompatibility in limit of FOR loop");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
C_bra(l1);
|
||||||
|
C_df_ilb(l2);
|
||||||
|
WalkNode(right, lab);
|
||||||
|
*pds = InitDesig;
|
||||||
|
C_loc(incr);
|
||||||
|
CodeDesig(left->nd_left->nd_left, pds);
|
||||||
|
CodeValue(pds, size);
|
||||||
|
C_adi(int_size);
|
||||||
|
*pds = InitDesig;
|
||||||
|
CodeDesig(left->nd_left->nd_left, pds);
|
||||||
|
CodeStore(pds, size);
|
||||||
|
C_df_ilb(l1);
|
||||||
|
*pds = InitDesig;
|
||||||
|
CodeDesig(left->nd_left->nd_left, pds);
|
||||||
|
CodeValue(pds, size);
|
||||||
|
if (tmp) C_lol(tmp); else C_loc(fnd->nd_INT);
|
||||||
|
if (incr > 0) {
|
||||||
|
C_ble(l2);
|
||||||
|
}
|
||||||
|
else C_bge(l2);
|
||||||
|
if (tmp) FreeInt(tmp);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WITH:
|
case WITH:
|
||||||
|
@ -358,7 +441,7 @@ WalkStat(nd, lab)
|
||||||
pds->dsg_kind = DSG_PFIXED;
|
pds->dsg_kind = DSG_PFIXED;
|
||||||
/* the record is indirectly available */
|
/* the record is indirectly available */
|
||||||
}
|
}
|
||||||
wds.w_desig = Desig;
|
wds.w_desig = *pds;
|
||||||
link.sc_scope = wds.w_scope;
|
link.sc_scope = wds.w_scope;
|
||||||
link.next = CurrVis;
|
link.next = CurrVis;
|
||||||
CurrVis = &link;
|
CurrVis = &link;
|
||||||
|
@ -432,10 +515,47 @@ WalkDesignator(nd)
|
||||||
|
|
||||||
DO_DEBUG(1, (DumpTree(nd), print("\n")));
|
DO_DEBUG(1, (DumpTree(nd), print("\n")));
|
||||||
|
|
||||||
if (! chk_designator(nd, DESIGNATOR|VARIABLE)) return;
|
if (! chk_designator(nd, DESIGNATOR|VARIABLE, D_DEFINED)) return;
|
||||||
|
|
||||||
Desig = InitDesig;
|
Desig = InitDesig;
|
||||||
CodeDesig(nd, &Desig);
|
CodeDesig(nd, &Desig);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DoAssign(nd, left, right, forloopass)
|
||||||
|
struct node *nd;
|
||||||
|
register struct node *left, *right;
|
||||||
|
{
|
||||||
|
/* May we do it in this order (expression first) ??? */
|
||||||
|
struct desig ds;
|
||||||
|
|
||||||
|
WalkExpr(right, NO_LABEL, NO_LABEL);
|
||||||
|
if (! chk_designator(left, DESIGNATOR|VARIABLE, D_DEFINED)) return;
|
||||||
|
|
||||||
|
if (forloopass) {
|
||||||
|
if (! TstCompat(left->nd_type, right->nd_type)) {
|
||||||
|
node_error(nd, "type incompatibility in FOR loop");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Test if the left hand side may be a for loop variable ??? */
|
||||||
|
}
|
||||||
|
else if (! TstAssCompat(left->nd_type, right->nd_type)) {
|
||||||
|
node_error(nd, "type incompatibility in assignment");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (complex(right->nd_type)) {
|
||||||
|
CodeAddress(&Desig);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CodeValue(&Desig, right->nd_type->tp_size);
|
||||||
|
CheckAssign(left->nd_type, right->nd_type);
|
||||||
|
}
|
||||||
|
ds = Desig;
|
||||||
|
Desig = InitDesig;
|
||||||
|
CodeDesig(left, &Desig);
|
||||||
|
|
||||||
|
CodeAssign(nd, &ds, &Desig);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
Loading…
Add table
Reference in a new issue