1 21 22 package org.armedbear.j; 23 24 public final class SchemeFormatter extends Formatter 25 { 26 private static final int SCHEME_FORMAT_TEXT = 0; 28 private static final int SCHEME_FORMAT_COMMENT = 1; 29 private static final int SCHEME_FORMAT_STRING = 2; 30 private static final int SCHEME_FORMAT_KEYWORD = 3; 31 private static final int SCHEME_FORMAT_FUNCTION = 4; 32 private static final int SCHEME_FORMAT_NUMBER = 5; 33 34 private FastStringBuffer sb = new FastStringBuffer(); 35 private int tokStart; 36 37 public SchemeFormatter(Buffer buffer) 38 { 39 this.buffer = buffer; 40 } 41 42 private void endToken(int state) 43 { 44 if (sb.length() > 0) { 45 int format = -1; 46 switch (state) { 47 case STATE_NEUTRAL: 48 break; 49 case STATE_QUOTE: 50 format = SCHEME_FORMAT_STRING; 51 break; 52 case STATE_IDENTIFIER: 53 break; 54 case STATE_COMMENT: 55 format = SCHEME_FORMAT_COMMENT; 56 break; 57 case STATE_NUMBER: 58 case STATE_HEXNUMBER: 59 format = SCHEME_FORMAT_NUMBER; 60 break; 61 } 62 addSegment(sb.toString(), format); 63 tokStart += sb.length(); 64 sb.setLength(0); 65 } 66 } 67 68 private void parseLine(String text, int state) 69 { 70 if (Editor.tabsAreVisible()) 71 text = Utilities.makeTabsVisible(text, buffer.getTabWidth()); 72 else 73 text = Utilities.detab(text, buffer.getTabWidth()); 74 clearSegmentList(); 75 sb.setLength(0); 76 int i = 0; 77 tokStart = 0; 78 final int limit = text.length(); 79 while (i < limit) { 81 char c = text.charAt(i); 82 if (Character.isWhitespace(c)) { 83 sb.append(c); 84 ++i; 85 } else { 86 endToken(state); 87 break; 88 } 89 } 90 while (i < limit) { 91 char c = text.charAt(i); 92 if (c == '\\' && i < limit-1) { 93 sb.append(c); 94 sb.append(text.charAt(++i)); 95 ++i; 96 continue; 97 } 98 if (state == STATE_COMMENT) { 99 if (c == '|' && i < limit-1) { 100 c = text.charAt(i+1); 101 if (c == '#') { 102 sb.append("|#"); 103 endToken(state); 104 state = STATE_NEUTRAL; 105 i += 2; 106 continue; 107 } 108 } 109 sb.append(c); 110 ++i; 111 continue; 112 } 113 if (state == STATE_QUOTE) { 114 sb.append(c); 115 if (c == '"') { 116 endToken(state); 117 state = STATE_NEUTRAL; 118 } 119 ++i; 120 continue; 121 } 122 if (c == '"') { 124 endToken(state); 125 sb.append(c); 126 state = STATE_QUOTE; 127 ++i; 128 continue; 129 } 130 if (c == ';') { 131 endToken(state); 132 state = STATE_COMMENT; 133 sb.append(text.substring(i)); 134 endToken(state); 135 return; 136 } 137 if (c == '#' && i < limit-1) { 138 if (text.charAt(i+1) == '|') { 139 endToken(state); 140 state = STATE_COMMENT; 141 sb.append("#|"); 142 i += 2; 143 continue; 144 } 145 } 146 if (state == STATE_IDENTIFIER) { 147 if (buffer.getMode().isIdentifierPart(c)) 148 sb.append(c); 149 else { 150 endToken(state); 151 sb.append(c); 152 state = STATE_NEUTRAL; 153 } 154 ++i; 155 continue; 156 } 157 if (state == STATE_NUMBER) { 158 if (Character.isDigit(c)) 159 sb.append(c); 160 else if (c == 'u' || c == 'U' || c == 'l' || c == 'L') 161 sb.append(c); else if (sb.length() == 1 && c == 'x' || c == 'X') { 163 sb.append(c); 164 state = STATE_HEXNUMBER; 165 } else { 166 endToken(state); 167 sb.append(c); 168 if (Character.isJavaIdentifierStart(c)) 169 state = STATE_IDENTIFIER; 170 else 171 state = STATE_NEUTRAL; 172 } 173 ++i; 174 continue; 175 } 176 if (state == STATE_HEXNUMBER) { 177 if (Character.isDigit(c)) 178 sb.append(c); 179 else if ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) 180 sb.append(c); 181 else if (c == 'u' || c == 'U' || c == 'l' || c == 'L') 182 sb.append(c); else { 184 endToken(state); 185 sb.append(c); 186 if (Character.isJavaIdentifierStart(c)) 187 state = STATE_IDENTIFIER; 188 else 189 state = STATE_NEUTRAL; 190 } 191 ++i; 192 continue; 193 } 194 if (state == STATE_NEUTRAL) { 195 if (buffer.mode.isIdentifierStart(c)) { 196 endToken(state); 197 sb.append(c); 198 state = STATE_IDENTIFIER; 199 } else if (Character.isDigit(c)) { 200 endToken(state); 201 sb.append(c); 202 state = STATE_NUMBER; 203 } else sb.append(c); 205 } 206 ++i; 207 } 208 endToken(state); 209 } 210 211 public LineSegmentList formatLine(Line line) 212 { 213 if (line == null) { 214 clearSegmentList(); 215 addSegment("", SCHEME_FORMAT_TEXT); 216 return segmentList; 217 } 218 parseLine(line.getText(), line.flags()); 219 final int size = segmentList.size(); 220 for (int i = 0; i < size; i++) { 221 LineSegment segment = segmentList.getSegment(i); 222 if (segment.getFormat() >= 0) 223 continue; 224 String token = segment.getText(); 225 if (isKeyword(token)) 226 segment.setFormat(SCHEME_FORMAT_KEYWORD); 227 else { 228 boolean isFunction = false; 229 if (i >= 2) { 230 LineSegment prevSegment = segmentList.getSegment(i-2); 231 String prevToken = prevSegment.getText(); 232 String trim = prevToken.trim(); 233 if (trim.equals("define")) 234 isFunction = true; 235 } 236 segment.setFormat(isFunction ? SCHEME_FORMAT_FUNCTION : SCHEME_FORMAT_TEXT); 237 } 238 } 239 return segmentList; 240 } 241 242 public boolean parseBuffer() 243 { 244 int state = STATE_NEUTRAL; 245 boolean changed = false; 246 Line line = buffer.getFirstLine(); 247 while (line != null) { 248 int oldflags = line.flags(); 249 if (state != oldflags) { 250 line.setFlags(state); 251 changed = true; 252 } 253 final int limit = line.length(); 254 for (int i = 0; i < limit; i++) { 255 char c = line.charAt(i); 256 if (c == '\\' && i < limit-1) { 257 ++i; 259 continue; 260 } 261 if (state == STATE_COMMENT) { 262 if (c == '|' && i < limit-1 && line.charAt(i+1) == '#') { 263 ++i; 264 state = STATE_NEUTRAL; 265 } 266 continue; 267 } 268 if (state == STATE_QUOTE) { 269 if (c == '"') 270 state = STATE_NEUTRAL; 271 continue; 272 } 273 if (c == ';') { 275 break; 277 } 278 if (c == '#') { 279 if (i < limit-1 && line.charAt(i+1) == '|') { 280 state = STATE_COMMENT; 281 ++i; 282 } 283 continue; 284 } 285 if (c == '"') 286 state = STATE_QUOTE; 287 } 288 line = line.next(); 289 } 290 buffer.setNeedsParsing(false); 291 return changed; 292 } 293 294 public FormatTable getFormatTable() 295 { 296 if (formatTable == null) { 297 formatTable = new FormatTable("SchemeMode"); 298 formatTable.addEntryFromPrefs(SCHEME_FORMAT_TEXT, "text"); 299 formatTable.addEntryFromPrefs(SCHEME_FORMAT_COMMENT, "comment"); 300 formatTable.addEntryFromPrefs(SCHEME_FORMAT_STRING, "string"); 301 formatTable.addEntryFromPrefs(SCHEME_FORMAT_KEYWORD, "keyword"); 302 formatTable.addEntryFromPrefs(SCHEME_FORMAT_FUNCTION, "function"); 303 formatTable.addEntryFromPrefs(SCHEME_FORMAT_NUMBER, "number"); 304 } 305 return formatTable; 306 } 307 } 308 | Popular Tags |