1 21 22 package org.armedbear.j; 23 24 import java.util.ArrayList ; 25 26 public final class LispTagger extends Tagger 27 { 28 private static final int NEUTRAL = 0; 30 private static final int OPEN_PAREN = 1; 31 private static final int DEFINITION = 2; 32 33 private static final Mode mode = LispMode.getMode(); 34 35 private ArrayList tags; 36 37 public LispTagger(SystemBuffer buffer) 38 { 39 super(buffer); 40 } 41 42 public synchronized void run() 43 { 44 tags = new ArrayList (); 45 Position pos = new Position(buffer.getFirstLine(), 0); 46 int state = NEUTRAL; 47 String definer = null; 48 while (!pos.atEnd()) { 49 char c = pos.getChar(); 50 if (Character.isWhitespace(c)) { 51 pos.skipWhitespace(); 52 continue; 53 } 54 if (c == '\\') { 55 if (pos.getOffset() < pos.getLineLength()-1) 57 pos.skip(2); 58 else { 59 Line nextLine = pos.getNextLine(); 60 if (nextLine == null) 61 break; 62 pos.moveTo(nextLine, 0); 63 } 64 continue; 65 } 66 if (c == '#' && pos.lookingAt("#|")) { 67 pos.skip(2); 68 skipComment(pos); 69 continue; 70 } 71 if (c == '\"') { 72 pos.skipQuote(); 73 continue; 74 } 75 if (c == ';') { 76 Line nextLine = pos.getNextLine(); 78 if (nextLine == null) 79 break; 80 pos.moveTo(nextLine, 0); 81 continue; 82 } 83 if (c == '(') { 84 if (state == DEFINITION) { 85 if (definer != null) { 86 if (definer.equals("defun")) { 87 Position tokenStart = pos.copy(); 88 String name = gatherList(pos); 89 addTag(name, tokenStart, definer); 90 state = NEUTRAL; 91 definer = null; 92 continue; 93 } 94 if (definer.equals("defstruct")) { 95 pos.next(); 96 pos.skipWhitespace(); 97 c = pos.getChar(); 98 if (mode.isIdentifierStart(c)) { 99 Position tokenStart = pos.copy(); 100 String token = gatherToken(pos); 101 addTag(token, tokenStart, definer); 102 state = NEUTRAL; 103 definer = null; 104 continue; 105 } 106 } 107 } 108 } 109 state = OPEN_PAREN; 110 pos.next(); 111 continue; 112 } 113 if (mode.isIdentifierStart(c)) { 114 if (state == DEFINITION) { 115 Position tokenStart = pos.copy(); 116 String token = gatherToken(pos); 117 addTag(token, tokenStart, definer); 118 state = NEUTRAL; 119 definer = null; 120 continue; 121 } 122 if (state == OPEN_PAREN) { 123 String preceding = 124 pos.getLine().substring(0, pos.getOffset()).trim(); 125 if (!preceding.equals("(")) { 126 state = NEUTRAL; 127 continue; 128 } 129 String token = gatherToken(pos).toLowerCase(); 130 token = LispMode.translateDefiner(token); 131 if (token != null) { 132 state = DEFINITION; 133 definer = token; 134 } else 135 state = NEUTRAL; 136 continue; 137 } 138 skipToken(pos); 139 continue; 140 } 141 state = NEUTRAL; 142 pos.next(); 143 } 144 buffer.setTags(tags); 145 } 146 147 private void addTag(String name, Position pos, String definer) 148 { 149 int type = -1; 150 if (definer.equals("defclass")) 151 type = TAG_CLASS; 152 else if (definer.equals("defconstant")) 153 type = TAG_CONSTANT; 154 else if (definer.equals("defgeneric")) 155 type = TAG_GENERIC_FUNCTION; 156 else if (definer.equals("define-condition")) 157 type = TAG_CONDITION; 158 else if (definer.equals("defmacro")) 159 type = TAG_MACRO; 160 else if (definer.equals("defmethod")) 161 type = TAG_METHOD; 162 else if (definer.equals("defparameter")) 163 type = TAG_PARAMETER; 164 else if (definer.equals("defstruct")) 165 type = TAG_STRUCT; 166 else if (definer.equals("deftype")) 167 type = TAG_TYPE; 168 else if (definer.equals("defun")) 169 type = TAG_DEFUN; 170 else if (definer.equals("defvar")) 171 type = TAG_VAR; 172 else 173 Debug.bug(); 174 tags.add(new LispTag(name, pos, type)); 175 } 176 177 private String gatherList(Position pos) 179 { 180 FastStringBuffer sb = new FastStringBuffer(); 181 char c = pos.getChar(); 182 Debug.bugIf(c != '('); 183 if (pos.next()) { 184 while ((c = pos.getChar()) != ')') { 185 sb.append(c); 186 if (!pos.next()) 187 break; 188 } 189 } 190 return sb.toString(); 191 } 192 193 private String gatherToken(Position pos) 195 { 196 FastStringBuffer sb = new FastStringBuffer(); 197 char c; 198 while (mode.isIdentifierPart(c = pos.getChar()) || c == ':') { 199 sb.append(c); 200 if (!pos.next()) 201 break; 202 } 203 return sb.toString(); 204 } 205 206 private void skipToken(Position pos) 208 { 209 while (mode.isIdentifierPart(pos.getChar())) { 210 if (!pos.next()) 211 return; 212 } 213 } 214 215 private void skipComment(Position pos) 216 { 217 while (!pos.atEnd()) { 218 char c = pos.getChar(); 219 if (c == '\\') { 220 if (pos.getOffset() < pos.getLineLength()-1) 222 pos.skip(2); 223 else { 224 Line nextLine = pos.getNextLine(); 225 if (nextLine == null) 226 break; 227 pos.moveTo(nextLine, 0); 228 } 229 continue; 230 } 231 if (c == '|' && pos.lookingAt("|#")) { 232 pos.skip(2); 233 return; 234 } 235 pos.next(); 236 } 237 } 238 } 239 | Popular Tags |