001: /*
002: * @(#)Preprocessor.java 1.4 05/05/09
003: *
004: * Copyright (c) 1997-2004 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution
007: * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package pnuts.compiler;
010:
011: import pnuts.lang.Context;
012: import pnuts.lang.SimpleNode;
013: import pnuts.lang.Visitor;
014: import pnuts.lang.PnutsParserTreeConstants;
015:
016: /**
017: * Preprocessor
018: *
019: * This visitor translates AST to a modified AST, so that
020: * function calls could be done faster, by resolving the
021: * function outside a loop;
022: *
023: * The translation occurs when:
024: * (1) the call is in a local scope (in a function)
025: * (2) the call is in a loop (while, for, or foreach) or a nested function
026: *
027: * e.g. before:
028: * <pre>
029: * function foo(){
030: * for (i = 0; i < 100; i++){
031: * println("hello")
032: * }
033: * }
034: * </pre>
035: *
036: * after:
037: * <pre>
038: * function foo(){
039: * println = println
040: * for (i = 0; i < 100; i++){
041: * println("hello")
042: * }
043: * }
044: * </pre>
045: *
046: */
047: class Preprocessor extends ScopeAnalyzer {
048:
049: protected boolean isTargetIdNode(SimpleNode node, Context context) {
050: SimpleNode parent = node.jjtGetParent();
051: if (parent == null) {
052: return false;
053: }
054: int id = parent.id;
055: if (id == PnutsParserTreeConstants.JJTAPPLICATIONNODE
056: || id == PnutsParserTreeConstants.JJTSTATICMETHODNODE
057: || id == PnutsParserTreeConstants.JJTMEMBERNODE) {
058: TranslateContext cc = (TranslateContext) context;
059: return cc.env.parent != null;
060: }
061: return false;
062: }
063:
064: protected void handleFreeVariable(SimpleNode node, Context context) {
065: TranslateContext cc = (TranslateContext) context;
066: SimpleNode n = node.jjtGetParent();
067: String symbol = node.str;
068: while (n != null) {
069: SimpleNode p = n.jjtGetParent();
070: if (p == null) {
071: break;
072: }
073: if (p.id == PnutsParserTreeConstants.JJTFUNCTIONSTATEMENT) {
074: if (cc.env.parent.parent == null) {
075: cc.addToFreeVarSet(symbol);
076: break;
077: } else {
078: break;
079: }
080: } else if (p.id == PnutsParserTreeConstants.JJTWHILESTATEMENT
081: || p.id == PnutsParserTreeConstants.JJTDOSTATEMENT) {
082: cc.addToFreeVarSet(symbol);
083: break;
084: } else if (p.id == PnutsParserTreeConstants.JJTFORSTATEMENT) {
085: if (p.jjtGetChild(0).str != symbol) {
086: cc.addToFreeVarSet(symbol);
087: }
088: break;
089: } else if (p.id == PnutsParserTreeConstants.JJTFOREACHSTATEMENT) {
090: if (p.str != symbol) {
091: cc.addToFreeVarSet(symbol);
092: }
093: break;
094: }
095: n = p;
096: }
097: }
098:
099: public Object tryStatement(SimpleNode node, Context context) {
100: super .tryStatement(node, context);
101: int n = node.jjtGetNumChildren();
102: for (int i = 1; i < n; i++) {
103: acceptChildren(node.jjtGetChild(i), context);
104: }
105: while (node != null) {
106: if (node.id == PnutsParserTreeConstants.JJTFUNCTIONSTATEMENT) {
107: break;
108: }
109: node.setAttribute("hasTryStatement", Boolean.TRUE);
110: node = node.jjtGetParent();
111: }
112: return null;
113: }
114:
115: }
|