1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/* Useful for dumping out the input stream after doing some 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * augmentation or other manipulations. 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * You can insert stuff, replace, and delete chunks. Note that the 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * operations are done lazily--only if you convert the buffer to a 6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * String. This is very efficient because you are not moving data around 7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * all the time. As the buffer of tokens is converted to strings, the 8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * toString() method(s) check to see if there is an operation at the 9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * current index. If so, the operation is done and then normal String 10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * rendering continues on the buffer. This is like having multiple Turing 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * machine instruction streams (programs) operating on a single input tape. :) 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Since the operations are done lazily at toString-time, operations do not 14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * screw up the token index values. That is, an insert operation at token 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * index i does not change the index values for tokens i+1..n-1. 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Because operations never actually alter the buffer, you may always get 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * the original token stream back without undoing anything. Since 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * the instructions are queued up, you can easily simulate transactions and 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * roll back any changes if there is an error just by removing instructions. 21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * For example, 22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * CharStream input = new ANTLRFileStream("input"); 24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * TLexer lex = new TLexer(input); 25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * TokenRewriteStream tokens = new TokenRewriteStream(lex); 26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * T parser = new T(tokens); 27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * parser.startRule(); 28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Then in the rules, you can execute 30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Token t,u; 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * ... 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * input.insertAfter(t, "text to put after t");} 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * input.insertAfter(u, "text after u");} 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * System.out.println(tokens.toString()); 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Actually, you have to cast the 'input' to a TokenRewriteStream. :( 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * You can also have multiple "instruction streams" and get multiple 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * rewrites from a single pass over the input. Just name the instruction 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * streams and use that name again when printing the buffer. This could be 41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * useful for generating a C file and also its header file--all from the 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * same buffer: 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * tokens.insertAfter("pass1", t, "text to put after t");} 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * tokens.insertAfter("pass2", u, "text after u");} 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * System.out.println(tokens.toString("pass1")); 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * System.out.println(tokens.toString("pass2")); 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * If you don't use named rewrite streams, a "default" stream is used as 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * the first example shows. 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverorg.antlr.runtime.TokenRewriteStream = function() { 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var sup = org.antlr.runtime.TokenRewriteStream.superclass; 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** You may have multiple, named streams of rewrite operations. 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * I'm calling these things "programs." 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Maps String (name) -> rewrite (List) 59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.programs = null; 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Map String (program name) -> Integer index */ 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.lastRewriteTokenIndexes = null; 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (arguments.length===0) { 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.init(); 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else { 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver sup.constructor.apply(this, arguments); 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.init(); 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}; 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver(function(){ 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervar trs = org.antlr.runtime.TokenRewriteStream; 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverorg.antlr.lang.augmentObject(trs, { 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DEFAULT_PROGRAM_NAME: "default", 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver PROGRAM_INIT_SIZE: 100, 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver MIN_TOKEN_INDEX: 0 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}); 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Define the rewrite operation hierarchy 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvertrs.RewriteOperation = function(index, text) { 88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.index = index; 89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.text = text; 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}; 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Execute the rewrite operation by possibly adding to the buffer. 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Return the index of the next token to operate on. 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvertrs.RewriteOperation.prototype = { 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver execute: function(buf) { 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return this.index; 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver }, 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver toString: function() { 100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /*String opName = getClass().getName(); 101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int $index = opName.indexOf('$'); 102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opName = opName.substring($index+1, opName.length()); 103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return opName+"@"+index+'"'+text+'"';*/ 104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return this.text; 105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}; 107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvertrs.InsertBeforeOp = function(index, text) { 109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver trs.InsertBeforeOp.superclass.constructor.call(this, index, text); 110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}; 111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverorg.antlr.lang.extend(trs.InsertBeforeOp, trs.RewriteOperation, { 112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver execute: function(buf) { 113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver buf.push(this.text); 114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return this.index; 115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}); 117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** I'm going to try replacing range from x..y with (y-x)+1 ReplaceOp 119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * instructions. 120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvertrs.ReplaceOp = function(from, to, text) { 122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver trs.ReplaceOp.superclass.constructor.call(this, from, text); 123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.lastIndex = to; 124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}; 125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverorg.antlr.lang.extend(trs.ReplaceOp, trs.RewriteOperation, { 126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver execute: function(buf) { 127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (org.antlr.lang.isValue(this.text)) { 128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver buf.push(this.text); 129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return this.lastIndex+1; 131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}); 133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvertrs.DeleteOp = function(from, to) { 135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver trs.DeleteOp.superclass.constructor.call(this, from, to); 136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}; 137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverorg.antlr.lang.extend(trs.DeleteOp, trs.ReplaceOp); 138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverorg.antlr.lang.extend(trs, org.antlr.runtime.CommonTokenStream, { 140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver init: function() { 141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.programs = {}; 142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.programs[trs.DEFAULT_PROGRAM_NAME] = []; 143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.lastRewriteTokenIndexes = {}; 144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver }, 145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Rollback the instruction stream for a program so that 147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * the indicated instruction (via instructionIndex) is no 148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * longer in the stream. UNTESTED! 149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rollback: function() { 151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var programName, 152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver instructionIndex; 153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (arguments.length===1) { 155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName = trs.DEFAULT_PROGRAM_NAME; 156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver instructionIndex = arguments[0]; 157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else if (arguments.length===2) { 158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName = arguments[0]; 159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver instructionIndex = arguments[1]; 160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var is = this.programs[programName]; 162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (is) { 163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programs[programName] = is.slice(trs.MIN_TOKEN_INDEX, this.instructionIndex); 164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver }, 166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Reset the program so that no instructions exist */ 168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver deleteProgram: function(programName) { 169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName = programName || trs.DEFAULT_PROGRAM_NAME; 170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.rollback(programName, trs.MIN_TOKEN_INDEX); 171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver }, 172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Add an instruction to the rewrite instruction list ordered by 174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * the instruction number (use a binary search for efficiency). 175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * The list is ordered so that toString() can be done efficiently. 176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * When there are multiple instructions at the same index, the instructions 178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * must be ordered to ensure proper behavior. For example, a delete at 179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * index i must kill any replace operation at i. Insert-before operations 180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * must come before any replace / delete instructions. If there are 181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * multiple insert instructions for a single index, they are done in 182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * reverse insertion order so that "insert foo" then "insert bar" yields 183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * "foobar" in front rather than "barfoo". This is convenient because 184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * I can insert new InsertOp instructions at the index returned by 185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * the binary search. A ReplaceOp kills any previous replace op. Since 186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * delete is the same as replace with null text, i can check for 187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * ReplaceOp and cover DeleteOp at same time. :) 188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver addToSortedRewriteList: function() { 190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var programName, 191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver op; 192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (arguments.length===1) { 193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName = trs.DEFAULT_PROGRAM_NAME; 194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver op = arguments[0]; 195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else if (arguments.length===2) { 196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName = arguments[0]; 197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver op = arguments[1]; 198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var rewrites = this.getProgram(programName); 201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var len, pos, searchOp, replaced, prevOp, i; 202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (pos=0, len=rewrites.length; pos<len; pos++) { 203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver searchOp = rewrites[pos]; 204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (searchOp.index===op.index) { 205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // now pos is the index in rewrites of first op with op.index 206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // an instruction operating already on that index was found; 208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // make this one happen after all the others 209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (op instanceof trs.ReplaceOp) { 210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver replaced = false; 211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // look for an existing replace 212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (i=pos; i<rewrites.length; i++) { 213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver prevOp = rewrites[pos]; 214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (prevOp.index!==op.index) { 215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver break; 216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (prevOp instanceof trs.ReplaceOp) { 218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rewrites[pos] = op; // replace old with new 219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver replaced=true; 220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver break; 221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // keep going; must be an insert 223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( !replaced ) { 225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // add replace op to the end of all the inserts 226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rewrites.splice(i, 0, op); 227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else { 229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // inserts are added in front of existing inserts 230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rewrites.splice(pos, 0, op); 231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver break; 233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else if (searchOp.index > op.index) { 234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rewrites.splice(pos, 0, op); 235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver break; 236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (pos===len) { 239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rewrites.push(op); 240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver }, 242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver insertAfter: function() { 244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var index, programName, text; 245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (arguments.length===2) { 246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName = trs.DEFAULT_PROGRAM_NAME; 247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver index = arguments[0]; 248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = arguments[1]; 249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else if (arguments.length===3) { 250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName = arguments[0]; 251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver index = arguments[1]; 252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = arguments[2]; 253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (index instanceof org.antlr.runtime.Token) { 256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // index is a Token, grab it's stream index 257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver index = index.index; // that's ugly 258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // insert after is the same as insert before the next index 261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.insertBefore(programName, index+1, text); 262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver }, 263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver insertBefore: function() { 265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var index, programName, text; 266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (arguments.length===2) { 267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName = trs.DEFAULT_PROGRAM_NAME; 268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver index = arguments[0]; 269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = arguments[1]; 270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else if (arguments.length===3) { 271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName = arguments[0]; 272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver index = arguments[1]; 273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = arguments[2]; 274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (index instanceof org.antlr.runtime.Token) { 277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // index is a Token, grab it's stream index 278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver index = index.index; // that's ugly 279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.addToSortedRewriteList( 282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName, 283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver new trs.InsertBeforeOp(index,text) 284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ); 285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver }, 286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver replace: function() { 288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var programName, first, last, text; 289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (arguments.length===2) { 290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName = trs.DEFAULT_PROGRAM_NAME; 291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver first = arguments[0]; 292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver last = arguments[0]; 293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = arguments[1]; 294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else if (arguments.length===3) { 295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName = trs.DEFAULT_PROGRAM_NAME; 296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver first = arguments[0]; 297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver last = arguments[1]; 298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = arguments[2]; 299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } if (arguments.length===4) { 300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName = arguments[0]; 301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver first = arguments[1]; 302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver last = arguments[2]; 303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = arguments[3]; 304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (first instanceof org.antlr.runtime.Token) { 307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver first = first.index; 308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (last instanceof org.antlr.runtime.Token) { 311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver last = last.index; // that's ugly 312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( first > last || last<0 || first<0 ) { 315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.addToSortedRewriteList( 318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName, 319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver new trs.ReplaceOp(first, last, text)); 320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver }, 321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // !!! API Break: delete is a JS keyword, so using remove instead. 323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver remove: function() { 324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // convert arguments to a real array 325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var args=[], i=arguments.length-1; 326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (i>=0) { 327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver args[i] = arguments[i]; 328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver i--; 329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver args.push(""); 332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.replace.apply(this, args); 333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver }, 334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver getLastRewriteTokenIndex: function(programName) { 336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName = programName || trs.DEFAULT_PROGRAM_NAME; 337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return this.lastRewriteTokenIndexes[programName] || -1; 338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver }, 339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver setLastRewriteTokenIndex: function(programName, i) { 341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.lastRewriteTokenIndexes[programName] = i; 342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver }, 343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver getProgram: function(name) { 345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var is = this.programs[name]; 346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( !is ) { 347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver is = this.initializeProgram(name); 348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return is; 350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver }, 351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver initializeProgram: function(name) { 353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var is = []; 354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.programs[name] = is; 355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return is; 356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver }, 357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver toOriginalString: function(start, end) { 359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (!org.antlr.lang.isNumber(start)) { 360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver start = trs.MIN_TOKEN_INDEX; 361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (!org.antlr.lang.isNumber(end)) { 363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end = this.size()-1; 364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var buf = [], i; 367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (i=start; i>=trs.MIN_TOKEN_INDEX && i<=end && i<this.tokens.length; i++) { 368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver buf.push(this.get(i).getText()); 369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return buf.join(""); 371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver }, 372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver toString: function() { 374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var programName, start, end; 375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (arguments.length===0) { 376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName = trs.DEFAULT_PROGRAM_NAME; 377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver start = trs.MIN_TOKEN_INDEX; 378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end = this.size() - 1; 379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else if (arguments.length===1) { 380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName = arguments[0]; 381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver start = trs.MIN_TOKEN_INDEX; 382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end = this.size() - 1; 383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else if (arguments.length===2) { 384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver programName = trs.DEFAULT_PROGRAM_NAME; 385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver start = arguments[0]; 386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end = arguments[1]; 387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var rewrites = this.programs[programName]; 390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( !rewrites || rewrites.length===0 ) { 391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return this.toOriginalString(start,end); 392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /// Index of first rewrite we have not done 395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var rewriteOpIndex = 0, 396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokenCursor=start, 397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver buf = [], 398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver op; 399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while ( tokenCursor>=trs.MIN_TOKEN_INDEX && 400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokenCursor<=end && 401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokenCursor<this.tokens.length ) 402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // execute instructions associated with this token index 404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( rewriteOpIndex<rewrites.length ) { 405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver op = rewrites[rewriteOpIndex]; 406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // skip all ops at lower index 408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (op.index<tokenCursor && rewriteOpIndex<rewrites.length) { 409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rewriteOpIndex++; 410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( rewriteOpIndex<rewrites.length ) { 411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver op = rewrites[rewriteOpIndex]; 412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // while we have ops for this token index, exec them 416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (tokenCursor===op.index && rewriteOpIndex<rewrites.length) { 417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.out.println("execute "+op+" at instruction "+rewriteOpIndex); 418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokenCursor = op.execute(buf); 419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.out.println("after execute tokenCursor = "+tokenCursor); 420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rewriteOpIndex++; 421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( rewriteOpIndex<rewrites.length ) { 422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver op = rewrites[rewriteOpIndex]; 423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // dump the token at this index 427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( tokenCursor<=end ) { 428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver buf.push(this.get(tokenCursor).getText()); 429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokenCursor++; 430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // now see if there are operations (append) beyond last token index 433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var opi; 434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (opi=rewriteOpIndex; opi<rewrites.length; opi++) { 435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver op = rewrites[opi]; 436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( op.index>=this.size() ) { 437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver op.execute(buf); // must be insertions if after last token 438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return buf.join(""); 442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver }, 443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver toDebugString: function(start, end) { 445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (!org.antlr.lang.isNumber(start)) { 446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver start = trs.MIN_TOKEN_INDEX; 447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (!org.antlr.lang.isNumber(end)) { 449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end = this.size()-1; 450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver var buf = [], 453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver i; 454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (i=start; i>=trs.MIN_TOKEN_INDEX && i<=end && i<this.tokens.length; i++) { 455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver buf.push(this.get(i)); 456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return buf.join(""); 458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}); 460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver})(); 462