No arquivo tinypy.jflex
:
[rR][eE][pP][eE][aA][tT] { return new Token(Token.REPEAT, yyline); }
[uU][nN][tT][iI][lL] { return new Token(Token.UNTIL, yyline); }
No arquivo tinypy.jacc
, primeira seção:
%token <Token> READ WRITE IF WHILE ELSE ELIF INT BOOL VOID NEG REPEAT
%token <Token> PASS TRUE FALSE AND OR NOT ATRIB ID NUM BEGIN END UNTIL
No arquivo tinypy.jacc
, segunda seção, não-terminal cmd
:
| REPEAT BEGIN cmds END UNTIL exp { $$ = new Repeat($3, $6, $5.lin); }
Arquivo ast\Repeat.java
:
package ast;
import java.util.List;
import java.util.Map;
public class Repeat implements Cmd {
List<Cmd> corpo;
Exp cond;
int lin;
public Repeat(List<Cmd> _corpo, Exp _cond, int _lin) {
corpo = _corpo;
cond = _cond;
lin = _lin;
}
@Override
public void tipos(Map<String, Func> funcs, TabSimb<String> vars) {
TabSimb<String> vcorpo = new TabSimb<String>(vars);
for(Cmd cmd: corpo)
cmd.tipos(funcs, vcorpo);
String tcond = cond.tipo(funcs, vcorpo);
if(!tcond.equals("bool"))
throw new RuntimeException("condição do repeat tem que ser bool na linha " + lin);
}
@Override
public void run(Map<String, Func> funcs, TabSimb<Integer> vars) {
TabSimb<Integer> vcorpo;
do {
vcorpo = new TabSimb<Integer>(vars);
for(Cmd cmd: corpo)
cmd.run(funcs, vcorpo);
} while(cond.val(funcs, vcorpo) == 0);
}
@Override
public void codigo(Contexto ctx, TabSimb<Endereco> vars) {
// labCorpo:
// <corpo>
// <cond>
// se cond for falso salta pra labCorpo
int labCorpo = ctx.label();
ctx.label(labCorpo);
TabSimb<Endereco> vcorpo = new TabSimb<Endereco>(vars);
ctx.entraEscopo();
for(Cmd cmd: corpo)
cmd.codigo(ctx, vcorpo);
cond.codigoSaltoF(ctx, vcorpo, labCorpo);
ctx.saiEscopo();
}
}