|
|
@@ -1288,8 +1288,11 @@ PRODUCTIONS
|
|
|
SymTab.ProcTypeAdd(t, isV, pt); .) ) .
|
|
|
(* Arrays: "OF" without bounds is an open formal (allowed only
|
|
|
where allowOpen); "[lo..hi, ...]" nests bounded levels inside
|
|
|
- out. Bounds are folded literals (int/char); anything else 230.
|
|
|
- Bare-type indices ("ARRAY Color OF") wait for enum ordinals. *)
|
|
|
+ out. The PIM/ISO multi-index form repeats the bracket group
|
|
|
+ ("ARRAY [lo..hi], [lo..hi] OF T"); the bounds of every group
|
|
|
+ nest in the same inside-out order as the comma list. Bounds are
|
|
|
+ folded literals (int/char); anything else 230. Bare-type indices
|
|
|
+ ("ARRAY Color OF") wait for enum ordinals. *)
|
|
|
ArrayType<VAR t: SymTab.TypeIndex; allowOpen: BOOLEAN>
|
|
|
(. VAR elem: SymTab.TypeIndex;
|
|
|
eb: SymTab.Name;
|
|
|
@@ -1317,19 +1320,39 @@ PRODUCTIONS
|
|
|
ELSE SemError(230);
|
|
|
t := SymTab.InvalidType
|
|
|
END; .)
|
|
|
- | "[" (. SymTab.BoundBegin; ok := TRUE; .)
|
|
|
+ | "[" (. SymTab.BoundBegin; ok := TRUE;
|
|
|
+ nb := 0; .)
|
|
|
BoundPair<ok>
|
|
|
{ "," BoundPair<ok> }
|
|
|
- "]" (. (* snapshot before the element
|
|
|
- type, which reuses the bound
|
|
|
- buffer for a nested ARRAY *)
|
|
|
- nb := SymTab.BoundCount();
|
|
|
- k := 0;
|
|
|
- WHILE k < nb DO
|
|
|
- bnds[k] := SymTab.BoundLo(k);
|
|
|
- bndh[k] := SymTab.BoundHi(k);
|
|
|
- INC(k)
|
|
|
+ "]" (. (* snapshot this bracket group
|
|
|
+ before the element type, which
|
|
|
+ reuses the bound buffer for a
|
|
|
+ nested ARRAY *)
|
|
|
+ IF nb + SymTab.BoundCount() >
|
|
|
+ HIGH(bnds) + 1 THEN
|
|
|
+ SemError(230); ok := FALSE
|
|
|
+ ELSE
|
|
|
+ k := 0;
|
|
|
+ WHILE k < SymTab.BoundCount() DO
|
|
|
+ bnds[nb] := SymTab.BoundLo(k);
|
|
|
+ bndh[nb] := SymTab.BoundHi(k);
|
|
|
+ INC(k); INC(nb)
|
|
|
+ END
|
|
|
END; .)
|
|
|
+ { "," "[" (. SymTab.BoundBegin; .)
|
|
|
+ BoundPair<ok>
|
|
|
+ { "," BoundPair<ok> }
|
|
|
+ "]" (. IF nb + SymTab.BoundCount() >
|
|
|
+ HIGH(bnds) + 1 THEN
|
|
|
+ SemError(230); ok := FALSE
|
|
|
+ ELSE
|
|
|
+ k := 0;
|
|
|
+ WHILE k < SymTab.BoundCount() DO
|
|
|
+ bnds[nb] := SymTab.BoundLo(k);
|
|
|
+ bndh[nb] := SymTab.BoundHi(k);
|
|
|
+ INC(k); INC(nb)
|
|
|
+ END
|
|
|
+ END; .) }
|
|
|
"OF" Type<elem, FALSE>
|
|
|
(. IF ok THEN
|
|
|
k := nb;
|
|
|
@@ -1387,7 +1410,13 @@ PRODUCTIONS
|
|
|
t := SymTab.NewSet(base)
|
|
|
ELSE bcls :=
|
|
|
SymTab.ClassOf(base);
|
|
|
- IF bcls = SymTab.ClBool THEN
|
|
|
+ (* a subrange keeps its own
|
|
|
+ span even when its base is
|
|
|
+ CHAR/BOOLEAN/an enum *)
|
|
|
+ IF SymTab.SubBounds(base,
|
|
|
+ blo, bhi) THEN
|
|
|
+ bspan := bhi - blo + 1
|
|
|
+ ELSIF bcls = SymTab.ClBool THEN
|
|
|
blo := 0; bspan := 2
|
|
|
ELSIF bcls = SymTab.ClChar THEN
|
|
|
blo := 0; bspan := 256
|
|
|
@@ -1395,9 +1424,6 @@ PRODUCTIONS
|
|
|
blo := 0;
|
|
|
bspan := VAL(INTEGER,
|
|
|
SymTab.EnumCount(base))
|
|
|
- ELSIF SymTab.SubBounds(base,
|
|
|
- blo, bhi) THEN
|
|
|
- bspan := bhi - blo + 1
|
|
|
ELSE bspan := 0 END;
|
|
|
IF (bspan <= 0)
|
|
|
OR (bspan > 65536) THEN
|
|
|
@@ -1541,7 +1567,13 @@ PRODUCTIONS
|
|
|
OR (lo > hi) THEN
|
|
|
SemError(230);
|
|
|
t := SymTab.InvalidType
|
|
|
+ ELSE IF SymTab.SameType(tlo, thi) THEN
|
|
|
+ (* keep the base type: ['A'..'Z']
|
|
|
+ is character, [red..blue]
|
|
|
+ that enumeration *)
|
|
|
+ t := SymTab.NewSubB(lo, hi, tlo)
|
|
|
ELSE t := SymTab.NewSubR(lo, hi)
|
|
|
+ END
|
|
|
END; .)
|
|
|
"]" .
|
|
|
Enum<VAR t: SymTab.TypeIndex> (. VAR n: SymTab.Name;
|
|
|
@@ -2586,16 +2618,18 @@ PRODUCTIONS
|
|
|
AND (SymTab.SymKind(lv) #
|
|
|
SymTab.KindParam) THEN
|
|
|
SemError(220); ok := FALSE
|
|
|
- ELSIF NOT SymTab.IsIntFamily(
|
|
|
+ ELSIF NOT SymTab.IsOrdinal(
|
|
|
SymTab.SymType(lv)) THEN
|
|
|
SemError(220); ok := FALSE
|
|
|
END; .)
|
|
|
":=" Expr<tlo, qlo> (. astLo := astCur;
|
|
|
- IF NOT SymTab.IsIntFamily(tlo) THEN
|
|
|
+ IF NOT SymTab.Assignable(tlo,
|
|
|
+ SymTab.SymType(lv)) THEN
|
|
|
SemError(220); ok := FALSE
|
|
|
END; .)
|
|
|
"TO" Expr<thi, qhi> (. astHi := astCur;
|
|
|
- IF NOT SymTab.IsIntFamily(thi) THEN
|
|
|
+ IF NOT SymTab.Assignable(thi,
|
|
|
+ SymTab.SymType(lv)) THEN
|
|
|
SemError(220); ok := FALSE
|
|
|
END; .)
|
|
|
[ "BY" Expr<tby, qby> (. astBy := astCur;
|
|
|
@@ -3710,7 +3744,13 @@ PRODUCTIONS
|
|
|
QbeGen.IntStr(hi, q)
|
|
|
ELSE QbeGen.IntStr(lo, q)
|
|
|
END;
|
|
|
- t := SymTab.IntType()
|
|
|
+ (* a set's bounds are those
|
|
|
+ of its base type *)
|
|
|
+ IF SymTab.ClassOf(dt) =
|
|
|
+ SymTab.ClSet THEN
|
|
|
+ t := SymTab.SetBase(dt)
|
|
|
+ ELSE t := SymTab.IntType()
|
|
|
+ END
|
|
|
ELSE SemError(230);
|
|
|
t := SymTab.InvalidType;
|
|
|
QbeGen.CopyOp("0", q)
|