001 package nl.cwi.sen1.tide.tool.support; 002 003 //{{{ imports 004 005 import java.util.Iterator; 006 import java.util.List; 007 008 import aterm.ATerm; 009 import aterm.ATermAppl; 010 import aterm.ATermFactory; 011 import aterm.ATermList; 012 013 014 //}}} 015 016 public class Expr 017 { 018 //{{{ Patterns 019 020 private static final String PATTERN_LOC_LC = 021 "location(lc(<str>,<int>,<int>))"; 022 private static final String PATTERN_LOC_LINE = 023 "location(line(<str>,<int>))"; 024 private static final String PATTERN_LOC_AREA = 025 "location(area-in-file(<str>,area(<int>,<int>,<int>,<int>,<int>,<int>)))"; 026 private static final String PAT_SOURCE_VAR = 027 "source-var(<str>,<int>,<int>,<int>,<str>)"; 028 private static final String PAT_VARIABLE = 029 "variable(<str>,<term>)"; 030 private static final String PAT_VAR = 031 "var(<str>,<term>,<int>,<int>,<int>,<int>)"; 032 private static final String PAT_VAR_UNKNOWN = 033 "var-unknown(<str>)"; 034 private static final String PAT_ERROR = 035 "error(<str>,<term>)"; 036 private static final String PAT_SOURCE_PATH = 037 "source-path(<str>)"; 038 private static final String PAT_SOURCE_LIST = 039 "source-list([<list>])"; 040 private static final String PAT_STACK_TRACE = 041 "stack([<list>])"; 042 private static final String PAT_STACK_FRAME = 043 "frame(<int>,<str>,<term>,<term>)"; 044 045 //}}} 046 047 public static ATermFactory factory; 048 049 private ATerm term; 050 051 //{{{ public static void initialize(ATermFactory factory) 052 053 public static void initialize(ATermFactory factory) 054 { 055 Expr.factory = factory; 056 } 057 058 //}}} 059 060 //{{{ public static Expr parse(String spec) 061 062 public static Expr parse(String spec) 063 { 064 try { 065 return fromTerm(factory.parse(spec)); 066 } catch (Exception e) { 067 return null; 068 } 069 } 070 071 //}}} 072 073 //{{{ public static Expr makeTrue() 074 075 public static Expr makeTrue() 076 { 077 return make("true"); 078 } 079 080 //}}} 081 //{{{ public static Expr makeFalse() 082 083 public static Expr makeFalse() 084 { 085 return make("false"); 086 } 087 088 //}}} 089 //{{{ public static Expr makeCpe() 090 091 public static Expr makeCpe() 092 { 093 return make("cpe"); 094 } 095 096 //}}} 097 //{{{ public static Expr makeBreak() 098 099 public static Expr makeBreak() 100 { 101 return make("break"); 102 } 103 104 //}}} 105 //{{{ public static Expr makeResume() 106 107 public static Expr makeResume() 108 { 109 return make("resume"); 110 } 111 112 //}}} 113 //{{{ public static Expr makeLocation(String file, int line, int col) 114 115 public static Expr makeLocation(String file, int line, int column) 116 { 117 return make(factory.make(PATTERN_LOC_LC, file, new Integer(line), 118 new Integer(column))); 119 } 120 121 //}}} 122 //{{{ public static Expr makeListSources() 123 124 public static Expr makeListSources() 125 { 126 return make("list-sources"); 127 } 128 129 //}}} 130 //{{{ public static Expr makeStackTrace() 131 132 public static Expr makeStackTrace() 133 { 134 return make("stack-trace"); 135 } 136 137 //}}} 138 //{{{ public static Expr make(String expr) 139 140 public static Expr make(String expr) 141 { 142 return make(factory.parse(expr)); 143 } 144 145 //}}} 146 //{{{ public static Expr make(ATerm expr) 147 148 public static Expr make(ATerm expr) 149 { 150 return new Expr(expr); 151 } 152 153 //}}} 154 //{{{ public static Expr fromTerm(ATerm expr) 155 156 public static Expr fromTerm(ATerm expr) 157 { 158 return make(expr); 159 } 160 161 //}}} 162 163 //{{{ public static Expr makeSourceVar(file, pos, linenr, col, line) 164 165 public static Expr makeSourceVar(String file, int pos, 166 int linenr, int col, String line) 167 { 168 return Expr.make(Expr.factory.make(PAT_SOURCE_VAR, 169 file, 170 new Integer(pos), 171 new Integer(linenr), 172 new Integer(col), line)); 173 } 174 175 //}}} 176 177 //{{{ Expr(ATerm term) 178 179 Expr(ATerm term) 180 { 181 this.term = term; 182 } 183 184 //}}} 185 186 //{{{ public boolean isError() 187 188 public boolean isError() 189 { 190 return term.match(PAT_ERROR) != null; 191 } 192 193 //}}} 194 //{{{ public String getErrorMessage() 195 196 public String getErrorMessage() 197 { 198 List<?> result = term.match(PAT_ERROR); 199 200 if (result != null) { 201 return (String)result.get(0); 202 } 203 204 throw new RuntimeException("not an error: " + term); 205 } 206 207 //}}} 208 //{{{ public Expr getErrorData() 209 210 public Expr getErrorData() 211 { 212 List<?> result = term.match(PAT_ERROR); 213 214 if (result != null) { 215 return Expr.make((ATerm)result.get(1)); 216 } 217 218 throw new RuntimeException("not an error: " + term); 219 } 220 221 public boolean isLocation() 222 { 223 return term.match("location(<list>)") != null; 224 } 225 226 public boolean isLocationUnknown() 227 { 228 return term.match("location(unknown)") != null; 229 } 230 231 //{{{ public String getLocationFileName() 232 233 public String getLocationFileName() 234 { 235 List<?> args = term.match(PATTERN_LOC_LINE); 236 if (args != null) { 237 return (String)args.get(0); 238 } 239 240 args = term.match(PATTERN_LOC_LC); 241 if (args != null) { 242 return (String)args.get(0); 243 } 244 245 args = term.match(PATTERN_LOC_AREA); 246 if (args != null) { 247 return (String)args.get(0); 248 } 249 250 throw new RuntimeException("illegal location: " + term); 251 } 252 253 //}}} 254 //{{{ public String getLocationShortFile() 255 256 public String getLocationShortFile() 257 { 258 String file = getLocationFileName(); 259 int index = file.lastIndexOf('/'); 260 return file.substring(index+1); 261 } 262 263 //}}} 264 //{{{ public int getLocationStartLine() 265 266 public int getLocationStartLine() 267 { 268 List<?> args = term.match(PATTERN_LOC_LINE); 269 if (args != null) { 270 return ((Integer)args.get(1)).intValue(); 271 } 272 273 args = term.match(PATTERN_LOC_LC); 274 if (args != null) { 275 return ((Integer)args.get(1)).intValue(); 276 } 277 278 args = term.match(PATTERN_LOC_AREA); 279 if (args != null) { 280 return ((Integer)args.get(1)).intValue(); 281 } 282 283 throw new RuntimeException("illegal location: " + term); 284 } 285 286 //}}} 287 //{{{ public int getLocationStartColumn() 288 289 public int getLocationStartColumn() 290 { 291 List<?> args = term.match(PATTERN_LOC_LINE); 292 if (args != null) { 293 return 0; 294 } 295 296 args = term.match(PATTERN_LOC_LC); 297 if (args != null) { 298 return ((Integer)args.get(2)).intValue(); 299 } 300 301 args = term.match(PATTERN_LOC_AREA); 302 if (args != null) { 303 return ((Integer)args.get(2)).intValue(); 304 } 305 306 throw new RuntimeException("illegal location: " + term); 307 } 308 309 //}}} 310 //{{{ public int getLocationEndLine() 311 312 public int getLocationEndLine() 313 { 314 List<?> args = term.match(PATTERN_LOC_LINE); 315 if (args != null) { 316 return ((Integer)args.get(1)).intValue(); 317 } 318 319 args = term.match(PATTERN_LOC_LC); 320 if (args != null) { 321 return ((Integer)args.get(1)).intValue(); 322 } 323 324 args = term.match(PATTERN_LOC_AREA); 325 if (args != null) { 326 return ((Integer)args.get(3)).intValue(); 327 } 328 329 throw new RuntimeException("illegal location: " + term); 330 } 331 332 //}}} 333 //{{{ public int getLocationEndColumn() 334 335 public int getLocationEndColumn() 336 { 337 List<?> args = term.match(PATTERN_LOC_LINE); 338 if (args != null) { 339 return -1; 340 } 341 342 args = term.match(PATTERN_LOC_LC); 343 if (args != null) { 344 return ((Integer)args.get(2)).intValue(); 345 } 346 347 args = term.match(PATTERN_LOC_AREA); 348 if (args != null) { 349 return ((Integer)args.get(4)).intValue(); 350 } 351 352 throw new RuntimeException("illegal location: " + term); 353 } 354 355 //}}} 356 357 //{{{ public boolean isVariable() 358 359 public boolean isVariable() 360 { 361 List<?> result = term.match(PAT_VARIABLE); 362 return result != null; 363 } 364 365 //}}} 366 //{{{ public String getVariableName() 367 368 public String getVariableName() 369 { 370 List<?> result = term.match(PAT_VARIABLE); 371 if (result != null) { 372 return (String)result.get(0); 373 } 374 375 throw new RuntimeException("not a variable: " + term); 376 } 377 378 //}}} 379 //{{{ public Expr getVariableValue() 380 381 public Expr getVariableValue() 382 { 383 List<?> result = term.match(PAT_VARIABLE); 384 if (result != null) { 385 return Expr.make((ATerm)result.get(1)); 386 } 387 388 throw new RuntimeException("not a variable: " + term); 389 } 390 391 //}}} 392 393 //{{{ public boolean isVar() 394 395 public boolean isVar() 396 { 397 List<?> result = term.match(PAT_VAR); 398 return result != null; 399 } 400 401 //}}} 402 //{{{ public String getVarName() 403 404 public String getVarName() 405 { 406 List<?> result = term.match(PAT_VAR); 407 if (result != null) { 408 return (String)result.get(0); 409 } 410 411 throw new RuntimeException("not a variable spec: " + term); 412 } 413 414 //}}} 415 //{{{ public Expr getVarValue() 416 417 public Expr getVarValue() 418 { 419 List<?> result = term.match(PAT_VAR); 420 if (result != null) { 421 return Expr.make((ATerm)result.get(1)); 422 } 423 424 throw new RuntimeException("not a variable spec: " + term); 425 } 426 427 //}}} 428 //{{{ public int getVarSourceStart() 429 430 public int getVarSourceStart() 431 { 432 List<?> result = term.match(PAT_VAR); 433 if (result != null) { 434 return ((Integer)result.get(2)).intValue(); 435 } 436 437 throw new RuntimeException("not a variable spec: " + term); 438 } 439 440 //}}} 441 //{{{ public int getVarSourceLineNr() 442 443 public int getVarSourceLineNr() 444 { 445 List<?> result = term.match(PAT_VAR); 446 if (result != null) { 447 return ((Integer)result.get(3)).intValue(); 448 } 449 450 throw new RuntimeException("not a variable spec: " + term); 451 } 452 453 //}}} 454 //{{{ public int getVarSourceStartColumn() 455 456 public int getVarSourceStartColumn() 457 { 458 List<?> result = term.match(PAT_VAR); 459 if (result != null) { 460 return ((Integer)result.get(4)).intValue(); 461 } 462 463 throw new RuntimeException("not a variable spec: " + term); 464 } 465 466 //}}} 467 //{{{ public int getVarSourceLength() 468 469 public int getVarSourceLength() 470 { 471 List<?> result = term.match(PAT_VAR); 472 if (result != null) { 473 return ((Integer)result.get(5)).intValue(); 474 } 475 476 throw new RuntimeException("not a variable spec: " + term); 477 } 478 479 //}}} 480 481 //{{{ public boolean isVarUnknown() 482 483 public boolean isVarUnknown() 484 { 485 List<?> result = term.match(PAT_VAR_UNKNOWN); 486 return result != null; 487 } 488 489 //}}} 490 //{{{ public String getVarUnknownMessage() 491 492 public String getVarUnknownMessage() 493 { 494 List<?> result = term.match(PAT_VAR_UNKNOWN); 495 if (result != null) { 496 return (String)result.get(0); 497 } 498 throw new RuntimeException("not a var-unknown spec: " + term); 499 } 500 501 //}}} 502 503 //{{{ public boolean isBreak() 504 505 public boolean isBreak() 506 { 507 return term.isEqual(factory.parse("break")); 508 } 509 510 //}}} 511 512 //{{{ public boolean isSourcePath() 513 514 public boolean isSourcePath() 515 { 516 List<?> result = term.match(PAT_SOURCE_PATH); 517 return result != null; 518 } 519 520 //}}} 521 //{{{ public String getSourcePath() 522 523 public String getSourcePath() 524 { 525 List<?> result = term.match(PAT_SOURCE_PATH); 526 if (result != null) { 527 return (String)result.get(0); 528 } 529 530 throw new RuntimeException("not a source path: " + term); 531 } 532 533 //}}} 534 535 //{{{ public boolean isSourceList() 536 537 public boolean isSourceList() 538 { 539 List<?> result = term.match(PAT_SOURCE_LIST); 540 return result != null; 541 } 542 543 //}}} 544 //{{{ public Iterator sourceIterator() 545 546 public Iterator<String> sourceIterator() 547 { 548 List<?> result = term.match(PAT_SOURCE_LIST); 549 if (result != null) { 550 return new StringIterator((ATermList)result.get(0)); 551 } 552 553 throw new RuntimeException("not a source-list: " + term); 554 } 555 556 //}}} 557 558 //{{{ public boolean isStackTrace() 559 560 public boolean isStackTrace() 561 { 562 return term.match(PAT_STACK_TRACE) != null; 563 } 564 565 //}}} 566 //{{{ public Iterator frameIterator() 567 568 public Iterator<Expr> frameIterator() 569 { 570 List<?> result = term.match(PAT_STACK_TRACE); 571 if (result != null) { 572 return new ExprIterator((ATermList)result.get(0)); 573 } 574 575 throw new RuntimeException("not a stacktrace: " + term); 576 } 577 578 //}}} 579 //{{{ public boolean isStackFrame() 580 581 public boolean isStackFrame() 582 { 583 return term.match(PAT_STACK_FRAME) != null; 584 } 585 586 //}}} 587 //{{{ public int getFrameDepth() 588 589 public int getFrameDepth() 590 { 591 List<?> result = term.match(PAT_STACK_FRAME); 592 if (result != null) { 593 return ((Integer)result.get(0)).intValue(); 594 } 595 throw new RuntimeException("not a stackframe: " + term); 596 } 597 598 //}}} 599 //{{{ public String getFrameName() 600 601 public String getFrameName() 602 { 603 List<?> result = term.match(PAT_STACK_FRAME); 604 if (result != null) { 605 return (String)result.get(1); 606 } 607 throw new RuntimeException("not a stackframe: " + term); 608 } 609 610 //}}} 611 //{{{ public Expr getFrameLocation() 612 613 public Expr getFrameLocation() 614 { 615 List<?> result = term.match(PAT_STACK_FRAME); 616 if (result != null) { 617 return new Expr((ATerm)result.get(2)); 618 } 619 throw new RuntimeException("not a stackframe: " + term); 620 } 621 622 //}}} 623 //{{{ public Expr getFrameVariables() 624 625 public Expr getFrameVariables() 626 { 627 List<?> result = term.match(PAT_STACK_FRAME); 628 if (result != null) { 629 return new Expr((ATerm)result.get(3)); 630 } 631 throw new RuntimeException("not a stackframe: " + term); 632 } 633 634 //}}} 635 636 //{{{ public Iterator iterator() 637 638 public Iterator<Expr> iterator() 639 { 640 return new ExprIterator(term); 641 } 642 643 //}}} 644 645 //{{{ public ATerm toTerm() 646 647 public ATerm toTerm() 648 { 649 return term; 650 } 651 652 //}}} 653 //{{{ public String toString() 654 655 public String toString() 656 { 657 if (isVariable()) { 658 return getVariableName() + " = " + getVariableValue(); 659 } else if (isLocation() && !isLocationUnknown()) { 660 return getLocationShortFile() + " " 661 + getLocationStartLine() + "," + getLocationStartColumn() 662 + "-" 663 + getLocationEndLine() + "," + getLocationEndColumn(); 664 } 665 666 return term.toString(); 667 } 668 669 //}}} 670 } 671 672 class ExprIterator 673 implements Iterator<Expr> 674 { 675 private ATerm term; 676 677 //{{{ public ExprIterator(ATerm term) 678 679 public ExprIterator(ATerm term) 680 { 681 this.term = term; 682 } 683 684 //}}} 685 686 //{{{ public boolean hasNext() 687 688 public boolean hasNext() 689 { 690 if (term == null || (term.getType() == ATerm.LIST && 691 ((ATermList)term).isEmpty())) { 692 return false; 693 } 694 695 return true; 696 } 697 698 //}}} 699 //{{{ public Object next() 700 701 public Expr next() 702 { 703 ATerm result; 704 705 if (term.getType() == ATerm.LIST) { 706 result = ((ATermList)term).getFirst(); 707 term = ((ATermList)term).getNext(); 708 } else { 709 result = term; 710 term = null; 711 } 712 713 return new Expr(result); 714 } 715 716 //}}} 717 //{{{ public void remove() 718 719 public void remove() 720 { 721 throw new UnsupportedOperationException(); 722 } 723 724 //}}} 725 } 726 727 class StringIterator 728 implements Iterator<String> 729 { 730 private ATermList list; 731 732 //{{{ public StringIterator(ATermList list) 733 734 public StringIterator(ATermList list) 735 { 736 this.list = list; 737 } 738 739 //}}} 740 //{{{ public boolean hasNext() 741 742 public boolean hasNext() 743 { 744 if (list.isEmpty()) { 745 return false; 746 } 747 748 return true; 749 } 750 751 //}}} 752 //{{{ public Object next() 753 754 public String next() 755 { 756 ATerm result; 757 758 result = list.getFirst(); 759 list = list.getNext(); 760 761 return ((ATermAppl)result).getAFun().getName(); 762 } 763 764 //}}} 765 //{{{ public void remove() 766 767 public void remove() 768 { 769 throw new UnsupportedOperationException(); 770 } 771 772 //}}} 773 } 774