Jelajahi Sumber

step9: type exports, tailed whole-copy fix, Showcase2; 137/137 tests green

Eric Streit 1 bulan lalu
induk
melakukan
32f8905056
40 mengubah file dengan 2344 tambahan dan 1752 penghapusan
  1. TEMPAT SAMPAH
      CFcopy.MC4
  2. TEMPAT SAMPAH
      CRow.MC4
  3. TEMPAT SAMPAH
      M2c
  4. 39 8
      M2c.atg
  5. 1770 1739
      M2c.lst
  6. 36 5
      M2cP.mod
  7. TEMPAT SAMPAH
      M2cP.o
  8. 81 0
      Showcase2.LST
  9. TEMPAT SAMPAH
      Showcase2.MC4
  10. 75 0
      Showcase2.mod
  11. TEMPAT SAMPAH
      TBadMGhost.MC4
  12. TEMPAT SAMPAH
      TBadMMod.MC4
  13. TEMPAT SAMPAH
      TBadMType.MC4
  14. TEMPAT SAMPAH
      TMArr.MC4
  15. TEMPAT SAMPAH
      TMEnum.MC4
  16. TEMPAT SAMPAH
      TMInt.MC4
  17. TEMPAT SAMPAH
      TMPtr.MC4
  18. TEMPAT SAMPAH
      TMRec.MC4
  19. 50 0
      docs/summary_step9.md
  20. 14 0
      run_tests.sh
  21. 15 0
      tests/c_fcopy.LST
  22. 9 0
      tests/c_fcopy.mod
  23. 14 0
      tests/c_row.LST
  24. 8 0
      tests/c_row.mod
  25. 16 0
      tests/t_bad_mghost.LST
  26. 9 0
      tests/t_bad_mghost.mod
  27. 16 0
      tests/t_bad_mmod.LST
  28. 9 0
      tests/t_bad_mmod.mod
  29. 16 0
      tests/t_bad_mtype.LST
  30. 9 0
      tests/t_bad_mtype.mod
  31. 20 0
      tests/t_marr.LST
  32. 14 0
      tests/t_marr.mod
  33. 20 0
      tests/t_menum.LST
  34. 14 0
      tests/t_menum.mod
  35. 16 0
      tests/t_mint.LST
  36. 10 0
      tests/t_mint.mod
  37. 17 0
      tests/t_mptr.LST
  38. 11 0
      tests/t_mptr.mod
  39. 21 0
      tests/t_mrec.LST
  40. 15 0
      tests/t_mrec.mod

TEMPAT SAMPAH
CFcopy.MC4


TEMPAT SAMPAH
CRow.MC4


TEMPAT SAMPAH
M2c


+ 39 - 8
M2c.atg

@@ -4,9 +4,9 @@ COMPILER M2c
 
    - program module only, no DEFINITION / IMPLEMENTATION split
    - local MODULEs (single-file, no nesting, no bodies): EXPORT of
-     VARs, CONSTs and procedures (value/VAR params, functions, open
-     array formals with fixed actuals); use as M.x / M.P(args);
-     no EXPORT of types, no PRIORITY
+     VARs, CONSTs, TYPEs and procedures (value/VAR params, functions,
+     open array formals with fixed actuals); use as M.x / M.P(args);
+     no PRIORITY
    - procedures: declarations (nested), value and VAR parameters,
      functions with RETURN, recursion, FORWARD headings;
      no procedure types/variables, no cones
@@ -323,17 +323,34 @@ PRODUCTIONS
     = GetIdent<n>                       (. IF ~SymTab.Lookup(n) THEN
                                              SemError(201);
                                              t := SymTab.InvalidType
+                                           ELSIF SymTab.SymKind(n)
+                                              = SymTab.KindModule THEN
+                                             t := SymTab.InvalidType
                                            ELSIF (SymTab.SymKind(n) #
                                                   SymTab.KindType)
-                                             & (SymTab.SymKind(n) #
-                                                SymTab.KindPredef)
-                                             & (SymTab.SymKind(n) #
-                                                SymTab.KindImport) THEN
+                                              & (SymTab.SymKind(n) #
+                                                 SymTab.KindPredef)
+                                              & (SymTab.SymKind(n) #
+                                                 SymTab.KindImport) THEN
                                              SemError(221);
                                              t := SymTab.InvalidType
                                            ELSE t := SymTab.SymType(n) END; .)
       { "."
-        GetIdent<m>                     (. t := SymTab.InvalidType; .) } .
+        GetIdent<m>                     (. IF SymTab.SymKind(n)
+                                            = SymTab.KindModule THEN
+                                           IF SymTab.ExpKind(n, m)
+                                              = SymTab.KindType THEN
+                                             t := SymTab.ExpType(n, m)
+                                           ELSE
+                                             IF SymTab.ExpKind(n, m) = -1 THEN
+                                               SemError(201)
+                                             ELSE SemError(221)
+                                             END;
+                                             t := SymTab.InvalidType
+                                           END
+                                         ELSE
+                                           t := SymTab.InvalidType
+                                         END; .) } .
 
   (* Types: ProcedureType removed; subrange factored for LL(1) *)
   Type <VAR t: SymTab.TypeIndex>
@@ -612,6 +629,20 @@ PRODUCTIONS
                                                     = SymTab.ClRecord)) THEN
                                              MGen.PushAddr(bn);
                                              pushedDst := TRUE
