2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
5 * Author: Ceriel J.H. Jacobs
8 /* E X P R E S S I O N C H E C K I N G */
10 /* $Id: chk_expr.c,v 1.103 1996/08/14 07:42:25 ceriel Exp $ */
12 /* Check expressions, and try to evaluate them as far as possible.
22 #include "strict3rd.h"
30 #include "standards.h"
37 extern char *symbol2str();
38 extern char *sprint();
39 extern arith flt_flt2arith();
42 df_error(nd, mess, edf)
43 t_node *nd; /* node on which error occurred */
44 char *mess; /* error message */
45 register t_def *edf; /* do we have a name? */
48 if (edf->df_kind != D_ERROR) {
49 node_error(nd,"\"%s\": %s", edf->df_idf->id_text, mess);
52 else node_error(nd, mess);
59 /* Make a coercion from the node indicated by *pnd to the
60 type indicated by tp. If the node indicated by *pnd
61 is constant, try to do the coercion compile-time.
62 Coercions are inserted in the tree when
63 - the expression is not constant or
64 - we are in the second pass and the coercion might cause
67 register t_node *nd = *pnd;
68 register t_type *nd_tp = nd->nd_type;
73 if (nd_tp == tp || nd_tp->tp_fund == T_STRING /* Why ??? */) return;
74 nd_tp = BaseType(nd_tp);
75 if (nd->nd_class == Value && nd->nd_type != error_type && tp != error_type) {
76 if (nd_tp->tp_fund == T_REAL) {
82 op = flt_flt2arith(&nd->nd_RVAL, 1);
85 op = flt_flt2arith(&nd->nd_RVAL, 0);
91 if (flt_status == FLT_OVFL) {
94 if (!wmess || pass_1) {
95 if (nd->nd_RSTR) free(nd->nd_RSTR);
96 free_real(nd->nd_REAL);
98 nd->nd_symb = INTEGER;
101 switch(tp->tp_fund) {
103 struct real *p = new_real();
104 switch(BaseType(nd_tp)->tp_fund) {
107 flt_arith2flt(nd->nd_INT, &p->r_val, 1);
110 flt_arith2flt(nd->nd_INT, &p->r_val, 0);
122 if (! in_range(nd->nd_INT, tp)) {
123 wmess = "range bound";
129 if ((nd_tp->tp_fund == T_INTEGER && nd->nd_INT < 0) ||
130 (nd->nd_INT & ~full_mask[(int)(tp->tp_size)])) {
131 wmess = "conversion";
135 if (! chk_bounds(nd->nd_INT,
136 max_int[(int)(tp->tp_size)],
138 ! chk_bounds(min_int[(int)(tp->tp_size)],
141 wmess = "conversion";
146 node_warning(nd, W_ORDINARY, "might cause %s error", wmess);
148 if (!wmess || pass_1) {
155 nd->nd_symb = COERCION;
157 nd->nd_LEFT = NULLNODE;
159 nd->nd_lineno = (*pnd)->nd_lineno;
164 ChkVariable(expp, flags)
165 register t_node **expp;
167 /* Check that "expp" indicates an item that can be
170 register t_node *exp;
172 if (! ChkDesig(expp, flags)) return 0;
175 if (exp->nd_class == Def &&
176 ! (exp->nd_def->df_kind & (D_FIELD|D_VARIABLE))) {
177 df_error(exp, "variable expected", exp->nd_def);
187 /* Check an application of the '^' operator.
188 The operand must be a variable of a pointer type.
191 register t_node *exp = *expp;
193 assert(exp->nd_class == Arrow);
194 assert(exp->nd_symb == '^');
196 exp->nd_type = error_type;
198 if (! ChkVariable(&(exp->nd_RIGHT), D_USED)) return 0;
200 tp = exp->nd_RIGHT->nd_type;
202 if (tp->tp_fund != T_POINTER) {
203 node_error(exp, "\"^\": illegal operand type");
207 if ((tp = RemoveEqual(PointedtoType(tp))) == 0) tp = error_type;
216 /* Check an array selection.
217 The left hand side must be a variable of an array type,
218 and the right hand side must be an expression that is
219 assignment compatible with the array-index.
222 register t_type *tpl;
223 register t_node *exp = *expp;
225 assert(exp->nd_class == Arrsel);
226 assert(exp->nd_symb == '[' || exp->nd_symb == ',');
228 exp->nd_type = error_type;
230 if (! (ChkVariable(&(exp->nd_LEFT), flags) &
231 ChkExpression(&(exp->nd_RIGHT)))) {
232 /* Bitwise and, because we want them both evaluated.
237 tpl = exp->nd_LEFT->nd_type;
239 if (tpl->tp_fund != T_ARRAY) {
240 node_error(exp, "not indexing an ARRAY type");
243 exp->nd_type = RemoveEqual(tpl->arr_elem);
245 /* Type of the index must be assignment compatible with
246 the index type of the array (Def 8.1).
247 However, the index type of a conformant array is not specified.
248 In our implementation it is CARDINAL.
250 return ChkAssCompat(&(exp->nd_RIGHT),
251 BaseType(IndexType(tpl)),
261 switch((*expp)->nd_symb) {
275 ChkSelOrName(expp, flags)
278 /* Check either an ID or a construction of the form
282 register t_node *exp = *expp;
284 exp->nd_type = error_type;
286 if (exp->nd_class == Name) {
287 df = lookfor(exp, CurrVis, 1, flags);
290 exp->nd_lineno = (*expp)->nd_lineno;
291 exp->nd_type = RemoveEqual(df->df_type);
295 else if (exp->nd_class == Select) {
296 /* A selection from a record or a module.
297 Modules also have a record type.
299 register t_node *left;
301 assert(exp->nd_symb == '.');
303 if (! ChkDesig(&(exp->nd_NEXT), flags)) return 0;
306 if (left->nd_class==Def &&
307 (left->nd_type->tp_fund != T_RECORD ||
308 !(left->nd_def->df_kind & (D_MODULE|D_VARIABLE|D_FIELD))
311 df_error(left, "illegal selection", left->nd_def);
314 if (left->nd_type->tp_fund != T_RECORD) {
315 node_error(left, "illegal selection");
319 if (!(df = lookup(exp->nd_IDF, left->nd_type->rec_scope, D_IMPORTED, flags))) {
320 id_not_declared(exp);
325 exp->nd_type = RemoveEqual(df->df_type);
326 exp->nd_lineno = (*expp)->nd_lineno;
329 if (!(df->df_flags & (D_EXPORTED|D_QEXPORTED))) {
330 /* Fields of a record are always D_QEXPORTED,
333 df_error(exp, "not exported from qualifying module", df);
336 if (!(left->nd_class == Def &&
337 left->nd_def->df_kind == D_MODULE)) {
344 assert(exp->nd_class == Def);
346 return exp->nd_def->df_kind != D_ERROR;
353 /* Check either an ID or an ID.ID [.ID]* occurring in an
357 register t_node *exp;
359 if (! ChkSelOrName(expp, D_USED)) return 0;
365 if (df->df_kind & (D_ENUM | D_CONST)) {
366 /* Replace an enum-literal or a CONST identifier by its value.
368 exp = getnode(Value);
369 exp->nd_type = df->df_type;
370 if (df->df_kind == D_ENUM) {
371 exp->nd_INT = df->enm_val;
372 exp->nd_symb = INTEGER;
375 assert(df->df_kind == D_CONST);
376 exp->nd_token = df->con_const;
378 exp->nd_lineno = (*expp)->nd_lineno;
379 if (df->df_type->tp_fund == T_SET) {
381 inc_refcount(exp->nd_set);
383 else if (df->df_type->tp_fund == T_PROCEDURE) {
384 /* for procedure constants */
387 if (df->df_type->tp_fund == T_REAL) {
388 struct real *p = exp->nd_REAL;
390 exp->nd_REAL = new_real();
391 *(exp->nd_REAL) = *p;
393 p->r_real = Salloc(p->r_real,
394 (unsigned)(strlen(p->r_real)+1));
401 if (!(df->df_kind & D_VALUE)) {
402 df_error(exp, "value expected", df);
406 if (df->df_kind == D_PROCEDURE) {
407 /* Check that this procedure is one that we may take the
410 if (df->df_type == std_type || df->df_scope->sc_level > 0) {
411 /* Address of standard or nested procedure
415 "standard or local procedures may not be assigned");
425 register t_node **expp;
429 return ChkExpression(expp) && ChkCompat(expp, tp, "set element");
433 ChkElement(expp, tp, set)
438 /* Check elements of a set. This routine may call itself
440 Also try to compute the set!
442 register t_node *expr = *expp;
443 t_type *el_type = ElementType(tp);
444 register unsigned int i;
447 if (expr->nd_class == Link && expr->nd_symb == UPTO) {
448 /* { ... , expr1 .. expr2, ... }
449 First check expr1 and expr2, and try to compute them.
451 if (! (ChkEl(&(expr->nd_LEFT), el_type) &
452 ChkEl(&(expr->nd_RIGHT), el_type))) {
456 if (!(expr->nd_LEFT->nd_class == Value &&
457 expr->nd_RIGHT->nd_class == Value)) {
460 /* We have a constant range. Put all elements in the
464 low = expr->nd_LEFT->nd_INT;
465 high = expr->nd_RIGHT->nd_INT;
468 if (! ChkEl(expp, el_type)) return 0;
470 if (expr->nd_class != Value) {
473 low = high = expr->nd_INT;
475 if (! chk_bounds(low, high, BaseType(el_type)->tp_fund)) {
476 node_error(expr, "lower bound exceeds upper bound in range");
480 if (! in_range(low, el_type) || ! in_range(high, el_type)) {
481 node_error(expr, "set element out of range");
487 for (i=(unsigned)low; i<= (unsigned)high; i++) {
488 set[i/wrd_bits] |= (1<<(i%wrd_bits));
499 register arith *s, *t;
501 s = t = (arith *) Malloc(size);
503 size /= sizeof(arith);
504 while (size--) *t++ = 0;
513 if (refcount(s) <= 0) {
514 assert(refcount(s) == 0);
515 free((char *) (s-1));
523 /* Check the legality of a SET aggregate, and try to evaluate it
524 compile time. Unfortunately this is all rather complicated.
527 register t_node *exp = *expp;
531 int SetIsConstant = 1;
533 assert(exp->nd_symb == SET);
535 *expp = getnode(Set);
536 (*expp)->nd_type = error_type;
537 (*expp)->nd_lineno = exp->nd_lineno;
539 /* First determine the type of the set
542 /* A type was given. Check it out
544 if (! ChkDesig(&(exp->nd_LEFT), D_USED)) return 0;
546 assert(nd->nd_class == Def);
550 (df->df_type->tp_fund != T_SET)) {
551 df_error(nd, "not a SET type", df);
556 else tp = bitset_type;
557 (*expp)->nd_type = tp;
561 /* Now check the elements given, and try to compute a constant set.
562 First allocate room for the set.
565 (*expp)->nd_set = MkSet(tp->set_sz);
567 /* Now check the elements, one by one
570 assert(nd->nd_class == Link && nd->nd_symb == ',');
572 if (!ChkElement(&(nd->nd_LEFT), tp, (*expp)->nd_set)) {
575 if (nd->nd_LEFT) SetIsConstant = 0;
579 if (! SetIsConstant) {
580 (*expp)->nd_NEXT = exp->nd_RIGHT;
592 register t_node *arg = (*argp)->nd_RIGHT;
595 df_error(*argp, "too few arguments supplied", edf);
604 getarg(argp, bases, designator, edf)
608 /* This routine is used to fetch the next argument from an
609 argument list. The argument list is indicated by "argp".
610 The parameter "bases" is a bitset indicating which types
611 are allowed at this point, and "designator" is a flag
612 indicating that the address from this argument is taken, so
613 that it must be a designator and may not be a register
616 register t_node *arg = nextarg(argp, edf);
617 register t_node *left;
621 ! (designator ? ChkVariable(&(arg->nd_LEFT), D_USED|D_DEFINED) : ChkExpression(&(arg->nd_LEFT)))) {
626 if (designator && left->nd_class==Def) {
627 left->nd_def->df_flags |= D_NOREG;
631 t_type *tp = BaseType(left->nd_type);
633 if (! designator) MkCoercion(&(arg->nd_LEFT), tp);
635 if (!(tp->tp_fund & bases)) {
636 df_error(left, "unexpected parameter type", edf);
645 getname(argp, kinds, bases, edf)
649 /* Get the next argument from argument list "argp".
650 The argument must indicate a definition, and the
651 definition kind must be one of "kinds".
653 register t_node *arg = nextarg(argp, edf);
654 register t_node *left;
656 if (!arg || !arg->nd_LEFT || ! ChkDesig(&(arg->nd_LEFT), D_USED)) return 0;
659 if (left->nd_class != Def) {
660 df_error(left, "identifier expected", edf);
664 if (!(left->nd_def->df_kind & kinds) ||
665 (bases && !(left->nd_type->tp_fund & bases))) {
666 df_error(left, "unexpected parameter type", edf);
675 register t_node *exp;
677 /* Check a procedure call
679 register t_node *left;
682 register t_param *param;
687 if (left->nd_class == Def) {
690 if (left->nd_type == error_type) {
691 /* Just check parameters as if they were value parameters
694 while (argp->nd_RIGHT) {
695 if (getarg(&argp, 0, 0, edf)) { }
700 exp->nd_type = RemoveEqual(ResultType(left->nd_type));
702 /* Check parameter list
705 for (param = ParamList(left->nd_type); param; param = param->par_next) {
706 if (!(left = getarg(&argp, 0, IsVarParam(param), edf))) {
712 if (left->nd_symb == STRING) {
713 TryToString(left, TypeOfParam(param));
715 if (! TstParCompat(cnt,
716 RemoveEqual(TypeOfParam(param)),
726 df_error(exp->nd_RIGHT,"too many parameters supplied",edf);
727 while (argp->nd_RIGHT) {
728 if (getarg(&argp, 0, 0, edf)) { }
738 register t_node **expp;
740 /* Check a call that must have a result
744 if ((*expp)->nd_type != 0) return 1;
745 node_error(*expp, "function call expected");
747 (*expp)->nd_type = error_type;
751 STATIC int ChkStandard();
752 STATIC int ChkCast();
758 /* Check something that looks like a procedure or function call.
759 Of course this does not have to be a call at all,
760 it may also be a cast or a standard procedure call.
763 /* First, get the name of the function or procedure
765 if (ChkDesig(&((*expp)->nd_LEFT), D_USED)) {
766 register t_node *left = (*expp)->nd_LEFT;
769 /* It was a type cast.
771 return ChkCast(expp);
774 if (IsProc(left) || left->nd_type == error_type) {
776 It may also be a call to a standard procedure
778 if (left->nd_type == std_type) {
779 /* A standard procedure
781 return ChkStandard(expp);
783 /* Here, we have found a real procedure call.
784 The left hand side may also represent a procedure
789 node_error(left, "procedure, type, or function expected");
790 left->nd_type = error_type;
793 return ChkProcCall(*expp);
797 ResultOfOperation(operator, tp)
800 /* Return the result type of the binary operation "operator",
801 with operand type "tp".
818 #define Boolean(operator) (operator == OR || operator == AND)
821 AllowedTypes(operator)
823 /* Return a bit mask indicating the allowed operand types
824 for binary operator "operator".
831 return T_NUMERIC|T_SET;
839 return T_ENUMERATION;
842 return T_POINTER|T_HIDDEN|T_SET|T_NUMERIC|T_ENUMERATION|T_CHAR;
845 return T_SET|T_NUMERIC|T_CHAR|T_ENUMERATION;
848 return T_NUMERIC|T_CHAR|T_ENUMERATION;
850 crash("(AllowedTypes)");
856 ChkAddressOper(tpl, tpr, expp)
857 register t_type *tpl, *tpr;
858 register t_node *expp;
860 /* Check that either "tpl" or "tpr" are both of type
861 address_type, or that one of them is, but the other is
863 Also insert proper coercions, making sure that the EM pointer
864 arithmetic instructions can be generated whenever possible
867 if (tpr == address_type && expp->nd_symb == '+') {
868 /* use the fact that '+' is a commutative operator */
869 t_type *tmptype = tpr;
870 t_node *tmpnode = expp->nd_RIGHT;
873 expp->nd_RIGHT = expp->nd_LEFT;
875 expp->nd_LEFT = tmpnode;
878 if (tpl == address_type) {
879 expp->nd_type = address_type;
880 if (tpr == address_type) {
883 if (tpr->tp_fund & T_CARDINAL) {
884 MkCoercion(&(expp->nd_RIGHT),
885 expp->nd_symb=='+' || expp->nd_symb=='-' ?
893 if (tpr == address_type && tpl->tp_fund & T_CARDINAL) {
894 expp->nd_type = address_type;
895 MkCoercion(&(expp->nd_LEFT), address_type);
906 /* Check a binary operation.
908 register t_node *exp = *expp;
909 register t_type *tpl, *tpr;
915 /* First, check BOTH operands */
917 retval = ChkExpression(&(exp->nd_LEFT));
918 retval &= ChkExpression(&(exp->nd_RIGHT));
920 tpl = BaseType(exp->nd_LEFT->nd_type);
921 tpr = BaseType(exp->nd_RIGHT->nd_type);
923 if (intorcard(tpl, tpr) != 0) {
924 if (tpl->tp_fund == T_INTORCARD) {
925 exp->nd_LEFT->nd_type = tpl = tpr;
927 if (tpr->tp_fund == T_INTORCARD) {
928 exp->nd_RIGHT->nd_type = tpr = tpl;
932 exp->nd_type = result_type = ResultOfOperation(exp->nd_symb, tpr);
934 /* Check that the application of the operator is allowed on the type
936 There are three tricky parts:
937 - Boolean operators are only allowed on boolean operands, but
938 the "allowed-mask" of "AllowedTypes" can only indicate
940 - All operations that are allowed on CARDINALS are also allowed
942 - The IN-operator has as right-hand-size operand a set.
944 if (exp->nd_symb == IN) {
945 if (tpr->tp_fund != T_SET) {
946 node_error(exp, "\"IN\": right operand must be a set");
949 if (!TstAssCompat(ElementType(tpr), tpl)) {
950 /* Assignment compatible ???
951 I don't know! Should we be allowed to check
952 if a INTEGER is a member of a BITSET???
954 node_error(exp->nd_LEFT, "type incompatibility in IN");
957 MkCoercion(&(exp->nd_LEFT), word_type);
958 if (exp->nd_LEFT->nd_class == Value &&
959 exp->nd_RIGHT->nd_class == Set &&
960 ! exp->nd_RIGHT->nd_NEXT) {
966 if (!retval) return 0;
968 allowed = AllowedTypes(exp->nd_symb);
970 symb = symbol2str(exp->nd_symb);
971 if (!(tpr->tp_fund & allowed) || !(tpl->tp_fund & allowed)) {
972 if (!((T_CARDINAL & allowed) &&
973 ChkAddressOper(tpl, tpr, exp))) {
974 node_error(exp, "\"%s\": illegal operand type(s)", symb);
977 if (result_type == bool_type) exp->nd_type = bool_type;
980 if (Boolean(exp->nd_symb) && tpl != bool_type) {
981 node_error(exp, "\"%s\": illegal operand type(s)", symb);
985 /* Operands must be compatible (distilled from Def 8.2)
987 if (!TstCompat(tpr, tpl)) {
988 extern char *incompat();
989 node_error(exp, "\"%s\": %s in operands", symb, incompat(tpl, tpr));
993 MkCoercion(&(exp->nd_LEFT), tpl);
994 MkCoercion(&(exp->nd_RIGHT), tpr);
997 if (tpl->tp_fund == T_SET) {
998 if (exp->nd_LEFT->nd_class == Set &&
999 ! exp->nd_LEFT->nd_NEXT &&
1000 exp->nd_RIGHT->nd_class == Set &&
1001 ! exp->nd_RIGHT->nd_NEXT) {
1005 else if ( exp->nd_LEFT->nd_class == Value &&
1006 exp->nd_RIGHT->nd_class == Value) {
1007 if (tpl->tp_fund == T_INTEGER) {
1010 else if (tpl->tp_fund == T_REAL) {
1023 /* Check an unary operation.
1025 register t_node *exp = *expp;
1026 register t_node *right = exp->nd_RIGHT;
1027 register t_type *tpr;
1029 if (exp->nd_symb == COERCION) return 1;
1030 if (exp->nd_symb == '(') {
1033 return ChkExpression(expp);
1035 exp->nd_type = error_type;
1036 if (! ChkExpression(&(exp->nd_RIGHT))) return 0;
1037 exp->nd_type = tpr = BaseType(exp->nd_RIGHT->nd_type);
1038 MkCoercion(&(exp->nd_RIGHT), tpr);
1039 right = exp->nd_RIGHT;
1041 if (tpr == address_type) tpr = card_type;
1043 switch(exp->nd_symb) {
1045 if (!(tpr->tp_fund & T_NUMERIC)) break;
1051 if (tpr->tp_fund == T_INTORCARD || tpr->tp_fund == T_INTEGER) {
1052 if (tpr == intorcard_type) {
1053 exp->nd_type = int_type;
1055 else if (tpr == longintorcard_type) {
1056 exp->nd_type = longint_type;
1058 if (right->nd_class == Value) {
1063 else if (tpr->tp_fund == T_REAL) {
1064 if (right->nd_class == Value) {
1066 flt_umin(&(right->nd_RVAL));
1067 if (right->nd_RSTR) {
1068 free(right->nd_RSTR);
1079 if (tpr == bool_type) {
1080 if (right->nd_class == Value) {
1090 node_error(exp, "\"%s\": illegal operand type", symbol2str(exp->nd_symb));
1095 getvariable(argp, edf, flags)
1099 /* Get the next argument from argument list "argp".
1100 It must obey the rules of "ChkVariable".
1102 register t_node *arg = nextarg(argp, edf);
1106 ! ChkVariable(&(arg->nd_LEFT), flags)) return 0;
1108 return arg->nd_LEFT;
1115 /* Check a call of a standard procedure or function
1117 register t_node *exp = *expp;
1118 t_node *arglink = exp;
1119 register t_node *arg;
1120 register t_def *edf = exp->nd_LEFT->nd_def;
1124 assert(exp->nd_LEFT->nd_class == Def);
1126 exp->nd_type = error_type;
1127 switch(edf->df_value.df_stdname) {
1129 if (!(arg = getarg(&arglink, T_NUMERIC, 0, edf))) return 0;
1130 exp->nd_type = BaseType(arg->nd_type);
1131 MkCoercion(&(arglink->nd_LEFT), exp->nd_type);
1132 arg = arglink->nd_LEFT;
1133 if (! (exp->nd_type->tp_fund & (T_INTEGER|T_REAL))) {
1136 if (arg->nd_class == Value) {
1137 switch(exp->nd_type->tp_fund) {
1139 arg->nd_RVAL.flt_sign = 0;
1150 exp->nd_type = char_type;
1151 if (!(arg = getarg(&arglink, T_CHAR, 0, edf))) return 0;
1152 if (arg->nd_class == Value) isconstant = 1;
1157 if (! getarg(&arglink, T_INTORCARD, 0, edf)) return 0;
1159 if (edf->df_value.df_stdname == S_FLOAT) {
1160 MkCoercion(&(arg->nd_LEFT), card_type);
1162 MkCoercion(&(arg->nd_LEFT),
1163 edf->df_value.df_stdname == S_FLOATD ?
1172 t_type *s1, *s2, *s3, *d1, *d2, *d3;
1174 if (!(arg = getarg(&arglink, 0, 0, edf))) {
1177 tp = BaseType(arg->nd_type);
1179 if (edf->df_value.df_stdname == S_SHORT) {
1197 MkCoercion(&(arglink->nd_LEFT), d1);
1199 else if (tp == s2) {
1200 MkCoercion(&(arglink->nd_LEFT), d2);
1202 else if (options['l'] && tp == s3) {
1203 MkCoercion(&(arglink->nd_LEFT), d3);
1206 df_error(arg, "unexpected parameter type", edf);
1214 if (!(arg = getarg(&arglink, T_ARRAY|T_STRING|T_CHAR, 0, edf))) {
1217 if (arg->nd_type->tp_fund == T_ARRAY) {
1218 exp->nd_type = IndexType(arg->nd_type);
1219 if (! IsConformantArray(arg->nd_type)) {
1220 arg->nd_type = exp->nd_type;
1225 if (arg->nd_symb != STRING) {
1226 df_error(arg,"array parameter expected", edf);
1229 exp = getnode(Value);
1230 exp->nd_type = card_type;
1231 /* Notice that we could disallow HIGH("") here by checking
1232 that arg->nd_type->tp_fund != T_CHAR || arg->nd_INT != 0.
1233 ??? For the time being, we don't. !!!
1234 Maybe the empty string should not be allowed at all.
1236 exp->nd_INT = arg->nd_type->tp_fund == T_CHAR ? 0 :
1238 exp->nd_symb = INTEGER;
1239 exp->nd_lineno = (*expp)->nd_lineno;
1240 (*expp)->nd_RIGHT = 0;
1247 if (!(arg = getname(&arglink, D_ISTYPE, T_DISCRETE, edf))) {
1250 exp->nd_type = arg->nd_type;
1255 if (! (arg = getarg(&arglink, T_INTORCARD, 0, edf))) return 0;
1256 MkCoercion(&(arglink->nd_LEFT), BaseType(arg->nd_type));
1257 exp->nd_type = bool_type;
1258 if (arglink->nd_LEFT->nd_class == Value) isconstant = 1;
1262 if (! (arg = getarg(&arglink, T_NOSUB, 0, edf))) return 0;
1263 exp->nd_type = card_type;
1264 if (arg->nd_class == Value) {
1265 arg->nd_type = card_type;
1270 #ifndef STRICT_3RD_ED
1274 static int warning_given = 0;
1276 if (!warning_given) {
1279 node_warning(exp, W_OLDFASHIONED, "NEW and DISPOSE are obsolete");
1281 node_error(exp, "NEW and DISPOSE are obsolete");
1285 arg = getvariable(&arglink, edf, D_USED|D_DEFINED);
1286 if (! arg) return 0;
1287 if (! (arg->nd_type->tp_fund == T_POINTER)) {
1288 df_error(arg, "pointer variable expected", edf);
1291 /* Now, make it look like a call to ALLOCATE or DEALLOCATE */
1292 arglink->nd_RIGHT = arg = getnode(Link);
1293 arg->nd_lineno = exp->nd_lineno;
1295 arg->nd_LEFT = getnode(Value);
1297 arg->nd_INT = PointedtoType(arglink->nd_LEFT->nd_type)->tp_size;
1298 arg->nd_symb = INTEGER;
1299 arg->nd_lineno = exp->nd_lineno;
1300 arg->nd_type = card_type;
1301 /* Ignore other arguments to NEW and/or DISPOSE ??? */
1303 FreeNode(exp->nd_LEFT);
1304 exp->nd_LEFT = arg = getnode(Name);
1305 arg->nd_symb = IDENT;
1306 arg->nd_lineno = exp->nd_lineno;
1307 arg->nd_IDF = str2idf(edf->df_value.df_stdname==S_NEW ?
1308 "ALLOCATE" : "DEALLOCATE", 0);
1309 return ChkCall(expp);
1312 case S_TSIZE: /* ??? */
1314 exp->nd_type = intorcard_type;
1315 if (!(arg = getname(&arglink,D_FIELD|D_VARIABLE|D_ISTYPE,0,edf))) {
1318 if (! IsConformantArray(arg->nd_type)) isconstant = 1;
1320 else node_warning(exp,
1322 "%s on conformant array",
1323 edf->df_idf->id_text);
1325 #ifndef STRICT_3RD_ED
1326 if (! options['3'] && edf->df_value.df_stdname == S_TSIZE) {
1327 if (arg = arglink->nd_RIGHT) {
1330 "TSIZE with multiple parameters, only first parameter used");
1332 arglink->nd_RIGHT = 0;
1340 if (! getarg(&arglink, T_REAL, 0, edf)) return 0;
1341 MkCoercion(&(arglink->nd_LEFT),
1342 edf->df_value.df_stdname == S_TRUNCD ?
1343 options['l'] ? longcard_type : longint_type
1349 if (!(arg = getname(&arglink, D_ISTYPE, T_NOSUB, edf))) {
1352 exp->nd_type = arg->nd_def->df_type;
1353 exp->nd_RIGHT = arglink->nd_RIGHT;
1354 arglink->nd_RIGHT = 0;
1359 if (! getarg(&arglink, T_CARDINAL, 0, edf)) return 0;
1360 if (edf->df_value.df_stdname == S_CHR) {
1361 exp->nd_type = char_type;
1363 if (exp->nd_type != int_type) {
1364 MkCoercion(&(arglink->nd_LEFT), exp->nd_type);
1370 exp->nd_type = address_type;
1371 if (! getarg(&arglink, 0, 1, edf)) return 0;
1377 if (! (arg = getvariable(&arglink, edf, D_USED|D_DEFINED))) return 0;
1378 if (! (arg->nd_type->tp_fund & T_DISCRETE)) {
1379 df_error(arg,"illegal parameter type", edf);
1382 if (arglink->nd_RIGHT) {
1383 if (! getarg(&arglink, T_INTORCARD, 0, edf)) return 0;
1394 register t_type *tp;
1398 if (!(arg = getvariable(&arglink, edf, D_USED|D_DEFINED))) return 0;
1400 if (tp->tp_fund != T_SET) {
1401 df_error(arg, "SET parameter expected", edf);
1404 if (!(dummy = getarg(&arglink, 0, 0, edf))) return 0;
1405 if (!ChkAssCompat(&dummy, ElementType(tp), "EXCL/INCL")) {
1406 /* What type of compatibility do we want here?
1407 apparently assignment compatibility! ??? ???
1408 But we don't want the coercion in the tree, because
1409 we don't want a range check here. We want a SET
1414 MkCoercion(&(arglink->nd_LEFT), word_type);
1419 crash("(ChkStandard)");
1424 if (arg->nd_RIGHT) {
1425 df_error(arg->nd_RIGHT, "too many parameters supplied", edf);
1430 cstcall(expp, edf->df_value.df_stdname);
1434 *expp = arg->nd_LEFT;
1435 exp->nd_RIGHT = arg;
1447 /* Check a cast and perform it if the argument is constant.
1448 If the sizes don't match, only complain if at least one of them
1449 has a size larger than the word size.
1450 If both sizes are equal to or smaller than the word size, there
1451 is no problem as such values take a word on the EM stack
1454 register t_node *exp = *expp;
1455 register t_node *arg = exp->nd_RIGHT;
1456 register t_type *lefttype = exp->nd_LEFT->nd_type;
1457 t_def *df = exp->nd_LEFT->nd_def;
1459 if ((! arg) || arg->nd_RIGHT) {
1460 df_error(exp, "type cast must have 1 parameter", df);
1464 if (! ChkExpression(&(arg->nd_LEFT))) return 0;
1466 MkCoercion(&(arg->nd_LEFT), BaseType(arg->nd_LEFT->nd_type));
1469 if (arg->nd_type->tp_size != lefttype->tp_size &&
1470 (arg->nd_type->tp_size > word_size ||
1471 lefttype->tp_size > word_size)) {
1472 df_error(exp, "unequal sizes in type cast", df);
1476 if (IsConformantArray(arg->nd_type)) {
1478 "type transfer function on conformant array not supported",
1483 exp->nd_RIGHT->nd_LEFT = 0;
1485 if (arg->nd_class == Value) {
1487 if (lefttype->tp_fund == T_SET) {
1488 /* User deserves what he gets here ... */
1490 exp->nd_set = MkSet((unsigned)(lefttype->set_sz));
1491 exp->nd_set[0] = arg->nd_INT;
1492 exp->nd_lineno = arg->nd_lineno;
1497 exp = getnode(Uoper);
1498 exp->nd_symb = CAST;
1499 exp->nd_lineno = arg->nd_lineno;
1500 exp->nd_RIGHT = arg;
1503 exp->nd_type = lefttype;
1509 register t_node *nd;
1512 /* Try a coercion from character constant to string.
1516 assert(nd->nd_symb == STRING);
1518 if (tp->tp_fund == T_ARRAY && nd->nd_type == char_type) {
1519 buf[0] = nd->nd_INT;
1520 nd->nd_type = standard_type(T_STRING, 1, (arith) 2);
1522 (struct string *) Malloc(sizeof(struct string));
1523 nd->nd_STR = Salloc(buf, (unsigned) word_size);
1532 node_error(*expp, "designator expected");
1537 add_flags(expp, flags)
1540 (*expp)->nd_def->df_flags |= flags;
1544 extern int PNodeCrash();
1546 int (*ExprChkTable[])() = {
1562 int (*DesigChkTable[])() = {