Source Code Cross Referenced for Compiler.java in  » Ajax » Laszlo-4.0.10 » org » openlaszlo » sc » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Ajax » Laszlo 4.0.10 » org.openlaszlo.sc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* -*- mode: Java; c-basic-offset: 2; -*- */
002:
003:        /***
004:         * Compiler.java
005:         * Author: Oliver Steele, P T Withington
006:         * Description: JavaScript -> SWF bytecode compiler
007:         */package org.openlaszlo.sc;
008:
009:        import java.io.*;
010:        import java.util.*;
011:        import java.util.regex.Pattern;
012:        import java.text.SimpleDateFormat;
013:        import java.text.DecimalFormat;
014:
015:        import org.openlaszlo.server.LPS;
016:        import org.openlaszlo.sc.parser.*;
017:        import org.openlaszlo.sc.Translator;
018:
019:        // Values
020:        import org.openlaszlo.sc.Values;
021:
022:        // Instructions
023:        import org.openlaszlo.sc.Instructions;
024:        import org.openlaszlo.sc.Instructions.Instruction;
025:        import org.openlaszlo.sc.InstructionPrinter;
026:
027:        public class Compiler {
028:            // The parse tree is stored with the key (fname) and the
029:            // value (ASTProgram, hasIncludes).
030:            // It doesn't save any time to persist this cache to disk.
031:            public static ScriptCompilerCache CachedParses;
032:            // The instructions are stored with the keys (fname, cpass) where
033:            // cpass is one of the compiler passes (1 or 2).  The checksum in
034:            // both cases is the file content string.
035:            // It costs 10s to persist this to disk, but speeds up subsequent
036:            // compiles.
037:            // Instantiate this lazily, so that we don't construct it in server
038:            // mode (since the call to os.getenv in the cache constructor won't
039:            // work there).
040:            public static ScriptCompilerCache CachedInstructions;
041:
042:            public OptionMap options;
043:
044:            //
045:            // Compiler Facade
046:            //
047:            public Compiler(Map initialOptions) {
048:                this .options = new OptionMap(initialOptions);
049:                if (!options.containsKey(ACTIVATION_OBJECT)) {
050:                    options.putBoolean(ACTIVATION_OBJECT, !options
051:                            .getBoolean(FLASH_COMPILER_COMPATABILITY));
052:                }
053:                if (!options.containsKey(COMPILE_TIME_CONSTANTS)) {
054:                    options.put(COMPILE_TIME_CONSTANTS, new HashMap());
055:                }
056:                // TODO: [2002-1-05 ows] enable this instead of the line that
057:                // follows it, once the sources comply
058:                //- options.put(ALLOW_ROOT,
059:                //- options.get(FLASH_COMPILER_COMPATABILITY))
060:                if (!options.containsKey(ALLOW_ROOT)) {
061:                    options.putBoolean(ALLOW_ROOT, true);
062:                }
063:                if (!options.containsKey(OBFUSCATE)) {
064:                    options.putBoolean(OBFUSCATE, false);
065:                }
066:                if (!options.containsKey(RUNTIME)) {
067:                    options.put(RUNTIME, LPS
068:                            .getProperty("compiler.runtime.default", LPS
069:                                    .getRuntimeDefault()));
070:                }
071:                defaultOptions();
072:                if (options.getBoolean(PRINT_COMPILER_OPTIONS)) {
073:                    System.err.println("init compiler options"
074:                            + options.toString());
075:                }
076:            }
077:
078:            public Compiler() {
079:                this (new HashMap());
080:            }
081:
082:            // Map for options
083:            public static class OptionMap extends HashMap {
084:                OptionMap() {
085:                    super ();
086:                }
087:
088:                OptionMap(Map m) {
089:                    super (m);
090:                }
091:
092:                OptionMap(List pairs) {
093:                    for (Iterator i = pairs.iterator(); i.hasNext();) {
094:                        List pair = (List) i.next();
095:                        put(pair.get(0), pair.get(1));
096:                    }
097:                }
098:
099:                // Python
100:                public OptionMap copy() {
101:                    return (OptionMap) clone();
102:                }
103:
104:                public Object get(Object key) {
105:                    if (containsKey(key)) {
106:                        return (super .get(key));
107:                    }
108:                    return null;
109:                }
110:
111:                // For Jython
112:                public Object get(Object key, Object deflt) {
113:                    if (containsKey(key)) {
114:                        return (get(key));
115:                    }
116:                    return deflt;
117:                }
118:
119:                public boolean getBoolean(Object key) {
120:                    boolean result = false;
121:                    Object value = null;
122:                    if (containsKey(key)) {
123:                        value = get(key);
124:                    }
125:                    if (value != null) {
126:                        if (value instanceof  String) {
127:                            result = "true".equalsIgnoreCase((String) value);
128:                        } else if (value instanceof  Integer) {
129:                            result = (!Integer.valueOf("0").equals(value));
130:                        } else {
131:                            result = ((Boolean) value).booleanValue();
132:                        }
133:                    }
134:                    return result;
135:                }
136:
137:                public void putBoolean(Object key, boolean value) {
138:                    put(key, Boolean.valueOf(value));
139:                }
140:
141:                public void putBoolean(Object key, String value) {
142:                    put(key, Boolean.valueOf(value));
143:                }
144:            }
145:
146:            // Error support
147:            public static String getLocationString(SimpleNode node) {
148:                StringBuffer location = new StringBuffer();
149:                if (node != null) {
150:                    if (node.filename != null) {
151:                        location.append(node.filename);
152:                        if (node.beginLine != 0) {
153:                            location.append("#");
154:                            location.append(Integer.toString(node.beginLine));
155:                            location.append(".");
156:                            location.append(Integer.toString(node.beginColumn));
157:                        }
158:                    }
159:                }
160:                return location.toString();
161:            }
162:
163:            public static Instruction NONE = Instructions.NONE;
164:            public static Instruction NextFrame = Instructions.NextFrame;
165:            public static Instruction PreviousFrame = Instructions.PreviousFrame;
166:            public static Instruction PLAY = Instructions.PLAY;
167:            public static Instruction STOP = Instructions.STOP;
168:            public static Instruction ToggleQuality = Instructions.ToggleQuality;
169:            public static Instruction StopSounds = Instructions.StopSounds;
170:            public static Instruction NumericAdd = Instructions.NumericAdd;
171:            public static Instruction SUBTRACT = Instructions.SUBTRACT;
172:            public static Instruction MULTIPLY = Instructions.MULTIPLY;
173:            public static Instruction DIVIDE = Instructions.DIVIDE;
174:            public static Instruction OldEquals = Instructions.OldEquals;
175:            public static Instruction OldLessThan = Instructions.OldLessThan;
176:            public static Instruction LogicalAnd = Instructions.LogicalAnd;
177:            public static Instruction LogicalOr = Instructions.LogicalOr;
178:            public static Instruction NOT = Instructions.NOT;
179:            public static Instruction StringEqual = Instructions.StringEqual;
180:            public static Instruction StringLength = Instructions.StringLength;
181:            public static Instruction SUBSTRING = Instructions.SUBSTRING;
182:            public static Instruction POP = Instructions.POP;
183:            public static Instruction INT = Instructions.INT;
184:            public static Instruction GetVariable = Instructions.GetVariable;
185:            public static Instruction SetVariable = Instructions.SetVariable;
186:            public static Instruction SetTargetExpression = Instructions.SetTargetExpression;
187:            public static Instruction StringConcat = Instructions.StringConcat;
188:            public static Instruction GetProperty = Instructions.GetProperty;
189:            public static Instruction SetProperty = Instructions.SetProperty;
190:            public static Instruction DuplicateMovieClip = Instructions.DuplicateMovieClip;
191:            public static Instruction RemoveClip = Instructions.RemoveClip;
192:            public static Instruction TRACE = Instructions.TRACE;
193:            public static Instruction StartDragMovie = Instructions.StartDragMovie;
194:            public static Instruction StopDragMovie = Instructions.StopDragMovie;
195:            public static Instruction StringLessThan = Instructions.StringLessThan;
196:            public static Instruction RANDOM = Instructions.RANDOM;
197:            public static Instruction MBLENGTH = Instructions.MBLENGTH;
198:            public static Instruction ORD = Instructions.ORD;
199:            public static Instruction CHR = Instructions.CHR;
200:            public static Instruction GetTimer = Instructions.GetTimer;
201:            public static Instruction MBSUBSTRING = Instructions.MBSUBSTRING;
202:            public static Instruction MBORD = Instructions.MBORD;
203:            public static Instruction MBCHR = Instructions.MBCHR;
204:            public static Instruction GotoFrame = Instructions.GotoFrame;
205:            public static Instruction GetUrl = Instructions.GetUrl;
206:            public static Instruction WaitForFrame = Instructions.WaitForFrame;
207:            public static Instruction SetTarget = Instructions.SetTarget;
208:            public static Instruction GotoLabel = Instructions.GotoLabel;
209:            public static Instruction WaitForFrameExpression = Instructions.WaitForFrameExpression;
210:            public static Instruction PUSH = Instructions.PUSH;
211:            public static Instruction BRANCH = Instructions.BRANCH;
212:            public static Instruction GetURL2 = Instructions.GetURL2;
213:            public static Instruction BranchIfTrue = Instructions.BranchIfTrue;
214:            public static Instruction CallFrame = Instructions.CallFrame;
215:            public static Instruction GotoExpression = Instructions.GotoExpression;
216:            public static Instruction DELETE = Instructions.DELETE;
217:            public static Instruction DELETE2 = Instructions.DELETE2;
218:            public static Instruction VarEquals = Instructions.VarEquals;
219:            public static Instruction CallFunction = Instructions.CallFunction;
220:            public static Instruction RETURN = Instructions.RETURN;
221:            public static Instruction MODULO = Instructions.MODULO;
222:            public static Instruction NEW = Instructions.NEW;
223:            public static Instruction VAR = Instructions.VAR;
224:            public static Instruction InitArray = Instructions.InitArray;
225:            public static Instruction InitObject = Instructions.InitObject;
226:            public static Instruction TypeOf = Instructions.TypeOf;
227:            public static Instruction TargetPath = Instructions.TargetPath;
228:            public static Instruction ENUMERATE = Instructions.ENUMERATE;
229:            public static Instruction ADD = Instructions.ADD;
230:            public static Instruction LessThan = Instructions.LessThan;
231:            public static Instruction EQUALS = Instructions.EQUALS;
232:            public static Instruction ObjectToNumber = Instructions.ObjectToNumber;
233:            public static Instruction ObjectToString = Instructions.ObjectToString;
234:            public static Instruction DUP = Instructions.DUP;
235:            public static Instruction SWAP = Instructions.SWAP;
236:            public static Instruction GetMember = Instructions.GetMember;
237:            public static Instruction SetMember = Instructions.SetMember;
238:            public static Instruction Increment = Instructions.Increment;
239:            public static Instruction Decrement = Instructions.Decrement;
240:            public static Instruction CallMethod = Instructions.CallMethod;
241:            public static Instruction NewMethod = Instructions.NewMethod;
242:            public static Instruction BitwiseAnd = Instructions.BitwiseAnd;
243:            public static Instruction BitwiseOr = Instructions.BitwiseOr;
244:            public static Instruction BitwiseXor = Instructions.BitwiseXor;
245:            public static Instruction ShiftLeft = Instructions.ShiftLeft;
246:            public static Instruction ShiftRight = Instructions.ShiftRight;
247:            public static Instruction UShiftRight = Instructions.UShiftRight;
248:            public static Instruction SetRegister = Instructions.SetRegister;
249:            public static Instruction CONSTANTS = Instructions.CONSTANTS;
250:            public static Instruction WITH = Instructions.WITH;
251:            public static Instruction DefineFunction = Instructions.DefineFunction;
252:            public static Instruction DefineFunction2 = Instructions.DefineFunction2;
253:            public static Instruction InstanceOf = Instructions.InstanceOf;
254:            public static Instruction EnumerateValue = Instructions.EnumerateValue;
255:            public static Instruction StrictEquals = Instructions.StrictEquals;
256:            public static Instruction GreaterThan = Instructions.GreaterThan;
257:            public static Instruction StringGreaterThan = Instructions.StringGreaterThan;
258:            public static Instruction BranchIfFalse = Instructions.BranchIfFalse;
259:            public static Instruction LABEL = Instructions.LABEL;
260:            public static Instruction COMMENT = Instructions.COMMENT;
261:            public static Instruction CHECKPOINT = Instructions.CHECKPOINT;
262:            public static Instruction BLOB = Instructions.BLOB;
263:
264:            // Set internal flags that depend on external flags
265:            public void defaultOptions() {
266:                if (options.getBoolean(DEBUG)) {
267:                    options.put(WARN_UNDEFINED_REFERENCES, Boolean.TRUE);
268:                    if (!options.containsKey(WARN_GLOBAL_ASSIGNMENTS)) {
269:                        options.put(WARN_GLOBAL_ASSIGNMENTS, Boolean
270:                                .valueOf(LPS.getProperty(
271:                                        "compiler.warn.globalassignments",
272:                                        "false")));
273:                    }
274:                    if (!options.containsKey(WARN_UNUSED_LOCALS)) {
275:                        options.put(WARN_UNUSED_LOCALS, Boolean.valueOf(LPS
276:                                .getProperty("compiler.warn.unusedlocals",
277:                                        "false")));
278:                    }
279:                    if (!options.containsKey(WARN_UNUSED_PARAMETERS)) {
280:                        options.put(WARN_UNUSED_PARAMETERS, Boolean.valueOf(LPS
281:                                .getProperty("compiler.warn.unusedparameters",
282:                                        "false")));
283:                    }
284:                    options.putBoolean(NAME_FUNCTIONS, true);
285:                }
286:
287:                // TODO: [2005-04-15 ptw] This pretty much sucks, but the debug
288:                // lfc only sets nameFunctions, not debug.  This can go away
289:                // when we can turn on debug for the lfc.
290:                if (options.getBoolean(DEBUG)
291:                        || options.getBoolean(NAME_FUNCTIONS)) {
292:                    if (!options.containsKey(DEBUG_BACKTRACE)) {
293:                        options.putBoolean(DEBUG_BACKTRACE, false);
294:                    }
295:                    if (!options.containsKey(DEBUG_SIMPLE)) {
296:                        options.putBoolean(DEBUG_SIMPLE, false);
297:                    }
298:                }
299:                if (!options.containsKey(PROFILE)) {
300:                    options.putBoolean(PROFILE, false);
301:                }
302:                if (options.getBoolean(PROFILE)) {
303:                    options.putBoolean(NAME_FUNCTIONS, true);
304:                }
305:                options.putBoolean(GENERATE_FUNCTION_2, true);
306:                options.putBoolean(GENERATE_FUNCTION_2_FOR_LZX, true);
307:            }
308:
309:            public void setProperties(Map properties) {
310:                // Canonicalize String-valued properties.  This is pretty bogus
311:                // (dispatching on the value to decide if the property is a
312:                // boolean-valued property, but it is the way the compiler always
313:                // worked.
314:                for (Iterator i = properties.keySet().iterator(); i.hasNext();) {
315:                    Object key = i.next();
316:                    Object value = properties.get(key);
317:                    if (value instanceof  String) {
318:                        String v = (String) value;
319:                        if ("true".equalsIgnoreCase(v)
320:                                || "false".equalsIgnoreCase(v)) {
321:                            options.putBoolean(key, v);
322:                            continue;
323:                        }
324:                    }
325:                    options.put(key, value);
326:                }
327:                defaultOptions();
328:                if (options.getBoolean(PRINT_COMPILER_OPTIONS)) {
329:                    System.err.println("set compiler options"
330:                            + options.toString());
331:                }
332:            }
333:
334:            public byte[] compile(String source) {
335:                try {
336:                    Profiler profiler = new Profiler();
337:                    profiler.enter("parse");
338:                    SimpleNode program = new Parser().parse(source);
339:                    profiler.phase("generate");
340:                    Translator cg;
341:                    byte[] bytes;
342:                    String runtime = (String) options.get(RUNTIME);
343:                    boolean compress = (!options.getBoolean(NAME_FUNCTIONS));
344:                    boolean obfuscate = options.getBoolean(OBFUSCATE);
345:                    if (org.openlaszlo.compiler.Compiler.SCRIPT_RUNTIMES
346:                            .contains(runtime)) {
347:                        cg = new JavascriptGenerator();
348:                        cg.setOptions(options);
349:                        SimpleNode translated = cg.translate(program);
350:                        ByteArrayOutputStream stream = new ByteArrayOutputStream();
351:                        (new ParseTreePrinter(compress, obfuscate)).print(
352:                                translated, stream);
353:                        bytes = stream.toByteArray();
354:                    } else {
355:                        cg = new CodeGenerator();
356:                        cg.setOptions(options);
357:                        cg.translate(program);
358:                        if (options.getBoolean(PROGRESS)) {
359:                            System.err.println("Assembling...");
360:                        }
361:                        profiler.phase("collect");
362:                        List instrs = ((InstructionCollector) cg.getCollector())
363:                                .getInstructions(true);
364:                        if (options.getBoolean(PRINT_INSTRUCTIONS)) {
365:                            new Optimizer(new InstructionPrinter())
366:                                    .assemble(instrs);
367:                        }
368:                        profiler.phase("assemble");
369:                        Emitter asm = new Optimizer(new Assembler());
370:                        // end marker
371:                        instrs.add(NONE);
372:                        bytes = asm.assemble(instrs);
373:                    }
374:                    profiler.exit();
375:                    if (options.getBoolean(PROFILE_COMPILER)) {
376:                        profiler.pprint();
377:                        System.err.println();
378:                    }
379:                    if (options.getBoolean(PROGRESS)) {
380:                        System.err.println("done.");
381:                    }
382:                    return bytes;
383:                } catch (CompilerImplementationError e) {
384:                    String ellipses = source.trim().length() > 80 ? "..." : "";
385:                    System.err.println("while compiling "
386:                            + source.trim().substring(0, 80) + ellipses);
387:                    throw (e);
388:                } catch (CompilerError e) {
389:                    throw (new CompilerException(e.toString()));
390:                }
391:            }
392:
393:            //
394:            // Compiler Options
395:            //
396:
397:            // TODO [2004-03-11 ptw] share with CompilationEnvironment.java
398:            public static String ACTIVATION_OBJECT = "createActivationObject";
399:            public static String COMPUTE_METAREFERENCES = "computeMetaReferences";
400:            public static String CONDITIONAL_COMPILATION = "conditionalCompilation";
401:            public static String ALLOW_ROOT = "allowRoot";
402:            public static String CACHE_COMPILES = "cacheCompiles";
403:            public static String COMPILE_TRACE = "compileTrace";
404:            public static String COMPILE_TIME_CONSTANTS = "compileTimeConstants";
405:            public static String CONSTRAINT_FUNCTION = "constraintFunction";
406:            public static String DEBUG = "debug";
407:            public static String DEBUG_BACKTRACE = "debugBacktrace";
408:            public static String DEBUG_SIMPLE = "debugSimple";
409:            public static String DISABLE_CONSTANT_POOL = "disableConstantPool";
410:            public static String ELIMINATE_DEAD_EXPRESSIONS = "eliminateDeadExpressions";
411:            public static String FLASH_COMPILER_COMPATABILITY = "flashCompilerCompatability";
412:            public static String GENERATE_FUNCTION_2 = "generateFunction2";
413:            public static String GENERATE_FUNCTION_2_FOR_LZX = "generateFunction2ForLZX";
414:            public static String GENERATE_PREDICTABLE_TEMPS = "generatePredictableTemps";
415:            public static String INCLUDES = "processIncludes";
416:            public static String INSTR_STATS = "instrStats";
417:            public static String LINK = "link";
418:            public static String RUNTIME = "runtime";
419:            public static String METHOD_NAME = "methodName";
420:            public static String NAME_FUNCTIONS = "nameFunctions";
421:            public static String OBFUSCATE = "obfuscate";
422:            public static String PROFILE = "profile";
423:            public static String PROFILE_COMPILER = "profileCompiler";
424:            public static String PROGRESS = "progress";
425:            public static String PRINT_COMPILER_OPTIONS = "printCompilerOptions";
426:            public static String PRINT_CONSTRAINTS = "printConstraints";
427:            public static String PRINT_INSTRUCTIONS = "printInstructions";
428:            public static String RESOLVER = "resolver";
429:            public static String SCRIPT_ELEMENT = "scriptElement";
430:            public static String VALIDATE_CACHES = "validateCaches";
431:            public static String WARN_UNDEFINED_REFERENCES = "warnUndefinedReferences";
432:            public static String WARN_GLOBAL_ASSIGNMENTS = "warnGlobalAssignments";
433:            public static String WARN_UNUSED_LOCALS = "warnUnusedLocals";
434:            public static String WARN_UNUSED_PARAMETERS = "warnUnusedParameters";
435:            public static String WITH_THIS = "withThis";
436:
437:            //
438:            // Parser
439:            //
440:
441:            // A scanner and parser generated by JavaCC and jjtree are used to
442:            // create a Java AST of the input, with literals annotated by Java
443:            // objects (instances of String and the numeric types).
444:            public static class Ops implements  ParserConstants {
445:            };
446:
447:            // Wrapper for values that Parser.substitute should splice into
448:            // place, instead of substituting at the level of the template
449:            // variable.
450:            public static class Splice {
451:                SimpleNode value[];
452:
453:                public Splice(SimpleNode[] value) {
454:                    this .value = value;
455:                }
456:
457:                public String toString() {
458:                    return "Splice(" + value.toString() + ")";
459:                }
460:            }
461:
462:            // Wrapper for the Java parser.  Returns a tuple-tree.
463:            public static class Parser {
464:                public SimpleNode parse0(String str, String type) {
465:                    org.openlaszlo.sc.parser.Parser p = new org.openlaszlo.sc.parser.Parser(
466:                            new StringReader(str));
467:                    assert "Program".equals(type);
468:                    try {
469:                        return p.Program();
470:                    } catch (ParseException pe) {
471:                        // NOTE: [2007-03-27 ptw]
472:                        // The parser tracks #file declarations, but does not pass the
473:                        // file to the exception constructor, so we fix that up here.
474:                        // (This is really a limitation of javacc.)
475:                        pe.initPathname(p.token_source.pathname);
476:                        throw pe;
477:                    }
478:                }
479:
480:                public SimpleNode parse0(String str) {
481:                    return parse0(str, "Program");
482:                }
483:
484:                public SimpleNode parse(String str) {
485:                    SimpleNode node = parse0(str, "Program");
486:                    SimpleNode refactored = refactorAST(node);
487:                    if (refactored != null) {
488:                        return refactored;
489:                    } else {
490:                        return node;
491:                    }
492:                }
493:
494:                private ParseTreePrinter ptp = new ParseTreePrinter();
495:
496:                // The transforms in this branch insure that each binary
497:                // expression sequence has exactly two children (not
498:                // counting the operator).
499:                private void fold(SimpleNode node, int arity) {
500:                    // Transform K(a0,a1,a2) -> K(K(a0,a1),a2), such that no K node
501:                    // has an arity greater than arity.
502:                    int size = node.size();
503:                    if (size > arity) {
504:                        try {
505:                            // TODO: [2005-11-21 ptw] clone would be simpler, if you
506:                            // could make it work
507:                            java.lang.reflect.Constructor constructor = node
508:                                    .getClass().getConstructor(
509:                                            new Class[] { int.class });
510:                            SimpleNode child = (SimpleNode) constructor
511:                                    .newInstance(new Object[] { Integer
512:                                            .valueOf("0") });
513:                            child.setBeginLocation(node.filename,
514:                                    node.beginLine, node.beginColumn);
515:                            int split = size - (arity - 1);
516:                            SimpleNode[] children = new SimpleNode[split];
517:                            for (int i = 0; i < split; i++) {
518:                                children[i] = node.get(i);
519:                            }
520:                            child.setChildren(children);
521:                            if (child.size() > arity) {
522:                                fold(child, arity);
523:                            }
524:                            children = new SimpleNode[arity];
525:                            children[0] = child;
526:                            for (int i = split, j = 1; i < size; i++, j++) {
527:                                children[j] = node.get(i);
528:                            }
529:                            node.setChildren(children);
530:                        } catch (InstantiationException e) {
531:                            assert false : e.toString();
532:                        } catch (IllegalAccessException e) {
533:                            assert false : e.toString();
534:                        } catch (NoSuchMethodException e) {
535:                            assert false : e.toString();
536:                        } catch (java.lang.reflect.InvocationTargetException e) {
537:                            assert false : e.toString();
538:                        }
539:                    }
540:                }
541:
542:                // Modify the AST tree rooted at n so that its branching
543:                // structure matches evaluation order.  This is necessary because
544:                // the parser is right-recursive, and generates flat trees for
545:                // a+b+c and a.b.c.
546:                public SimpleNode refactorAST(SimpleNode node) {
547:                    if (node == null || node.size() == 0) {
548:                        return null;
549:                    }
550:                    for (int i = 0; i < node.size(); i++) {
551:                        SimpleNode x = refactorAST(node.get(i));
552:                        if (x != null) {
553:                            node.set(i, x);
554:                        }
555:                    }
556:                    if (node instanceof  ASTBinaryExpressionSequence) {
557:                        // Transform a flat sequence of subexpressions with
558:                        // alternating operators into a right-branching binary
559:                        // tree.  This corrects the fact that the parser, being
560:                        // recursive-descent, is right-factored, but the operators
561:                        // are left-associative.
562:                        //
563:                        // For example:
564:                        // K(a, o1, b, o2, c) -> K(K(a, o1, b), o2, c)
565:                        // K(a, o1, b, o2, c, o3, d) -> K(K(K(a, o1, b), o2, c), o3, d)
566:                        fold(node, 3);
567:                    } else if (node instanceof  ASTAndExpressionSequence
568:                            || node instanceof  ASTOrExpressionSequence) {
569:                        // Transforms K(a, b, c) -> K(K(a, b), c),
570:                        // where node is in (AndExpressionSequence, OrExpressionSequence)
571:                        fold(node, 2);
572:                    }
573:                    if (node instanceof  ASTCallExpression) {
574:                        // cf., CallExpression in Parser.jjt
575:                        // C(a, P(b)) -> P(a, b)
576:                        // C(a, P(b), P(c)) -> P(P(a, b), c)
577:                        // C(a, P(b), A) -> C(P(a, b), A)
578:                        // C(a, P(b), P(c), A) -> C(P(P(a, b), c), A)
579:                        // C(a, A) -> C(a, A)
580:                        // C(a, A, P(b)) -> P(C(a, A), b)
581:                        // where
582:                        //   C = CallExpression
583:                        //   P = PropertyIdentifierReference
584:                        //   A = FunctionCallParameters
585:                        while (node.size() > 1) {
586:                            if (node.get(1) instanceof  ASTFunctionCallParameters) {
587:                                if (node.size() > 2) {
588:                                    try {
589:                                        int size = node.size();
590:                                        // TODO: [2005-11-21 ptw] clone would be simpler, if
591:                                        // you could make it work
592:                                        java.lang.reflect.Constructor constructor = node
593:                                                .getClass()
594:                                                .getConstructor(
595:                                                        new Class[] { int.class });
596:                                        SimpleNode child = (SimpleNode) constructor
597:                                                .newInstance(new Object[] { Integer
598:                                                        .valueOf("0") });
599:                                        child.setBeginLocation(node.filename,
600:                                                node.beginLine,
601:                                                node.beginColumn);
602:                                        SimpleNode children[] = new SimpleNode[2];
603:                                        children[0] = node.get(0);
604:                                        children[1] = node.get(1);
605:                                        child.setChildren(children);
606:                                        children = new SimpleNode[size - 2 + 1];
607:                                        children[0] = child;
608:                                        for (int i = 2, j = 1; i < size; i++, j++) {
609:                                            children[j] = node.get(i);
610:                                        }
611:                                        node.setChildren(children);
612:                                    } catch (InstantiationException e) {
613:                                        assert false : e.toString();
614:                                    } catch (IllegalAccessException e) {
615:                                        assert false : e.toString();
616:                                    } catch (NoSuchMethodException e) {
617:                                        assert false : e.toString();
618:                                    } catch (java.lang.reflect.InvocationTargetException e) {
619:                                        assert false : e.toString();
620:                                    }
621:                                    continue;
622:                                } else {
623:                                    break;
624:                                }
625:                            }
626:                            SimpleNode prop = node.get(1);
627:                            assert ((prop instanceof  ASTPropertyIdentifierReference || prop instanceof  ASTPropertyValueReference) && prop
628:                                    .size() > 0) : (new ParseTreePrinter())
629:                                    .visit(prop);
630:                            int size = node.size();
631:                            SimpleNode children[] = new SimpleNode[2];
632:                            children[0] = node.get(0);
633:                            children[1] = prop.get(0);
634:                            prop.setChildren(children);
635:                            children = new SimpleNode[size - 1];
636:                            for (int i = 1, j = 0; i < size; i++, j++) {
637:                                children[j] = node.get(i);
638:                            }
639:                            node.setChildren(children);
640:                        }
641:                        if (node.size() == 1) {
642:                            return node.get(0);
643:                        }
644:                    }
645:                    // After refactoring, assure each function has a name
646:                    // for debugging and profiling
647:                    if (node instanceof  ASTAssignmentExpression) {
648:                        SimpleNode rhs = node.get(2);
649:                        if (rhs instanceof  ASTFunctionExpression) {
650:                            // fn children are [(name), arglist, body]
651:                            if (rhs.size() == 2) {
652:                                String name = ptp.visit(node.get(0));
653:                                SimpleNode child = rhs;
654:                                int size = child.size();
655:                                SimpleNode children[] = new SimpleNode[size + 1];
656:                                children[0] = new ASTIdentifier(name);
657:                                for (int i = 0, j = 1; i < size; i++, j++) {
658:                                    children[j] = child.get(i);
659:                                }
660:                                child.setChildren(children);
661:                            }
662:                        }
663:                    }
664:                    return node;
665:                }
666:
667:                // UNUSED
668:                //     // Build a node out of an AST tuple-tree
669:                //     public void build(*tuple) {
670:                //         node = tuple[0]
671:                //         assert ! node.children
672:                //         for (child in tuple[1)]:
673:                //             if (isinstance(child, TupleType))
674:                //                 child = build(*child)
675:                //             node.jjtAddChild(child, len(node.children))
676:                //         return node
677:
678:                private SimpleNode visit(SimpleNode node, Map keys) {
679:                    List result = new ArrayList();
680:                    int size = node.size();
681:                    for (int i = 0; i < size; i++) {
682:                        SimpleNode child = node.get(i);
683:                        if (child instanceof  ASTIdentifier) {
684:                            String name = ((ASTIdentifier) child).getName();
685:                            if (keys.containsKey(name)) {
686:                                Object value = keys.get(name);
687:                                if (value instanceof  Splice) {
688:                                    result.addAll(Arrays
689:                                            .asList(((Splice) value).value));
690:                                } else {
691:                                    result.add(value);
692:                                }
693:                                continue;
694:                            }
695:                        }
696:                        result.add(visit(child, keys));
697:                    }
698:                    SimpleNode[] children = new SimpleNode[result.size()];
699:                    node.setChildren((SimpleNode[]) result.toArray(children));
700:                    return node;
701:                }
702:
703:                // Parse an expression and replace any identifier with the same
704:                // name as a keyword argument to this function, with the value of
705:                // that key.  If the value has type Splice, it's spliced into
706:                // place instead of substituting at the same level.
707:                //
708:                // >>> s = Parser().substitute
709:                // >>> s("[0,1,2]")
710:                // (ASTArrayLiteral, Literal(0.0), Literal(1), Literal(2))
711:                // >>> s("[_0,1,2]", _0=Literal("sub"))
712:                // (ASTArrayLiteral, Literal(sub), Literal(1), Literal(2))
713:                // >>> s("[_0,1,2]", _0=s("[a,b,c]"))
714:                // (ASTArrayLiteral, (ASTArrayLiteral, ASTIdentifier(a), ASTIdentifier(b), ASTIdentifier(c)), Literal(1), Literal(2))
715:                // >>> s("[_0,1,2]", _0=Splice(s("[a,b,c]")))
716:                // (ASTArrayLiteral, ASTArrayLiteral, ASTIdentifier(a), ASTIdentifier(b), ASTIdentifier(c), Literal(1), Literal(2))
717:                //
718:                // N.B., there is no attempt to enforce macro hygiene
719:                public SimpleNode substitute(String str, Map keys) {
720:                    // Since the parser can't parse an Expression, turn the source
721:                    // into a Program, and extract the Expression from the parse tree.
722:                    SimpleNode node = parse(
723:                            "x = \n#file Compiler.substitute\n#line 0\n" + str)
724:                            .get(0).get(0).get(2);
725:                    return visit(node, keys);
726:                }
727:            }
728:
729:            // Visitor -- only works for ParseTreePrinter so far
730:            //   public abstract static class Visitor {
731:            //     public java.lang.reflect.Method getVisitor(SimpleNode node) {
732:            //       // trim the module name, and the initial "AST"
733:            //       String name;
734:            //       if (node instanceof ASTIdentifier) {
735:            //         name = "Identifier";
736:            //       } else {
737:            //         name = node.getClass().getName();
738:            //         name = name.substring(name.lastIndexOf(".")+4, name.length());
739:            //       }
740:            //       try {
741:            //         return getClass().getMethod(
742:            //           "visit" + name,
743:            //           new Class[] { SimpleNode.class, String[].class }
744:            //           );
745:            //       } catch (NoSuchMethodException e) {
746:            //         System.err.println("Missing visitor: " + e.toString());
747:            //         try {
748:            //           return getClass().getMethod(
749:            //             "defaultVisitor",
750:            //             new Class[] { Object.class, Object[].class }
751:            //             );
752:            //         } catch (NoSuchMethodException ee) {
753:            //           assert false : ee.toString();
754:            //         }
755:            //       }
756:            //       assert false : "can't happen";
757:            //       return null;
758:            //     }
759:
760:            //     public abstract Object defaultVisitor(Object o, Object[] children);
761:            //   }
762:
763:            // ASTNode -> fname, lineno
764:            public static class SourceLocation {
765:                private String file;
766:                private int line;
767:
768:                public SourceLocation(String file, int line) {
769:                    this .file = file;
770:                    this .line = line;
771:                }
772:
773:                public static SourceLocation get(SimpleNode node) {
774:                    return new SourceLocation(
775:                            node.filename != null ? node.filename
776:                                    : "unknown file", node.beginLine);
777:                }
778:            }
779:
780:            public static class PassThroughNode extends SimpleNode {
781:                public SimpleNode realNode;
782:
783:                public PassThroughNode(SimpleNode realNode) {
784:                    this .realNode = realNode;
785:                }
786:            }
787:
788:            //
789:            // Profiler for hand-instrumentation of Compiler
790:            //
791:            public static class Profiler {
792:                static SimpleDateFormat timeFormatter = new SimpleDateFormat(
793:                        "HH:mm:ss.SS");
794:                static {
795:                    timeFormatter.setTimeZone(TimeZone.getTimeZone("GMT"));
796:                }
797:                static DecimalFormat percentFormatter = new DecimalFormat(
798:                        "###.00");
799:
800:                public static class Block {
801:                    Date startTime;
802:                    long elapsed;
803:                    String name;
804:                    Block parent;
805:                    List children;
806:
807:                    Block(String name) {
808:                        this .startTime = new Date();
809:                        this .name = name;
810:                        this .children = new ArrayList();
811:                    }
812:
813:                    Block make(String name) {
814:                        Block block = new Block(name);
815:                        block.parent = this ;
816:                        children.add(block);
817:                        return block;
818:                    }
819:                }
820:
821:                List names;
822:                Block main;
823:                Block current;
824:
825:                Profiler() {
826:                    this .names = new ArrayList();
827:                    Block block = new Block("__main__");
828:                    this .main = block;
829:                    this .current = block;
830:                }
831:
832:                public void enter(String name) {
833:                    Block block = current.make(name);
834:                    current = block;
835:                }
836:
837:                public void exit() {
838:                    current.elapsed = (new Date()).getTime()
839:                            - current.startTime.getTime();
840:                    current = current.parent;
841:                }
842:
843:                public void phase(String name) {
844:                    exit();
845:                    enter(name);
846:                }
847:
848:                public void pprint() {
849:                    long total = 0;
850:                    for (Iterator i = current.children.iterator(); i.hasNext();) {
851:                        Block next = (Block) i.next();
852:                        total += next.elapsed;
853:                    }
854:                    for (Iterator i = current.children.iterator(); i.hasNext();) {
855:                        Block next = (Block) i.next();
856:                        long time = next.elapsed;
857:                        Object interval = new Date(next.elapsed);
858:                        System.out.println(next.name + "\t"
859:                                + timeFormatter.format(interval) + "\t"
860:                                + percentFormatter.format(time * 100 / total));
861:                    }
862:                }
863:            }
864:
865:            private static ParseTreePrinter ptp = new ParseTreePrinter();
866:
867:            public static String nodeString(SimpleNode node) {
868:                return ptp.visit(node);
869:            }
870:
871:        }
872:
873:        /**
874:         * @copyright Copyright 2001-2007 Laszlo Systems, Inc.  All Rights
875:         * Reserved.  Use is subject to license terms.
876:         */
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.