use of org.develnext.jphp.core.tokenizer.token.stmt.CatchStmtToken in project jphp by jphp-compiler.
the class TokenizerTest method testStmt.
@Test
public void testStmt() throws IOException {
Tokenizer tokenizer = new Tokenizer(new Context("class function private public protected static final try catch for if foreach switch while " + "default return declare case do else elseif endif endfor endforeach endwhile endswitch " + "abstract use namespace finally extends implements global"));
assertTrue(tokenizer.nextToken() instanceof ClassStmtToken);
assertTrue(tokenizer.nextToken() instanceof FunctionStmtToken);
assertTrue(tokenizer.nextToken() instanceof PrivateStmtToken);
assertTrue(tokenizer.nextToken() instanceof PublicStmtToken);
assertTrue(tokenizer.nextToken() instanceof ProtectedStmtToken);
assertTrue(tokenizer.nextToken() instanceof StaticExprToken);
assertTrue(tokenizer.nextToken() instanceof FinalStmtToken);
assertTrue(tokenizer.nextToken() instanceof TryStmtToken);
assertTrue(tokenizer.nextToken() instanceof CatchStmtToken);
assertTrue(tokenizer.nextToken() instanceof ForStmtToken);
assertTrue(tokenizer.nextToken() instanceof IfStmtToken);
assertTrue(tokenizer.nextToken() instanceof ForeachStmtToken);
assertTrue(tokenizer.nextToken() instanceof SwitchStmtToken);
assertTrue(tokenizer.nextToken() instanceof WhileStmtToken);
assertTrue(tokenizer.nextToken() instanceof DefaultStmtToken);
assertTrue(tokenizer.nextToken() instanceof ReturnStmtToken);
assertTrue(tokenizer.nextToken() instanceof DeclareStmtToken);
assertTrue(tokenizer.nextToken() instanceof CaseStmtToken);
assertTrue(tokenizer.nextToken() instanceof DoStmtToken);
assertTrue(tokenizer.nextToken() instanceof ElseStmtToken);
assertTrue(tokenizer.nextToken() instanceof ElseIfStmtToken);
assertTrue(tokenizer.nextToken() instanceof EndifStmtToken);
assertTrue(tokenizer.nextToken() instanceof EndforStmtToken);
assertTrue(tokenizer.nextToken() instanceof EndforeachStmtToken);
assertTrue(tokenizer.nextToken() instanceof EndwhileStmtToken);
assertTrue(tokenizer.nextToken() instanceof EndswitchStmtToken);
assertTrue(tokenizer.nextToken() instanceof AbstractStmtToken);
assertTrue(tokenizer.nextToken() instanceof NamespaceUseStmtToken);
assertTrue(tokenizer.nextToken() instanceof NamespaceStmtToken);
assertTrue(tokenizer.nextToken() instanceof FinallyStmtToken);
assertTrue(tokenizer.nextToken() instanceof ExtendsStmtToken);
assertTrue(tokenizer.nextToken() instanceof ImplementsStmtToken);
assertTrue(tokenizer.nextToken() instanceof GlobalStmtToken);
}
use of org.develnext.jphp.core.tokenizer.token.stmt.CatchStmtToken in project jphp by jphp-compiler.
the class TryCatchGenerator method processCatches.
protected void processCatches(TryStmtToken result, Token current, ListIterator<Token> iterator) {
List<CatchStmtToken> catches = result.getCatches();
do {
CatchStmtToken _catch = (CatchStmtToken) current;
processCatch(_catch, iterator);
catches.add(_catch);
if (!iterator.hasNext())
break;
current = iterator.next();
if (!(current instanceof CatchStmtToken)) {
if (current instanceof FinallyStmtToken) {
processFinally(result, current, iterator);
break;
}
iterator.previous();
break;
}
} while (true);
}
use of org.develnext.jphp.core.tokenizer.token.stmt.CatchStmtToken in project jphp by jphp-compiler.
the class TryCatchGenerator method processCatch.
public void processCatch(CatchStmtToken result, ListIterator<Token> iterator) {
Token next = nextToken(iterator);
if (!isOpenedBrace(next, BraceExprToken.Kind.SIMPLE))
unexpectedToken(next, "(");
List<FulledNameToken> exceptions = new ArrayList<>();
do {
next = nextToken(iterator);
if (!(next instanceof NameToken)) {
if (exceptions.isEmpty()) {
unexpectedToken(next, TokenType.T_STRING);
} else {
iterator.previous();
break;
}
}
FulledNameToken exception = analyzer.getRealName((NameToken) next);
exceptions.add(exception);
next = nextToken(iterator);
if (!(next instanceof OrExprToken)) {
iterator.previous();
break;
}
} while (true);
result.setExceptions(exceptions);
next = nextToken(iterator);
if (!(next instanceof VariableExprToken))
unexpectedToken(next, TokenType.T_VARIABLE);
VariableExprToken variable = (VariableExprToken) next;
result.setVariable(variable);
if (analyzer.getFunction() != null) {
analyzer.getFunction().variable(variable).setUnstable(true);
}
analyzer.getScope().addVariable(variable);
next = nextToken(iterator);
if (!isClosedBrace(next, BraceExprToken.Kind.SIMPLE))
unexpectedToken(next, ")");
BodyStmtToken body = analyzer.generator(BodyGenerator.class).getToken(nextToken(iterator), iterator);
result.setBody(body);
}
use of org.develnext.jphp.core.tokenizer.token.stmt.CatchStmtToken in project jphp by jphp-compiler.
the class TryCatchGenerator method getToken.
@Override
public TryStmtToken getToken(Token current, ListIterator<Token> iterator) {
if (current instanceof TryStmtToken) {
TryStmtToken result = (TryStmtToken) current;
analyzer.addScope(false);
BodyStmtToken body = analyzer.generator(BodyGenerator.class).getToken(nextToken(iterator), iterator);
result.setBody(body);
Token next = nextToken(iterator);
result.setCatches(new ArrayList<CatchStmtToken>());
if (next instanceof CatchStmtToken) {
processCatches(result, next, iterator);
} else if (next instanceof FinallyStmtToken) {
analyzer.getScope().setLevelForGoto(true);
processFinally(result, next, iterator);
analyzer.getScope().setLevelForGoto(false);
} else
unexpectedToken(next, TokenType.T_CATCH);
result.setLocal(analyzer.removeScope().getVariables());
return result;
}
return null;
}
use of org.develnext.jphp.core.tokenizer.token.stmt.CatchStmtToken in project jphp by jphp-compiler.
the class TryCatchCompiler method write.
@Override
public void write(TryStmtToken token) {
if (token.getBody() == null || token.getBody().getInstructions().isEmpty()) {
if (token.getFinally() != null)
expr.write(BodyStmtToken.class, token.getFinally());
return;
}
expr.writeDefineVariables(token.getLocal());
LabelNode tryStart = expr.writeLabel(node, token.getMeta().getStartLine());
LabelNode tryEnd = new LabelNode();
LabelNode catchStart = new LabelNode();
LabelNode catchEnd = new LabelNode();
LabelNode returnLabel = new LabelNode();
method.node.tryCatchBlocks.add(0, new TryCatchBlockNode(tryStart, tryEnd, catchStart, Type.getInternalName(BaseBaseException.class)));
if (token.getFinally() != null) {
method.getTryStack().push(new MethodStmtCompiler.TryCatchItem(token, returnLabel));
}
expr.write(BodyStmtToken.class, token.getBody());
if (token.getFinally() != null) {
method.getTryStack().pop();
}
add(tryEnd);
add(new JumpInsnNode(GOTO, catchEnd));
add(catchStart);
LocalVariable exception = method.addLocalVariable("~catch~" + method.nextStatementIndex(BaseException.class), catchStart, BaseBaseException.class);
exception.setEndLabel(catchEnd);
expr.makeVarStore(exception);
LabelNode nextCatch = null;
int i = 0, size = token.getCatches().size();
LocalVariable local = null;
LabelNode catchFail = new LabelNode();
for (CatchStmtToken _catch : token.getCatches()) {
if (nextCatch != null) {
add(nextCatch);
}
if (i == size - 1) {
nextCatch = catchFail;
} else {
nextCatch = new LabelNode();
}
local = method.getLocalVariable(_catch.getVariable().getName());
List<FulledNameToken> catchExceptions = _catch.getExceptions();
LabelNode bodyLabel = new LabelNode();
LabelNode nextCatchLocal = new LabelNode();
int j = 0;
for (FulledNameToken catchException : catchExceptions) {
if (j > 0) {
add(nextCatchLocal);
nextCatchLocal = new LabelNode();
}
expr.writePushEnv();
expr.writeVarLoad(exception);
expr.writePushConstString(catchException.toName());
expr.writePushConstString(catchException.toName().toLowerCase());
expr.writeSysDynamicCall(Environment.class, "__throwCatch", Memory.class, BaseBaseException.class, String.class, String.class);
expr.writeVarAssign(local, _catch.getVariable(), true, false);
expr.writePopBoolean();
add(new JumpInsnNode(IFEQ, j == catchExceptions.size() - 1 ? nextCatch : nextCatchLocal));
expr.stackPop();
if (catchExceptions.size() > 1) {
add(new JumpInsnNode(GOTO, bodyLabel));
}
j++;
}
if (catchExceptions.size() > 1) {
add(bodyLabel);
}
expr.write(BodyStmtToken.class, _catch.getBody());
add(new JumpInsnNode(GOTO, catchEnd));
i++;
}
add(catchFail);
if (token.getFinally() != null) {
expr.write(BodyStmtToken.class, token.getFinally());
}
/*if (method.getTryStack().empty()) {
expr.writePushEnv();
expr.writeVarLoad(exception);
expr.writeSysDynamicCall(Environment.class, "__throwFailedCatch", void.class, BaseException.class);
} else {*/
expr.makeVarLoad(exception);
add(new InsnNode(ATHROW));
// }
add(catchEnd);
if (token.getFinally() != null) {
LabelNode skip = new LabelNode();
add(new JumpInsnNode(GOTO, skip));
// finally for return
add(returnLabel);
expr.write(BodyStmtToken.class, token.getFinally());
if (method.getTryStack().empty()) {
// all finally blocks are done
LocalVariable retVar = method.getOrAddLocalVariable("~result~", null, Memory.class);
expr.writeVarLoad(retVar);
add(new InsnNode(ARETURN));
expr.stackPop();
} else {
// goto next finally block
add(new JumpInsnNode(GOTO, method.getTryStack().peek().getReturnLabel()));
}
add(skip);
// other finally
expr.write(BodyStmtToken.class, token.getFinally());
}
expr.writeUndefineVariables(token.getLocal());
method.prevStatementIndex(BaseBaseException.class);
}
Aggregations