+                                           ELSIF ((dk = SymTab.KindVar)
+                                                  OR (dk
+                                                      = SymTab.KindParam)
+                                                  OR (dk
+                                                      = SymTab.KindVarPar)
+                                                  OR (dk
+                                                      = SymTab.KindField))
+                                              & sfx
+                                              & (dt # SymTab.InvalidType)
+                                              & ((SymTab.ClassOf(dt)
+                                                 = SymTab.ClArray)
+                                                 OR (SymTab.ClassOf(dt)
+                                                    = SymTab.ClRecord)) THEN
+                                             pushedDst := TRUE
                                            END;
                                            IF storable & ~sfx
                                               & ~pushedDst THEN

+ 1770 - 1739
M2c.lst

@@ -26,9 +26,9 @@ Listing:
     4  
     5     - program module only, no DEFINITION / IMPLEMENTATION split
     6     - local MODULEs (single-file, no nesting, no bodies): EXPORT of
-    7       VARs, CONSTs and procedures (value/VAR params, functions, open
-    8       array formals with fixed actuals); use as M.x / M.P(args);
-    9       no EXPORT of types, no PRIORITY
+    7       VARs, CONSTs, TYPEs and procedures (value/VAR params, functions,
+    8       open array formals with fixed actuals); use as M.x / M.P(args);
+    9       no PRIORITY
    10     - procedures: declarations (nested), value and VAR parameters,
    11       functions with RETURN, recursion, FORWARD headings;
    12       no procedure types/variables, no cones
@@ -345,1748 +345,1779 @@ Listing:
   323      = GetIdent<n>                       (. IF ~SymTab.Lookup(n) THEN
   324                                               SemError(201);
   325                                               t := SymTab.InvalidType
-  326                                             ELSIF (SymTab.SymKind(n) #
-  327                                                    SymTab.KindType)
-  328                                               & (SymTab.SymKind(n) #
-  329                                                  SymTab.KindPredef)
-  330                                               & (SymTab.SymKind(n) #
-  331                                                  SymTab.KindImport) THEN
-  332                                               SemError(221);
-  333                                               t := SymTab.InvalidType
-  334                                             ELSE t := SymTab.SymType(n) END; .)
-  335        { "."
-  336          GetIdent<m>                     (. t := SymTab.InvalidType; .) } .
-  337  
-  338    (* Types: ProcedureType removed; subrange factored for LL(1) *)
-  339    Type <VAR t: SymTab.TypeIndex>
-  340      = SimpleType<t> | ArrayType<t> | RecordType<t>
-  341      | SetType<t> | PointerType<t> .
-  342    SimpleType <VAR t: SymTab.TypeIndex>
-  343                                          (. VAR t1, t2: SymTab.TypeIndex;
-  344                                               lx1, lx2: MGen.LitStr;
-  345                                               vD: BOOLEAN;
-  346                                               vnD: SymTab.Name;
-  347                                               loI, hiI: INTEGER;
-  348                                               lok, hik: BOOLEAN; .)
-  349      = QualIdent<t> [ "["
-  350                        (. MGen.NoEmitEnter; lok := FALSE; hik := FALSE;
-  351                           loI := 0; hiI := -1; .)
-  352                        ConstExpr<t1, lx1> (. IF (t1 # SymTab.InvalidType)
-  353                                              & (SymTab.ClassOf(t1) #
-  354                                                 SymTab.ClInt)
-  355                                              & (SymTab.ClassOf(t1) #
-  356                                                 SymTab.ClChar)
-  357                                              & (SymTab.ClassOf(t1) #
-  358                                                 SymTab.ClEnum) THEN
-  359                                              SemError(224) END; .)
-  360                        ".."
-  361                        ConstExpr<t2, lx2> (. IF (t2 # SymTab.InvalidType)
-  362                                              & (SymTab.ClassOf(t2) #
-  363                                                 SymTab.ClInt)
-  364                                              & (SymTab.ClassOf(t2) #
-  365                                                 SymTab.ClChar)
-  366                                              & (SymTab.ClassOf(t2) #
-  367                                                 SymTab.ClEnum) THEN
-  368                                              SemError(224) END; .)
-  369                        "]"
-  370                                       (. IF (t1 # SymTab.InvalidType)
-  371                                           & (t2 # SymTab.InvalidType) THEN
-  372                                             IF MGen.IsLit(lx1) THEN
-  373                                               IF SymTab.ClassOf(t1)
-  374                                                  = SymTab.ClChar THEN
-  375                                                 loI := MGen.CharOrd(lx1);
-  376                                                 lok := TRUE
-  377                                               ELSIF MGen.ParseInt(lx1, loI) THEN
-  378                                                 lok := TRUE
-  379                                               END
-  380                                             END;
-  381                                             IF MGen.IsLit(lx2) THEN
-  382                                               IF SymTab.ClassOf(t2)
-  383                                                  = SymTab.ClChar THEN
-  384                                                 hiI := MGen.CharOrd(lx2);
-  385                                                 hik := TRUE
-  386                                               ELSIF MGen.ParseInt(lx2, hiI) THEN
-  387                                                 hik := TRUE
-  388                                               END
-  389                                             END
-  390                                           END;
-  391                                          IF lok & hik THEN
-  392                                            t := SymTab.NewSubB(t1, loI, hiI)
-  393                                          ELSE
-  394                                            t := SymTab.NewSub(t1);
-  395                                            IF (t1 # SymTab.InvalidType)
-  396                                               & (t2 # SymTab.InvalidType) THEN
-  397                                              SemError(230)
-  398                                            END
-  399                                          END;
-  400                                          MGen.NoEmitExit; .) ]
-  401      | "["                               (. MGen.NoEmitEnter; lok := FALSE;
-  402                                             hik := FALSE; loI := 0; hiI := -1; .)
-  403        ConstExpr<t1, lx1>                (. IF (t1 # SymTab.InvalidType)
-  404                                              & (SymTab.ClassOf(t1) #
-  405                                                 SymTab.ClInt)
-  406                                              & (SymTab.ClassOf(t1) #
-  407                                                 SymTab.ClChar)
-  408                                              & (SymTab.ClassOf(t1) #
-  409                                                 SymTab.ClEnum) THEN
-  410                                              SemError(224) END; .)
-  411        ".."
-  412        ConstExpr<t2, lx2>                (. IF (t2 # SymTab.InvalidType)
-  413                                              & (SymTab.ClassOf(t2) #
-  414                                                 SymTab.ClInt)
-  415                                              & (SymTab.ClassOf(t2) #
-  416                                                 SymTab.ClChar)
-  417                                              & (SymTab.ClassOf(t2) #
-  418                                                 SymTab.ClEnum) THEN
-  419                                              SemError(224) END; .)
-  420        "]"                               (. IF (t1 # SymTab.InvalidType)
-  421                                             & (t2 # SymTab.InvalidType) THEN
-  422                                               IF MGen.IsLit(lx1) THEN
-  423                                                 IF SymTab.ClassOf(t1)
-  424                                                    = SymTab.ClChar THEN
-  425                                                   loI := MGen.CharOrd(lx1);
-  426                                                   lok := TRUE
-  427                                                 ELSIF MGen.ParseInt(lx1,
-  428                                                           loI) THEN
-  429                                                   lok := TRUE
-  430                                                 END
-  431                                               END;
-  432                                               IF MGen.IsLit(lx2) THEN
-  433                                                 IF SymTab.ClassOf(t2)
-  434                                                    = SymTab.ClChar THEN
-  435                                                   hiI := MGen.CharOrd(lx2);
-  436                                                   hik := TRUE
-  437                                                 ELSIF MGen.ParseInt(lx2,
-  438                                                           hiI) THEN
-  439                                                   hik := TRUE
-  440                                                 END
-  441                                               END
-  442                                             END;
-  443                                            IF lok & hik THEN
-  444                                              t := SymTab.NewSubB(t1, loI, hiI)
-  445                                            ELSE
-  446                                              t := SymTab.NewSub(t1);
-  447                                              IF (t1 # SymTab.InvalidType)
-  448                                                 & (t2 # SymTab.InvalidType) THEN
-  449                                                SemError(230)
-  450                                              END
-  451                                            END;
-  452                                             MGen.NoEmitExit; .)
-  453      | Enum<t> .
-  454    Enum <VAR t: SymTab.TypeIndex>
-  455                                          (. VAR n: SymTab.Name;
-  456                                               ord: INTEGER; .)
-  457      = "("                               (. t := SymTab.NewEnum();
-  458                                             ord := 0; .)
-  459        GetIdent<n>                       (. IF ~SymTab.Enter(n,
-  460                                               SymTab.KindConst)
-  461                                             THEN SemError(200) END;
-  462                                             SymTab.SetSymType(n, t);
-  463                                             SymTab.EnumAdd(t);
-  464                                             MGen.DeclConstInt(n, ord);
-  465                                             INC(ord); .)
-  466        { ","
-  467          GetIdent<n>                     (. IF ~SymTab.Enter(n,
-  468                                               SymTab.KindConst)
-  469                                             THEN SemError(200) END;
-  470                                             SymTab.SetSymType(n, t);
-  471                                             SymTab.EnumAdd(t);
-  472                                             MGen.DeclConstInt(n, ord);
-  473                                             INC(ord); .) }
-  474        ")" .
-  475    ArrayType <VAR t: SymTab.TypeIndex>
-  476                                          (. VAR s, s2, e: SymTab.TypeIndex;
-  477                                               idx: ARRAY [0 .. 7] OF
-  478                                                 SymTab.TypeIndex;
-  479                                               nc, kk: CARDINAL;
-  480                                               loA, hiA: INTEGER;
-  481                                               isOpenA: BOOLEAN; .)
-  482      = "ARRAY"
-  483        [ SimpleType<s>                     (. IF (s # SymTab.InvalidType)
-  484                                              & (SymTab.ClassOf(s) #
-  485                                                 SymTab.ClInt)
-  486                                              & (SymTab.ClassOf(s) #
-  487                                                 SymTab.ClChar)
-  488                                              & (SymTab.ClassOf(s) #
-  489                                                 SymTab.ClEnum) THEN
-  490                                              SemError(224) END;
-  491                                             nc := 0; isOpenA := FALSE;
-  492                                             idx[nc] := s; INC(nc); .)
-  493          { ","
-  494            SimpleType<s2>                  (. IF (s2 # SymTab.InvalidType)
-  495                                              & (SymTab.ClassOf(s2) #
-  496                                                 SymTab.ClInt)
-  497                                              & (SymTab.ClassOf(s2) #
-  498                                                 SymTab.ClChar)
-  499                                              & (SymTab.ClassOf(s2) #
-  500                                                 SymTab.ClEnum) THEN
-  501                                              SemError(224) END;
-  502                                             IF nc <= HIGH(idx) THEN
-  503                                               idx[nc] := s2; INC(nc)
-  504                                             END; .) }
-  505        |                                   (. nc := 0; isOpenA := TRUE; .) ]
-  506        "OF"
-  507        Type<e>                           (. IF isOpenA THEN
-  508                                             t := SymTab.NewOpen(e)
-  509                                           ELSE
-  510                                             t := e;
-  511                                             kk := nc;
-  512                                             WHILE kk > 0 DO
-  513                                               DEC(kk);
-  514                                               loA := SymTab.TypeLo(idx[kk]);
-  515                                               hiA := SymTab.TypeHi(idx[kk]);
-  516                                               IF SymTab.TypeLen(idx[kk]) = 0 THEN
-  517                                                 IF idx[kk]
-  518                                                    # SymTab.InvalidType THEN
-  519                                                   SemError(230)
-  520                                                 END;
-  521                                                 loA := 0; hiA := -1
-  522                                               END;
-  523                                               t := SymTab.NewArrayB(t,
-  524                                                       loA, hiA)
-  525                                             END
-  526                                           END; .) .
-  527    RecordType <VAR t: SymTab.TypeIndex>
-  528      = "RECORD"                          (. t := SymTab.NewRecord(); .)
-  529        FieldSeq<t>
-  530        "END" .
-  531    FieldSeq <rt: SymTab.TypeIndex>
-  532      = Field<rt> { ";"
-  533                    Field<rt> } .
-  534    Field <rt: SymTab.TypeIndex>
-  535                                          (. VAR et: SymTab.TypeIndex; .)
-  536      = [ FieldIdents<rt> ":"
-  537          Type<et>                       (. IF (et # SymTab.InvalidType)
-  538                                             & SymTab.IsOpen(et) THEN
-  539                                             SemError(230)
-  540                                           END;
-  541                                           SymTab.FixPendingF(rt, et); .) ] .
-  542    FieldIdents <rt: SymTab.TypeIndex>
-  543                                          (. VAR n: SymTab.Name; .)
-  544      = GetIdent<n>                       (. IF ~SymTab.FieldPending(rt, n)
-  545                                             THEN SemError(200) END .)
-  546        { ","
-  547          GetIdent<n>                     (. IF ~SymTab.FieldPending(rt, n)
-  548                                             THEN SemError(200) END .) } .
-  549    SetType <VAR t: SymTab.TypeIndex>
-  550                                          (. VAR s: SymTab.TypeIndex; .)
-  551      = "SET"
-  552        "OF"
-  553        SimpleType<s>                     (. IF (s # SymTab.InvalidType)
-  554                                              & (SymTab.ClassOf(s) #
-  555                                                 SymTab.ClInt)
-  556                                              & (SymTab.ClassOf(s) #
-  557                                                 SymTab.ClChar)
-  558                                              & (SymTab.ClassOf(s) #
-  559                                                 SymTab.ClEnum) THEN
-  560                                              SemError(224) END;
-  561                                             t := SymTab.NewSet(s); .) .
-  562    PointerType <VAR t: SymTab.TypeIndex>
-  563                                          (. VAR b: SymTab.TypeIndex; .)
-  564      = "POINTER"
-  565        "TO"
-  566        Type<b>                           (. t := SymTab.NewPtr(b); .) .
-  567  
-  568    (* Statements: RETURN added; calls via AssignOrCall *)
-  569    StatSeq    = Stat { ";"
-  570                       Stat } .
-  571    Stat                                  (. VAR lx: INTEGER; .)
-  572      = [ AssignOrCall | IfStat | CaseStat | WhileStat
-  573        | RepeatStat | LoopStat | ForStat | WithStat | ReturnStat
-  574        | NewStat | DispStat | WriteIntStat | WriteStrStat
-  575        | "EXIT"                 (. IF MGen.TopLoop(lx) THEN
-  576                                      MGen.Jmp(lx)
-  577                                    ELSE SemError(230) END; .) ] .
-  578    AssignOrCall                          (. VAR dt, et: SymTab.TypeIndex;
-  579                                               dk: INTEGER;
-  580                                               bn: SymTab.Name;
-  581                                               lxD, lxe: MGen.LitStr;
-  582                                               vE: BOOLEAN;
-  583                                               vnE: SymTab.Name;
-  584                                               sfx: BOOLEAN;
-  585                                               okC: BOOLEAN;
-  586                                               isR, conv,
-  587                                               storable, pushedDst,
-  588                                               pushedFld: BOOLEAN;
-  589                                               dstBytes, srcBytes: CARDINAL;
-  590                                               elemDt: SymTab.TypeIndex;
-  591                                               modBare: INTEGER; .)
-  592      =                                   (. sfx := FALSE; pushedDst := FALSE;
-  593                                             pushedFld := FALSE; .)
-  594        DesignHead<dt, dk, bn, FALSE, lxD>
-  595        DesignTail<dt, dk, bn, FALSE, lxD, sfx>
-  596        ( ":="
-  597                                          (. storable :=
-  598                                               (dk = SymTab.KindVar)
-  599                                               OR (dk = SymTab.KindParam)
-  600                                               OR (dk = SymTab.KindVarPar);
-  601                                             IF (dk = SymTab.KindField)
-  602                                                & (~sfx)
-  603                                                & (dt # SymTab.InvalidType) THEN
-  604                                               MGen.WithAddr(bn);
-  605                                               pushedFld := TRUE
-  606                                             END;
-  607                                             IF storable & ~sfx
-  608                                                & (dt # SymTab.InvalidType)
-  609                                                & ((SymTab.ClassOf(dt)
-  610                                                   = SymTab.ClArray)
-  611                                                   OR (SymTab.ClassOf(dt)
-  612                                                      = SymTab.ClRecord)) THEN
-  613                                               MGen.PushAddr(bn);
-  614                                               pushedDst := TRUE
-  615                                             END;
-  616                                             IF storable & ~sfx
-  617                                                & ~pushedDst THEN
-  618                                               IF (dt # SymTab.InvalidType)
-  619                                                  & (SymTab.TypeSlots(dt)
-  620                                                     > 1) THEN
-  621                                               ELSE MGen.StoreSetup(bn)
-  622                                               END
-  623                                             END; .)
-  624          Expr<et, lxe, vE, vnE>                                                  (. IF (dt # SymTab.InvalidType)
-  625                                             & (dk # SymTab.KindVar)
-  626                                             & (dk # SymTab.KindParam)
-  627                                             & (dk # SymTab.KindVarPar)
-  628                                             & (dk # SymTab.KindField)
-  629                                             & (dk # SymTab.KindImport) THEN
-  630                                             SemError(210)
-  631                                           ELSIF pushedDst THEN
-  632                                             IF et = SymTab.InvalidType THEN
-  633                                               MGen.Drop; MGen.Drop
-  634                                             ELSIF (SymTab.ClassOf(dt)
-  635                                                    = SymTab.ClArray)
-  636                                                & (SymTab.ClassOf(
-  637                                                   SymTab.ArrayElem(dt))
-  638                                                   = SymTab.ClChar)
-  639                                                & (SymTab.ClassOf(et)
-  640                                                   = SymTab.ClStr) THEN
-  641                                               srcBytes :=
-  642                                                 MGen.StrLenOf(lxe) + 1;
-  643                                               dstBytes :=
-  644                                                 SymTab.TypeSlots(dt) * 8;
-  645                                               IF srcBytes > dstBytes THEN
-  646                                                 SemError(210);
-  647                                                 MGen.Drop; MGen.Drop
-  648                                               ELSE
-  649                                                 MGen.PushBytes(srcBytes);
-  650                                                 MGen.CopyBlock
-  651                                               END
-  652                                             ELSIF ~SymTab.Assignable(et,
-  653                                                       dt) THEN
-  654                                               SemError(210);
-  655                                               MGen.Drop; MGen.Drop
-  656                                             ELSE
-  657                                               dstBytes :=
-  658                                                 SymTab.TypeSlots(dt) * 8;
-  659                                               MGen.PushBytes(dstBytes);
-  660                                               MGen.CopyBlock
-  661                                             END
-  662                                           ELSIF pushedFld THEN
+  326                                             ELSIF SymTab.SymKind(n)
+  327                                                = SymTab.KindModule THEN
+  328                                               t := SymTab.InvalidType
+  329                                             ELSIF (SymTab.SymKind(n) #
+  330                                                    SymTab.KindType)
+  331                                                & (SymTab.SymKind(n) #
+  332                                                   SymTab.KindPredef)
+  333                                                & (SymTab.SymKind(n) #
+  334                                                   SymTab.KindImport) THEN
+  335                                               SemError(221);
+  336                                               t := SymTab.InvalidType
+  337                                             ELSE t := SymTab.SymType(n) END; .)
+  338        { "."
+  339          GetIdent<m>                     (. IF SymTab.SymKind(n)
+  340                                              = SymTab.KindModule THEN
+  341                                             IF SymTab.ExpKind(n, m)
+  342                                                = SymTab.KindType THEN
+  343                                               t := SymTab.ExpType(n, m)
+  344                                             ELSE
+  345                                               IF SymTab.ExpKind(n, m) = -1 THEN
+  346                                                 SemError(201)
+  347                                               ELSE SemError(221)
+  348                                               END;
+  349                                               t := SymTab.InvalidType
+  350                                             END
+  351                                           ELSE
+  352                                             t := SymTab.InvalidType
+  353                                           END; .) } .
+  354  
+  355    (* Types: ProcedureType removed; subrange factored for LL(1) *)
+  356    Type <VAR t: SymTab.TypeIndex>
+  357      = SimpleType<t> | ArrayType<t> | RecordType<t>
+  358      | SetType<t> | PointerType<t> .
+  359    SimpleType <VAR t: SymTab.TypeIndex>
+  360                                          (. VAR t1, t2: SymTab.TypeIndex;
+  361                                               lx1, lx2: MGen.LitStr;
+  362                                               vD: BOOLEAN;
+  363                                               vnD: SymTab.Name;
+  364                                               loI, hiI: INTEGER;
+  365                                               lok, hik: BOOLEAN; .)
+  366      = QualIdent<t> [ "["
+  367                        (. MGen.NoEmitEnter; lok := FALSE; hik := FALSE;
+  368                           loI := 0; hiI := -1; .)
+  369                        ConstExpr<t1, lx1> (. IF (t1 # SymTab.InvalidType)
+  370                                              & (SymTab.ClassOf(t1) #
+  371                                                 SymTab.ClInt)
+  372                                              & (SymTab.ClassOf(t1) #
+  373                                                 SymTab.ClChar)
+  374                                              & (SymTab.ClassOf(t1) #
+  375                                                 SymTab.ClEnum) THEN
+  376                                              SemError(224) END; .)
+  377                        ".."
+  378                        ConstExpr<t2, lx2> (. IF (t2 # SymTab.InvalidType)
+  379                                              & (SymTab.ClassOf(t2) #
+  380                                                 SymTab.ClInt)
+  381                                              & (SymTab.ClassOf(t2) #
+  382                                                 SymTab.ClChar)
+  383                                              & (SymTab.ClassOf(t2) #
+  384                                                 SymTab.ClEnum) THEN
+  385                                              SemError(224) END; .)
+  386                        "]"
+  387                                       (. IF (t1 # SymTab.InvalidType)
+  388                                           & (t2 # SymTab.InvalidType) THEN
+  389                                             IF MGen.IsLit(lx1) THEN
+  390                                               IF SymTab.ClassOf(t1)
+  391                                                  = SymTab.ClChar THEN
+  392                                                 loI := MGen.CharOrd(lx1);
+  393                                                 lok := TRUE
+  394                                               ELSIF MGen.ParseInt(lx1, loI) THEN
+  395                                                 lok := TRUE
+  396                                               END
+  397                                             END;
+  398                                             IF MGen.IsLit(lx2) THEN
+  399                                               IF SymTab.ClassOf(t2)
+  400                                                  = SymTab.ClChar THEN
+  401                                                 hiI := MGen.CharOrd(lx2);
+  402                                                 hik := TRUE
+  403                                               ELSIF MGen.ParseInt(lx2, hiI) THEN
+  404                                                 hik := TRUE
+  405                                               END
+  406                                             END
+  407                                           END;
+  408                                          IF lok & hik THEN
+  409                                            t := SymTab.NewSubB(t1, loI, hiI)
+  410                                          ELSE
+  411                                            t := SymTab.NewSub(t1);
+  412                                            IF (t1 # SymTab.InvalidType)
+  413                                               & (t2 # SymTab.InvalidType) THEN
+  414                                              SemError(230)
+  415                                            END
+  416                                          END;
+  417                                          MGen.NoEmitExit; .) ]
+  418      | "["                               (. MGen.NoEmitEnter; lok := FALSE;
+  419                                             hik := FALSE; loI := 0; hiI := -1; .)
+  420        ConstExpr<t1, lx1>                (. IF (t1 # SymTab.InvalidType)
+  421                                              & (SymTab.ClassOf(t1) #
+  422                                                 SymTab.ClInt)
+  423                                              & (SymTab.ClassOf(t1) #
+  424                                                 SymTab.ClChar)
+  425                                              & (SymTab.ClassOf(t1) #
+  426                                                 SymTab.ClEnum) THEN
+  427                                              SemError(224) END; .)
+  428        ".."
+  429        ConstExpr<t2, lx2>                (. IF (t2 # SymTab.InvalidType)
+  430                                              & (SymTab.ClassOf(t2) #
+  431                                                 SymTab.ClInt)
+  432                                              & (SymTab.ClassOf(t2) #
+  433                                                 SymTab.ClChar)
+  434                                              & (SymTab.ClassOf(t2) #
+  435                                                 SymTab.ClEnum) THEN
+  436                                              SemError(224) END; .)
+  437        "]"                               (. IF (t1 # SymTab.InvalidType)
+  438                                             & (t2 # SymTab.InvalidType) THEN
+  439                                               IF MGen.IsLit(lx1) THEN
+  440                                                 IF SymTab.ClassOf(t1)
+  441                                                    = SymTab.ClChar THEN
+  442                                                   loI := MGen.CharOrd(lx1);
+  443                                                   lok := TRUE
+  444                                                 ELSIF MGen.ParseInt(lx1,
+  445                                                           loI) THEN
+  446                                                   lok := TRUE
+  447                                                 END
+  448                                               END;
+  449                                               IF MGen.IsLit(lx2) THEN
+  450                                                 IF SymTab.ClassOf(t2)
+  451                                                    = SymTab.ClChar THEN
+  452                                                   hiI := MGen.CharOrd(lx2);
+  453                                                   hik := TRUE
+  454                                                 ELSIF MGen.ParseInt(lx2,
+  455                                                           hiI) THEN
+  456                                                   hik := TRUE
+  457                                                 END
+  458                                               END
+  459                                             END;
+  460                                            IF lok & hik THEN
+  461                                              t := SymTab.NewSubB(t1, loI, hiI)
+  462                                            ELSE
+  463                                              t := SymTab.NewSub(t1);
+  464                                              IF (t1 # SymTab.InvalidType)
+  465                                                 & (t2 # SymTab.InvalidType) THEN
+  466                                                SemError(230)
+  467                                              END
+  468                                            END;
+  469                                             MGen.NoEmitExit; .)
+  470      | Enum<t> .
+  471    Enum <VAR t: SymTab.TypeIndex>
+  472                                          (. VAR n: SymTab.Name;
+  473                                               ord: INTEGER; .)
+  474      = "("                               (. t := SymTab.NewEnum();
+  475                                             ord := 0; .)
+  476        GetIdent<n>                       (. IF ~SymTab.Enter(n,
+  477                                               SymTab.KindConst)
+  478                                             THEN SemError(200) END;
+  479                                             SymTab.SetSymType(n, t);
+  480                                             SymTab.EnumAdd(t);
+  481                                             MGen.DeclConstInt(n, ord);
+  482                                             INC(ord); .)
+  483        { ","
+  484          GetIdent<n>                     (. IF ~SymTab.Enter(n,
+  485                                               SymTab.KindConst)
+  486                                             THEN SemError(200) END;
+  487                                             SymTab.SetSymType(n, t);
+  488                                             SymTab.EnumAdd(t);
+  489                                             MGen.DeclConstInt(n, ord);
+  490                                             INC(ord); .) }
+  491        ")" .
+  492    ArrayType <VAR t: SymTab.TypeIndex>
+  493                                          (. VAR s, s2, e: SymTab.TypeIndex;
+  494                                               idx: ARRAY [0 .. 7] OF
+  495                                                 SymTab.TypeIndex;
+  496                                               nc, kk: CARDINAL;
+  497                                               loA, hiA: INTEGER;
+  498                                               isOpenA: BOOLEAN; .)
+  499      = "ARRAY"
+  500        [ SimpleType<s>                     (. IF (s # SymTab.InvalidType)
+  501                                              & (SymTab.ClassOf(s) #
+  502                                                 SymTab.ClInt)
+  503                                              & (SymTab.ClassOf(s) #
+  504                                                 SymTab.ClChar)
+  505                                              & (SymTab.ClassOf(s) #
+  506                                                 SymTab.ClEnum) THEN
+  507                                              SemError(224) END;
+  508                                             nc := 0; isOpenA := FALSE;
+  509                                             idx[nc] := s; INC(nc); .)
+  510          { ","
+  511            SimpleType<s2>                  (. IF (s2 # SymTab.InvalidType)
+  512                                              & (SymTab.ClassOf(s2) #
+  513                                                 SymTab.ClInt)
+  514                                              & (SymTab.ClassOf(s2) #
+  515                                                 SymTab.ClChar)
+  516                                              & (SymTab.ClassOf(s2) #
+  517                                                 SymTab.ClEnum) THEN
+  518                                              SemError(224) END;
+  519                                             IF nc <= HIGH(idx) THEN
+  520                                               idx[nc] := s2; INC(nc)
+  521                                             END; .) }
+  522        |                                   (. nc := 0; isOpenA := TRUE; .) ]
+  523        "OF"
+  524        Type<e>                           (. IF isOpenA THEN
+  525                                             t := SymTab.NewOpen(e)
+  526                                           ELSE
+  527                                             t := e;
+  528                                             kk := nc;
+  529                                             WHILE kk > 0 DO
+  530                                               DEC(kk);
+  531                                               loA := SymTab.TypeLo(idx[kk]);
+  532                                               hiA := SymTab.TypeHi(idx[kk]);
+  533                                               IF SymTab.TypeLen(idx[kk]) = 0 THEN
+  534                                                 IF idx[kk]
+  535                                                    # SymTab.InvalidType THEN
+  536                                                   SemError(230)
+  537                                                 END;
+  538                                                 loA := 0; hiA := -1
+  539                                               END;
+  540                                               t := SymTab.NewArrayB(t,
+  541                                                       loA, hiA)
+  542                                             END
+  543                                           END; .) .
+  544    RecordType <VAR t: SymTab.TypeIndex>
+  545      = "RECORD"                          (. t := SymTab.NewRecord(); .)
+  546        FieldSeq<t>
+  547        "END" .
+  548    FieldSeq <rt: SymTab.TypeIndex>
+  549      = Field<rt> { ";"
+  550                    Field<rt> } .
+  551    Field <rt: SymTab.TypeIndex>
+  552                                          (. VAR et: SymTab.TypeIndex; .)
+  553      = [ FieldIdents<rt> ":"
+  554          Type<et>                       (. IF (et # SymTab.InvalidType)
+  555                                             & SymTab.IsOpen(et) THEN
+  556                                             SemError(230)
+  557                                           END;
+  558                                           SymTab.FixPendingF(rt, et); .) ] .
+  559    FieldIdents <rt: SymTab.TypeIndex>
+  560                                          (. VAR n: SymTab.Name; .)
+  561      = GetIdent<n>                       (. IF ~SymTab.FieldPending(rt, n)
+  562                                             THEN SemError(200) END .)
+  563        { ","
+  564          GetIdent<n>                     (. IF ~SymTab.FieldPending(rt, n)
+  565                                             THEN SemError(200) END .) } .
+  566    SetType <VAR t: SymTab.TypeIndex>
+  567                                          (. VAR s: SymTab.TypeIndex; .)
+  568      = "SET"
+  569        "OF"
+  570        SimpleType<s>                     (. IF (s # SymTab.InvalidType)
+  571                                              & (SymTab.ClassOf(s) #
+  572                                                 SymTab.ClInt)
+  573                                              & (SymTab.ClassOf(s) #
+  574                                                 SymTab.ClChar)
+  575                                              & (SymTab.ClassOf(s) #
+  576                                                 SymTab.ClEnum) THEN
+  577                                              SemError(224) END;
+  578                                             t := SymTab.NewSet(s); .) .
+  579    PointerType <VAR t: SymTab.TypeIndex>
+  580                                          (. VAR b: SymTab.TypeIndex; .)
+  581      = "POINTER"
+  582        "TO"
+  583        Type<b>                           (. t := SymTab.NewPtr(b); .) .
+  584  
+  585    (* Statements: RETURN added; calls via AssignOrCall *)
+  586    StatSeq    = Stat { ";"
+  587                       Stat } .
+  588    Stat                                  (. VAR lx: INTEGER; .)
+  589      = [ AssignOrCall | IfStat | CaseStat | WhileStat
+  590        | RepeatStat | LoopStat | ForStat | WithStat | ReturnStat
+  591        | NewStat | DispStat | WriteIntStat | WriteStrStat
+  592        | "EXIT"                 (. IF MGen.TopLoop(lx) THEN
+  593                                      MGen.Jmp(lx)
+  594                                    ELSE SemError(230) END; .) ] .
+  595    AssignOrCall                          (. VAR dt, et: SymTab.TypeIndex;
+  596                                               dk: INTEGER;
+  597                                               bn: SymTab.Name;
+  598                                               lxD, lxe: MGen.LitStr;
+  599                                               vE: BOOLEAN;
+  600                                               vnE: SymTab.Name;
+  601                                               sfx: BOOLEAN;
+  602                                               okC: BOOLEAN;
+  603                                               isR, conv,
+  604                                               storable, pushedDst,
+  605                                               pushedFld: BOOLEAN;
+  606                                               dstBytes, srcBytes: CARDINAL;
+  607                                               elemDt: SymTab.TypeIndex;
+  608                                               modBare: INTEGER; .)
+  609      =                                   (. sfx := FALSE; pushedDst := FALSE;
+  610                                             pushedFld := FALSE; .)
+  611        DesignHead<dt, dk, bn, FALSE, lxD>
+  612        DesignTail<dt, dk, bn, FALSE, lxD, sfx>
+  613        ( ":="
+  614                                          (. storable :=
+  615                                               (dk = SymTab.KindVar)
+  616                                               OR (dk = SymTab.KindParam)
+  617                                               OR (dk = SymTab.KindVarPar);
+  618                                             IF (dk = SymTab.KindField)
+  619                                                & (~sfx)
+  620                                                & (dt # SymTab.InvalidType) THEN
+  621                                               MGen.WithAddr(bn);
+  622                                               pushedFld := TRUE
+  623                                             END;
+  624                                             IF storable & ~sfx
+  625                                                & (dt # SymTab.InvalidType)
+  626                                                & ((SymTab.ClassOf(dt)
+  627                                                   = SymTab.ClArray)
+  628                                                   OR (SymTab.ClassOf(dt)
+  629                                                      = SymTab.ClRecord)) THEN
+  630                                               MGen.PushAddr(bn);
+  631                                               pushedDst := TRUE
+  632                                             ELSIF ((dk = SymTab.KindVar)
+  633                                                    OR (dk
+  634                                                        = SymTab.KindParam)
+  635                                                    OR (dk
+  636                                                        = SymTab.KindVarPar)
+  637                                                    OR (dk
+  638                                                        = SymTab.KindField))
+  639                                                & sfx
+  640                                                & (dt # SymTab.InvalidType)
+  641                                                & ((SymTab.ClassOf(dt)
+  642                                                   = SymTab.ClArray)
+  643                                                   OR (SymTab.ClassOf(dt)
+  644                                                      = SymTab.ClRecord)) THEN
+  645                                               pushedDst := TRUE
+  646                                             END;
+  647                                             IF storable & ~sfx
+  648                                                & ~pushedDst THEN
+  649                                               IF (dt # SymTab.InvalidType)
+  650                                                  & (SymTab.TypeSlots(dt)
+  651                                                     > 1) THEN
+  652                                               ELSE MGen.StoreSetup(bn)
+  653                                               END
+  654                                             END; .)
+  655          Expr<et, lxe, vE, vnE>                                                  (. IF (dt # SymTab.InvalidType)
+  656                                             & (dk # SymTab.KindVar)
+  657                                             & (dk # SymTab.KindParam)
+  658                                             & (dk # SymTab.KindVarPar)
+  659                                             & (dk # SymTab.KindField)
+  660                                             & (dk # SymTab.KindImport) THEN
+  661                                             SemError(210)
+  662                                           ELSIF pushedDst THEN
   663                                             IF et = SymTab.InvalidType THEN
   664                                               MGen.Drop; MGen.Drop
-  665                                             ELSIF (SymTab.TypeSlots(dt) > 1) THEN
-  666                                               IF (SymTab.ClassOf(dt)
-  667                                                  = SymTab.ClArray)
-  668                                                  & (SymTab.ClassOf(
-  669                                                     SymTab.ArrayElem(dt))
-  670                                                     = SymTab.ClChar)
-  671                                                  & (SymTab.ClassOf(et)
-  672                                                     = SymTab.ClStr) THEN
-  673                                                 srcBytes :=
-  674                                                   MGen.StrLenOf(lxe) + 1;
-  675                                                 dstBytes :=
-  676                                                   SymTab.TypeSlots(dt) * 8;
-  677                                                 IF srcBytes > dstBytes THEN
-  678                                                   SemError(210);
-  679                                                   MGen.Drop; MGen.Drop
-  680                                                 ELSE
-  681                                                   MGen.PushBytes(srcBytes);
-  682                                                   MGen.CopyBlock
-  683                                                 END
-  684                                               ELSIF ~SymTab.Assignable(et,
-  685                                                         dt) THEN
-  686                                                 SemError(210);
-  687                                                 MGen.Drop; MGen.Drop
-  688                                               ELSE
-  689                                                 dstBytes :=
-  690                                                   SymTab.TypeSlots(dt) * 8;
-  691                                                 MGen.PushBytes(dstBytes);
-  692                                                 MGen.CopyBlock
-  693                                               END
-  694                                             ELSE
-  695                                               IF ~SymTab.Assignable(et,
-  696                                                         dt) THEN
-  697                                                 SemError(210);
-  698                                                 MGen.Drop; MGen.Drop
-  699                                               ELSE
-  700                                                 isR :=
-  701                                                   (SymTab.ClassOf(dt)
-  702                                                    = SymTab.ClReal);
-  703                                                 conv := isR
-  704                                                   & SymTab.IsIntFamily(et);
-  705                                                 IF conv THEN
-  706                                                   MGen.IntToReal
-  707                                                 END;
-  708                                                 IF (SymTab.ClassOf(dt)
-  709                                                    = SymTab.ClChar)
-  710                                                    OR (SymTab.ClassOf(dt)
-  711                                                       = SymTab.ClBool) THEN
-  712                                                   MGen.StoreByte
-  713                                                 ELSE MGen.StoreIndir0
+  665                                             ELSIF (SymTab.ClassOf(dt)
+  666                                                    = SymTab.ClArray)
+  667                                                & (SymTab.ClassOf(
+  668                                                   SymTab.ArrayElem(dt))
+  669                                                   = SymTab.ClChar)
+  670                                                & (SymTab.ClassOf(et)
+  671                                                   = SymTab.ClStr) THEN
+  672                                               srcBytes :=
+  673                                                 MGen.StrLenOf(lxe) + 1;
+  674                                               dstBytes :=
+  675                                                 SymTab.TypeSlots(dt) * 8;
+  676                                               IF srcBytes > dstBytes THEN
+  677                                                 SemError(210);
+  678                                                 MGen.Drop; MGen.Drop
+  679                                               ELSE
+  680                                                 MGen.PushBytes(srcBytes);
+  681                                                 MGen.CopyBlock
+  682                                               END
+  683                                             ELSIF ~SymTab.Assignable(et,
+  684                                                       dt) THEN
+  685                                               SemError(210);
+  686                                               MGen.Drop; MGen.Drop
+  687                                             ELSE
+  688                                               dstBytes :=
+  689                                                 SymTab.TypeSlots(dt) * 8;
+  690                                               MGen.PushBytes(dstBytes);
+  691                                               MGen.CopyBlock
+  692                                             END
+  693                                           ELSIF pushedFld THEN
+  694                                             IF et = SymTab.InvalidType THEN
+  695                                               MGen.Drop; MGen.Drop
+  696                                             ELSIF (SymTab.TypeSlots(dt) > 1) THEN
+  697                                               IF (SymTab.ClassOf(dt)
+  698                                                  = SymTab.ClArray)
+  699                                                  & (SymTab.ClassOf(
+  700                                                     SymTab.ArrayElem(dt))
+  701                                                     = SymTab.ClChar)
+  702                                                  & (SymTab.ClassOf(et)
+  703                                                     = SymTab.ClStr) THEN
+  704                                                 srcBytes :=
+  705                                                   MGen.StrLenOf(lxe) + 1;
+  706                                                 dstBytes :=
+  707                                                   SymTab.TypeSlots(dt) * 8;
+  708                                                 IF srcBytes > dstBytes THEN
+  709                                                   SemError(210);
+  710                                                   MGen.Drop; MGen.Drop
+  711                                                 ELSE
+  712                                                   MGen.PushBytes(srcBytes);
+  713                                                   MGen.CopyBlock
   714                                                 END
-  715                                               END
-  716                                             END
-  717                                           ELSIF (dt # SymTab.InvalidType)
-  718                                             & ~sfx
-  719                                             & (SymTab.TypeSlots(dt) > 1) THEN
-  720                                             IF ~SymTab.Assignable(et, dt) THEN
-  721                                               SemError(210)
-  722                                             ELSE SemError(230)
-  723                                             END
-  724                                           ELSIF ~SymTab.Assignable(et, dt) THEN
-  725                                             SemError(210) END;
-  726                                           IF dk = SymTab.KindImport THEN
-  727                                             SemError(230)
-  728                                           END;
-  729                                           isR := (dt # SymTab.InvalidType)
-  730                                                  & ~pushedDst
-  731                                                  & ~pushedFld
-  732                                                  & (SymTab.ClassOf(dt)
-  733                                                     = SymTab.ClReal);
-  734                                           conv := isR
+  715                                               ELSIF ~SymTab.Assignable(et,
+  716                                                         dt) THEN
+  717                                                 SemError(210);
+  718                                                 MGen.Drop; MGen.Drop
+  719                                               ELSE
+  720                                                 dstBytes :=
+  721                                                   SymTab.TypeSlots(dt) * 8;
+  722                                                 MGen.PushBytes(dstBytes);
+  723                                                 MGen.CopyBlock
+  724                                               END
+  725                                             ELSE
+  726                                               IF ~SymTab.Assignable(et,
+  727                                                         dt) THEN
+  728                                                 SemError(210);
+  729                                                 MGen.Drop; MGen.Drop
+  730                                               ELSE
+  731                                                 isR :=
+  732                                                   (SymTab.ClassOf(dt)
+  733                                                    = SymTab.ClReal);
+  734                                                 conv := isR
   735                                                   & SymTab.IsIntFamily(et);
-  736                                           IF pushedDst THEN
-  737                                           ELSIF pushedFld THEN
-  738                                           ELSIF (dt # SymTab.InvalidType)
-  739                                              & sfx THEN
-  740                                             IF conv THEN
-  741                                               MGen.IntToReal
-  742                                             END;
-  743                                             IF (SymTab.ClassOf(dt)
-  744                                                = SymTab.ClChar)
-  745                                                OR (SymTab.ClassOf(dt)
-  746                                                   = SymTab.ClBool) THEN
-  747                                               MGen.StoreByte
-  748                                             ELSE MGen.StoreIndir0
-  749                                             END
-  750                                           ELSIF storable & ~sfx THEN
-  751                                             IF (dt # SymTab.InvalidType)
-  752                                                & (SymTab.TypeSlots(dt)
-  753                                                   > 1) THEN
-  754                                               MGen.Drop
-  755                                             ELSE
-  756                                               IF conv THEN
-  757                                                 MGen.IntToReal
-  758                                               END;
-  759                                               MGen.StoreFinish(bn)
-  760                                             END
-  761                                           ELSE MGen.Drop
-  762                                           END; .)
-  763        | CallTail<bn, lxD, sfx, FALSE, okC, FALSE>
-  764        |                             (. IF (SymTab.SymKind(bn)
-  765                                                = SymTab.KindModule)
-  766                                               & sfx
-  767                                               & (SymTab.StrLen(lxD) > 0) THEN
-  768                                             modBare := SymTab.ExpProc(bn,
-  769                                                              lxD);
-  770                                             IF modBare < 0 THEN
-  771                                               IF SymTab.ExpKind(bn,
-  772                                                    lxD) # -1 THEN
-  773                                                 SemError(233)
-  774                                               END
-  775                                             ELSIF SymTab.ProcNParByNum(
-  776                                                      modBare) # 0 THEN
-  777                                               SemError(233)
-  778                                             ELSE
-  779                                               MGen.CallProc(modBare);
-  780                                               IF SymTab.ProcRetByNum(
-  781                                                    modBare)
-  782                                                  # SymTab.InvalidType THEN
-  783                                                 MGen.Drop
-  784                                               END
-  785                                             END
-  786                                           ELSE
-  787                                             MGen.ActBegin(bn);
-  788                                             IF MGen.ActEnd(bn, FALSE,
-  789                                                    FALSE) # 0 THEN
-  790                                               SemError(233)
+  736                                                 IF conv THEN
+  737                                                   MGen.IntToReal
+  738                                                 END;
+  739                                                 IF (SymTab.ClassOf(dt)
+  740                                                    = SymTab.ClChar)
+  741                                                    OR (SymTab.ClassOf(dt)
+  742                                                       = SymTab.ClBool) THEN
+  743                                                   MGen.StoreByte
+  744                                                 ELSE MGen.StoreIndir0
+  745                                                 END
+  746                                               END
+  747                                             END
+  748                                           ELSIF (dt # SymTab.InvalidType)
+  749                                             & ~sfx
+  750                                             & (SymTab.TypeSlots(dt) > 1) THEN
+  751                                             IF ~SymTab.Assignable(et, dt) THEN
+  752                                               SemError(210)
+  753                                             ELSE SemError(230)
+  754                                             END
+  755                                           ELSIF ~SymTab.Assignable(et, dt) THEN
+  756                                             SemError(210) END;
+  757                                           IF dk = SymTab.KindImport THEN
+  758                                             SemError(230)
+  759                                           END;
+  760                                           isR := (dt # SymTab.InvalidType)
+  761                                                  & ~pushedDst
+  762                                                  & ~pushedFld
+  763                                                  & (SymTab.ClassOf(dt)
+  764                                                     = SymTab.ClReal);
+  765                                           conv := isR
+  766                                                   & SymTab.IsIntFamily(et);
+  767                                           IF pushedDst THEN
+  768                                           ELSIF pushedFld THEN
+  769                                           ELSIF (dt # SymTab.InvalidType)
+  770                                              & sfx THEN
+  771                                             IF conv THEN
+  772                                               MGen.IntToReal
+  773                                             END;
+  774                                             IF (SymTab.ClassOf(dt)
+  775                                                = SymTab.ClChar)
+  776                                                OR (SymTab.ClassOf(dt)
+  777                                                   = SymTab.ClBool) THEN
+  778                                               MGen.StoreByte
+  779                                             ELSE MGen.StoreIndir0
+  780                                             END
+  781                                           ELSIF storable & ~sfx THEN
+  782                                             IF (dt # SymTab.InvalidType)
+  783                                                & (SymTab.TypeSlots(dt)
+  784                                                   > 1) THEN
+  785                                               MGen.Drop
+  786                                             ELSE
+  787                                               IF conv THEN
+  788                                                 MGen.IntToReal
+  789                                               END;
+  790                                               MGen.StoreFinish(bn)
   791                                             END
-  792                                           END; .) ) .
-  793    CallTail <pn: SymTab.Name; exp: SymTab.Name; sfx: BOOLEAN;
-  794              inExpr: BOOLEAN; VAR ok: BOOLEAN; hasDead: BOOLEAN>
-  795                                          (. VAR t: SymTab.TypeIndex;
-  796                                               lx: MGen.LitStr;
-  797                                               v: BOOLEAN;
-  798                                               vn: SymTab.Name;
-  799                                               isModP: BOOLEAN;
-  800                                               modPNum: INTEGER;
-  801                                               modErr: BOOLEAN; .)
-  802      = "("                               (. ok := FALSE; modErr := FALSE;
-  803                                             isModP :=
-  804                                               (SymTab.SymKind(pn)
-  805                                                = SymTab.KindModule)
-  806                                               & sfx
-  807                                               & (SymTab.StrLen(exp) > 0);
-  808                                             IF hasDead THEN MGen.Drop END;
-  809                                             IF isModP THEN
-  810                                               modPNum := SymTab.ExpProc(pn,
-  811                                                                exp);
-  812                                               IF modPNum < 0 THEN
-  813                                                 IF SymTab.ExpKind(pn,
-  814                                                      exp) # -1 THEN
-  815                                                   SemError(233)
-  816                                                 END;
-  817                                                 modErr := TRUE
-  818                                               ELSIF inExpr
-  819                                                  & (SymTab.ProcRetByNum(
-  820                                                       modPNum)
-  821                                                     = SymTab.InvalidType)
-  822                                               THEN
-  823                                                 SemError(233);
-  824                                                 modErr := TRUE
-  825                                               END;
-  826                                               MGen.ActBeginNum(modPNum)
-  827                                             ELSE
-  828                                               MGen.ActBegin(pn)
-  829                                             END; .)
-  830        [ Expr<t, lx, v, vn>              (. IF isModP THEN
-  831                                             IF ~modErr
-  832                                                & (MGen.ActValue(t, v, vn)
-  833                                                   # 0) THEN
-  834                                               SemError(233);
-  835                                               modErr := TRUE
-  836                                             END
-  837                                           ELSIF MGen.ActValue(t, v, vn) # 0 THEN
-  838                                             SemError(233)
-  839                                           END; .)
-  840          { "," Expr<t, lx, v, vn>        (. IF isModP THEN
-  841                                             IF ~modErr
-  842                                                & (MGen.ActValue(t, v, vn)
-  843                                                   # 0) THEN
-  844                                               SemError(233);
-  845                                               modErr := TRUE
-  846                                             END
-  847                                           ELSIF MGen.ActValue(t, v, vn) # 0 THEN
-  848                                             SemError(233)
-  849                                           END; .) } ]
-  850        ")"                               (. IF isModP THEN
-  851                                             IF ~modErr THEN
-  852                                               IF MGen.ActEndNum(modPNum,
-  853                                                    inExpr) # 0 THEN
-  854                                                 SemError(233)
-  855                                               ELSE ok := TRUE
-  856                                               END
-  857                                             END
-  858                                           ELSIF MGen.ActEnd(pn, sfx,
-  859                                                    inExpr) # 0
-  860                                           THEN SemError(233)
-  861                                           ELSE ok := TRUE
-  862                                           END; .) .
-  863    IfStat                                (. VAR t: SymTab.TypeIndex;
-  864                                               lxC: MGen.LitStr;
-  865                                               vC: BOOLEAN;
-  866                                               vnC: SymTab.Name;
-  867                                               elseL, endL: INTEGER;
-  868                                               hasElse: BOOLEAN; .)
-  869      = "IF"
-  870        Expr<t, lxC, vC, vnC>             (. IF ~SymTab.BoolCheck(t) THEN
-  871                                             SemError(214) END;
-  872                                             elseL := MGen.NewLabel();
-  873                                             endL := MGen.NewLabel();
-  874                                             MGen.Jz(elseL);
-  875                                             hasElse := FALSE; .)
-  876        "THEN"
-  877        StatSeq
-  878        { "ELSIF"                         (. MGen.Jmp(endL);
-  879                                             MGen.DefLabel(elseL); .)
-  880          Expr<t, lxC, vC, vnC>           (. IF ~SymTab.BoolCheck(t) THEN
-  881                                             SemError(214) END;
-  882                                             elseL := MGen.NewLabel();
-  883                                             MGen.Jz(elseL); .)
-  884          "THEN"
-  885          StatSeq }
-  886        [ "ELSE"                          (. MGen.Jmp(endL);
-  887                                             MGen.DefLabel(elseL);
-  888                                             hasElse := TRUE; .)
-  889          StatSeq ]
-  890        "END"                             (. IF ~hasElse THEN
-  891                                             MGen.DefLabel(elseL)
-  892                                           END;
-  893                                           MGen.DefLabel(endL); .) .
-  894    CaseStat                              (. VAR st: SymTab.TypeIndex;
-  895                                               lxS: MGen.LitStr;
-  896                                               vS: BOOLEAN;
-  897                                               vnS: SymTab.Name;
-  898                                               tmp, endL: INTEGER; .)
-  899      = "CASE"
-  900        Expr<st, lxS, vS, vnS>            (. tmp := MGen.TempGlobal();
-  901                                             MGen.StoreTemp(tmp);
-  902                                             endL := MGen.NewLabel(); .)
-  903        "OF"
-  904        Case<st, tmp, endL> { "|"
-  905                   Case<st, tmp, endL> }
-  906        [ "ELSE"
-  907          StatSeq ]
-  908        "END"                             (. MGen.DefLabel(endL); .) .
-  909    Case <sel: SymTab.TypeIndex; tmp: INTEGER; endL: INTEGER>
-  910                                          (. VAR lB, lN: INTEGER; .)
-  911      = [ LabelList<sel, tmp, lB, lN> ":" (. MGen.DefLabel(lB); .)
-  912          StatSeq                         (. MGen.Jmp(endL);
-  913                                             MGen.DefLabel(lN); .) ] .
-  914    LabelList <sel: SymTab.TypeIndex; tmp: INTEGER;
-  915               VAR lB: INTEGER; VAR lN: INTEGER>
-  916      =                                   (. lB := MGen.NewLabel();
-  917                                             lN := MGen.NewLabel(); .)
-  918        Labels<sel, tmp, lB> { ","
-  919                      Labels<sel, tmp, lB> }
-  920                                          (. MGen.Jmp(lN); .) .
-  921    Labels <sel: SymTab.TypeIndex; tmp: INTEGER; bodyL: INTEGER>
-  922                                          (. VAR t, t2: SymTab.TypeIndex;
-  923                                               lx1, lx2: MGen.LitStr;
-  924                                               v1, v2: BOOLEAN;
-  925                                               vn1, vn2: SymTab.Name;
-  926                                               ta, tb, chunk: INTEGER;
-  927                                               r, hasRange: BOOLEAN; .)
-  928      = ConstExpr<t, lx1>                 (. IF ~SymTab.EqCheck(t, sel) THEN
-  929                                             SemError(213) END;
-  930                                             r := (SymTab.ClassOf(sel)
-  931                                                   = SymTab.ClReal)
-  932                                                  & (SymTab.ClassOf(t)
-  933                                                     = SymTab.ClReal);
-  934                                             ta := MGen.TempGlobal();
-  935                                             MGen.StoreTemp(ta);
-  936                                             hasRange := FALSE; .)
-  937        [ ".."
-  938          ConstExpr<t2, lx2>              (. IF ~SymTab.EqCheck(t2, sel) THEN
-  939                                             SemError(213) END;
-  940                                             tb := MGen.TempGlobal();
-  941                                             MGen.StoreTemp(tb);
-  942                                             hasRange := TRUE; .) ]
-  943                                          (. IF hasRange THEN
-  944                                               MGen.LoadTemp(tmp);
-  945                                               MGen.LoadTemp(ta);
-  946                                               IF r THEN MGen.RealGe
-  947                                               ELSE MGen.IGe END;
-  948                                               MGen.LoadTemp(tmp);
-  949                                               MGen.LoadTemp(tb);
-  950                                               IF r THEN MGen.RealLe
-  951                                               ELSE MGen.ILe END;
-  952                                               MGen.And
-  953                                             ELSE
-  954                                               MGen.LoadTemp(tmp);
-  955                                               MGen.LoadTemp(ta);
-  956                                               IF r THEN MGen.RealEq
-  957                                               ELSE MGen.Eq END
-  958                                             END;
-  959                                             chunk := MGen.NewLabel();
-  960                                             MGen.Jz(chunk);
-  961                                             MGen.Jmp(bodyL);
-  962                                             MGen.DefLabel(chunk); .) .
-  963    WhileStat                             (. VAR t: SymTab.TypeIndex;
-  964                                               lxC: MGen.LitStr;
-  965                                               vC: BOOLEAN;
-  966                                               vnC: SymTab.Name;
-  967                                               topL, endL: INTEGER; .)
-  968      = "WHILE"                           (. topL := MGen.NewLabel();
-  969                                             endL := MGen.NewLabel();
-  970                                             MGen.DefLabel(topL); .)
-  971        Expr<t, lxC, vC, vnC>             (. IF ~SymTab.BoolCheck(t) THEN
-  972                                             SemError(214) END;
-  973                                             MGen.Jz(endL); .)
-  974        "DO"
-  975        StatSeq
-  976        "END"                             (. MGen.Jmp(topL);
-  977                                             MGen.DefLabel(endL); .) .
-  978    RepeatStat                            (. VAR t: SymTab.TypeIndex;
-  979                                               lxC: MGen.LitStr;
-  980                                               vC: BOOLEAN;
-  981                                               vnC: SymTab.Name;
-  982                                               topL: INTEGER; .)
-  983      = "REPEAT"                          (. topL := MGen.NewLabel();
-  984                                             MGen.DefLabel(topL); .)
-  985        StatSeq
-  986        "UNTIL"
-  987        Expr<t, lxC, vC, vnC>             (. IF ~SymTab.BoolCheck(t) THEN
-  988                                             SemError(214) END;
-  989                                             MGen.Jz(topL); .) .
-  990    LoopStat                              (. VAR topL, exitL: INTEGER; .)
-  991      = "LOOP"                            (. topL := MGen.NewLabel();
-  992                                             exitL := MGen.NewLabel();
-  993                                             MGen.DefLabel(topL);
-  994                                             MGen.PushLoop(exitL); .)
-  995        StatSeq
-  996        "END"                             (. MGen.Jmp(topL);
-  997                                             MGen.DefLabel(exitL);
-  998                                             MGen.PopLoop; .) .
-  999    ForStat                               (. VAR n, lv: SymTab.Name;
- 1000                                               fk: INTEGER;
- 1001                                               lo, hi: SymTab.TypeIndex;
- 1002                                               lxLo, lxHi: MGen.LitStr;
- 1003                                               vLo, vHi: BOOLEAN;
- 1004                                               vnLo, vnHi: SymTab.Name;
- 1005                                               byV, ht: INTEGER;
- 1006                                               lTop, lChk, lEnd: INTEGER;
- 1007                                               neg, storable: BOOLEAN; .)
- 1008      = "FOR"
- 1009        GetIdent<n>                       (. IF ~SymTab.Lookup(n) THEN
- 1010                                              SemError(201);
- 1011                                              fk := -1
- 1012                                            ELSIF (SymTab.SymKind(n) #
- 1013                                                   SymTab.KindVar)
- 1014                                              & (SymTab.SymKind(n) #
- 1015                                                 SymTab.KindParam)
- 1016                                              & (SymTab.SymKind(n) #
- 1017                                                 SymTab.KindVarPar)
- 1018                                              & (SymTab.SymKind(n) #
- 1019                                                 SymTab.KindField) THEN
- 1020                                              SemError(220);
- 1021                                              fk := -1
- 1022                                            ELSIF (SymTab.SymType(n) #
- 1023                                                   SymTab.InvalidType)
- 1024                                              & ~SymTab.IsIntFamily(
- 1025                                                  SymTab.SymType(n)) THEN
- 1026                                              SemError(220);
- 1027                                              fk := -1
- 1028                                            ELSE
- 1029                                              fk := SymTab.SymKind(n)
- 1030                                            END;
- 1031                                            MGen.CopyName(n, lv);
- 1032                                            storable := (fk = SymTab.KindVar)
- 1033                                              OR (fk = SymTab.KindParam)
- 1034                                              OR (fk = SymTab.KindVarPar);
- 1035                                            IF storable THEN
- 1036                                              MGen.StoreSetup(lv)
- 1037                                            END; .)
- 1038        ":="
- 1039        Expr<lo, lxLo, vLo, vnLo>         (. IF (lo # SymTab.InvalidType)
- 1040                                             & ~SymTab.IsIntFamily(lo) THEN
- 1041                                             SemError(220) END;
- 1042                                             IF storable THEN
- 1043                                               MGen.StoreFinish(lv)
- 1044                                             ELSE MGen.Drop
- 1045                                             END; .)
- 1046        "TO"
- 1047        Expr<hi, lxHi, vHi, vnHi>         (. IF (hi # SymTab.InvalidType)
- 1048                                             & ~SymTab.IsIntFamily(hi) THEN
- 1049                                             SemError(220) END;
- 1050                                             ht := MGen.TempGlobal();
- 1051                                             MGen.StoreTemp(ht);
- 1052                                             byV := 1; neg := FALSE; .)
- 1053        [ "BY"
- 1054          ByLit<byV>                      (. neg := byV < 0; .) ]
- 1055        "DO"                              (. lTop := MGen.NewLabel();
- 1056                                             lChk := MGen.NewLabel();
- 1057                                             lEnd := MGen.NewLabel();
- 1058                                             MGen.Jmp(lChk);
- 1059                                             MGen.DefLabel(lTop); .)
- 1060        StatSeq
- 1061        "END"                             (. MGen.PushVar(lv);
- 1062                                             MGen.PushInt(byV);
- 1063                                             MGen.Add;
- 1064                                             IF storable THEN
- 1065                                               MGen.StoreFinish(lv)
- 1066                                             ELSE MGen.Drop
- 1067                                             END;
- 1068                                             MGen.DefLabel(lChk);
- 1069                                             MGen.PushVar(lv);
- 1070                                             MGen.LoadTemp(ht);
- 1071                                             IF neg THEN MGen.IGe
- 1072                                             ELSE MGen.ILe END;
- 1073                                             MGen.Jz(lEnd);
- 1074                                             MGen.Jmp(lTop);
- 1075                                             MGen.DefLabel(lEnd); .) .
- 1076    ByLit <VAR v: INTEGER>                (. VAR s: ARRAY [0 .. 255] OF CHAR; .)
- 1077      = integer                           (. LexString(s);
- 1078                                             IF ~MGen.ParseInt(s, v) THEN
- 1079                                               v := 1
- 1080                                             END; .)
- 1081      | "-" integer                       (. LexString(s);
- 1082                                             IF MGen.ParseInt(s, v) THEN
- 1083                                               v := -v
- 1084                                             ELSE v := -1
- 1085                                             END; .) .
- 1086    WithStat                              (. VAR dt: SymTab.TypeIndex;
- 1087                                               dk: INTEGER;
- 1088                                               bnW: SymTab.Name;
- 1089                                               lxW: MGen.LitStr;
- 1090                                               sfxW: BOOLEAN;
- 1091                                               pushed: BOOLEAN; .)
- 1092      = "WITH"
- 1093        DesignHead<dt, dk, bnW, FALSE, lxW>
- 1094        DesignTail<dt, dk, bnW, FALSE, lxW, sfxW>
- 1095                                        (. pushed := FALSE;
- 1096                                             IF dt = SymTab.InvalidType THEN
- 1097                                               IF sfxW THEN MGen.Drop END
- 1098                                             ELSIF SymTab.ClassOf(dt)
- 1099                                                    # SymTab.ClRecord THEN
- 1100                                               SemError(215);
- 1101                                               IF sfxW THEN MGen.Drop END
- 1102                                             ELSE
- 1103                                               IF ~sfxW THEN
- 1104                                                 IF (dk
- 1105                                                    = SymTab.KindVar)
- 1106                                                    OR (dk
- 1107                                                       = SymTab.KindParam)
- 1108                                                    OR (dk
- 1109                                                    = SymTab.KindVarPar) THEN
- 1110                                                   MGen.PushAddr(bnW)
- 1111                                                 ELSIF dk
- 1112                                                   = SymTab.KindField THEN
- 1113                                                   MGen.WithAddr(bnW)
- 1114                                                 ELSE MGen.PushInt(0)
- 1115                                                 END
- 1116                                               END;
- 1117                                               MGen.WithEnter(dt);
- 1118                                               pushed :=
- 1119                                                 SymTab.PushRecord(dt);
- 1120                                               IF ~pushed THEN
- 1121                                                 SemError(215)
- 1122                                               END
- 1123                                             END; .)
- 1124        "DO"
- 1125        StatSeq
- 1126        "END"                             (. IF pushed THEN
- 1127                                               SymTab.PopScope;
- 1128                                               MGen.WithExit
- 1129                                             END; .) .
- 1130    ReturnStat                            (. VAR t: SymTab.TypeIndex;
- 1131                                               lx: MGen.LitStr;
- 1132                                               v: BOOLEAN;
- 1133                                               vn: SymTab.Name;
- 1134                                               hasE, doRet, conv: BOOLEAN; .)
- 1135      = "RETURN"                          (. hasE := FALSE; .)
- 1136        [ Expr<t, lx, v, vn>              (. hasE := TRUE;
- 1137                                             doRet := FALSE;
- 1138                                             IF ~SymTab.InProc() THEN
- 1139                                               SemError(232)
- 1140                                             ELSIF ~SymTab.InFunction() THEN
- 1141                                               SemError(232)
- 1142                                             ELSIF ~SymTab.Assignable(
- 1143                                                       t, SymTab.CurRet()) THEN
- 1144                                               SemError(232)
- 1145                                             ELSE doRet := TRUE
- 1146                                             END;
- 1147                                             conv := doRet
- 1148                                                     & SymTab.IsIntFamily(t)
- 1149                                                     & (SymTab.ClassOf(
- 1150                                                          SymTab.CurRet())
- 1151                                                        = SymTab.ClReal);
- 1152                                             IF doRet THEN
- 1153                                               IF conv THEN
- 1154                                                 MGen.IntToReal
- 1155                                               END;
- 1156                                               MGen.Leave(
- 1157                                                 SymTab.CurNPar(), TRUE)
- 1158                                             ELSE MGen.Drop
- 1159                                             END; .) ]
- 1160                                           (. IF ~hasE THEN
- 1161                                               IF ~SymTab.InProc() THEN
- 1162                                                 SemError(232)
- 1163                                               ELSIF SymTab.InFunction() THEN
- 1164                                                 SemError(232)
- 1165                                               ELSE MGen.Leave(
- 1166                                                 SymTab.CurNPar(), FALSE)
- 1167                                               END
- 1168                                             END; .) .
- 1169    NewStat                               (. VAR dt: SymTab.TypeIndex;
- 1170                                               dk: INTEGER;
- 1171                                               bnN: SymTab.Name;
- 1172                                               lxN: MGen.LitStr;
- 1173                                               sfxN: BOOLEAN;
- 1174                                               baseT: SymTab.TypeIndex;
- 1175                                               slN: CARDINAL; .)
- 1176      = "NEW"
- 1177        "(" DesignHead<dt, dk, bnN, FALSE, lxN>
- 1178            DesignTail<dt, dk, bnN, FALSE, lxN, sfxN>
- 1179        ")"                               (. IF dt = SymTab.InvalidType THEN
- 1180                                             IF sfxN THEN MGen.Drop END
- 1181                                           ELSIF SymTab.ClassOf(dt)
- 1182                                                  # SymTab.ClPtr THEN
- 1183                                             SemError(219);
- 1184                                             IF sfxN THEN MGen.Drop END
- 1185                                           ELSE
- 1186                                             baseT := SymTab.PtrBase(dt);
- 1187                                             slN := SymTab.TypeSlots(baseT);
- 1188                                             IF slN = 0 THEN
- 1189                                               SemError(230);
- 1190                                               slN := 1
- 1191                                             END;
- 1192                                             IF ~sfxN THEN
- 1193                                               IF (dk = SymTab.KindVar)
- 1194                                                  OR (dk
- 1195                                                      = SymTab.KindParam)
- 1196                                                  OR (dk
- 1197                                                   = SymTab.KindVarPar) THEN
- 1198                                                 MGen.PushAddr(bnN)
- 1199                                               ELSIF dk
- 1200                                                 = SymTab.KindField THEN
- 1201                                                 MGen.WithAddr(bnN)
- 1202                                               ELSE MGen.PushInt(0)
- 1203                                               END
- 1204                                             END;
- 1205                                             MGen.PushBytes(slN * 8);
- 1206                                             MGen.AllocOp
- 1207                                           END; .) .
- 1208    DispStat                              (. VAR dt: SymTab.TypeIndex;
- 1209                                               dk: INTEGER;
- 1210                                               bnD: SymTab.Name;
- 1211                                               lxD: MGen.LitStr;
- 1212                                               sfxD: BOOLEAN;
- 1213                                               baseT: SymTab.TypeIndex;
- 1214                                               slD: CARDINAL; .)
- 1215      = "DISPOSE"
- 1216        "(" DesignHead<dt, dk, bnD, FALSE, lxD>
- 1217            DesignTail<dt, dk, bnD, FALSE, lxD, sfxD>
- 1218        ")"                               (. IF dt = SymTab.InvalidType THEN
- 1219                                             IF sfxD THEN MGen.Drop END
- 1220                                           ELSIF SymTab.ClassOf(dt)
- 1221                                                  # SymTab.ClPtr THEN
- 1222                                             SemError(219);
- 1223                                             IF sfxD THEN MGen.Drop END
- 1224                                           ELSE
- 1225                                             baseT := SymTab.PtrBase(dt);
- 1226                                             slD := SymTab.TypeSlots(baseT);
- 1227                                             IF slD = 0 THEN
- 1228                                               SemError(230);
- 1229                                               slD := 1
- 1230                                             END;
- 1231                                             IF ~sfxD THEN
- 1232                                               IF (dk = SymTab.KindVar)
- 1233                                                  OR (dk
- 1234                                                      = SymTab.KindParam)
- 1235                                                  OR (dk
- 1236                                                   = SymTab.KindVarPar) THEN
- 1237                                                 MGen.PushAddr(bnD)
- 1238                                               ELSIF dk
- 1239                                                 = SymTab.KindField THEN
- 1240                                                 MGen.WithAddr(bnD)
- 1241                                               ELSE MGen.PushInt(0)
- 1242                                               END
- 1243                                             END;
- 1244                                             MGen.PushBytes(slD * 8);
- 1245                                             MGen.DeallocOp
- 1246                                           END; .) .
- 1247    WriteIntStat                          (. VAR t: SymTab.TypeIndex;
- 1248                                               lx: MGen.LitStr;
- 1249                                               v: BOOLEAN;
- 1250                                               vn: SymTab.Name; .)
- 1251      = "WriteInt"
- 1252        "(" Expr<t, lx, v, vn> ")"        (. IF t = SymTab.InvalidType THEN
- 1253                                             MGen.Drop
- 1254                                           ELSIF ~SymTab.IsIntFamily(t) THEN
- 1255                                             SemError(210);
- 1256                                             MGen.Drop
- 1257                                           ELSE
- 1258                                             MGen.CallPrint
- 1259                                           END; .) .
- 1260    WriteStrStat                          (. VAR t: SymTab.TypeIndex;
- 1261                                               lx: MGen.LitStr;
- 1262                                               v: BOOLEAN;
- 1263                                               vn: SymTab.Name; .)
- 1264      = "WriteString"
- 1265        "(" Expr<t, lx, v, vn> ")"        (. IF t = SymTab.InvalidType THEN
- 1266                                             MGen.Drop
- 1267                                           ELSIF (SymTab.ClassOf(t)
- 1268                                                  = SymTab.ClStr) THEN
- 1269                                             MGen.PushInt(1);
- 1270                                             MGen.SysCall
- 1271                                           ELSIF (SymTab.ClassOf(t)
- 1272                                                  = SymTab.ClArray)
- 1273                                              & (SymTab.ClassOf(
- 1274                                                 SymTab.ArrayElem(t))
- 1275                                                 = SymTab.ClChar) THEN
- 1276                                             MGen.PushInt(1);
- 1277                                             MGen.SysCall
- 1278                                           ELSE
- 1279                                             SemError(210);
- 1280                                             MGen.Drop
- 1281                                           END; .) .
- 1282  
- 1283    (* Expressions: Designator without ActualParameters (calls use
- 1284       CallTail). Each expression synthesizes its SymTab type in t,
- 1285       the source text in lx for single literals ("" otherwise), and
- 1286       whether it is a plain variable (v/vn) for VAR actuals.
- 1287       Values travel on the MC64 stack. *)
- 1288    DesignHead <VAR t: SymTab.TypeIndex; VAR k: INTEGER;
- 1289                VAR bn: SymTab.Name; doLoad: BOOLEAN; VAR lx: MGen.LitStr>
- 1290                                          (. VAR n: SymTab.Name;
- 1291                                               cls: INTEGER; .)
- 1292      = GetIdent<n>                       (. MGen.CopyName(n, bn);
- 1293                                             lx[0] := 0C;
- 1294                                             IF ~SymTab.Lookup(n) THEN
- 1295                                               SemError(201);
- 1296                                               t := SymTab.InvalidType; k := -1;
- 1297                                               IF doLoad THEN
- 1298                                                 MGen.PushInt(0)
- 1299                                               END
- 1300                                             ELSE
- 1301                                               t := SymTab.SymType(n);
- 1302                                               k := SymTab.SymKind(n);
- 1303                                               IF k = SymTab.KindConst THEN
- 1304                                                 IF SymTab.Equal(n, "TRUE") THEN
- 1305                                                   t := SymTab.BoolType();
- 1306                                                   MGen.CopyName("TRUE", lx);
- 1307                                                   IF doLoad THEN
- 1308                                                     MGen.PushInt(1)
- 1309                                                   END
- 1310                                                 ELSIF SymTab.Equal(n,
- 1311                                                         "FALSE") THEN
- 1312                                                   t := SymTab.BoolType();
- 1313                                                   MGen.CopyName("FALSE", lx);
- 1314                                                   IF doLoad THEN
- 1315                                                     MGen.PushInt(0)
- 1316                                                   END
- 1317                                                 ELSE
- 1318                                                   cls :=
- 1319                                                     SymTab.ClassOf(t);
- 1320                                                   IF (t #
- 1321                                                       SymTab.InvalidType)
- 1322                                                      & (cls # SymTab.ClStr)
- 1323                                                      & ((cls = SymTab.ClInt)
- 1324                                                      OR (cls = SymTab.ClReal)
- 1325                                                      OR (cls = SymTab.ClBool)
- 1326                                                      OR (cls = SymTab.ClChar)
- 1327                                                      OR (cls
- 1328                                                          = SymTab.ClEnum)) THEN
- 1329                                                     IF doLoad THEN
- 1330                                                       MGen.LoadVar(n)
- 1331                                                     END
- 1332                                                   ELSIF doLoad THEN
- 1333                                                     MGen.PushInt(0)
- 1334                                                   END
- 1335                                                 END
- 1336                                                ELSIF (k = SymTab.KindVar)
- 1337                                                   OR (k = SymTab.KindParam)
- 1338                                                   OR (k
- 1339                                                       = SymTab.KindVarPar) THEN
- 1340                                                  cls := SymTab.ClassOf(t);
- 1341                                                  IF (cls = SymTab.ClInt)
- 1342                                                     OR (cls = SymTab.ClReal)
- 1343                                                     OR (cls = SymTab.ClBool)
- 1344                                                     OR (cls = SymTab.ClChar)
- 1345                                                     OR (cls
- 1346                                                         = SymTab.ClEnum)
- 1347                                                     OR (cls
- 1348                                                         = SymTab.ClSet)
- 1349                                                     OR (cls
- 1350                                                         = SymTab.ClPtr) THEN
- 1351                                                    IF doLoad THEN
- 1352                                                      MGen.PushVar(n)
- 1353                                                    END
- 1354                                                  ELSIF (cls
- 1355                                                         = SymTab.ClArray)
- 1356                                                     OR (cls
- 1357                                                         = SymTab.ClRecord) THEN
- 1358                                                    IF doLoad THEN
- 1359                                                      MGen.PushAddr(n)
- 1360                                                    END
- 1361                                                  ELSIF t
- 1362                                                    = SymTab.InvalidType THEN
- 1363                                                    IF doLoad THEN
- 1364                                                      MGen.PushInt(0)
- 1365                                                    END
- 1366                                                  ELSE SemError(230);
- 1367                                                    IF doLoad THEN
- 1368                                                      MGen.PushInt(0)
- 1369                                                    END
- 1370                                                  END
- 1371                                               ELSE
- 1372                                                 IF doLoad THEN
- 1373                                                   IF k = SymTab.KindField THEN
- 1374                                                     MGen.WithAddr(n);
- 1375                                                     cls := SymTab.ClassOf(t);
- 1376                                                     IF (t
- 1377                                                        = SymTab.InvalidType)
- 1378                                                        OR (cls
- 1379                                                           = SymTab.ClArray)
- 1380                                                        OR (cls
- 1381                                                           = SymTab.ClRecord) THEN
- 1382                                                     ELSE
- 1383                                                       IF (cls
- 1384                                                          = SymTab.ClChar)
- 1385                                                          OR (cls
- 1386                                                             = SymTab.ClBool) THEN
- 1387                                                         MGen.LoadByte
- 1388                                                       ELSE MGen.LoadIndir
- 1389                                                       END
- 1390                                                     END
- 1391                                                   ELSE MGen.PushInt(0)
- 1392                                                   END
- 1393                                                 END;
- 1394                                                 IF k = SymTab.KindField THEN
- 1395                                                 ELSIF k
- 1396                                                       = SymTab.KindImport THEN
- 1397                                                   SemError(230)
- 1398                                                 END
- 1399                                               END
- 1400                                             END; .) .
- 1401    DesignTail <VAR t: SymTab.TypeIndex; VAR k: INTEGER;
- 1402                VAR bn: SymTab.Name; doLoad: BOOLEAN; VAR lx: MGen.LitStr;
- 1403                VAR sfx: BOOLEAN>
- 1404                                          (. VAR m: SymTab.Name;
- 1405                                               it: SymTab.TypeIndex;
- 1406                                               lxI: MGen.LitStr;
- 1407                                               vI: BOOLEAN;
- 1408                                               vnI: SymTab.Name;
- 1409                                               loA: INTEGER;
- 1410                                               elemT: SymTab.TypeIndex;
- 1411                                               esl, ebytes: CARDINAL;
- 1412                                               firstT: BOOLEAN;
- 1413                                               clsI: INTEGER;
- 1414                                               qM: SymTab.Name; .)
- 1415      =                                   (. sfx := FALSE; .)
- 1416        { "."                             (. firstT := ~sfx;
- 1417                                             sfx := TRUE; lx[0] := 0C;
- 1418                                             IF ~doLoad & firstT THEN
- 1419                                               IF (k = SymTab.KindVar)
- 1420                                                  OR (k = SymTab.KindParam)
- 1421                                                  OR (k
- 1422                                                      = SymTab.KindVarPar) THEN
- 1423                                                 MGen.PushAddr(bn)
- 1424                                               ELSIF k
- 1425                                                 = SymTab.KindField THEN
- 1426                                                 MGen.WithAddr(bn)
- 1427                                               ELSIF k
- 1428                                                 = SymTab.KindModule THEN
- 1429                                               ELSE MGen.PushInt(0)
+  792                                           ELSE MGen.Drop
+  793                                           END; .)
+  794        | CallTail<bn, lxD, sfx, FALSE, okC, FALSE>
+  795        |                             (. IF (SymTab.SymKind(bn)
+  796                                                = SymTab.KindModule)
+  797                                               & sfx
+  798                                               & (SymTab.StrLen(lxD) > 0) THEN
+  799                                             modBare := SymTab.ExpProc(bn,
+  800                                                              lxD);
+  801                                             IF modBare < 0 THEN
+  802                                               IF SymTab.ExpKind(bn,
+  803                                                    lxD) # -1 THEN
+  804                                                 SemError(233)
+  805                                               END
+  806                                             ELSIF SymTab.ProcNParByNum(
+  807                                                      modBare) # 0 THEN
+  808                                               SemError(233)
+  809                                             ELSE
+  810                                               MGen.CallProc(modBare);
+  811                                               IF SymTab.ProcRetByNum(
+  812                                                    modBare)
+  813                                                  # SymTab.InvalidType THEN
+  814                                                 MGen.Drop
+  815                                               END
+  816                                             END
+  817                                           ELSE
+  818                                             MGen.ActBegin(bn);
+  819                                             IF MGen.ActEnd(bn, FALSE,
+  820                                                    FALSE) # 0 THEN
+  821                                               SemError(233)
+  822                                             END
+  823                                           END; .) ) .
+  824    CallTail <pn: SymTab.Name; exp: SymTab.Name; sfx: BOOLEAN;
+  825              inExpr: BOOLEAN; VAR ok: BOOLEAN; hasDead: BOOLEAN>
+  826                                          (. VAR t: SymTab.TypeIndex;
+  827                                               lx: MGen.LitStr;
+  828                                               v: BOOLEAN;
+  829                                               vn: SymTab.Name;
+  830                                               isModP: BOOLEAN;
+  831                                               modPNum: INTEGER;
+  832                                               modErr: BOOLEAN; .)
+  833      = "("                               (. ok := FALSE; modErr := FALSE;
+  834                                             isModP :=
+  835                                               (SymTab.SymKind(pn)
+  836                                                = SymTab.KindModule)
+  837                                               & sfx
+  838                                               & (SymTab.StrLen(exp) > 0);
+  839                                             IF hasDead THEN MGen.Drop END;
+  840                                             IF isModP THEN
+  841                                               modPNum := SymTab.ExpProc(pn,
+  842                                                                exp);
+  843                                               IF modPNum < 0 THEN
+  844                                                 IF SymTab.ExpKind(pn,
+  845                                                      exp) # -1 THEN
+  846                                                   SemError(233)
+  847                                                 END;
+  848                                                 modErr := TRUE
+  849                                               ELSIF inExpr
+  850                                                  & (SymTab.ProcRetByNum(
+  851                                                       modPNum)
+  852                                                     = SymTab.InvalidType)
+  853                                               THEN
+  854                                                 SemError(233);
+  855                                                 modErr := TRUE
+  856                                               END;
+  857                                               MGen.ActBeginNum(modPNum)
+  858                                             ELSE
+  859                                               MGen.ActBegin(pn)
+  860                                             END; .)
+  861        [ Expr<t, lx, v, vn>              (. IF isModP THEN
+  862                                             IF ~modErr
+  863                                                & (MGen.ActValue(t, v, vn)
+  864                                                   # 0) THEN
+  865                                               SemError(233);
+  866                                               modErr := TRUE
+  867                                             END
+  868                                           ELSIF MGen.ActValue(t, v, vn) # 0 THEN
+  869                                             SemError(233)
+  870                                           END; .)
+  871          { "," Expr<t, lx, v, vn>        (. IF isModP THEN
+  872                                             IF ~modErr
+  873                                                & (MGen.ActValue(t, v, vn)
+  874                                                   # 0) THEN
+  875                                               SemError(233);
+  876                                               modErr := TRUE
+  877                                             END
+  878                                           ELSIF MGen.ActValue(t, v, vn) # 0 THEN
+  879                                             SemError(233)
+  880                                           END; .) } ]
+  881        ")"                               (. IF isModP THEN
+  882                                             IF ~modErr THEN
+  883                                               IF MGen.ActEndNum(modPNum,
+  884                                                    inExpr) # 0 THEN
+  885                                                 SemError(233)
+  886                                               ELSE ok := TRUE
+  887                                               END
+  888                                             END
+  889                                           ELSIF MGen.ActEnd(pn, sfx,
+  890                                                    inExpr) # 0
+  891                                           THEN SemError(233)
+  892                                           ELSE ok := TRUE
+  893                                           END; .) .
+  894    IfStat                                (. VAR t: SymTab.TypeIndex;
+  895                                               lxC: MGen.LitStr;
+  896                                               vC: BOOLEAN;
+  897                                               vnC: SymTab.Name;
+  898                                               elseL, endL: INTEGER;
+  899                                               hasElse: BOOLEAN; .)
+  900      = "IF"
+  901        Expr<t, lxC, vC, vnC>             (. IF ~SymTab.BoolCheck(t) THEN
+  902                                             SemError(214) END;
+  903                                             elseL := MGen.NewLabel();
+  904                                             endL := MGen.NewLabel();
+  905                                             MGen.Jz(elseL);
+  906                                             hasElse := FALSE; .)
+  907        "THEN"
+  908        StatSeq
+  909        { "ELSIF"                         (. MGen.Jmp(endL);
+  910                                             MGen.DefLabel(elseL); .)
+  911          Expr<t, lxC, vC, vnC>           (. IF ~SymTab.BoolCheck(t) THEN
+  912                                             SemError(214) END;
+  913                                             elseL := MGen.NewLabel();
+  914                                             MGen.Jz(elseL); .)
+  915          "THEN"
+  916          StatSeq }
+  917        [ "ELSE"                          (. MGen.Jmp(endL);
+  918                                             MGen.DefLabel(elseL);
+  919                                             hasElse := TRUE; .)
+  920          StatSeq ]
+  921        "END"                             (. IF ~hasElse THEN
+  922                                             MGen.DefLabel(elseL)
+  923                                           END;
+  924                                           MGen.DefLabel(endL); .) .
+  925    CaseStat                              (. VAR st: SymTab.TypeIndex;
+  926                                               lxS: MGen.LitStr;
+  927                                               vS: BOOLEAN;
+  928                                               vnS: SymTab.Name;
+  929                                               tmp, endL: INTEGER; .)
+  930      = "CASE"
+  931        Expr<st, lxS, vS, vnS>            (. tmp := MGen.TempGlobal();
+  932                                             MGen.StoreTemp(tmp);
+  933                                             endL := MGen.NewLabel(); .)
+  934        "OF"
+  935        Case<st, tmp, endL> { "|"
+  936                   Case<st, tmp, endL> }
+  937        [ "ELSE"
+  938          StatSeq ]
+  939        "END"                             (. MGen.DefLabel(endL); .) .
+  940    Case <sel: SymTab.TypeIndex; tmp: INTEGER; endL: INTEGER>
+  941                                          (. VAR lB, lN: INTEGER; .)
+  942      = [ LabelList<sel, tmp, lB, lN> ":" (. MGen.DefLabel(lB); .)
+  943          StatSeq                         (. MGen.Jmp(endL);
+  944                                             MGen.DefLabel(lN); .) ] .
+  945    LabelList <sel: SymTab.TypeIndex; tmp: INTEGER;
+  946               VAR lB: INTEGER; VAR lN: INTEGER>
+  947      =                                   (. lB := MGen.NewLabel();
+  948                                             lN := MGen.NewLabel(); .)
+  949        Labels<sel, tmp, lB> { ","
+  950                      Labels<sel, tmp, lB> }
+  951                                          (. MGen.Jmp(lN); .) .
+  952    Labels <sel: SymTab.TypeIndex; tmp: INTEGER; bodyL: INTEGER>
+  953                                          (. VAR t, t2: SymTab.TypeIndex;
+  954                                               lx1, lx2: MGen.LitStr;
+  955                                               v1, v2: BOOLEAN;
+  956                                               vn1, vn2: SymTab.Name;
+  957                                               ta, tb, chunk: INTEGER;
+  958                                               r, hasRange: BOOLEAN; .)
+  959      = ConstExpr<t, lx1>                 (. IF ~SymTab.EqCheck(t, sel) THEN
+  960                                             SemError(213) END;
+  961                                             r := (SymTab.ClassOf(sel)
+  962                                                   = SymTab.ClReal)
+  963                                                  & (SymTab.ClassOf(t)
+  964                                                     = SymTab.ClReal);
+  965                                             ta := MGen.TempGlobal();
+  966                                             MGen.StoreTemp(ta);
+  967                                             hasRange := FALSE; .)
+  968        [ ".."
+  969          ConstExpr<t2, lx2>              (. IF ~SymTab.EqCheck(t2, sel) THEN
+  970                                             SemError(213) END;
+  971                                             tb := MGen.TempGlobal();
+  972                                             MGen.StoreTemp(tb);
+  973                                             hasRange := TRUE; .) ]
+  974                                          (. IF hasRange THEN
+  975                                               MGen.LoadTemp(tmp);
+  976                                               MGen.LoadTemp(ta);
+  977                                               IF r THEN MGen.RealGe
+  978                                               ELSE MGen.IGe END;
+  979                                               MGen.LoadTemp(tmp);
+  980                                               MGen.LoadTemp(tb);
+  981                                               IF r THEN MGen.RealLe
+  982                                               ELSE MGen.ILe END;
+  983                                               MGen.And
+  984                                             ELSE
+  985                                               MGen.LoadTemp(tmp);
+  986                                               MGen.LoadTemp(ta);
+  987                                               IF r THEN MGen.RealEq
+  988                                               ELSE MGen.Eq END
+  989                                             END;
+  990                                             chunk := MGen.NewLabel();
+  991                                             MGen.Jz(chunk);
+  992                                             MGen.Jmp(bodyL);
+  993                                             MGen.DefLabel(chunk); .) .
+  994    WhileStat                             (. VAR t: SymTab.TypeIndex;
+  995                                               lxC: MGen.LitStr;
+  996                                               vC: BOOLEAN;
+  997                                               vnC: SymTab.Name;
+  998                                               topL, endL: INTEGER; .)
+  999      = "WHILE"                           (. topL := MGen.NewLabel();
+ 1000                                             endL := MGen.NewLabel();
+ 1001                                             MGen.DefLabel(topL); .)
+ 1002        Expr<t, lxC, vC, vnC>             (. IF ~SymTab.BoolCheck(t) THEN
+ 1003                                             SemError(214) END;
+ 1004                                             MGen.Jz(endL); .)
+ 1005        "DO"
+ 1006        StatSeq
+ 1007        "END"                             (. MGen.Jmp(topL);
+ 1008                                             MGen.DefLabel(endL); .) .
+ 1009    RepeatStat                            (. VAR t: SymTab.TypeIndex;
+ 1010                                               lxC: MGen.LitStr;
+ 1011                                               vC: BOOLEAN;
+ 1012                                               vnC: SymTab.Name;
+ 1013                                               topL: INTEGER; .)
+ 1014      = "REPEAT"                          (. topL := MGen.NewLabel();
+ 1015                                             MGen.DefLabel(topL); .)
+ 1016        StatSeq
+ 1017        "UNTIL"
+ 1018        Expr<t, lxC, vC, vnC>             (. IF ~SymTab.BoolCheck(t) THEN
+ 1019                                             SemError(214) END;
+ 1020                                             MGen.Jz(topL); .) .
+ 1021    LoopStat                              (. VAR topL, exitL: INTEGER; .)
+ 1022      = "LOOP"                            (. topL := MGen.NewLabel();
+ 1023                                             exitL := MGen.NewLabel();
+ 1024                                             MGen.DefLabel(topL);
+ 1025                                             MGen.PushLoop(exitL); .)
+ 1026        StatSeq
+ 1027        "END"                             (. MGen.Jmp(topL);
+ 1028                                             MGen.DefLabel(exitL);
+ 1029                                             MGen.PopLoop; .) .
+ 1030    ForStat                               (. VAR n, lv: SymTab.Name;
+ 1031                                               fk: INTEGER;
+ 1032                                               lo, hi: SymTab.TypeIndex;
+ 1033                                               lxLo, lxHi: MGen.LitStr;
+ 1034                                               vLo, vHi: BOOLEAN;
+ 1035                                               vnLo, vnHi: SymTab.Name;
+ 1036                                               byV, ht: INTEGER;
+ 1037                                               lTop, lChk, lEnd: INTEGER;
+ 1038                                               neg, storable: BOOLEAN; .)
+ 1039      = "FOR"
+ 1040        GetIdent<n>                       (. IF ~SymTab.Lookup(n) THEN
+ 1041                                              SemError(201);
+ 1042                                              fk := -1
+ 1043                                            ELSIF (SymTab.SymKind(n) #
+ 1044                                                   SymTab.KindVar)
+ 1045                                              & (SymTab.SymKind(n) #
+ 1046                                                 SymTab.KindParam)
+ 1047                                              & (SymTab.SymKind(n) #
+ 1048                                                 SymTab.KindVarPar)
+ 1049                                              & (SymTab.SymKind(n) #
+ 1050                                                 SymTab.KindField) THEN
+ 1051                                              SemError(220);
+ 1052                                              fk := -1
+ 1053                                            ELSIF (SymTab.SymType(n) #
+ 1054                                                   SymTab.InvalidType)
+ 1055                                              & ~SymTab.IsIntFamily(
+ 1056                                                  SymTab.SymType(n)) THEN
+ 1057                                              SemError(220);
+ 1058                                              fk := -1
+ 1059                                            ELSE
+ 1060                                              fk := SymTab.SymKind(n)
+ 1061                                            END;
+ 1062                                            MGen.CopyName(n, lv);
+ 1063                                            storable := (fk = SymTab.KindVar)
+ 1064                                              OR (fk = SymTab.KindParam)
+ 1065                                              OR (fk = SymTab.KindVarPar);
+ 1066                                            IF storable THEN
+ 1067                                              MGen.StoreSetup(lv)
+ 1068                                            END; .)
+ 1069        ":="
+ 1070        Expr<lo, lxLo, vLo, vnLo>         (. IF (lo # SymTab.InvalidType)
+ 1071                                             & ~SymTab.IsIntFamily(lo) THEN
+ 1072                                             SemError(220) END;
+ 1073                                             IF storable THEN
+ 1074                                               MGen.StoreFinish(lv)
+ 1075                                             ELSE MGen.Drop
+ 1076                                             END; .)
+ 1077        "TO"
+ 1078        Expr<hi, lxHi, vHi, vnHi>         (. IF (hi # SymTab.InvalidType)
+ 1079                                             & ~SymTab.IsIntFamily(hi) THEN
+ 1080                                             SemError(220) END;
+ 1081                                             ht := MGen.TempGlobal();
+ 1082                                             MGen.StoreTemp(ht);
+ 1083                                             byV := 1; neg := FALSE; .)
+ 1084        [ "BY"
+ 1085          ByLit<byV>                      (. neg := byV < 0; .) ]
+ 1086        "DO"                              (. lTop := MGen.NewLabel();
+ 1087                                             lChk := MGen.NewLabel();
+ 1088                                             lEnd := MGen.NewLabel();
+ 1089                                             MGen.Jmp(lChk);
+ 1090                                             MGen.DefLabel(lTop); .)
+ 1091        StatSeq
+ 1092        "END"                             (. MGen.PushVar(lv);
+ 1093                                             MGen.PushInt(byV);
+ 1094                                             MGen.Add;
+ 1095                                             IF storable THEN
+ 1096                                               MGen.StoreFinish(lv)
+ 1097                                             ELSE MGen.Drop
+ 1098                                             END;
+ 1099                                             MGen.DefLabel(lChk);
+ 1100                                             MGen.PushVar(lv);
+ 1101                                             MGen.LoadTemp(ht);
+ 1102                                             IF neg THEN MGen.IGe
+ 1103                                             ELSE MGen.ILe END;
+ 1104                                             MGen.Jz(lEnd);
+ 1105                                             MGen.Jmp(lTop);
+ 1106                                             MGen.DefLabel(lEnd); .) .
+ 1107    ByLit <VAR v: INTEGER>                (. VAR s: ARRAY [0 .. 255] OF CHAR; .)
+ 1108      = integer                           (. LexString(s);
+ 1109                                             IF ~MGen.ParseInt(s, v) THEN
+ 1110                                               v := 1
+ 1111                                             END; .)
+ 1112      | "-" integer                       (. LexString(s);
+ 1113                                             IF MGen.ParseInt(s, v) THEN
+ 1114                                               v := -v
+ 1115                                             ELSE v := -1
+ 1116                                             END; .) .
+ 1117    WithStat                              (. VAR dt: SymTab.TypeIndex;
+ 1118                                               dk: INTEGER;
+ 1119                                               bnW: SymTab.Name;
+ 1120                                               lxW: MGen.LitStr;
+ 1121                                               sfxW: BOOLEAN;
+ 1122                                               pushed: BOOLEAN; .)
+ 1123      = "WITH"
+ 1124        DesignHead<dt, dk, bnW, FALSE, lxW>
+ 1125        DesignTail<dt, dk, bnW, FALSE, lxW, sfxW>
+ 1126                                        (. pushed := FALSE;
+ 1127                                             IF dt = SymTab.InvalidType THEN
+ 1128                                               IF sfxW THEN MGen.Drop END
+ 1129                                             ELSIF SymTab.ClassOf(dt)
+ 1130                                                    # SymTab.ClRecord THEN
+ 1131                                               SemError(215);
+ 1132                                               IF sfxW THEN MGen.Drop END
+ 1133                                             ELSE
+ 1134                                               IF ~sfxW THEN
+ 1135                                                 IF (dk
+ 1136                                                    = SymTab.KindVar)
+ 1137                                                    OR (dk
+ 1138                                                       = SymTab.KindParam)
+ 1139                                                    OR (dk
+ 1140                                                    = SymTab.KindVarPar) THEN
+ 1141                                                   MGen.PushAddr(bnW)
+ 1142                                                 ELSIF dk
+ 1143                                                   = SymTab.KindField THEN
+ 1144                                                   MGen.WithAddr(bnW)
+ 1145                                                 ELSE MGen.PushInt(0)
+ 1146                                                 END
+ 1147                                               END;
+ 1148                                               MGen.WithEnter(dt);
+ 1149                                               pushed :=
+ 1150                                                 SymTab.PushRecord(dt);
+ 1151                                               IF ~pushed THEN
+ 1152                                                 SemError(215)
+ 1153                                               END
+ 1154                                             END; .)
+ 1155        "DO"
+ 1156        StatSeq
+ 1157        "END"                             (. IF pushed THEN
+ 1158                                               SymTab.PopScope;
+ 1159                                               MGen.WithExit
+ 1160                                             END; .) .
+ 1161    ReturnStat                            (. VAR t: SymTab.TypeIndex;
+ 1162                                               lx: MGen.LitStr;
+ 1163                                               v: BOOLEAN;
+ 1164                                               vn: SymTab.Name;
+ 1165                                               hasE, doRet, conv: BOOLEAN; .)
+ 1166      = "RETURN"                          (. hasE := FALSE; .)
+ 1167        [ Expr<t, lx, v, vn>              (. hasE := TRUE;
+ 1168                                             doRet := FALSE;
+ 1169                                             IF ~SymTab.InProc() THEN
+ 1170                                               SemError(232)
+ 1171                                             ELSIF ~SymTab.InFunction() THEN
+ 1172                                               SemError(232)
+ 1173                                             ELSIF ~SymTab.Assignable(
+ 1174                                                       t, SymTab.CurRet()) THEN
+ 1175                                               SemError(232)
+ 1176                                             ELSE doRet := TRUE
+ 1177                                             END;
+ 1178                                             conv := doRet
+ 1179                                                     & SymTab.IsIntFamily(t)
+ 1180                                                     & (SymTab.ClassOf(
+ 1181                                                          SymTab.CurRet())
+ 1182                                                        = SymTab.ClReal);
+ 1183                                             IF doRet THEN
+ 1184                                               IF conv THEN
+ 1185                                                 MGen.IntToReal
+ 1186                                               END;
+ 1187                                               MGen.Leave(
+ 1188                                                 SymTab.CurNPar(), TRUE)
+ 1189                                             ELSE MGen.Drop
+ 1190                                             END; .) ]
+ 1191                                           (. IF ~hasE THEN
+ 1192                                               IF ~SymTab.InProc() THEN
+ 1193                                                 SemError(232)
+ 1194                                               ELSIF SymTab.InFunction() THEN
+ 1195                                                 SemError(232)
+ 1196                                               ELSE MGen.Leave(
+ 1197                                                 SymTab.CurNPar(), FALSE)
+ 1198                                               END
+ 1199                                             END; .) .
+ 1200    NewStat                               (. VAR dt: SymTab.TypeIndex;
+ 1201                                               dk: INTEGER;
+ 1202                                               bnN: SymTab.Name;
+ 1203                                               lxN: MGen.LitStr;
+ 1204                                               sfxN: BOOLEAN;
+ 1205                                               baseT: SymTab.TypeIndex;
+ 1206                                               slN: CARDINAL; .)
+ 1207      = "NEW"
+ 1208        "(" DesignHead<dt, dk, bnN, FALSE, lxN>
+ 1209            DesignTail<dt, dk, bnN, FALSE, lxN, sfxN>
+ 1210        ")"                               (. IF dt = SymTab.InvalidType THEN
+ 1211                                             IF sfxN THEN MGen.Drop END
+ 1212                                           ELSIF SymTab.ClassOf(dt)
+ 1213                                                  # SymTab.ClPtr THEN
+ 1214                                             SemError(219);
+ 1215                                             IF sfxN THEN MGen.Drop END
+ 1216                                           ELSE
+ 1217                                             baseT := SymTab.PtrBase(dt);
+ 1218                                             slN := SymTab.TypeSlots(baseT);
+ 1219                                             IF slN = 0 THEN
+ 1220                                               SemError(230);
+ 1221                                               slN := 1
+ 1222                                             END;
+ 1223                                             IF ~sfxN THEN
+ 1224                                               IF (dk = SymTab.KindVar)
+ 1225                                                  OR (dk
+ 1226                                                      = SymTab.KindParam)
+ 1227                                                  OR (dk
+ 1228                                                   = SymTab.KindVarPar) THEN
+ 1229                                                 MGen.PushAddr(bnN)
+ 1230                                               ELSIF dk
+ 1231                                                 = SymTab.KindField THEN
+ 1232                                                 MGen.WithAddr(bnN)
+ 1233                                               ELSE MGen.PushInt(0)
+ 1234                                               END
+ 1235                                             END;
+ 1236                                             MGen.PushBytes(slN * 8);
+ 1237                                             MGen.AllocOp
+ 1238                                           END; .) .
+ 1239    DispStat                              (. VAR dt: SymTab.TypeIndex;
+ 1240                                               dk: INTEGER;
+ 1241                                               bnD: SymTab.Name;
+ 1242                                               lxD: MGen.LitStr;
+ 1243                                               sfxD: BOOLEAN;
+ 1244                                               baseT: SymTab.TypeIndex;
+ 1245                                               slD: CARDINAL; .)
+ 1246      = "DISPOSE"
+ 1247        "(" DesignHead<dt, dk, bnD, FALSE, lxD>
+ 1248            DesignTail<dt, dk, bnD, FALSE, lxD, sfxD>
+ 1249        ")"                               (. IF dt = SymTab.InvalidType THEN
+ 1250                                             IF sfxD THEN MGen.Drop END
+ 1251                                           ELSIF SymTab.ClassOf(dt)
+ 1252                                                  # SymTab.ClPtr THEN
+ 1253                                             SemError(219);
+ 1254                                             IF sfxD THEN MGen.Drop END
+ 1255                                           ELSE
+ 1256                                             baseT := SymTab.PtrBase(dt);
+ 1257                                             slD := SymTab.TypeSlots(baseT);
+ 1258                                             IF slD = 0 THEN
+ 1259                                               SemError(230);
+ 1260                                               slD := 1
+ 1261                                             END;
+ 1262                                             IF ~sfxD THEN
+ 1263                                               IF (dk = SymTab.KindVar)
+ 1264                                                  OR (dk
+ 1265                                                      = SymTab.KindParam)
+ 1266                                                  OR (dk
+ 1267                                                   = SymTab.KindVarPar) THEN
+ 1268                                                 MGen.PushAddr(bnD)
+ 1269                                               ELSIF dk
+ 1270                                                 = SymTab.KindField THEN
+ 1271                                                 MGen.WithAddr(bnD)
+ 1272                                               ELSE MGen.PushInt(0)
+ 1273                                               END
+ 1274                                             END;
+ 1275                                             MGen.PushBytes(slD * 8);
+ 1276                                             MGen.DeallocOp
+ 1277                                           END; .) .
+ 1278    WriteIntStat                          (. VAR t: SymTab.TypeIndex;
+ 1279                                               lx: MGen.LitStr;
+ 1280                                               v: BOOLEAN;
+ 1281                                               vn: SymTab.Name; .)
+ 1282      = "WriteInt"
+ 1283        "(" Expr<t, lx, v, vn> ")"        (. IF t = SymTab.InvalidType THEN
+ 1284                                             MGen.Drop
+ 1285                                           ELSIF ~SymTab.IsIntFamily(t) THEN
+ 1286                                             SemError(210);
+ 1287                                             MGen.Drop
+ 1288                                           ELSE
+ 1289                                             MGen.CallPrint
+ 1290                                           END; .) .
+ 1291    WriteStrStat                          (. VAR t: SymTab.TypeIndex;
+ 1292                                               lx: MGen.LitStr;
+ 1293                                               v: BOOLEAN;
+ 1294                                               vn: SymTab.Name; .)
+ 1295      = "WriteString"
+ 1296        "(" Expr<t, lx, v, vn> ")"        (. IF t = SymTab.InvalidType THEN
+ 1297                                             MGen.Drop
+ 1298                                           ELSIF (SymTab.ClassOf(t)
+ 1299                                                  = SymTab.ClStr) THEN
+ 1300                                             MGen.PushInt(1);
+ 1301                                             MGen.SysCall
+ 1302                                           ELSIF (SymTab.ClassOf(t)
+ 1303                                                  = SymTab.ClArray)
+ 1304                                              & (SymTab.ClassOf(
+ 1305                                                 SymTab.ArrayElem(t))
+ 1306                                                 = SymTab.ClChar) THEN
+ 1307                                             MGen.PushInt(1);
+ 1308                                             MGen.SysCall
+ 1309                                           ELSE
+ 1310                                             SemError(210);
+ 1311                                             MGen.Drop
+ 1312                                           END; .) .
+ 1313  
+ 1314    (* Expressions: Designator without ActualParameters (calls use
+ 1315       CallTail). Each expression synthesizes its SymTab type in t,
+ 1316       the source text in lx for single literals ("" otherwise), and
+ 1317       whether it is a plain variable (v/vn) for VAR actuals.
+ 1318       Values travel on the MC64 stack. *)
+ 1319    DesignHead <VAR t: SymTab.TypeIndex; VAR k: INTEGER;
+ 1320                VAR bn: SymTab.Name; doLoad: BOOLEAN; VAR lx: MGen.LitStr>
+ 1321                                          (. VAR n: SymTab.Name;
+ 1322                                               cls: INTEGER; .)
+ 1323      = GetIdent<n>                       (. MGen.CopyName(n, bn);
+ 1324                                             lx[0] := 0C;
+ 1325                                             IF ~SymTab.Lookup(n) THEN
+ 1326                                               SemError(201);
+ 1327                                               t := SymTab.InvalidType; k := -1;
+ 1328                                               IF doLoad THEN
+ 1329                                                 MGen.PushInt(0)
+ 1330                                               END
+ 1331                                             ELSE
+ 1332                                               t := SymTab.SymType(n);
+ 1333                                               k := SymTab.SymKind(n);
+ 1334                                               IF k = SymTab.KindConst THEN
+ 1335                                                 IF SymTab.Equal(n, "TRUE") THEN
+ 1336                                                   t := SymTab.BoolType();
+ 1337                                                   MGen.CopyName("TRUE", lx);
+ 1338                                                   IF doLoad THEN
+ 1339                                                     MGen.PushInt(1)
+ 1340                                                   END
+ 1341                                                 ELSIF SymTab.Equal(n,
+ 1342                                                         "FALSE") THEN
+ 1343                                                   t := SymTab.BoolType();
+ 1344                                                   MGen.CopyName("FALSE", lx);
+ 1345                                                   IF doLoad THEN
+ 1346                                                     MGen.PushInt(0)
+ 1347                                                   END
+ 1348                                                 ELSE
+ 1349                                                   cls :=
+ 1350                                                     SymTab.ClassOf(t);
+ 1351                                                   IF (t #
+ 1352                                                       SymTab.InvalidType)
+ 1353                                                      & (cls # SymTab.ClStr)
+ 1354                                                      & ((cls = SymTab.ClInt)
+ 1355                                                      OR (cls = SymTab.ClReal)
+ 1356                                                      OR (cls = SymTab.ClBool)
+ 1357                                                      OR (cls = SymTab.ClChar)
+ 1358                                                      OR (cls
+ 1359                                                          = SymTab.ClEnum)) THEN
+ 1360                                                     IF doLoad THEN
+ 1361                                                       MGen.LoadVar(n)
+ 1362                                                     END
+ 1363                                                   ELSIF doLoad THEN
+ 1364                                                     MGen.PushInt(0)
+ 1365                                                   END
+ 1366                                                 END
+ 1367                                                ELSIF (k = SymTab.KindVar)
+ 1368                                                   OR (k = SymTab.KindParam)
+ 1369                                                   OR (k
+ 1370                                                       = SymTab.KindVarPar) THEN
+ 1371                                                  cls := SymTab.ClassOf(t);
+ 1372                                                  IF (cls = SymTab.ClInt)
+ 1373                                                     OR (cls = SymTab.ClReal)
+ 1374                                                     OR (cls = SymTab.ClBool)
+ 1375                                                     OR (cls = SymTab.ClChar)
+ 1376                                                     OR (cls
+ 1377                                                         = SymTab.ClEnum)
+ 1378                                                     OR (cls
+ 1379                                                         = SymTab.ClSet)
+ 1380                                                     OR (cls
+ 1381                                                         = SymTab.ClPtr) THEN
+ 1382                                                    IF doLoad THEN
+ 1383                                                      MGen.PushVar(n)
+ 1384                                                    END
+ 1385                                                  ELSIF (cls
+ 1386                                                         = SymTab.ClArray)
+ 1387                                                     OR (cls
+ 1388                                                         = SymTab.ClRecord) THEN
+ 1389                                                    IF doLoad THEN
+ 1390                                                      MGen.PushAddr(n)
+ 1391                                                    END
+ 1392                                                  ELSIF t
+ 1393                                                    = SymTab.InvalidType THEN
+ 1394                                                    IF doLoad THEN
+ 1395                                                      MGen.PushInt(0)
+ 1396                                                    END
+ 1397                                                  ELSE SemError(230);
+ 1398                                                    IF doLoad THEN
+ 1399                                                      MGen.PushInt(0)
+ 1400                                                    END
+ 1401                                                  END
+ 1402                                               ELSE
+ 1403                                                 IF doLoad THEN
+ 1404                                                   IF k = SymTab.KindField THEN
+ 1405                                                     MGen.WithAddr(n);
+ 1406                                                     cls := SymTab.ClassOf(t);
+ 1407                                                     IF (t
+ 1408                                                        = SymTab.InvalidType)
+ 1409                                                        OR (cls
+ 1410                                                           = SymTab.ClArray)
+ 1411                                                        OR (cls
+ 1412                                                           = SymTab.ClRecord) THEN
+ 1413                                                     ELSE
+ 1414                                                       IF (cls
+ 1415                                                          = SymTab.ClChar)
+ 1416                                                          OR (cls
+ 1417                                                             = SymTab.ClBool) THEN
+ 1418                                                         MGen.LoadByte
+ 1419                                                       ELSE MGen.LoadIndir
+ 1420                                                       END
+ 1421                                                     END
+ 1422                                                   ELSE MGen.PushInt(0)
+ 1423                                                   END
+ 1424                                                 END;
+ 1425                                                 IF k = SymTab.KindField THEN
+ 1426                                                 ELSIF k
+ 1427                                                       = SymTab.KindImport THEN
+ 1428                                                   SemError(230)
+ 1429                                                 END
  1430                                               END
- 1431                                             END; .)
- 1432          GetIdent<m>                     (. IF (k = SymTab.KindModule) THEN
- 1433                                               IF SymTab.ExpKind(bn, m) = -1 THEN
- 1434                                                 SemError(201);
- 1435                                                 MGen.CopyName(m, lx);
- 1436                                                 t := SymTab.InvalidType;
- 1437                                                 IF doLoad THEN
- 1438                                                   MGen.Drop; MGen.PushInt(0)
- 1439                                                 ELSIF firstT THEN
- 1440                                                 ELSE MGen.Drop
- 1441                                                 END
- 1442                                               ELSIF SymTab.ExpKind(bn, m)
- 1443                                                      = SymTab.KindProc THEN
- 1444                                                 MGen.CopyName(m, lx);
- 1445                                                 t := SymTab.InvalidType;
- 1446                                                 IF doLoad THEN
- 1447                                                   MGen.Drop; MGen.PushInt(0)
- 1448                                                 ELSIF firstT THEN
- 1449                                                 ELSE MGen.Drop
- 1450                                                 END
- 1451                                               ELSE
- 1452                                                 t := SymTab.ExpType(bn, m);
- 1453                                                 k := SymTab.ExpKind(bn, m);
- 1454                                                 SymTab.ExpQual(bn, m, qM);
- 1455                                                 IF doLoad THEN
- 1456                                                   MGen.Drop;
- 1457                                                   MGen.GlobalAddr(qM)
- 1458                                                 ELSE
- 1459                                                   IF firstT THEN
- 1460                                                   ELSE MGen.Drop
- 1461                                                   END;
- 1462                                                   MGen.GlobalAddr(qM)
- 1463                                                 END
- 1464                                               END
- 1465                                             ELSIF t = SymTab.InvalidType THEN
- 1466                                               IF ~doLoad & firstT THEN
- 1467                                                 MGen.Drop
- 1468                                               ELSIF doLoad THEN
- 1469                                                 MGen.Drop; MGen.PushInt(0)
- 1470                                               END
- 1471                                             ELSIF SymTab.ClassOf(t) #
- 1472                                                   SymTab.ClRecord THEN
- 1473                                               SemError(215);
- 1474                                               t := SymTab.InvalidType;
- 1475                                               IF doLoad THEN
- 1476                                                 MGen.Drop; MGen.PushInt(0)
- 1477                                               ELSIF firstT THEN
- 1478                                                 MGen.Drop
- 1479                                               END
- 1480                                             ELSIF ~SymTab.FieldExists(t, m) THEN
- 1481                                               SemError(216);
- 1482                                               t := SymTab.InvalidType;
- 1483                                               IF doLoad THEN
- 1484                                                 MGen.Drop; MGen.PushInt(0)
- 1485                                               ELSIF firstT THEN
- 1486                                                 MGen.Drop
- 1487                                               END
- 1488                                             ELSE
- 1489                                               loA := SymTab.FieldOffset(t, m);
- 1490                                               elemT := SymTab.FieldType(t, m);
- 1491                                               IF loA < 0 THEN
- 1492                                                 SemError(216);
- 1493                                                 t := SymTab.InvalidType;
- 1494                                                 IF doLoad THEN
- 1495                                                   MGen.Drop; MGen.PushInt(0)
- 1496                                                 ELSIF firstT THEN
- 1497                                                   MGen.Drop
- 1498                                                 END
- 1499                                               ELSE
- 1500                                                 MGen.FieldAdd(
- 1501                                                   VAL(CARDINAL, loA));
- 1502                                                 t := elemT
- 1503                                               END
- 1504                                             END; .)
- 1505        | "["                             (. firstT := ~sfx;
- 1506                                             sfx := TRUE; lx[0] := 0C;
- 1507                                             IF ~doLoad & firstT THEN
- 1508                                               IF (k = SymTab.KindVar)
- 1509                                                  OR (k = SymTab.KindParam)
- 1510                                                  OR (k
- 1511                                                      = SymTab.KindVarPar) THEN
- 1512                                                 MGen.PushAddr(bn)
- 1513                                               ELSIF k
- 1514                                                 = SymTab.KindField THEN
- 1515                                                 MGen.WithAddr(bn)
- 1516                                               ELSE MGen.PushInt(0)
- 1517                                               END
- 1518                                             END; .)
- 1519          Expr<it, lxI, vI, vnI>          (. IF t = SymTab.InvalidType THEN
- 1520                                             MGen.Drop;
- 1521                                             IF doLoad THEN
- 1522                                               MGen.Drop; MGen.PushInt(0)
- 1523                                             ELSE
- 1524                                               IF ~firstT THEN
- 1525                                               ELSE MGen.Drop
- 1526                                               END
- 1527                                             END
- 1528                                           ELSIF SymTab.ClassOf(t) #
- 1529                                                   SymTab.ClArray THEN
- 1530                                             SemError(217);
- 1531                                             t := SymTab.InvalidType;
- 1532                                             MGen.Drop;
- 1533                                             IF doLoad THEN
- 1534                                               MGen.Drop; MGen.PushInt(0)
- 1535                                             ELSE
- 1536                                               IF ~firstT THEN
- 1537                                               ELSE MGen.Drop
- 1538                                               END
- 1539                                             END
- 1540                                           ELSE
- 1541                                             clsI := SymTab.ClassOf(it);
- 1542                                             IF (it
- 1543                                                # SymTab.InvalidType)
- 1544                                                & (clsI # SymTab.ClInt)
- 1545                                                & (clsI # SymTab.ClChar)
- 1546                                                & (clsI # SymTab.ClEnum)
- 1547                                                & (clsI
- 1548                                                   # SymTab.ClBool) THEN
- 1549                                               SemError(218);
- 1550                                               t := SymTab.InvalidType;
- 1551                                               MGen.Drop;
- 1552                                               IF doLoad THEN
- 1553                                                 MGen.Drop; MGen.PushInt(0)
- 1554                                               ELSE
- 1555                                                 IF ~firstT THEN
- 1556                                                 ELSE MGen.Drop
- 1557                                                 END
- 1558                                               END
- 1559                                             ELSE
- 1560                                               loA := SymTab.ArrayLo(t);
- 1561                                               elemT := SymTab.ArrayElem(t);
- 1562                                               esl := SymTab.TypeSlots(elemT);
- 1563                                               IF esl = 0 THEN
- 1564                                                 SemError(230);
- 1565                                                 esl := 1
- 1566                                               END;
- 1567                                               IF (SymTab.ClassOf(elemT)
- 1568                                                  = SymTab.ClChar)
- 1569                                                  OR (SymTab.ClassOf(elemT)
- 1570                                                     = SymTab.ClBool) THEN
- 1571                                                 ebytes := 1
- 1572                                               ELSE ebytes := esl * 8
- 1573                                               END;
- 1574                                               MGen.IdxScale(loA, ebytes);
- 1575                                               t := elemT
- 1576                                             END
- 1577                                           END; .)
- 1578          { ","
- 1579            Expr<it, lxI, vI, vnI>        (. IF t = SymTab.InvalidType THEN
- 1580                                             MGen.Drop;
- 1581                                             IF doLoad THEN
- 1582                                               MGen.Drop; MGen.PushInt(0);
- 1583                                               t := SymTab.InvalidType
- 1584                                             END
- 1585                                           ELSIF SymTab.ClassOf(t) #
- 1586                                                   SymTab.ClArray THEN
- 1587                                             SemError(217);
- 1588                                             t := SymTab.InvalidType;
- 1589                                             MGen.Drop;
- 1590                                             IF doLoad THEN
- 1591                                               MGen.Drop; MGen.PushInt(0)
- 1592                                             END
- 1593                                           ELSE
- 1594                                             clsI := SymTab.ClassOf(it);
- 1595                                             IF (it
- 1596                                                # SymTab.InvalidType)
- 1597                                                & (clsI # SymTab.ClInt)
- 1598                                                & (clsI # SymTab.ClChar)
- 1599                                                & (clsI # SymTab.ClEnum)
- 1600                                                & (clsI
- 1601                                                   # SymTab.ClBool) THEN
- 1602                                               SemError(218);
- 1603                                               t := SymTab.InvalidType;
- 1604                                               MGen.Drop;
- 1605                                               IF doLoad THEN
- 1606                                                 MGen.Drop; MGen.PushInt(0)
- 1607                                               END
- 1608                                             ELSE
- 1609                                               loA := SymTab.ArrayLo(t);
- 1610                                               elemT := SymTab.ArrayElem(t);
- 1611                                               esl := SymTab.TypeSlots(elemT);
- 1612                                               IF esl = 0 THEN
- 1613                                                 SemError(230);
- 1614                                                 esl := 1
- 1615                                               END;
- 1616                                               IF (SymTab.ClassOf(elemT)
- 1617                                                  = SymTab.ClChar)
- 1618                                                  OR (SymTab.ClassOf(elemT)
- 1619                                                     = SymTab.ClBool) THEN
- 1620                                                 ebytes := 1
- 1621                                               ELSE ebytes := esl * 8
- 1622                                               END;
- 1623                                               MGen.IdxScale(loA, ebytes);
- 1624                                               t := elemT
- 1625                                             END
- 1626                                           END; .) }
- 1627          "]"
- 1628        | "^"                             (. firstT := ~sfx;
- 1629                                             sfx := TRUE; lx[0] := 0C;
- 1630                                             IF ~doLoad & firstT THEN
- 1631                                               IF (k = SymTab.KindVar)
- 1632                                                  OR (k = SymTab.KindParam)
- 1633                                                  OR (k
- 1634                                                      = SymTab.KindVarPar) THEN
- 1635                                                 MGen.PushAddr(bn)
- 1636                                               ELSIF k
- 1637                                                 = SymTab.KindField THEN
- 1638                                                 MGen.WithAddr(bn)
- 1639                                               ELSE MGen.PushInt(0)
- 1640                                               END
- 1641                                             END; .)
- 1642                                          (. IF t = SymTab.InvalidType THEN
- 1643                                               IF doLoad THEN
- 1644                                                 MGen.Drop; MGen.PushInt(0)
- 1645                                               ELSIF firstT THEN
- 1646                                                 MGen.Drop
- 1647                                               END
- 1648                                             ELSIF SymTab.ClassOf(t) #
- 1649                                                   SymTab.ClPtr THEN
- 1650                                               SemError(219);
- 1651                                               t := SymTab.InvalidType;
- 1652                                               IF doLoad THEN
- 1653                                                 MGen.Drop; MGen.PushInt(0)
- 1654                                               ELSIF firstT THEN
- 1655                                                 MGen.Drop
- 1656                                               END
- 1657                                             ELSE
- 1658                                               elemT := SymTab.PtrBase(t);
- 1659                                               t := elemT;
- 1660                                               IF doLoad THEN
- 1661                                                 IF ~(firstT
- 1662                                                    & ((k
- 1663                                                        = SymTab.KindVar)
- 1664                                                    OR (k
- 1665                                                        = SymTab.KindParam)
- 1666                                                    OR (k
- 1667                                                        = SymTab.KindVarPar)))
- 1668                                                 THEN
- 1669                                                   MGen.LoadIndir
- 1670                                                 END
- 1671                                               ELSE
- 1672                                                 MGen.LoadIndir
- 1673                                               END
- 1674                                             END; .) } .
- 1675    Expr <VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr;
- 1676          VAR v: BOOLEAN; VAR vn: SymTab.Name>
- 1677                                          (. VAR t2: SymTab.TypeIndex;
- 1678                                               tc, op: INTEGER;
- 1679                                               lx2: MGen.LitStr;
- 1680                                               v2: BOOLEAN;
- 1681                                               vn2: SymTab.Name;
- 1682                                               r: BOOLEAN; .)
- 1683      = SimExpr<t, lx, v, vn> [ Rel<op> SimExpr<t2, lx2, v2, vn2>
- 1684        (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
- 1685           IF op = SymTab.OpIn THEN
- 1686             IF SymTab.InCheck(t, t2) THEN
- 1687               t := SymTab.BoolType();
- 1688               MGen.BitIn
- 1689             ELSE SemError(222);
- 1690               t := SymTab.InvalidType;
- 1691               MGen.Drop; MGen.Drop; MGen.PushInt(0)
- 1692             END
- 1693           ELSIF (t # SymTab.InvalidType)
- 1694              & (t2 # SymTab.InvalidType)
- 1695              & (SymTab.ClassOf(t) = SymTab.ClArray)
- 1696              & (SymTab.ClassOf(t2) = SymTab.ClArray)
- 1697              & (SymTab.ClassOf(SymTab.ArrayElem(t)) = SymTab.ClChar)
- 1698              & (SymTab.ClassOf(SymTab.ArrayElem(t2)) = SymTab.ClChar)
- 1699              & ~SymTab.IsOpen(t) & ~SymTab.IsOpen(t2) THEN
- 1700             t := SymTab.BoolType();
- 1701             MGen.PushBytes(SymTab.TypeSlots(t) * 8);
- 1702             MGen.PushBytes(SymTab.TypeSlots(t2) * 8);
- 1703             MGen.StrComp;
- 1704             IF op = SymTab.OpEq THEN MGen.Or; MGen.Not
- 1705             ELSIF (op = SymTab.OpNeq1)
- 1706                   OR (op = SymTab.OpNeq2) THEN MGen.Or
- 1707             ELSIF op = SymTab.OpLt THEN
- 1708               MGen.Swap; MGen.Drop
- 1709             ELSIF op = SymTab.OpLe THEN
- 1710               MGen.Drop; MGen.Not
- 1711             ELSIF op = SymTab.OpGt THEN
- 1712               MGen.Drop
- 1713             ELSE
- 1714               MGen.Swap; MGen.Drop; MGen.Not
- 1715             END
- 1716           ELSIF (t # SymTab.InvalidType)
- 1717              & (t2 # SymTab.InvalidType)
- 1718              & ((SymTab.ClassOf(t) = SymTab.ClArray)
- 1719                 OR (SymTab.ClassOf(t) = SymTab.ClRecord)
- 1720                 OR (SymTab.ClassOf(t2) = SymTab.ClArray)
- 1721                 OR (SymTab.ClassOf(t2) = SymTab.ClRecord)) THEN
- 1722             SemError(213); t := SymTab.InvalidType;
- 1723             MGen.Drop; MGen.Drop; MGen.PushInt(0)
- 1724           ELSE
- 1725             tc := SymTab.ClassOf(t);
- 1726             IF SymTab.RelCheck(t, t2, op) THEN
- 1727               t := SymTab.BoolType()
- 1728             ELSE SemError(213); t := SymTab.InvalidType END;
- 1729             IF t # SymTab.InvalidType THEN
- 1730               r := tc = SymTab.ClReal;
- 1731               IF r THEN
- 1732                 IF op = SymTab.OpEq THEN MGen.RealEq
- 1733                 ELSIF (op = SymTab.OpNeq1)
- 1734                       OR (op = SymTab.OpNeq2) THEN MGen.RealNe
- 1735                 ELSIF op = SymTab.OpLt THEN MGen.RealLt
- 1736                 ELSIF op = SymTab.OpLe THEN MGen.RealLe
- 1737                 ELSIF op = SymTab.OpGt THEN MGen.RealGt
- 1738                 ELSE MGen.RealGe END
- 1739               ELSE
- 1740                 IF op = SymTab.OpEq THEN MGen.Eq
- 1741                 ELSIF (op = SymTab.OpNeq1)
- 1742                       OR (op = SymTab.OpNeq2) THEN MGen.Neq
- 1743                 ELSIF op = SymTab.OpLt THEN MGen.ILt
- 1744                 ELSIF op = SymTab.OpLe THEN MGen.ILe
- 1745                 ELSIF op = SymTab.OpGt THEN MGen.IGt
- 1746                 ELSE MGen.IGe END
- 1747               END
- 1748             ELSE MGen.Drop; MGen.Drop; MGen.PushInt(0)
- 1749             END
- 1750           END; .) ] .
- 1751    Rel <VAR op: INTEGER>
- 1752      = "="                     (. op := SymTab.OpEq; .)
- 1753      | "#"                     (. op := SymTab.OpNeq1; .)
- 1754      | "<>"                    (. op := SymTab.OpNeq2; .)
- 1755      | "<"                     (. op := SymTab.OpLt; .)
- 1756      | "<="                    (. op := SymTab.OpLe; .)
- 1757      | ">"                     (. op := SymTab.OpGt; .)
- 1758      | ">="                    (. op := SymTab.OpGe; .)
- 1759      | "IN"                    (. op := SymTab.OpIn; .) .
- 1760    SimExpr <VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr;
- 1761             VAR v: BOOLEAN; VAR vn: SymTab.Name>
- 1762                                          (. VAR t2, res2: SymTab.TypeIndex;
- 1763                                               op: INTEGER;
- 1764                                               lx2: MGen.LitStr;
- 1765                                               v2: BOOLEAN;
- 1766                                               vn2: SymTab.Name;
- 1767                                               neg, isR: BOOLEAN; .)
- 1768      =                                   (. neg := FALSE; .)
- 1769        [ "+" | "-"                       (. neg := TRUE; .) ]
- 1770        Term<t, lx, v, vn>                (. IF neg THEN
- 1771                                             v := FALSE;
- 1772                                             MGen.ClrStash();
- 1773                                             IF MGen.IsLit(lx) THEN
- 1774                                               MGen.NegFold(lx, lx)
- 1775                                             ELSE lx[0] := 0C
- 1776                                             END;
- 1777                                             IF SymTab.ClassOf(t)
- 1778                                                = SymTab.ClReal THEN
- 1779                                               MGen.NegReal
- 1780                                             ELSE MGen.NegInt
- 1781                                             END
- 1782                                           END; .)
- 1783        { AddOp<op> Term<t2, lx2, v2, vn2>
- 1784        (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
- 1785           IF op = SymTab.OpOr THEN
- 1786             IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
- 1787               t := SymTab.BoolType()
- 1788             ELSE SemError(212); t := SymTab.InvalidType END;
- 1789             MGen.Or
- 1790           ELSIF (t # SymTab.InvalidType)
- 1791              & (t2 # SymTab.InvalidType)
- 1792              & (SymTab.ClassOf(t) = SymTab.ClSet)
- 1793              & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
- 1794             IF op = SymTab.OpAdd THEN
- 1795               MGen.Or
- 1796             ELSE
- 1797               MGen.PushBits(0FFFFFFFFFFFFFFFFH);
- 1798               MGen.BitXor;
- 1799               MGen.And
- 1800             END
- 1801           ELSE
- 1802             IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN t := res2
- 1803             ELSE SemError(211); t := SymTab.InvalidType END;
- 1804             isR := (t # SymTab.InvalidType)
- 1805                    & (SymTab.ClassOf(t) = SymTab.ClReal);
- 1806             IF op = SymTab.OpAdd THEN
- 1807               IF isR THEN MGen.RealAdd ELSE MGen.Add END
- 1808             ELSE
- 1809               IF isR THEN MGen.RealSub ELSE MGen.Sub END
- 1810             END
- 1811           END; .) } .
- 1812    AddOp <VAR op: INTEGER>
- 1813      = "+"                     (. op := SymTab.OpAdd; .)
- 1814      | "-"                     (. op := SymTab.OpSub; .)
- 1815      | "OR"                    (. op := SymTab.OpOr; .) .
- 1816    Term <VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr;
- 1817          VAR v: BOOLEAN; VAR vn: SymTab.Name>
- 1818                                          (. VAR t2, res2: SymTab.TypeIndex;
- 1819                                               op: INTEGER;
- 1820                                               lx2: MGen.LitStr;
- 1821                                               v2: BOOLEAN;
- 1822                                               vn2: SymTab.Name;
- 1823                                               isR: BOOLEAN;
- 1824                                               mt: INTEGER; .)
- 1825      = Fact<t, lx, v, vn> { MulOp<op> Fact<t2, lx2, v2, vn2>
- 1826        (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
- 1827           IF op = SymTab.OpAnd THEN
- 1828             IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
- 1829               t := SymTab.BoolType()
- 1830             ELSE SemError(212); t := SymTab.InvalidType END;
- 1831             MGen.And
- 1832           ELSIF (op = SymTab.OpTimes)
- 1833              & (t # SymTab.InvalidType)
- 1834              & (t2 # SymTab.InvalidType)
- 1835              & (SymTab.ClassOf(t) = SymTab.ClSet)
- 1836              & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
- 1837             MGen.And
- 1838           ELSE
- 1839             IF SymTab.ArithCheck(t, t2,
- 1840                  (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
- 1841                  res2) THEN t := res2
- 1842             ELSE SemError(211); t := SymTab.InvalidType END;
- 1843             isR := (t # SymTab.InvalidType)
- 1844                    & (SymTab.ClassOf(t) = SymTab.ClReal);
- 1845             IF op = SymTab.OpTimes THEN
- 1846               IF isR THEN MGen.RealMul ELSE MGen.MulU END
- 1847             ELSIF op = SymTab.OpSlash THEN
- 1848               IF isR THEN MGen.RealDiv ELSE MGen.DivI END
- 1849             ELSIF op = SymTab.OpDiv THEN
- 1850               MGen.DivI
- 1851             ELSE
- 1852               mt := MGen.TempGlobal();
- 1853               MGen.ModI(mt)
- 1854             END
- 1855           END; .) } .
- 1856    MulOp <VAR op: INTEGER>
- 1857      = "*"                     (. op := SymTab.OpTimes; .)
- 1858      | "/"                     (. op := SymTab.OpSlash; .)
- 1859      | "DIV"                   (. op := SymTab.OpDiv; .)
- 1860      | "MOD"                   (. op := SymTab.OpMod; .)
- 1861      | "AND"                   (. op := SymTab.OpAnd; .)
- 1862      | "&"                     (. op := SymTab.OpAnd; .) .
- 1863    Fact <VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr;
- 1864          VAR v: BOOLEAN; VAR vn: SymTab.Name>
- 1865                                          (. VAR s: ARRAY [0 .. 255] OF CHAR;
- 1866                                               t2, et, dt, st: SymTab.TypeIndex;
- 1867                                               dk: INTEGER;
- 1868                                               bnF: SymTab.Name;
- 1869                                               lxD, lx2: MGen.LitStr;
- 1870                                               v2: BOOLEAN;
- 1871                                               vn2: SymTab.Name;
- 1872                                               vi: INTEGER;
- 1873                                               c: CARDINAL;
- 1874                                               b: LONGCARD;
- 1875                                               sfxF: BOOLEAN;
- 1876                                               okF: BOOLEAN; .)
- 1877      = integer                         (. LexString(s);
- 1878                                           MGen.CopyName(s, lx);
- 1879                                           v := FALSE; MGen.ClrStash();
- 1880                                           IF MGen.ParseInt(s, vi) THEN
- 1881                                             MGen.PushInt(vi)
- 1882                                           ELSIF MGen.ParseCard(s, c) THEN
- 1883                                             MGen.PushBits(
- 1884                                               VAL(LONGCARD, c))
- 1885                                           ELSE MGen.PushInt(0)
- 1886                                           END;
- 1887                                           t := SymTab.IntType(); .)
- 1888      | real                            (. LexString(s);
- 1889                                           MGen.CopyName(s, lx);
- 1890                                           v := FALSE; MGen.ClrStash();
- 1891                                           IF MGen.ParseReal(s, b) THEN
- 1892                                             MGen.PushBits(b)
- 1893                                           ELSE MGen.PushBits(0H)
- 1894                                           END;
- 1895                                           t := SymTab.RealType(); .)
- 1896      | string                          (. LexString(s);
- 1897                                           v := FALSE; MGen.ClrStash();
- 1898                                           IF SymTab.StrLen(s) <= 3 THEN
- 1899                                             t := SymTab.CharType();
- 1900                                             MGen.CopyName(s, lx);
- 1901                                             MGen.PushInt(
- 1902                                               MGen.CharOrd(s))
- 1903                                           ELSE t := SymTab.NewStr();
- 1904                                             MGen.CopyName(s, lx);
- 1905                                             MGen.EmitString(s)
- 1906                                           END; .)
- 1907      | "HIGH"
- 1908        "(" DesignHead<dt, dk, bnF, FALSE, lxD>
- 1909            DesignTail<dt, dk, bnF, FALSE, lxD, sfxF>
- 1910        ")"                               (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
- 1911                                             IF dt = SymTab.InvalidType THEN
- 1912                                               IF sfxF THEN MGen.Drop END;
- 1913                                               MGen.PushInt(0);
- 1914                                               t := SymTab.InvalidType
- 1915                                             ELSIF SymTab.ClassOf(dt)
- 1916                                                    # SymTab.ClArray THEN
- 1917                                               SemError(217);
- 1918                                               IF sfxF THEN MGen.Drop END;
- 1919                                               MGen.PushInt(0);
- 1920                                               t := SymTab.InvalidType
- 1921                                             ELSIF SymTab.IsOpen(dt) THEN
- 1922                                               IF sfxF THEN MGen.Drop END;
- 1923                                               IF (dk = SymTab.KindParam)
- 1924                                                  OR (dk
- 1925                                                   = SymTab.KindVarPar) THEN
- 1926                                                 IF SymTab.CurDepth()
- 1927                                                    = SymTab.SymDepth(bnF) THEN
- 1928                                                   MGen.LoadLocal(
- 1929                                                     SymTab.SymSlot(bnF) + 1)
- 1930                                                 ELSE
- 1931                                                   MGen.FrameAddr(
- 1932                                                     SymTab.SymSlot(bnF) + 1,
- 1933                                                     VAL(CARDINAL,
- 1934                                                       SymTab.CurDepth() - 1
- 1935                                                       - SymTab.SymDepth(bnF)));
- 1936                                                   MGen.LoadIndir
- 1937                                                 END;
- 1938                                                 MGen.PushInt(1);
- 1939                                                 MGen.Sub;
- 1940                                                 t := SymTab.IntType()
- 1941                                               ELSE
- 1942                                                 MGen.PushInt(0);
- 1943                                                 t := SymTab.InvalidType
- 1944                                               END
- 1945                                             ELSE
- 1946                                               IF sfxF THEN MGen.Drop END;
- 1947                                               MGen.PushInt(
- 1948                                                 SymTab.ArrayHi(dt));
- 1949                                               t := SymTab.IntType()
- 1950                                             END; .)
- 1951      | DesignHead<dt, dk, bnF, TRUE, lxD>
- 1952        DesignTail<dt, dk, bnF, TRUE, lxD, sfxF>
- 1953                                          (. t := dt;
- 1954                                             MGen.CopyName(lxD, lx);
- 1955                                             IF sfxF
- 1956                                                & (t # SymTab.InvalidType)
- 1957                                                & MGen.ActIsVarNext()
- 1958                                                & ((dk = SymTab.KindVar)
- 1959                                                   OR (dk
- 1960                                                       = SymTab.KindParam)
- 1961                                                   OR (dk
- 1962                                                       = SymTab.KindVarPar)
- 1963                                                   OR (dk
- 1964                                                       = SymTab.KindField))
- 1965                                                & (SymTab.SymKind(bnF)
- 1966                                                   # SymTab.KindModule)
- 1967                                                & (SymTab.ClassOf(t)
- 1968                                                   # SymTab.ClChar)
- 1969                                                & (SymTab.ClassOf(t)
- 1970                                                   # SymTab.ClBool) THEN
- 1971                                               MGen.StashAddr()
- 1972                                             END;
- 1973                                             IF sfxF
- 1974                                                & (t # SymTab.InvalidType)
- 1975                                                & (SymTab.ClassOf(t)
- 1976                                                   # SymTab.ClArray)
- 1977                                                & (SymTab.ClassOf(t)
- 1978                                                   # SymTab.ClRecord) THEN
- 1979                                               IF (SymTab.ClassOf(t)
- 1980                                                  = SymTab.ClChar)
- 1981                                                  OR (SymTab.ClassOf(t)
- 1982                                                     = SymTab.ClBool) THEN
- 1983                                                 MGen.LoadByte
- 1984                                               ELSE MGen.LoadIndir
- 1985                                               END
- 1986                                             END;
- 1987                                             v := ~sfxF
- 1988                                                  & ((dk = SymTab.KindVar)
- 1989                                                  OR (dk = SymTab.KindParam)
- 1990                                                  OR (dk
- 1991                                                      = SymTab.KindVarPar));
- 1992                                             MGen.CopyName(bnF, vn); .)
- 1993        [ CallTail<bnF, lxD, sfxF, TRUE, okF, TRUE>
- 1994                                          (. IF okF THEN
- 1995                                               IF SymTab.SymKind(bnF)
- 1996                                                  = SymTab.KindProc THEN
- 1997                                                 t := SymTab.ProcRet(bnF)
- 1998                                               ELSIF (SymTab.SymKind(bnF)
- 1999                                                         = SymTab.KindModule)
- 2000                                                  & sfxF
- 2001                                                  & (SymTab.StrLen(lxD) > 0)
- 2002                                                  & (SymTab.ExpProc(bnF,
- 2003                                                       lxD) >= 0) THEN
- 2004                                                 t := SymTab.ProcRetByNum(
- 2005                                                        SymTab.ExpProc(bnF,
- 2006                                                          lxD))
- 2007                                               ELSE
- 2008                                                 t := SymTab.InvalidType
- 2009                                               END
- 2010                                             ELSE t := SymTab.InvalidType
- 2011                                             END;
- 2012                                             lx[0] := 0C; v := FALSE;
- 2013                                             MGen.ClrStash(); .) ]
- 2014      | "("
- 2015        Expr<et, lx, v, vn> ")"         (. t := et; .)
- 2016      | ( "NOT" | "~" )
- 2017        Fact<t2, lx2, v2, vn2>          (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
- 2018                                           IF SymTab.BoolCheck(t2) THEN
- 2019                                             t := SymTab.BoolType()
- 2020                                           ELSE SemError(212);
- 2021                                             t := SymTab.InvalidType END;
- 2022                                           MGen.Not; .)
- 2023      | SetLit<st>                      (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
- 2024                                           t := st; .) .
- 2025    SetLit <VAR t: SymTab.TypeIndex>
- 2026                                          (. VAR first, et: SymTab.TypeIndex;
- 2027                                               lxE, lxE2: MGen.LitStr;
- 2028                                               vE, vE2: BOOLEAN;
- 2029                                               vnE, vnE2: SymTab.Name;
- 2030                                               hasR: BOOLEAN; .)
- 2031      = "{"
- 2032                                  (. MGen.PushInt(0);
- 2033                                     t := SymTab.SetFor(SymTab.IntType()); .)
- 2034        [ Elem<et, lxE, lxE2, hasR>   (. first := et;
- 2035                                         t := SymTab.SetFor(et);
- 2036                                         MGen.ClrStash();
- 2037                                         IF hasR THEN
- 2038                                           MGen.PushInt(1); MGen.Add;
- 2039                                           MGen.FieldMask
- 2040                                         ELSE MGen.Power2 END;
- 2041                                         MGen.Or; .)
- 2042          { ","
- 2043            Elem<et, lxE, lxE2, hasR> (. IF ~SymTab.SetElemCheck(first, et) THEN
- 2044                                         SemError(222) END;
- 2045                                         MGen.ClrStash();
- 2046                                         IF hasR THEN
- 2047                                           MGen.PushInt(1); MGen.Add;
- 2048                                           MGen.FieldMask
- 2049                                         ELSE MGen.Power2 END;
- 2050                                         MGen.Or; .) } ]
- 2051        "}" .
- 2052    Elem <VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr;
- 2053          VAR lx2: MGen.LitStr; VAR hasR: BOOLEAN>
- 2054                                          (. VAR t2: SymTab.TypeIndex;
- 2055                                               vD, vD2: BOOLEAN;
- 2056                                               vnD, vnD2: SymTab.Name; .)
- 2057      = Expr<t, lx, vD, vnD>              (. hasR := FALSE;
- 2058                                             lx2[0] := 0C; .)
- 2059        [ ".."
- 2060          Expr<t2, lx2, vD2, vnD2>        (. IF ~SymTab.SetElemCheck(t, t2) THEN
- 2061                                             SemError(222) END;
- 2062                                             hasR := TRUE; .) ] .
- 2063  
- 2064    GetIdent <VAR n: SymTab.Name>
- 2065      = ident                           (. LexName(n); .) .
- 2066  
- 2067  END M2c.
+ 1431                                             END; .) .
+ 1432    DesignTail <VAR t: SymTab.TypeIndex; VAR k: INTEGER;
+ 1433                VAR bn: SymTab.Name; doLoad: BOOLEAN; VAR lx: MGen.LitStr;
+ 1434                VAR sfx: BOOLEAN>
+ 1435                                          (. VAR m: SymTab.Name;
+ 1436                                               it: SymTab.TypeIndex;
+ 1437                                               lxI: MGen.LitStr;
+ 1438                                               vI: BOOLEAN;
+ 1439                                               vnI: SymTab.Name;
+ 1440                                               loA: INTEGER;
+ 1441                                               elemT: SymTab.TypeIndex;
+ 1442                                               esl, ebytes: CARDINAL;
+ 1443                                               firstT: BOOLEAN;
+ 1444                                               clsI: INTEGER;
+ 1445                                               qM: SymTab.Name; .)
+ 1446      =                                   (. sfx := FALSE; .)
+ 1447        { "."                             (. firstT := ~sfx;
+ 1448                                             sfx := TRUE; lx[0] := 0C;
+ 1449                                             IF ~doLoad & firstT THEN
+ 1450                                               IF (k = SymTab.KindVar)
+ 1451                                                  OR (k = SymTab.KindParam)
+ 1452                                                  OR (k
+ 1453                                                      = SymTab.KindVarPar) THEN
+ 1454                                                 MGen.PushAddr(bn)
+ 1455                                               ELSIF k
+ 1456                                                 = SymTab.KindField THEN
+ 1457                                                 MGen.WithAddr(bn)
+ 1458                                               ELSIF k
+ 1459                                                 = SymTab.KindModule THEN
+ 1460                                               ELSE MGen.PushInt(0)
+ 1461                                               END
+ 1462                                             END; .)
+ 1463          GetIdent<m>                     (. IF (k = SymTab.KindModule) THEN
+ 1464                                               IF SymTab.ExpKind(bn, m) = -1 THEN
+ 1465                                                 SemError(201);
+ 1466                                                 MGen.CopyName(m, lx);
+ 1467                                                 t := SymTab.InvalidType;
+ 1468                                                 IF doLoad THEN
+ 1469                                                   MGen.Drop; MGen.PushInt(0)
+ 1470                                                 ELSIF firstT THEN
+ 1471                                                 ELSE MGen.Drop
+ 1472                                                 END
+ 1473                                               ELSIF SymTab.ExpKind(bn, m)
+ 1474                                                      = SymTab.KindProc THEN
+ 1475                                                 MGen.CopyName(m, lx);
+ 1476                                                 t := SymTab.InvalidType;
+ 1477                                                 IF doLoad THEN
+ 1478                                                   MGen.Drop; MGen.PushInt(0)
+ 1479                                                 ELSIF firstT THEN
+ 1480                                                 ELSE MGen.Drop
+ 1481                                                 END
+ 1482                                               ELSE
+ 1483                                                 t := SymTab.ExpType(bn, m);
+ 1484                                                 k := SymTab.ExpKind(bn, m);
+ 1485                                                 SymTab.ExpQual(bn, m, qM);
+ 1486                                                 IF doLoad THEN
+ 1487                                                   MGen.Drop;
+ 1488                                                   MGen.GlobalAddr(qM)
+ 1489                                                 ELSE
+ 1490                                                   IF firstT THEN
+ 1491                                                   ELSE MGen.Drop
+ 1492                                                   END;
+ 1493                                                   MGen.GlobalAddr(qM)
+ 1494                                                 END
+ 1495                                               END
+ 1496                                             ELSIF t = SymTab.InvalidType THEN
+ 1497                                               IF ~doLoad & firstT THEN
+ 1498                                                 MGen.Drop
+ 1499                                               ELSIF doLoad THEN
+ 1500                                                 MGen.Drop; MGen.PushInt(0)
+ 1501                                               END
+ 1502                                             ELSIF SymTab.ClassOf(t) #
+ 1503                                                   SymTab.ClRecord THEN
+ 1504                                               SemError(215);
+ 1505                                               t := SymTab.InvalidType;
+ 1506                                               IF doLoad THEN
+ 1507                                                 MGen.Drop; MGen.PushInt(0)
+ 1508                                               ELSIF firstT THEN
+ 1509                                                 MGen.Drop
+ 1510                                               END
+ 1511                                             ELSIF ~SymTab.FieldExists(t, m) THEN
+ 1512                                               SemError(216);
+ 1513                                               t := SymTab.InvalidType;
+ 1514                                               IF doLoad THEN
+ 1515                                                 MGen.Drop; MGen.PushInt(0)
+ 1516                                               ELSIF firstT THEN
+ 1517                                                 MGen.Drop
+ 1518                                               END
+ 1519                                             ELSE
+ 1520                                               loA := SymTab.FieldOffset(t, m);
+ 1521                                               elemT := SymTab.FieldType(t, m);
+ 1522                                               IF loA < 0 THEN
+ 1523                                                 SemError(216);
+ 1524                                                 t := SymTab.InvalidType;
+ 1525                                                 IF doLoad THEN
+ 1526                                                   MGen.Drop; MGen.PushInt(0)
+ 1527                                                 ELSIF firstT THEN
+ 1528                                                   MGen.Drop
+ 1529                                                 END
+ 1530                                               ELSE
+ 1531                                                 MGen.FieldAdd(
+ 1532                                                   VAL(CARDINAL, loA));
+ 1533                                                 t := elemT
+ 1534                                               END
+ 1535                                             END; .)
+ 1536        | "["                             (. firstT := ~sfx;
+ 1537                                             sfx := TRUE; lx[0] := 0C;
+ 1538                                             IF ~doLoad & firstT THEN
+ 1539                                               IF (k = SymTab.KindVar)
+ 1540                                                  OR (k = SymTab.KindParam)
+ 1541                                                  OR (k
+ 1542                                                      = SymTab.KindVarPar) THEN
+ 1543                                                 MGen.PushAddr(bn)
+ 1544                                               ELSIF k
+ 1545                                                 = SymTab.KindField THEN
+ 1546                                                 MGen.WithAddr(bn)
+ 1547                                               ELSE MGen.PushInt(0)
+ 1548                                               END
+ 1549                                             END; .)
+ 1550          Expr<it, lxI, vI, vnI>          (. IF t = SymTab.InvalidType THEN
+ 1551                                             MGen.Drop;
+ 1552                                             IF doLoad THEN
+ 1553                                               MGen.Drop; MGen.PushInt(0)
+ 1554                                             ELSE
+ 1555                                               IF ~firstT THEN
+ 1556                                               ELSE MGen.Drop
+ 1557                                               END
+ 1558                                             END
+ 1559                                           ELSIF SymTab.ClassOf(t) #
+ 1560                                                   SymTab.ClArray THEN
+ 1561                                             SemError(217);
+ 1562                                             t := SymTab.InvalidType;
+ 1563                                             MGen.Drop;
+ 1564                                             IF doLoad THEN
+ 1565                                               MGen.Drop; MGen.PushInt(0)
+ 1566                                             ELSE
+ 1567                                               IF ~firstT THEN
+ 1568                                               ELSE MGen.Drop
+ 1569                                               END
+ 1570                                             END
+ 1571                                           ELSE
+ 1572                                             clsI := SymTab.ClassOf(it);
+ 1573                                             IF (it
+ 1574                                                # SymTab.InvalidType)
+ 1575                                                & (clsI # SymTab.ClInt)
+ 1576                                                & (clsI # SymTab.ClChar)
+ 1577                                                & (clsI # SymTab.ClEnum)
+ 1578                                                & (clsI
+ 1579                                                   # SymTab.ClBool) THEN
+ 1580                                               SemError(218);
+ 1581                                               t := SymTab.InvalidType;
+ 1582                                               MGen.Drop;
+ 1583                                               IF doLoad THEN
+ 1584                                                 MGen.Drop; MGen.PushInt(0)
+ 1585                                               ELSE
+ 1586                                                 IF ~firstT THEN
+ 1587                                                 ELSE MGen.Drop
+ 1588                                                 END
+ 1589                                               END
+ 1590                                             ELSE
+ 1591                                               loA := SymTab.ArrayLo(t);
+ 1592                                               elemT := SymTab.ArrayElem(t);
+ 1593                                               esl := SymTab.TypeSlots(elemT);
+ 1594                                               IF esl = 0 THEN
+ 1595                                                 SemError(230);
+ 1596                                                 esl := 1
+ 1597                                               END;
+ 1598                                               IF (SymTab.ClassOf(elemT)
+ 1599                                                  = SymTab.ClChar)
+ 1600                                                  OR (SymTab.ClassOf(elemT)
+ 1601                                                     = SymTab.ClBool) THEN
+ 1602                                                 ebytes := 1
+ 1603                                               ELSE ebytes := esl * 8
+ 1604                                               END;
+ 1605                                               MGen.IdxScale(loA, ebytes);
+ 1606                                               t := elemT
+ 1607                                             END
+ 1608                                           END; .)
+ 1609          { ","
+ 1610            Expr<it, lxI, vI, vnI>        (. IF t = SymTab.InvalidType THEN
+ 1611                                             MGen.Drop;
+ 1612                                             IF doLoad THEN
+ 1613                                               MGen.Drop; MGen.PushInt(0);
+ 1614                                               t := SymTab.InvalidType
+ 1615                                             END
+ 1616                                           ELSIF SymTab.ClassOf(t) #
+ 1617                                                   SymTab.ClArray THEN
+ 1618                                             SemError(217);
+ 1619                                             t := SymTab.InvalidType;
+ 1620                                             MGen.Drop;
+ 1621                                             IF doLoad THEN
+ 1622                                               MGen.Drop; MGen.PushInt(0)
+ 1623                                             END
+ 1624                                           ELSE
+ 1625                                             clsI := SymTab.ClassOf(it);
+ 1626                                             IF (it
+ 1627                                                # SymTab.InvalidType)
+ 1628                                                & (clsI # SymTab.ClInt)
+ 1629                                                & (clsI # SymTab.ClChar)
+ 1630                                                & (clsI # SymTab.ClEnum)
+ 1631                                                & (clsI
+ 1632                                                   # SymTab.ClBool) THEN
+ 1633                                               SemError(218);
+ 1634                                               t := SymTab.InvalidType;
+ 1635                                               MGen.Drop;
+ 1636                                               IF doLoad THEN
+ 1637                                                 MGen.Drop; MGen.PushInt(0)
+ 1638                                               END
+ 1639                                             ELSE
+ 1640                                               loA := SymTab.ArrayLo(t);
+ 1641                                               elemT := SymTab.ArrayElem(t);
+ 1642                                               esl := SymTab.TypeSlots(elemT);
+ 1643                                               IF esl = 0 THEN
+ 1644                                                 SemError(230);
+ 1645                                                 esl := 1
+ 1646                                               END;
+ 1647                                               IF (SymTab.ClassOf(elemT)
+ 1648                                                  = SymTab.ClChar)
+ 1649                                                  OR (SymTab.ClassOf(elemT)
+ 1650                                                     = SymTab.ClBool) THEN
+ 1651                                                 ebytes := 1
+ 1652                                               ELSE ebytes := esl * 8
+ 1653                                               END;
+ 1654                                               MGen.IdxScale(loA, ebytes);
+ 1655                                               t := elemT
+ 1656                                             END
+ 1657                                           END; .) }
+ 1658          "]"
+ 1659        | "^"                             (. firstT := ~sfx;
+ 1660                                             sfx := TRUE; lx[0] := 0C;
+ 1661                                             IF ~doLoad & firstT THEN
+ 1662                                               IF (k = SymTab.KindVar)
+ 1663                                                  OR (k = SymTab.KindParam)
+ 1664                                                  OR (k
+ 1665                                                      = SymTab.KindVarPar) THEN
+ 1666                                                 MGen.PushAddr(bn)
+ 1667                                               ELSIF k
+ 1668                                                 = SymTab.KindField THEN
+ 1669                                                 MGen.WithAddr(bn)
+ 1670                                               ELSE MGen.PushInt(0)
+ 1671                                               END
+ 1672                                             END; .)
+ 1673                                          (. IF t = SymTab.InvalidType THEN
+ 1674                                               IF doLoad THEN
+ 1675                                                 MGen.Drop; MGen.PushInt(0)
+ 1676                                               ELSIF firstT THEN
+ 1677                                                 MGen.Drop
+ 1678                                               END
+ 1679                                             ELSIF SymTab.ClassOf(t) #
+ 1680                                                   SymTab.ClPtr THEN
+ 1681                                               SemError(219);
+ 1682                                               t := SymTab.InvalidType;
+ 1683                                               IF doLoad THEN
+ 1684                                                 MGen.Drop; MGen.PushInt(0)
+ 1685                                               ELSIF firstT THEN
+ 1686                                                 MGen.Drop
+ 1687                                               END
+ 1688                                             ELSE
+ 1689                                               elemT := SymTab.PtrBase(t);
+ 1690                                               t := elemT;
+ 1691                                               IF doLoad THEN
+ 1692                                                 IF ~(firstT
+ 1693                                                    & ((k
+ 1694                                                        = SymTab.KindVar)
+ 1695                                                    OR (k
+ 1696                                                        = SymTab.KindParam)
+ 1697                                                    OR (k
+ 1698                                                        = SymTab.KindVarPar)))
+ 1699                                                 THEN
+ 1700                                                   MGen.LoadIndir
+ 1701                                                 END
+ 1702                                               ELSE
+ 1703                                                 MGen.LoadIndir
+ 1704                                               END
+ 1705                                             END; .) } .
+ 1706    Expr <VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr;
+ 1707          VAR v: BOOLEAN; VAR vn: SymTab.Name>
+ 1708                                          (. VAR t2: SymTab.TypeIndex;
+ 1709                                               tc, op: INTEGER;
+ 1710                                               lx2: MGen.LitStr;
+ 1711                                               v2: BOOLEAN;
+ 1712                                               vn2: SymTab.Name;
+ 1713                                               r: BOOLEAN; .)
+ 1714      = SimExpr<t, lx, v, vn> [ Rel<op> SimExpr<t2, lx2, v2, vn2>
+ 1715        (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
+ 1716           IF op = SymTab.OpIn THEN
+ 1717             IF SymTab.InCheck(t, t2) THEN
+ 1718               t := SymTab.BoolType();
+ 1719               MGen.BitIn
+ 1720             ELSE SemError(222);
+ 1721               t := SymTab.InvalidType;
+ 1722               MGen.Drop; MGen.Drop; MGen.PushInt(0)
+ 1723             END
+ 1724           ELSIF (t # SymTab.InvalidType)
+ 1725              & (t2 # SymTab.InvalidType)
+ 1726              & (SymTab.ClassOf(t) = SymTab.ClArray)
+ 1727              & (SymTab.ClassOf(t2) = SymTab.ClArray)
+ 1728              & (SymTab.ClassOf(SymTab.ArrayElem(t)) = SymTab.ClChar)
+ 1729              & (SymTab.ClassOf(SymTab.ArrayElem(t2)) = SymTab.ClChar)
+ 1730              & ~SymTab.IsOpen(t) & ~SymTab.IsOpen(t2) THEN
+ 1731             t := SymTab.BoolType();
+ 1732             MGen.PushBytes(SymTab.TypeSlots(t) * 8);
+ 1733             MGen.PushBytes(SymTab.TypeSlots(t2) * 8);
+ 1734             MGen.StrComp;
+ 1735             IF op = SymTab.OpEq THEN MGen.Or; MGen.Not
+ 1736             ELSIF (op = SymTab.OpNeq1)
+ 1737                   OR (op = SymTab.OpNeq2) THEN MGen.Or
+ 1738             ELSIF op = SymTab.OpLt THEN
+ 1739               MGen.Swap; MGen.Drop
+ 1740             ELSIF op = SymTab.OpLe THEN
+ 1741               MGen.Drop; MGen.Not
+ 1742             ELSIF op = SymTab.OpGt THEN
+ 1743               MGen.Drop
+ 1744             ELSE
+ 1745               MGen.Swap; MGen.Drop; MGen.Not
+ 1746             END
+ 1747           ELSIF (t # SymTab.InvalidType)
+ 1748              & (t2 # SymTab.InvalidType)
+ 1749              & ((SymTab.ClassOf(t) = SymTab.ClArray)
+ 1750                 OR (SymTab.ClassOf(t) = SymTab.ClRecord)
+ 1751                 OR (SymTab.ClassOf(t2) = SymTab.ClArray)
+ 1752                 OR (SymTab.ClassOf(t2) = SymTab.ClRecord)) THEN
+ 1753             SemError(213); t := SymTab.InvalidType;
+ 1754             MGen.Drop; MGen.Drop; MGen.PushInt(0)
+ 1755           ELSE
+ 1756             tc := SymTab.ClassOf(t);
+ 1757             IF SymTab.RelCheck(t, t2, op) THEN
+ 1758               t := SymTab.BoolType()
+ 1759             ELSE SemError(213); t := SymTab.InvalidType END;
+ 1760             IF t # SymTab.InvalidType THEN
+ 1761               r := tc = SymTab.ClReal;
+ 1762               IF r THEN
+ 1763                 IF op = SymTab.OpEq THEN MGen.RealEq
+ 1764                 ELSIF (op = SymTab.OpNeq1)
+ 1765                       OR (op = SymTab.OpNeq2) THEN MGen.RealNe
+ 1766                 ELSIF op = SymTab.OpLt THEN MGen.RealLt
+ 1767                 ELSIF op = SymTab.OpLe THEN MGen.RealLe
+ 1768                 ELSIF op = SymTab.OpGt THEN MGen.RealGt
+ 1769                 ELSE MGen.RealGe END
+ 1770               ELSE
+ 1771                 IF op = SymTab.OpEq THEN MGen.Eq
+ 1772                 ELSIF (op = SymTab.OpNeq1)
+ 1773                       OR (op = SymTab.OpNeq2) THEN MGen.Neq
+ 1774                 ELSIF op = SymTab.OpLt THEN MGen.ILt
+ 1775                 ELSIF op = SymTab.OpLe THEN MGen.ILe
+ 1776                 ELSIF op = SymTab.OpGt THEN MGen.IGt
+ 1777                 ELSE MGen.IGe END
+ 1778               END
+ 1779             ELSE MGen.Drop; MGen.Drop; MGen.PushInt(0)
+ 1780             END
+ 1781           END; .) ] .
+ 1782    Rel <VAR op: INTEGER>
+ 1783      = "="                     (. op := SymTab.OpEq; .)
+ 1784      | "#"                     (. op := SymTab.OpNeq1; .)
+ 1785      | "<>"                    (. op := SymTab.OpNeq2; .)
+ 1786      | "<"                     (. op := SymTab.OpLt; .)
+ 1787      | "<="                    (. op := SymTab.OpLe; .)
+ 1788      | ">"                     (. op := SymTab.OpGt; .)
+ 1789      | ">="                    (. op := SymTab.OpGe; .)
+ 1790      | "IN"                    (. op := SymTab.OpIn; .) .
+ 1791    SimExpr <VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr;
+ 1792             VAR v: BOOLEAN; VAR vn: SymTab.Name>
+ 1793                                          (. VAR t2, res2: SymTab.TypeIndex;
+ 1794                                               op: INTEGER;
+ 1795                                               lx2: MGen.LitStr;
+ 1796                                               v2: BOOLEAN;
+ 1797                                               vn2: SymTab.Name;
+ 1798                                               neg, isR: BOOLEAN; .)
+ 1799      =                                   (. neg := FALSE; .)
+ 1800        [ "+" | "-"                       (. neg := TRUE; .) ]
+ 1801        Term<t, lx, v, vn>                (. IF neg THEN
+ 1802                                             v := FALSE;
+ 1803                                             MGen.ClrStash();
+ 1804                                             IF MGen.IsLit(lx) THEN
+ 1805                                               MGen.NegFold(lx, lx)
+ 1806                                             ELSE lx[0] := 0C
+ 1807                                             END;
+ 1808                                             IF SymTab.ClassOf(t)
+ 1809                                                = SymTab.ClReal THEN
+ 1810                                               MGen.NegReal
+ 1811                                             ELSE MGen.NegInt
+ 1812                                             END
+ 1813                                           END; .)
+ 1814        { AddOp<op> Term<t2, lx2, v2, vn2>
+ 1815        (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
+ 1816           IF op = SymTab.OpOr THEN
+ 1817             IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
+ 1818               t := SymTab.BoolType()
+ 1819             ELSE SemError(212); t := SymTab.InvalidType END;
+ 1820             MGen.Or
+ 1821           ELSIF (t # SymTab.InvalidType)
+ 1822              & (t2 # SymTab.InvalidType)
+ 1823              & (SymTab.ClassOf(t) = SymTab.ClSet)
+ 1824              & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
+ 1825             IF op = SymTab.OpAdd THEN
+ 1826               MGen.Or
+ 1827             ELSE
+ 1828               MGen.PushBits(0FFFFFFFFFFFFFFFFH);
+ 1829               MGen.BitXor;
+ 1830               MGen.And
+ 1831             END
+ 1832           ELSE
+ 1833             IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN t := res2
+ 1834             ELSE SemError(211); t := SymTab.InvalidType END;
+ 1835             isR := (t # SymTab.InvalidType)
+ 1836                    & (SymTab.ClassOf(t) = SymTab.ClReal);
+ 1837             IF op = SymTab.OpAdd THEN
+ 1838               IF isR THEN MGen.RealAdd ELSE MGen.Add END
+ 1839             ELSE
+ 1840               IF isR THEN MGen.RealSub ELSE MGen.Sub END
+ 1841             END
+ 1842           END; .) } .
+ 1843    AddOp <VAR op: INTEGER>
+ 1844      = "+"                     (. op := SymTab.OpAdd; .)
+ 1845      | "-"                     (. op := SymTab.OpSub; .)
+ 1846      | "OR"                    (. op := SymTab.OpOr; .) .
+ 1847    Term <VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr;
+ 1848          VAR v: BOOLEAN; VAR vn: SymTab.Name>
+ 1849                                          (. VAR t2, res2: SymTab.TypeIndex;
+ 1850                                               op: INTEGER;
+ 1851                                               lx2: MGen.LitStr;
+ 1852                                               v2: BOOLEAN;
+ 1853                                               vn2: SymTab.Name;
+ 1854                                               isR: BOOLEAN;
+ 1855                                               mt: INTEGER; .)
+ 1856      = Fact<t, lx, v, vn> { MulOp<op> Fact<t2, lx2, v2, vn2>
+ 1857        (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
+ 1858           IF op = SymTab.OpAnd THEN
+ 1859             IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
+ 1860               t := SymTab.BoolType()
+ 1861             ELSE SemError(212); t := SymTab.InvalidType END;
+ 1862             MGen.And
+ 1863           ELSIF (op = SymTab.OpTimes)
+ 1864              & (t # SymTab.InvalidType)
+ 1865              & (t2 # SymTab.InvalidType)
+ 1866              & (SymTab.ClassOf(t) = SymTab.ClSet)
+ 1867              & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
+ 1868             MGen.And
+ 1869           ELSE
+ 1870             IF SymTab.ArithCheck(t, t2,
+ 1871                  (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
+ 1872                  res2) THEN t := res2
+ 1873             ELSE SemError(211); t := SymTab.InvalidType END;
+ 1874             isR := (t # SymTab.InvalidType)
+ 1875                    & (SymTab.ClassOf(t) = SymTab.ClReal);
+ 1876             IF op = SymTab.OpTimes THEN
+ 1877               IF isR THEN MGen.RealMul ELSE MGen.MulU END
+ 1878             ELSIF op = SymTab.OpSlash THEN
+ 1879               IF isR THEN MGen.RealDiv ELSE MGen.DivI END
+ 1880             ELSIF op = SymTab.OpDiv THEN
+ 1881               MGen.DivI
+ 1882             ELSE
+ 1883               mt := MGen.TempGlobal();
+ 1884               MGen.ModI(mt)
+ 1885             END
+ 1886           END; .) } .
+ 1887    MulOp <VAR op: INTEGER>
+ 1888      = "*"                     (. op := SymTab.OpTimes; .)
+ 1889      | "/"                     (. op := SymTab.OpSlash; .)
+ 1890      | "DIV"                   (. op := SymTab.OpDiv; .)
+ 1891      | "MOD"                   (. op := SymTab.OpMod; .)
+ 1892      | "AND"                   (. op := SymTab.OpAnd; .)
+ 1893      | "&"                     (. op := SymTab.OpAnd; .) .
+ 1894    Fact <VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr;
+ 1895          VAR v: BOOLEAN; VAR vn: SymTab.Name>
+ 1896                                          (. VAR s: ARRAY [0 .. 255] OF CHAR;
+ 1897                                               t2, et, dt, st: SymTab.TypeIndex;
+ 1898                                               dk: INTEGER;
+ 1899                                               bnF: SymTab.Name;
+ 1900                                               lxD, lx2: MGen.LitStr;
+ 1901                                               v2: BOOLEAN;
+ 1902                                               vn2: SymTab.Name;
+ 1903                                               vi: INTEGER;
+ 1904                                               c: CARDINAL;
+ 1905                                               b: LONGCARD;
+ 1906                                               sfxF: BOOLEAN;
+ 1907                                               okF: BOOLEAN; .)
+ 1908      = integer                         (. LexString(s);
+ 1909                                           MGen.CopyName(s, lx);
+ 1910                                           v := FALSE; MGen.ClrStash();
+ 1911                                           IF MGen.ParseInt(s, vi) THEN
+ 1912                                             MGen.PushInt(vi)
+ 1913                                           ELSIF MGen.ParseCard(s, c) THEN
+ 1914                                             MGen.PushBits(
+ 1915                                               VAL(LONGCARD, c))
+ 1916                                           ELSE MGen.PushInt(0)
+ 1917                                           END;
+ 1918                                           t := SymTab.IntType(); .)
+ 1919      | real                            (. LexString(s);
+ 1920                                           MGen.CopyName(s, lx);
+ 1921                                           v := FALSE; MGen.ClrStash();
+ 1922                                           IF MGen.ParseReal(s, b) THEN
+ 1923                                             MGen.PushBits(b)
+ 1924                                           ELSE MGen.PushBits(0H)
+ 1925                                           END;
+ 1926                                           t := SymTab.RealType(); .)
+ 1927      | string                          (. LexString(s);
+ 1928                                           v := FALSE; MGen.ClrStash();
+ 1929                                           IF SymTab.StrLen(s) <= 3 THEN
+ 1930                                             t := SymTab.CharType();
+ 1931                                             MGen.CopyName(s, lx);
+ 1932                                             MGen.PushInt(
+ 1933                                               MGen.CharOrd(s))
+ 1934                                           ELSE t := SymTab.NewStr();
+ 1935                                             MGen.CopyName(s, lx);
+ 1936                                             MGen.EmitString(s)
+ 1937                                           END; .)
+ 1938      | "HIGH"
+ 1939        "(" DesignHead<dt, dk, bnF, FALSE, lxD>
+ 1940            DesignTail<dt, dk, bnF, FALSE, lxD, sfxF>
+ 1941        ")"                               (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
+ 1942                                             IF dt = SymTab.InvalidType THEN
+ 1943                                               IF sfxF THEN MGen.Drop END;
+ 1944                                               MGen.PushInt(0);
+ 1945                                               t := SymTab.InvalidType
+ 1946                                             ELSIF SymTab.ClassOf(dt)
+ 1947                                                    # SymTab.ClArray THEN
+ 1948                                               SemError(217);
+ 1949                                               IF sfxF THEN MGen.Drop END;
+ 1950                                               MGen.PushInt(0);
+ 1951                                               t := SymTab.InvalidType
+ 1952                                             ELSIF SymTab.IsOpen(dt) THEN
+ 1953                                               IF sfxF THEN MGen.Drop END;
+ 1954                                               IF (dk = SymTab.KindParam)
+ 1955                                                  OR (dk
+ 1956                                                   = SymTab.KindVarPar) THEN
+ 1957                                                 IF SymTab.CurDepth()
+ 1958                                                    = SymTab.SymDepth(bnF) THEN
+ 1959                                                   MGen.LoadLocal(
+ 1960                                                     SymTab.SymSlot(bnF) + 1)
+ 1961                                                 ELSE
+ 1962                                                   MGen.FrameAddr(
+ 1963                                                     SymTab.SymSlot(bnF) + 1,
+ 1964                                                     VAL(CARDINAL,
+ 1965                                                       SymTab.CurDepth() - 1
+ 1966                                                       - SymTab.SymDepth(bnF)));
+ 1967                                                   MGen.LoadIndir
+ 1968                                                 END;
+ 1969                                                 MGen.PushInt(1);
+ 1970                                                 MGen.Sub;
+ 1971                                                 t := SymTab.IntType()
+ 1972                                               ELSE
+ 1973                                                 MGen.PushInt(0);
+ 1974                                                 t := SymTab.InvalidType
+ 1975                                               END
+ 1976                                             ELSE
+ 1977                                               IF sfxF THEN MGen.Drop END;
+ 1978                                               MGen.PushInt(
+ 1979                                                 SymTab.ArrayHi(dt));
+ 1980                                               t := SymTab.IntType()
+ 1981                                             END; .)
+ 1982      | DesignHead<dt, dk, bnF, TRUE, lxD>
+ 1983        DesignTail<dt, dk, bnF, TRUE, lxD, sfxF>
+ 1984                                          (. t := dt;
+ 1985                                             MGen.CopyName(lxD, lx);
+ 1986                                             IF sfxF
+ 1987                                                & (t # SymTab.InvalidType)
+ 1988                                                & MGen.ActIsVarNext()
+ 1989                                                & ((dk = SymTab.KindVar)
+ 1990                                                   OR (dk
+ 1991                                                       = SymTab.KindParam)
+ 1992                                                   OR (dk
+ 1993                                                       = SymTab.KindVarPar)
+ 1994                                                   OR (dk
+ 1995                                                       = SymTab.KindField))
+ 1996                                                & (SymTab.SymKind(bnF)
+ 1997                                                   # SymTab.KindModule)
+ 1998                                                & (SymTab.ClassOf(t)
+ 1999                                                   # SymTab.ClChar)
+ 2000                                                & (SymTab.ClassOf(t)
+ 2001                                                   # SymTab.ClBool) THEN
+ 2002                                               MGen.StashAddr()
+ 2003                                             END;
+ 2004                                             IF sfxF
+ 2005                                                & (t # SymTab.InvalidType)
+ 2006                                                & (SymTab.ClassOf(t)
+ 2007                                                   # SymTab.ClArray)
+ 2008                                                & (SymTab.ClassOf(t)
+ 2009                                                   # SymTab.ClRecord) THEN
+ 2010                                               IF (SymTab.ClassOf(t)
+ 2011                                                  = SymTab.ClChar)
+ 2012                                                  OR (SymTab.ClassOf(t)
+ 2013                                                     = SymTab.ClBool) THEN
+ 2014                                                 MGen.LoadByte
+ 2015                                               ELSE MGen.LoadIndir
+ 2016                                               END
+ 2017                                             END;
+ 2018                                             v := ~sfxF
+ 2019                                                  & ((dk = SymTab.KindVar)
+ 2020                                                  OR (dk = SymTab.KindParam)
+ 2021                                                  OR (dk
+ 2022                                                      = SymTab.KindVarPar));
+ 2023                                             MGen.CopyName(bnF, vn); .)
+ 2024        [ CallTail<bnF, lxD, sfxF, TRUE, okF, TRUE>
+ 2025                                          (. IF okF THEN
+ 2026                                               IF SymTab.SymKind(bnF)
+ 2027                                                  = SymTab.KindProc THEN
+ 2028                                                 t := SymTab.ProcRet(bnF)
+ 2029                                               ELSIF (SymTab.SymKind(bnF)
+ 2030                                                         = SymTab.KindModule)
+ 2031                                                  & sfxF
+ 2032                                                  & (SymTab.StrLen(lxD) > 0)
+ 2033                                                  & (SymTab.ExpProc(bnF,
+ 2034                                                       lxD) >= 0) THEN
+ 2035                                                 t := SymTab.ProcRetByNum(
+ 2036                                                        SymTab.ExpProc(bnF,
+ 2037                                                          lxD))
+ 2038                                               ELSE
+ 2039                                                 t := SymTab.InvalidType
+ 2040                                               END
+ 2041                                             ELSE t := SymTab.InvalidType
+ 2042                                             END;
+ 2043                                             lx[0] := 0C; v := FALSE;
+ 2044                                             MGen.ClrStash(); .) ]
+ 2045      | "("
+ 2046        Expr<et, lx, v, vn> ")"         (. t := et; .)
+ 2047      | ( "NOT" | "~" )
+ 2048        Fact<t2, lx2, v2, vn2>          (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
+ 2049                                           IF SymTab.BoolCheck(t2) THEN
+ 2050                                             t := SymTab.BoolType()
+ 2051                                           ELSE SemError(212);
+ 2052                                             t := SymTab.InvalidType END;
+ 2053                                           MGen.Not; .)
+ 2054      | SetLit<st>                      (. lx[0] := 0C; v := FALSE; MGen.ClrStash();
+ 2055                                           t := st; .) .
+ 2056    SetLit <VAR t: SymTab.TypeIndex>
+ 2057                                          (. VAR first, et: SymTab.TypeIndex;
+ 2058                                               lxE, lxE2: MGen.LitStr;
+ 2059                                               vE, vE2: BOOLEAN;
+ 2060                                               vnE, vnE2: SymTab.Name;
+ 2061                                               hasR: BOOLEAN; .)
+ 2062      = "{"
+ 2063                                  (. MGen.PushInt(0);
+ 2064                                     t := SymTab.SetFor(SymTab.IntType()); .)
+ 2065        [ Elem<et, lxE, lxE2, hasR>   (. first := et;
+ 2066                                         t := SymTab.SetFor(et);
+ 2067                                         MGen.ClrStash();
+ 2068                                         IF hasR THEN
+ 2069                                           MGen.PushInt(1); MGen.Add;
+ 2070                                           MGen.FieldMask
+ 2071                                         ELSE MGen.Power2 END;
+ 2072                                         MGen.Or; .)
+ 2073          { ","
+ 2074            Elem<et, lxE, lxE2, hasR> (. IF ~SymTab.SetElemCheck(first, et) THEN
+ 2075                                         SemError(222) END;
+ 2076                                         MGen.ClrStash();
+ 2077                                         IF hasR THEN
+ 2078                                           MGen.PushInt(1); MGen.Add;
+ 2079                                           MGen.FieldMask
+ 2080                                         ELSE MGen.Power2 END;
+ 2081                                         MGen.Or; .) } ]
+ 2082        "}" .
+ 2083    Elem <VAR t: SymTab.TypeIndex; VAR lx: MGen.LitStr;
+ 2084          VAR lx2: MGen.LitStr; VAR hasR: BOOLEAN>
+ 2085                                          (. VAR t2: SymTab.TypeIndex;
+ 2086                                               vD, vD2: BOOLEAN;
+ 2087                                               vnD, vnD2: SymTab.Name; .)
+ 2088      = Expr<t, lx, vD, vnD>              (. hasR := FALSE;
+ 2089                                             lx2[0] := 0C; .)
+ 2090        [ ".."
+ 2091          Expr<t2, lx2, vD2, vnD2>        (. IF ~SymTab.SetElemCheck(t, t2) THEN
+ 2092                                             SemError(222) END;
+ 2093                                             hasR := TRUE; .) ] .
+ 2094  
+ 2095    GetIdent <VAR n: SymTab.Name>
+ 2096      = ident                           (. LexName(n); .) .
+ 2097  
+ 2098  END M2c.
 
     0 errors
 

+ 36 - 5
M2cP.mod

@@ -1688,6 +1688,20 @@ PROCEDURE AssignOrCall;
                = SymTab.ClRecord)) THEN
         MGen.PushAddr(bn);
         pushedDst := TRUE
+      ELSIF ((dk = SymTab.KindVar)
+             OR (dk
+                 = SymTab.KindParam)
+             OR (dk
+                 = SymTab.KindVarPar)
+             OR (dk
+                 = SymTab.KindField))
+         & sfx
+         & (dt # SymTab.InvalidType)
+         & ((SymTab.ClassOf(dt)
+            = SymTab.ClArray)
+            OR (SymTab.ClassOf(dt)
+               = SymTab.ClRecord)) THEN
+        pushedDst := TRUE
       END;
       IF storable & ~sfx
          & ~pushedDst THEN
@@ -2259,19 +2273,36 @@ PROCEDURE QualIdent (VAR t: SymTab.TypeIndex);
     IF ~SymTab.Lookup(n) THEN
       SemError(201);
       t := SymTab.InvalidType
+    ELSIF SymTab.SymKind(n)
+       = SymTab.KindModule THEN
+      t := SymTab.InvalidType
     ELSIF (SymTab.SymKind(n) #
            SymTab.KindType)
-      & (SymTab.SymKind(n) #
-         SymTab.KindPredef)
-      & (SymTab.SymKind(n) #
-         SymTab.KindImport) THEN
+       & (SymTab.SymKind(n) #
+          SymTab.KindPredef)
+       & (SymTab.SymKind(n) #
+          SymTab.KindImport) THEN
       SemError(221);
       t := SymTab.InvalidType
     ELSE t := SymTab.SymType(n) END;;
     WHILE (sym = 7) DO
       Get;
       GetIdent(m);
-      t := SymTab.InvalidType;;
+      IF SymTab.SymKind(n)
+       = SymTab.KindModule THEN
+      IF SymTab.ExpKind(n, m)
+         = SymTab.KindType THEN
+        t := SymTab.ExpType(n, m)
+      ELSE
+        IF SymTab.ExpKind(n, m) = -1 THEN
+          SemError(201)
+        ELSE SemError(221)
+        END;
+        t := SymTab.InvalidType
+      END
+      ELSE
+      t := SymTab.InvalidType
+      END;;
     END;
   END QualIdent;
 

TEMPAT SAMPAH
M2cP.o


+ 81 - 0
Showcase2.LST

@@ -0,0 +1,81 @@
+Listing:
+
+    1  MODULE Showcase2;
+    2  
+    3  (* Step-9 tour: exported TYPEs, module whole-copy both directions,
+    4     enum literals, field/row copy, VAR tails, open arrays, I/O. *)
+    5  
+    6  MODULE M EXPORT Point, Color, Red, Green, Blue, Vec, G, N, Reset;
+    7  TYPE Point = RECORD x, y : INTEGER END;
+    8  TYPE Color = (Red, Green, Blue);
+    9  TYPE Vec = ARRAY [1 .. 3] OF INTEGER;
+   10  VAR G : Point;
+   11  VAR N : INTEGER;
+   12  PROCEDURE Reset;
+   13  BEGIN
+   14    G.x := 0;
+   15    G.y := 0;
+   16    N := 0
+   17  END Reset;
+   18  END M;
+   19  
+   20  TYPE Inner = RECORD u, v : INTEGER END;
+   21  TYPE Outer = RECORD a : INTEGER; b : Inner END;
+   22  
+   23  VAR p, q : M.Point;
+   24  VAR c : M.Color;
+   25  VAR v : M.Vec;
+   26  VAR m, n : ARRAY [1 .. 2], [1 .. 2] OF INTEGER;
+   27  VAR r1, r2 : Outer;
+   28  VAR total : INTEGER;
+   29  VAR ExitCode : INTEGER;
+   30  
+   31  PROCEDURE Bump(VAR x : INTEGER);
+   32  BEGIN
+   33    x := x + 1
+   34  END Bump;
+   35  
+   36  PROCEDURE SumOpen(x : ARRAY OF INTEGER) : INTEGER;
+   37  VAR i, s : INTEGER;
+   38  BEGIN
+   39    s := 0;
+   40    FOR i := 0 TO HIGH(x) DO s := s + x[i] END;
+   41    RETURN s
+   42  END SumOpen;
+   43  
+   44  BEGIN
+   45    total := 0;
+   46    WriteString("show2");
+   47    M.Reset();
+   48    M.N := 7;
+   49    total := total + M.N;
+   50    p.x := 3;
+   51    p.y := 4;
+   52    M.G := p;
+   53    total := total + M.G.x + M.G.y;
+   54    q := M.G;
+   55    total := total + q.x * q.y;
+   56    c := M.Blue;
+   57    CASE c OF
+   58      M.Red : total := total + 0 |
+   59      M.Green : total := total + 0 |
+   60      M.Blue : total := total + 6
+   61    END;
+   62    IF c # M.Red THEN total := total + 1 END;
+   63    m[1,1] := 1; m[1,2] := 2; m[2,1] := 3; m[2,2] := 4;
+   64    n[2] := m[1];
+   65    total := total + n[2,1] + n[2,2];
+   66    r1.a := 0; r1.b.u := 10; r1.b.v := 20;
+   67    r2.b := r1.b;
+   68    total := total + r2.b.u + r2.b.v;
+   69    Bump(q.y);
+   70    total := total + q.y;
+   71    v[1] := 2; v[2] := 4; v[3] := 6;
+   72    total := total + SumOpen(v);
+   73    WriteInt(total);
+   74    ExitCode := total
+   75  END Showcase2.
+
+    0 errors
+
+

TEMPAT SAMPAH
Showcase2.MC4


+ 75 - 0
Showcase2.mod

@@ -0,0 +1,75 @@
+MODULE Showcase2;
+
+(* Step-9 tour: exported TYPEs, module whole-copy both directions,
+   enum literals, field/row copy, VAR tails, open arrays, I/O. *)
+
+MODULE M EXPORT Point, Color, Red, Green, Blue, Vec, G, N, Reset;
+TYPE Point = RECORD x, y : INTEGER END;
+TYPE Color = (Red, Green, Blue);
+TYPE Vec = ARRAY [1 .. 3] OF INTEGER;
+VAR G : Point;
+VAR N : INTEGER;
+PROCEDURE Reset;
+BEGIN
+  G.x := 0;
+  G.y := 0;
+  N := 0
+END Reset;
+END M;
+
+TYPE Inner = RECORD u, v : INTEGER END;
+TYPE Outer = RECORD a : INTEGER; b : Inner END;
+
+VAR p, q : M.Point;
+VAR c : M.Color;
+VAR v : M.Vec;
+VAR m, n : ARRAY [1 .. 2], [1 .. 2] OF INTEGER;
+VAR r1, r2 : Outer;
+VAR total : INTEGER;
+VAR ExitCode : INTEGER;
+
+PROCEDURE Bump(VAR x : INTEGER);
+BEGIN
+  x := x + 1
+END Bump;
+
+PROCEDURE SumOpen(x : ARRAY OF INTEGER) : INTEGER;
+VAR i, s : INTEGER;
+BEGIN
+  s := 0;
+  FOR i := 0 TO HIGH(x) DO s := s + x[i] END;
+  RETURN s
+END SumOpen;
+
+BEGIN
+  total := 0;
+  WriteString("show2");
+  M.Reset();
+  M.N := 7;
+  total := total + M.N;
+  p.x := 3;
+  p.y := 4;
+  M.G := p;
+  total := total + M.G.x + M.G.y;
+  q := M.G;
+  total := total + q.x * q.y;
+  c := M.Blue;
+  CASE c OF
+    M.Red : total := total + 0 |
+    M.Green : total := total + 0 |
+    M.Blue : total := total + 6
+  END;
+  IF c # M.Red THEN total := total + 1 END;
+  m[1,1] := 1; m[1,2] := 2; m[2,1] := 3; m[2,2] := 4;
+  n[2] := m[1];
+  total := total + n[2,1] + n[2,2];
+  r1.a := 0; r1.b.u := 10; r1.b.v := 20;
+  r2.b := r1.b;
+  total := total + r2.b.u + r2.b.v;
+  Bump(q.y);
+  total := total + q.y;
+  v[1] := 2; v[2] := 4; v[3] := 6;
+  total := total + SumOpen(v);
+  WriteInt(total);
+  ExitCode := total
+END Showcase2.

TEMPAT SAMPAH
TBadMGhost.MC4


TEMPAT SAMPAH
TBadMMod.MC4


TEMPAT SAMPAH
TBadMType.MC4


TEMPAT SAMPAH
TMArr.MC4


TEMPAT SAMPAH
TMEnum.MC4


TEMPAT SAMPAH
TMInt.MC4


TEMPAT SAMPAH
TMPtr.MC4


TEMPAT SAMPAH
TMRec.MC4


+ 50 - 0
docs/summary_step9.md

@@ -0,0 +1,50 @@
+# Step 9 — Type exports + tailed whole-copy fix (uncommitted)
+
+137/137 tests green (127 + 7 run + 3 rejection), mc64 boot + example
+green, Showcase still 157, new Showcase2 (type exports, module/field/row
+copy, enum literals, VAR tails) prints 83 as hand-computed.
+
+## Goal
+
+Export `TYPE`s from local `MODULE`s (`M.T` in every type position) and
+repair what the first probes exposed: whole-copy into a composite
+destination with tails silently emitted a single-slot store.
+
+## What was built
+
+- `M2c.atg` `QualIdent`: a `KindModule` head no longer 221s; the `"."`
+  tail resolves through `ExpKind`/`ExpType` — `KindType` accepted,
+  unknown → 201, non-type → 221. One edit covers all positions
+  (`SimpleType` delegates: `VAR`, params, return types, `POINTER` /
+  `ARRAY` / `SET` / record-field element types), since export type
+  indexes are global and persistent.
+- `M2c.atg` `AssignOrCall` setup: a second `pushedDst` arm for
+  tailed composite destinations (`M.G := p`, `r.b := q`, `mat[1] := row`,
+  `p^ := q`) whose address is already on the stack — same `copy_block`
+  path, no extra push. Scalar tails are excluded by the Array/Record
+  class check, so `M.cnt := 10` is untouched.
+- Bonus, free of charge: exported enum *literals* (`EXPORT Red...`)
+  ride the `KindConst` path — `c := M.Green`, `M.Red` `CASE` labels work.
+- `run_tests.sh`: step-9 sections added.
+
+## Tests — 137/137 (127 + 7 + 3)
+
+7 run: `t_mint` 5 (alias), `t_mrec` 30 (record whole-copy both directions
+through `M.Origin`), `t_marr` 18 (`VAR M.Vec` param + whole copy),
+`t_mptr` 7 (`M.PNode` + `NEW`), `t_menum` 11 (literals + qualified `CASE`
+labels), `c_fcopy` 5 (field-destination copy), `c_row` 15 (matrix-row
+copy). 3 rejections, each exactly one error: `t_bad_mtype` 221
+(`M.cnt` as a type), `t_bad_mghost` 201, `t_bad_mmod` 230 (bare `M`).
+
+## Bugs found and fixed
+
+1. `M.Origin := p` (same type!) silently stored one slot (584 instead of
+   30): tailed composite destinations fell into the scalar `StoreIndir0`
+   emission. Same latent bug in plain field tails (`r2.b := r1.b` → 584,
+   pre-existing since step 5 — old copy tests only used plain
+   destinations). Fixed by the `pushedDst` extension; 127/127 stayed green.
+
+## Known limits (deferred)
+
+`DEFINITION`/`IMPLEMENTATION` split, module `BEGIN` bodies, `WITH`-field
+`VAR` actuals, `CHAR`/`BOOLEAN` tails as `VAR` actuals, open-to-open.

+ 14 - 0
run_tests.sh

@@ -259,5 +259,19 @@ echo "=== Step-8 rejection tests ==="
 expect_fail v_bad_byte.mod "invalid procedure call"
 expect_fail v_bad_with.mod "invalid procedure call"
 
+echo "=== Step-9 run tests (type exports + tailed copy) ==="
+expect_run t_mint.mod 5
+expect_run t_mrec.mod 30
+expect_run t_marr.mod 18
+expect_run t_mptr.mod 7
+expect_run t_menum.mod 11
+expect_run c_fcopy.mod 5
+expect_run c_row.mod 15
+
+echo "=== Step-9 rejection tests ==="
+expect_fail t_bad_mtype.mod "not a type name"
+expect_fail t_bad_mghost.mod "undeclared identifier"
+expect_fail t_bad_mmod.mod "not supported in this phase"
+
 echo "=== $pass passed, $fail failed ==="
 test "$fail" = 0

+ 15 - 0
tests/c_fcopy.LST

@@ -0,0 +1,15 @@
+Listing:
+
+    1  MODULE CFcopy;
+    2  TYPE Inner = RECORD u, v : INTEGER END;
+    3  TYPE Outer = RECORD a : INTEGER; b : Inner END;
+    4  VAR r1, r2 : Outer; ExitCode : INTEGER;
+    5  BEGIN
+    6    r1.a := 1; r1.b.u := 2; r1.b.v := 3;
+    7    r2.b := r1.b;
+    8    ExitCode := r2.b.u + r2.b.v
+    9  END CFcopy.
+
+    0 errors
+
+

+ 9 - 0
tests/c_fcopy.mod

@@ -0,0 +1,9 @@
+MODULE CFcopy;
+TYPE Inner = RECORD u, v : INTEGER END;
+TYPE Outer = RECORD a : INTEGER; b : Inner END;
+VAR r1, r2 : Outer; ExitCode : INTEGER;
+BEGIN
+  r1.a := 1; r1.b.u := 2; r1.b.v := 3;
+  r2.b := r1.b;
+  ExitCode := r2.b.u + r2.b.v
+END CFcopy.

+ 14 - 0
tests/c_row.LST

@@ -0,0 +1,14 @@
+Listing:
+
+    1  MODULE CRow;
+    2  VAR m, n : ARRAY [1 .. 2], [1 .. 3] OF INTEGER; ExitCode : INTEGER;
+    3  BEGIN
+    4    m[1,1] := 1; m[1,2] := 2; m[1,3] := 3;
+    5    m[2,1] := 4; m[2,2] := 5; m[2,3] := 6;
+    6    n[1] := m[2];
+    7    ExitCode := n[1,1] + n[1,2] + n[1,3]
+    8  END CRow.
+
+    0 errors
+
+

+ 8 - 0
tests/c_row.mod

@@ -0,0 +1,8 @@
+MODULE CRow;
+VAR m, n : ARRAY [1 .. 2], [1 .. 3] OF INTEGER; ExitCode : INTEGER;
+BEGIN
+  m[1,1] := 1; m[1,2] := 2; m[1,3] := 3;
+  m[2,1] := 4; m[2,2] := 5; m[2,3] := 6;
+  n[1] := m[2];
+  ExitCode := n[1,1] + n[1,2] + n[1,3]
+END CRow.

+ 16 - 0
tests/t_bad_mghost.LST

@@ -0,0 +1,16 @@
+Listing:
+
+    1  MODULE TBadMGhost;
+    2  MODULE M EXPORT cnt;
+    3  VAR cnt : INTEGER;
+    4  END M;
+    5  VAR x : M.ghost;
+*****            ^ undeclared identifier
+    6  VAR ExitCode : INTEGER;
+    7  BEGIN
+    8    ExitCode := 0
+    9  END TBadMGhost.
+
+    1 error
+
+

+ 9 - 0
tests/t_bad_mghost.mod

@@ -0,0 +1,9 @@
+MODULE TBadMGhost;
+MODULE M EXPORT cnt;
+VAR cnt : INTEGER;
+END M;
+VAR x : M.ghost;
+VAR ExitCode : INTEGER;
+BEGIN
+  ExitCode := 0
+END TBadMGhost.

+ 16 - 0
tests/t_bad_mmod.LST

@@ -0,0 +1,16 @@
+Listing:
+
+    1  MODULE TBadMMod;
+    2  MODULE M EXPORT cnt;
+    3  VAR cnt : INTEGER;
+    4  END M;
+    5  VAR x : M;
+*****          ^ not supported in this phase
+    6  VAR ExitCode : INTEGER;
+    7  BEGIN
+    8    ExitCode := 0
+    9  END TBadMMod.
+
+    1 error
+
+

+ 9 - 0
tests/t_bad_mmod.mod

@@ -0,0 +1,9 @@
+MODULE TBadMMod;
+MODULE M EXPORT cnt;
+VAR cnt : INTEGER;
+END M;
+VAR x : M;
+VAR ExitCode : INTEGER;
+BEGIN
+  ExitCode := 0
+END TBadMMod.

+ 16 - 0
tests/t_bad_mtype.LST

@@ -0,0 +1,16 @@
+Listing:
+
+    1  MODULE TBadMType;
+    2  MODULE M EXPORT cnt;
+    3  VAR cnt : INTEGER;
+    4  END M;
+    5  VAR x : M.cnt;
+*****            ^ not a type name
+    6  VAR ExitCode : INTEGER;
+    7  BEGIN
+    8    ExitCode := 0
+    9  END TBadMType.
+
+    1 error
+
+

+ 9 - 0
tests/t_bad_mtype.mod

@@ -0,0 +1,9 @@
+MODULE TBadMType;
+MODULE M EXPORT cnt;
+VAR cnt : INTEGER;
+END M;
+VAR x : M.cnt;
+VAR ExitCode : INTEGER;
+BEGIN
+  ExitCode := 0
+END TBadMType.

+ 20 - 0
tests/t_marr.LST

@@ -0,0 +1,20 @@
+Listing:
+
+    1  MODULE TMArr;
+    2  MODULE M EXPORT Vec;
+    3  TYPE Vec = ARRAY [1 .. 3] OF INTEGER;
+    4  END M;
+    5  VAR v, w : M.Vec; ExitCode : INTEGER;
+    6  PROCEDURE Fill(VAR a : M.Vec);
+    7  BEGIN
+    8    a[1] := 5; a[2] := 6; a[3] := 7
+    9  END Fill;
+   10  BEGIN
+   11    Fill(v);
+   12    w := v;
+   13    ExitCode := w[1] + w[2] + w[3]
+   14  END TMArr.
+
+    0 errors
+
+

+ 14 - 0
tests/t_marr.mod

@@ -0,0 +1,14 @@
+MODULE TMArr;
+MODULE M EXPORT Vec;
+TYPE Vec = ARRAY [1 .. 3] OF INTEGER;
+END M;
+VAR v, w : M.Vec; ExitCode : INTEGER;
+PROCEDURE Fill(VAR a : M.Vec);
+BEGIN
+  a[1] := 5; a[2] := 6; a[3] := 7
+END Fill;
+BEGIN
+  Fill(v);
+  w := v;
+  ExitCode := w[1] + w[2] + w[3]
+END TMArr.

+ 20 - 0
tests/t_menum.LST

@@ -0,0 +1,20 @@
+Listing:
+
+    1  MODULE TMEnum;
+    2  MODULE M EXPORT Color, Red, Green, Blue;
+    3  TYPE Color = (Red, Green, Blue);
+    4  END M;
+    5  VAR c : M.Color; ExitCode : INTEGER;
+    6  BEGIN
+    7    c := M.Green;
+    8    IF c = M.Green THEN ExitCode := 4 ELSE ExitCode := 0 END;
+    9    CASE c OF
+   10      M.Red : ExitCode := 0 |
+   11      M.Green : ExitCode := ExitCode + 7 |
+   12      M.Blue : ExitCode := 0
+   13    END
+   14  END TMEnum.
+
+    0 errors
+
+

+ 14 - 0
tests/t_menum.mod

@@ -0,0 +1,14 @@
+MODULE TMEnum;
+MODULE M EXPORT Color, Red, Green, Blue;
+TYPE Color = (Red, Green, Blue);
+END M;
+VAR c : M.Color; ExitCode : INTEGER;
+BEGIN
+  c := M.Green;
+  IF c = M.Green THEN ExitCode := 4 ELSE ExitCode := 0 END;
+  CASE c OF
+    M.Red : ExitCode := 0 |
+    M.Green : ExitCode := ExitCode + 7 |
+    M.Blue : ExitCode := 0
+  END
+END TMEnum.

+ 16 - 0
tests/t_mint.LST

@@ -0,0 +1,16 @@
+Listing:
+
+    1  MODULE TMInt;
+    2  MODULE M EXPORT MyInt;
+    3  TYPE MyInt = INTEGER;
+    4  END M;
+    5  VAR x : M.MyInt;
+    6  VAR ExitCode : INTEGER;
+    7  BEGIN
+    8    x := 5;
+    9    ExitCode := x
+   10  END TMInt.
+
+    0 errors
+
+

+ 10 - 0
tests/t_mint.mod

@@ -0,0 +1,10 @@
+MODULE TMInt;
+MODULE M EXPORT MyInt;
+TYPE MyInt = INTEGER;
+END M;
+VAR x : M.MyInt;
+VAR ExitCode : INTEGER;
+BEGIN
+  x := 5;
+  ExitCode := x
+END TMInt.

+ 17 - 0
tests/t_mptr.LST

@@ -0,0 +1,17 @@
+Listing:
+
+    1  MODULE TMPtr;
+    2  MODULE M EXPORT PNode;
+    3  TYPE Node = RECORD val : INTEGER; next : POINTER TO Node END;
+    4  TYPE PNode = POINTER TO Node;
+    5  END M;
+    6  VAR p : M.PNode; ExitCode : INTEGER;
+    7  BEGIN
+    8    NEW(p);
+    9    p^.val := 7;
+   10    ExitCode := p^.val
+   11  END TMPtr.
+
+    0 errors
+
+

+ 11 - 0
tests/t_mptr.mod

@@ -0,0 +1,11 @@
+MODULE TMPtr;
+MODULE M EXPORT PNode;
+TYPE Node = RECORD val : INTEGER; next : POINTER TO Node END;
+TYPE PNode = POINTER TO Node;
+END M;
+VAR p : M.PNode; ExitCode : INTEGER;
+BEGIN
+  NEW(p);
+  p^.val := 7;
+  ExitCode := p^.val
+END TMPtr.

+ 21 - 0
tests/t_mrec.LST

@@ -0,0 +1,21 @@
+Listing:
+
+    1  MODULE TMRec;
+    2  MODULE M EXPORT Point, Origin;
+    3  TYPE Point = RECORD x, y : INTEGER END;
+    4  VAR Origin : Point;
+    5  END M;
+    6  VAR p : M.Point; ExitCode : INTEGER;
+    7  BEGIN
+    8    p.x := 10;
+    9    p.y := 20;
+   10    M.Origin := p;
+   11    p.x := 0;
+   12    p.y := 0;
+   13    p := M.Origin;
+   14    ExitCode := p.x + p.y
+   15  END TMRec.
+
+    0 errors
+
+

+ 15 - 0
tests/t_mrec.mod

@@ -0,0 +1,15 @@
+MODULE TMRec;
+MODULE M EXPORT Point, Origin;
+TYPE Point = RECORD x, y : INTEGER END;
+VAR Origin : Point;
+END M;
+VAR p : M.Point; ExitCode : INTEGER;
+BEGIN
+  p.x := 10;
+  p.y := 20;
+  M.Origin := p;
+  p.x := 0;
+  p.y := 0;
+  p := M.Origin;
+  ExitCode := p.x + p.y
+END TMRec.