1 /* 2 * Permission is hereby granted, free of charge, to any person obtaining a copy of 3 * this software and associated documentation files (the "Software"), to deal in 4 * the Software without restriction, including without limitation the rights to 5 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 6 * of the Software, and to permit persons to whom the Software is furnished to do 7 * so, subject to the following conditions: 8 * 9 * The above copyright notice and this permission notice shall be included in all 10 * copies or substantial portions of the Software. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 * SOFTWARE. 19 */ 20 package jdk.nashorn.internal.joni.ast; 21 22 import java.util.Set; 23 24 import jdk.nashorn.internal.joni.WarnCallback; 25 import jdk.nashorn.internal.joni.exception.ErrorMessages; 26 import jdk.nashorn.internal.joni.exception.InternalException; 27 28 public final class ConsAltNode extends Node { 29 public Node car; 30 public ConsAltNode cdr; 31 private int type; // List or Alt 32 33 private ConsAltNode(Node car, ConsAltNode cdr, int type) { 34 this.car = car; 35 if (car != null) car.parent = this; 36 this.cdr = cdr; 37 if (cdr != null) cdr.parent = this; 38 39 this.type = type; 40 } 41 42 public static ConsAltNode newAltNode(Node left, ConsAltNode right) { 43 return new ConsAltNode(left, right, ALT); 44 } 45 46 public static ConsAltNode newListNode(Node left, ConsAltNode right) { 47 return new ConsAltNode(left, right, LIST); 48 } 49 50 public static ConsAltNode listAdd(ConsAltNode list, Node x) { 51 ConsAltNode n = newListNode(x, null); 52 53 if (list != null) { 54 while (list.cdr != null) { 55 list = list.cdr; 56 } 57 list.setCdr(n); 58 } 59 return n; 60 } 61 62 public void toListNode() { 63 type = LIST; 64 } 65 66 public void toAltNode() { 67 type = ALT; 68 } 69 70 @Override 71 public int getType() { 72 return type; 73 } 74 75 @Override 76 protected void setChild(Node newChild) { 77 car = newChild; 78 } 79 80 @Override 81 protected Node getChild() { 82 return car; 83 } 84 85 @Override 86 public void swap(Node with) { 87 if (cdr != null) { 88 cdr.parent = with; 89 if (with instanceof ConsAltNode) { 90 ConsAltNode withCan = (ConsAltNode)with; 91 withCan.cdr.parent = this; 92 ConsAltNode tmp = cdr; 93 cdr = withCan.cdr; 94 withCan.cdr = tmp; 95 } 96 } 97 super.swap(with); 98 } 99 100 @Override 101 public void verifyTree(Set<Node> set, WarnCallback warnings) { 102 if (!set.contains(this)) { 103 set.add(this); 104 if (car != null) { 105 if (car.parent != this) { 106 warnings.warn("broken list car: " + this.getAddressName() + " -> " + car.getAddressName()); 107 } 108 car.verifyTree(set,warnings); 109 } 110 if (cdr != null) { 111 if (cdr.parent != this) { 112 warnings.warn("broken list cdr: " + this.getAddressName() + " -> " + cdr.getAddressName()); 113 } 114 cdr.verifyTree(set,warnings); 115 } 116 } 117 } 118 119 public Node setCar(Node ca) { 120 car = ca; 121 ca.parent = this; 122 return car; 123 } 124 125 public ConsAltNode setCdr(ConsAltNode cd) { 126 cdr = cd; 127 cd.parent = this; 128 return cdr; 129 } 130 131 @Override 132 public String getName() { 133 switch (type) { 134 case ALT: 135 return "Alt"; 136 case LIST: 137 return "List"; 138 default: 139 throw new InternalException(ErrorMessages.ERR_PARSER_BUG); 140 } 141 } 142 143 @Override 144 public String toString(int level) { 145 StringBuilder value = new StringBuilder(); 146 value.append("\n car: " + pad(car, level + 1)); 147 value.append("\n cdr: " + (cdr == null ? "NULL" : cdr.toString())); 148 149 return value.toString(); 150 } 151 152 }