/*
* $Id: ContinueStatement.java,v 1.12 2002/09/16 08:05:06 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.script.statements;
import anvil.Location;
import anvil.core.Any;
import anvil.codec.Code;
import anvil.parser.Tag;
import anvil.ErrorListener;
import anvil.script.compiler.ByteCompiler;
import anvil.script.Context;
import anvil.script.parser.TemplateParser;
import anvil.script.expression.Expression;
import java.io.IOException;
/**
* class ContinueStatement
*
* @author: Jani Lehtim�ki
*/
public class ContinueStatement extends Statement
{
private String _label = null;
private int _depth = 0;
private int _target = 0;
private Expression _expr = null;
private Case _case = null;
public ContinueStatement(Statement parent, Location location)
{
super(parent, location);
}
public ContinueStatement(Statement parent, Location location,
String label, int depth, int target, Expression expr)
{
super(parent, location);
_label = label;
_target = target;
_expr = expr;
}
public int typeOf()
{
return Statement.ST_CONTINUE;
}
public String name()
{
return "continue";
}
public void parse(TemplateParser parser, Tag tag)
{
String label = tag.getValue("to");
if (label != null) {
_depth = getLabelDepth(label);
if (_depth == -1) {
parser.error(getLocation(), "Label '"+label+"' is not declared");
return;
}
}
_label = label;
}
public void check(ErrorListener context)
{
Any key = null;
if (_expr != null) {
_expr.check(context);
if (!_expr.isConstant()) {
context.error(getLocation(), "Continue expression is not a constant");
return;
} else {
key = _expr.eval();
}
}
if (_target != 0) {
SwitchStatement stmt = getSwitch(_label);
if (stmt != null) {
switch(_target) {
case ST_CASE:
_case = stmt.getCase(key);
if (_case == null) {
context.error(getLocation(), "Continue expression points into non-constant or non-existent case");
}
break;
case ST_DEFAULT:
_case = stmt.getDefault();
if (_case == null) {
context.error(getLocation(), "Continue .. default statement's target switch does not have default");
}
break;
}
} else {
context.error(getLocation(), "Continue does not point into switch");
}
}
}
public Jumps eliminate(ErrorListener context)
{
Jumps jumps = new Jumps();
if (_label != null) {
jumps.setContinue(_depth).setBlocked(true);
} else {
jumps.setContinue().setBlocked(true);
}
//jumps.print("continue");
return jumps;
}
public void compile(ByteCompiler context)
{
boolean blocked = false;
Code code = context.getCode();
Statement stmt = this;
if (_target != 0) {
SwitchStatement target = getSwitch(_label);
while(!blocked && stmt!=target) {
blocked = stmt.callFinalizer();
stmt = stmt.getParentStatement();
}
if (!blocked) {
_case.go_to(code);
}
} else {
Labeled target = getLabeled(_label, true);
while(!blocked && stmt!=target) {
blocked = stmt.callFinalizer();
stmt = stmt.getParentStatement();
}
if (!blocked) {
code.go_to(target.getStartOfScope());
}
}
}
public boolean isBlocked()
{
return true;
}
}