001: /*
002: * GeneratorHelper.java
003: *
004: * Copyright (c) 2005,2006 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 org.pnuts.lang;
010:
011: import java.util.*;
012: import pnuts.lang.*;
013: import pnuts.lang.Runtime;
014: import pnuts.compiler.*; // TODO
015:
016: public class GeneratorHelper extends ScopeAnalyzer {
017: private String identity;
018: private ArrayList locals = new ArrayList();
019:
020: public GeneratorHelper(String identity) {
021: this .identity = identity;
022: }
023:
024: protected void handleLocalVariable(SimpleNode node, Context context) {
025: locals.add(node);
026: }
027:
028: public void resolve() {
029: for (Iterator it = locals.iterator(); it.hasNext();) {
030: SimpleNode n = (SimpleNode) it.next();
031: n.str = (n.str + "!" + identity).intern();
032: }
033: }
034:
035: public Object assignment(SimpleNode node, Context context) {
036: SimpleNode n0 = node.jjtGetChild(0);
037: if (n0.id == PnutsParserTreeConstants.JJTIDNODE) {
038: locals.add(n0);
039: }
040: return super .assignment(node, context);
041: }
042:
043: public Object foreachStatement(SimpleNode node, Context context) {
044: locals.add(node);
045: return super .foreachStatement(node, context);
046: }
047:
048: public Object forStatement(SimpleNode node, Context context) {
049: SimpleNode n = node.jjtGetChild(0);
050: if (n.id == PnutsParserTreeConstants.JJTFORENUM) {
051: locals.add(n);
052: } else if (n.id == PnutsParserTreeConstants.JJTFORINIT) {
053: for (int i = 0; i < n.jjtGetNumChildren(); i++) {
054: locals.add(n.jjtGetChild(i));
055: }
056: }
057: return super .forStatement(node, context);
058: }
059:
060: public Object functionStatement(SimpleNode node, Context context) {
061: super .functionStatement(node, context);
062: SimpleNode params = node.jjtGetChild(0);
063: for (int i = 0; i < params.jjtGetNumChildren(); i++) {
064: locals.add(params.jjtGetChild(i));
065: }
066: return null;
067: }
068:
069: public static SimpleNode renameLocals(SimpleNode node,
070: String identity) {
071: org.pnuts.lang.GeneratorHelper gh = new org.pnuts.lang.GeneratorHelper(
072: identity);
073: gh.analyze(node.jjtGetParent());
074: gh.resolve();
075: return node;
076: }
077:
078: /*
079: * Insert var_0 = try {tmpVar[0]} catch (IndexOutOfBoundsException e){}); .... into blockNode
080: */
081: public static SimpleNode expandMultiAssign(String[] vars,
082: String tmpVar, SimpleNode blockNode) {
083: List children = new ArrayList();
084: int nc = blockNode.jjtGetNumChildren();
085: for (int i = 0; i < vars.length; i++) {
086: SimpleNode lhs = new SimpleNode(
087: PnutsParserTreeConstants.JJTIDNODE);
088: lhs.str = vars[i];
089: SimpleNode tryNode = new SimpleNode(
090: PnutsParserTreeConstants.JJTTRYSTATEMENT);
091: SimpleNode tryBlock = new SimpleNode(
092: PnutsParserTreeConstants.JJTBLOCK);
093: SimpleNode catchBlock = new SimpleNode(
094: PnutsParserTreeConstants.JJTCATCHBLOCK);
095: catchBlock.str = "e";
096: SimpleNode emptyBlock = new SimpleNode(
097: PnutsParserTreeConstants.JJTBLOCK);
098: SimpleNode className = new SimpleNode(
099: PnutsParserTreeConstants.JJTCLASSNAME);
100: SimpleNode pkg = new SimpleNode(
101: PnutsParserTreeConstants.JJTPACKAGE);
102: pkg.str = "IndexOutOfBoundsException";
103:
104: SimpleNode rhs = new SimpleNode(
105: PnutsParserTreeConstants.JJTINDEXNODE);
106: SimpleNode id = new SimpleNode(
107: PnutsParserTreeConstants.JJTIDNODE);
108: id.str = tmpVar;
109: SimpleNode idx = new SimpleNode(
110: PnutsParserTreeConstants.JJTINTEGERNODE);
111: idx.str = String.valueOf(i);
112: try {
113: idx.info = Runtime.parseInt(idx.str);
114: } catch (ParseException pe) {
115: continue;
116: }
117: rhs.jjtAddChild(idx, 1);
118: rhs.jjtAddChild(id, 0);
119:
120: className.jjtAddChild(pkg, 0);
121: catchBlock.jjtAddChild(className, 0);
122: catchBlock.jjtAddChild(emptyBlock, 1);
123: tryNode.jjtAddChild(tryBlock, 0);
124: tryNode.jjtAddChild(catchBlock, 1);
125: tryBlock.jjtAddChild(rhs, 0);
126:
127: SimpleNode assign = new SimpleNode(
128: PnutsParserTreeConstants.JJTASSIGNMENT);
129: assign.jjtAddChild(tryNode, 1);
130: assign.jjtAddChild(lhs, 0);
131: children.add(assign);
132: }
133: for (int i = 0; i < nc; i++) {
134: children.add(blockNode.jjtGetChild(i));
135: }
136: SimpleNode block = new SimpleNode(
137: PnutsParserTreeConstants.JJTBLOCK);
138: int size = children.size();
139: for (int i = 0; i < size; i++) {
140: int pos = size - i - 1;
141: SimpleNode node = (SimpleNode) children.get(pos);
142: block.jjtAddChild(node, pos);
143: }
144: return block;
145: }
146:
147: // public static void main(String[] args) throws Exception {
148: // new GeneratorHelper("ZZZ").analyze(new java.io.FileReader(args[0]));
149: // }
150: }
|