Computer Science 301 - Translators


Tutorial 12 - A Python-like "for" loop for extended Parva - Solutions

A Python-like version of the ForStatement has syntax that can be described by

         ForStatement = "for" Ident "in" "(" Expression { "," Expression } ")" Statement .

The suggested implementation strategy was as follows:

At run time, just before the Statement is executed, the top elements on the stack could be set up in a manner that is exemplified by the statement

              for i in (35, 64, -1, 235) write(i);   // loop to be executed 4 times

              ──────┬───────┬───────┬───────┬───────┬───────┬────────┬─────────
               ...  │   4   │  235  │  -1   │  64   │  35   │ adr i  │  ....
              ──────┴───────┴───────┴───────┴───────┴───────┴────────┴─────────

In this example the 4 on the top of the stack can then be used as a counter and decremented on each pass of the loop. The values below that can be assigned, one by one on each pass, to the designator whose address is lurking at the bottom of this segment.

The constraints that we must enforce are (a) the identifier denoting the control variable must have been declared and be of the variable kind (b) the expressions in the list must all return a value that is type-compatible with the type of the control variable. The code needed should be familiar by now!

    ForStatement<StackFrame frame>        (. type = Entry.noType, expType;
                                             String name; .)
    =  "for" Ident<out name>              (. Entry var = Table.find(name);
                                             type = var.type;
                                             if (!var.declared)
                                               SemError("undeclared identifier");
                                             if (var.kind != Entry.Var)
                                               SemError("illegal control variable"); .)
        "in" "("
          Expression<out expType>         (. if (!compatible(type, expType))
                                               SemError("type mismatch"); .)
          { WEAK ","
            Expression<out expType>       (. if (!compatible(type, expType))
                                               SemError("type mismatch"); .)
          } ")"
        Statement<frame> .

Adding the code generation is fairly straightforward:

    ForStatement<StackFrame frame>        (. type = Entry.noType, expType, expCount = 1;
                                             String name; .)
    =  "for" Ident<out name>              (. Entry var = Table.find(name);
                                             type = var.type;
                                             if (!var.declared)
                                               SemError("undeclared identifier");
                                             if (var.kind != Entry.Var)
                                               SemError("illegal control variable");
 *                                           CodeGen.loadAddress(var); .)
        "in" "("
           Expression<out expType>        (. if (!compatible(type, expType))
                                               SemError("type mismatch"); .)
           { WEAK ","
             Expression<out expType>      (. if (!compatible(type, expType))
                                               SemError("type mismatch");
                                             expCount++; .)
 *         } ")"                          (. CodeGen.loadConstant(expCount);
 *                                           Label loopBody = new Label(known);
 *                                           CodeGen.nextControl(expCount); .)
 *      Statement<frame>                  (. CodeGen.testFor(loopBody);
 *                                           CodeGen.exitFor(expCount); .) .

Notes


Home  © P.D. Terry