📄 block.java
字号:
/* * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * Free SoftwareFoundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */package com.caucho.es.parser;import com.caucho.es.ESBase;import com.caucho.es.ESException;import com.caucho.es.ESId;import com.caucho.util.CharBuffer;import java.util.ArrayList;import java.util.HashMap;/** * Block is an intermediate form representing an expression. */class Block { private static HashMap specialNames; Function function; private Block parent; private Expr lastExpr; boolean isDead; private boolean hasStatementValue; private Parser parser; private boolean isLoop; private boolean canExit; private boolean hasDefault; private int withDepth; private ESId id; private Expr mark; private Object switchTop; private Object top; private int topMark; private Block() { } Block create() throws ESException { evalExpr(); Block block = new Block(); block.function = function; block.parent = this; block.lastExpr = null; block.isDead = false; block.hasStatementValue = hasStatementValue; block.parser = parser; block.isLoop = false; block.canExit = false; block.withDepth = withDepth; block.id = null; block.mark = null; block.switchTop = null; block.top = null; block.setTop(); return block; } static Block create(Parser parser, Function function) { Block block = new Block(); block.function = function; block.parent = null; block.lastExpr = null; block.isDead = false; block.hasStatementValue = function.needsStatementResults(); block.parser = parser; block.isLoop = false; block.canExit = false; block.withDepth = 0; block.id = null; block.top = null; block.topMark = 0; function.setVars(); return block; } ClassLoader getClassLoader() { return parser.getClassLoader(); } void setTop() { top = function.getTop(); if (top instanceof CharBuffer) { CharBuffer cb = (CharBuffer) top; topMark = cb.length(); } else topMark = 0; } Block pop() { Block parent = this.parent; function.setVars(); free(); return parent; } boolean isGlobal() { return function.isGlobal(); } int getDepth() { return withDepth; } boolean allowSpecial() { return parent == null; } String getFilename() { String filename = parser.lexer.getLastFilename(); int p = filename.lastIndexOf('/'); if (p > 0) filename = filename.substring(p + 1); p = filename.lastIndexOf('\\'); if (p > 0) filename = filename.substring(p + 1); return filename; } int getLine() { int line = parser.lexer.getLastLine(); return line; } void setLine(int line) { } /** * Returns true if the variable is already declared. */ boolean hasVar(ESId name) { return function.hasVar(name) || specialNames.get(name) != null; } /** * Returns an expression for a new variable */ IdExpr newVar(ESId name) { return newVar(name, null); } IdExpr newVar(ESId name, Expr type) { if (withDepth > 0) return new IdExpr(this, new Variable(this, name, type, false)); IdExpr expr = function.newVar(this, name, type); // Kill variables inside an if if (parent != null) expr.getType(); return expr; } /** * Define a new variable. */ void defVar(ESId name) { function.addVariable(this, name, null); } /** * Define a new variable with the given type. */ void defVar(ESId name, Expr type) { function.addVariable(this, name, type); } Expr newLiteral(ESBase value) { return new LiteralExpr(this, value); } Expr newRegexp(ESBase value, String flags) throws ESException { return new RegexpExpr(this, value, flags); } Expr newThis() { return new SpecialExpr(this, SpecialExpr.THIS); } Expr newArray(Expr expr) { return new SpecialExpr(this, SpecialExpr.ARRAY, expr); } Expr hasNext(String iter) { return new SpecialExpr(this, SpecialExpr.HAS_NEXT, iter); } Expr newType(ESId name) { return TypeExpr.create(this, name); } void addExpr(Expr expr) throws ESException { if (isDead) throw error("Statement is unreachable."); if (lastExpr != null) lastExpr.exprStatement(function); if (hasStatementValue && ! void.class.equals(expr.getJavaClass())) lastExpr = expr; else { lastExpr = null; expr.exprStatement(function); } } Block startBlock() throws ESException { evalExpr(); function.println("{"); return create(); } Block startBlock(ESId id) throws ESException { if (findBlock(id) != null) throw error("duplicate label `" + id + "'"); evalExpr(); Block block = create(); block.id = id; function.println(id + ": {"); block.setTop(); return block; } Block finishBlock() throws ESException { evalExpr(); function.println("}"); this.id = null; Block old = pop(); if (isDead && ! canExit) old.isDead = true; return old; } void endBlock() throws ESException { evalExpr(); function.println("}"); this.id = null; } void startIf(Expr expr, boolean isElse) throws ESException { evalExpr(); if (isElse) function.print(" else "); function.print("if ("); function.addBoolean(expr); function.println(") {"); setTop(); } void startElse() throws ESException { evalExpr(); function.println(" else {"); setTop(); } Block startWhile(ESId id, Expr expr) throws ESException { evalExpr(); if (id != null) function.println(id + ":"); function.print("while ("); function.addBoolean(expr); function.println(") {"); Block block = create(); startLoop(id); if (! (expr instanceof LiteralExpr) || ! ((LiteralExpr) expr).getLiteral().toBoolean()) canExit = true; return block; } Block startFor(ESId id, Expr test, Expr incr) throws ESException { evalExpr(); if (id != null) function.println(id + ":"); function.print("for (;"); if (test != null) function.addBoolean(test); function.print(";"); if (incr != null) function.addExpr(incr); function.println(") {"); function.cl.pushDepth(); Block block = create(); startLoop(id); if (test == null) canExit = false; else if (! (test instanceof LiteralExpr) || ! ((LiteralExpr) test).getLiteral().toBoolean()) canExit = true; return block; } Block startDo(ESId id) throws ESException { evalExpr(); if (id != null) function.println(id + ":"); function.print("do {"); Block block = create(); startLoop(id); return block; } Block endDo(Expr expr) throws ESException { evalExpr(); Block old = endLoop(); if (! (expr instanceof LiteralExpr) || ! ((LiteralExpr) expr).getLiteral().toBoolean()) old.canExit = true; if (old.canExit) old.isDead = false; function.print("while ("); function.addBoolean(expr); function.println(");"); return old; } void startLoop(ESId id) { String oldVar = function.getStatementVar(); function.pushStatementLoop(); String newVar = function.getStatementVar(); if (oldVar != null) function.println(newVar + " = " + oldVar + ";"); this.id = id; isLoop = true; canExit = false; } Block endLoop() throws ESException { evalExpr(); String newVar = function.getStatementVar(); function.popStatementLoop(); String oldVar = function.getStatementVar(); if (oldVar != null && ! isDead) function.println(oldVar + " = " + newVar + ";");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -