1 package kawa.lang; 2 import gnu.mapping.*; 3 import gnu.expr.*; 4 import gnu.kawa.reflect.*; 5 import gnu.bytecode.Type; 6 import gnu.bytecode.ClassType; 7 import gnu.text.SourceMessages; 8 import gnu.lists.*; 9 import gnu.kawa.lispexpr.*; 10 import java.util.*; 11 import gnu.kawa.functions.GetNamedPart; 12 import gnu.text.SourceLocator; 13 14 21 22 public class Translator extends Compilation 23 { 24 private Environment env; 26 27 29 public Macro currentMacroDefinition; 30 31 33 public PatternScope patternScope; 34 35 public Declaration templateScopeDecl; 36 37 39 public Declaration matchArray; 40 41 42 Stack renamedAliasStack; 43 44 public Stack formStack = new Stack(); 45 public int firstForm; 46 public Object pendingForm; 47 48 public LambdaExp curMethodLambda; 49 50 51 public boolean isLexical (Declaration decl) 52 { 53 if (decl == null) 54 return false; 55 if (! decl.isFluid()) 56 return true; 57 ScopeExp scope = currentScope(); 58 ScopeExp context = decl.getContext(); 59 for (;; scope = scope.outer) 60 { 61 if (scope == null) 62 return false; 63 if (scope == context) 64 return true; 65 if (scope instanceof LambdaExp 66 && ! ((LambdaExp) scope).getInlineOnly()) 67 return false; 68 } 69 } 70 71 private static Expression errorExp = new ErrorExp ("unknown syntax error"); 72 73 public Translator (Language language, SourceMessages messages) 74 { 75 super(language, messages); 76 this.env = Environment.getCurrent(); 77 } 78 79 public final Environment getGlobalEnvironment() { return env; } 80 81 public Expression parse (Object input) 82 { 83 return rewrite(input); 84 } 85 86 public final Expression rewrite_car (Pair pair, SyntaxForm syntax) 87 { 88 if (syntax == null || syntax.scope == current_scope 89 || pair.car instanceof SyntaxForm) 90 return rewrite_car(pair, false); 91 ScopeExp save_scope = current_scope; 92 try 93 { 94 setCurrentScope(syntax.scope); 95 return rewrite_car(pair, false); 96 } 97 finally 98 { 99 setCurrentScope(save_scope); 100 } 101 } 102 103 public final Expression rewrite_car (Pair pair, boolean function) 104 { 105 Object car = pair.car; 106 if (pair instanceof PairWithPosition) 107 return rewrite_with_position (car, function, (PairWithPosition) pair); 108 else 109 return rewrite (car, function); 110 } 111 112 Syntax currentSyntax; 113 public Syntax getCurrentSyntax() { return currentSyntax; } 114 115 119 Declaration macroContext; 120 121 127 Expression apply_rewrite (Syntax syntax, Pair form) 128 { 129 Expression exp = errorExp; 130 Syntax saveSyntax = currentSyntax; 131 currentSyntax = syntax; 132 try 133 { 134 exp = syntax.rewriteForm(form, this); 135 } 136 finally 137 { 138 currentSyntax = saveSyntax; 139 } 140 return exp; 141 } 142 143 146 static ReferenceExp getOriginalRef(Declaration decl) 147 { 148 if (decl != null && decl.isAlias() && ! decl.isIndirectBinding()) 149 { 150 Expression value = decl.getValue(); 151 if (value instanceof ReferenceExp) 152 return (ReferenceExp) value; 153 } 154 return null; 155 } 156 157 final boolean selfEvaluatingSymbol (Object obj) 158 { 159 return ((LispLanguage) getLanguage()).selfEvaluatingSymbol(obj); 160 } 161 162 163 public final boolean matches(Object form, String literal) 164 { 165 return matches(form, null, literal); 166 } 167 168 public boolean matches(Object form, SyntaxForm syntax, String literal) 169 { 170 if (syntax != null) 171 { 172 } 174 if (form instanceof SyntaxForm) 175 { 176 return literal == ((SyntaxForm) form).form; 178 } 179 if (form instanceof Symbol && ! selfEvaluatingSymbol(form)) 180 { 181 ReferenceExp rexp = getOriginalRef(lexical.lookup(form, -1)); 182 if (rexp != null) 183 form = rexp.getSymbol(); 184 } 185 return form == literal; 186 } 187 188 public Declaration lookup(Object name, int namespace) 189 { 190 Declaration decl = lexical.lookup(name, namespace); 191 if (decl != null && getLanguage().hasNamespace(decl, namespace)) 192 return decl; 193 return currentModule().lookup(name, getLanguage(), namespace); 194 } 195 196 197 public Declaration lookupGlobal(Object name) 198 { 199 return lookupGlobal(name, -1); 200 } 201 202 203 public Declaration lookupGlobal(Object name, int namespace) 204 { 205 ModuleExp module = currentModule(); 206 Declaration decl = module.lookup(name, getLanguage(), namespace); 207 if (decl == null) 208 { 209 decl = module.getNoDefine(name); 210 decl.setIndirectBinding(true); 211 } 212 return decl; 213 } 214 215 220 Syntax check_if_Syntax (Declaration decl) 221 { 222 Declaration d = Declaration.followAliases(decl); 223 224 Expression dval = d.getValue(); 225 if (dval != null && d.getFlag(Declaration.IS_SYNTAX)) 226 { 227 try 228 { 229 if (decl.getValue() instanceof ReferenceExp) 230 { 231 Declaration context 232 = ((ReferenceExp) decl.getValue()).contextDecl(); 233 if (context != null) 234 macroContext = context; 235 else if (current_scope instanceof TemplateScope) 236 macroContext = ((TemplateScope) current_scope).macroContext; 237 } 238 else if (current_scope instanceof TemplateScope) 239 macroContext = ((TemplateScope) current_scope).macroContext; 240 Object obj = dval.eval(env); 241 return obj instanceof Syntax ? (Syntax) obj : null; 242 } 243 catch (Throwable ex) 244 { 245 ex.printStackTrace(); 246 error('e', "unable to evaluate macro for "+decl.getSymbol()); 247 } 248 } 249 return null; 250 } 251 252 public Expression rewrite_pair (Pair p, boolean function) 253 { 254 if (p.car instanceof Syntax) 255 return apply_rewrite((Syntax) p.car, p); 256 Object cdr = p.cdr; 257 258 Expression func = rewrite_car (p, true); 259 Object proc = null; 260 ReferenceExp ref = null; 261 if (func instanceof ReferenceExp) 262 { 263 ref = (ReferenceExp) func; 264 Declaration decl = ref.getBinding(); 265 if (decl == null) 266 { 267 Object sym = ref.getSymbol(); 268 Symbol symbol; 269 String name; 270 if (sym instanceof Symbol && ! selfEvaluatingSymbol(sym)) 271 { 272 symbol = (Symbol) sym; 273 name = symbol.getName(); 274 } 275 else 276 { 277 name = sym.toString(); 278 symbol = env.getSymbol(name); 279 } 280 proc = env.get(symbol, 281 getLanguage().hasSeparateFunctionNamespace() 282 ? EnvironmentKey.FUNCTION 283 : null, 284 null); 285 if (proc instanceof Syntax) 286 return apply_rewrite ((Syntax) proc, p); 287 if (proc instanceof AutoloadProcedure) 288 { 289 try 290 { 291 proc = ((AutoloadProcedure) proc).getLoaded(); 292 } 293 catch (RuntimeException ex) 294 { 295 proc = null; 296 } 297 } 298 } 299 else 300 { 301 Declaration saveContext = macroContext; 302 Syntax syntax = check_if_Syntax (decl); 303 if (syntax != null) 304 { 305 Expression e = apply_rewrite (syntax, p); 306 macroContext = saveContext; 307 return e; 308 } 309 } 310 311 ref.setProcedureName(true); 312 if (getLanguage().hasSeparateFunctionNamespace()) 313 func.setFlag(ReferenceExp.PREFER_BINDING2); 314 } 315 316 int cdr_length = listLength(cdr); 317 318 if (cdr_length == -1) 319 return syntaxError("circular list is not allowed after "+p.car); 320 if (cdr_length < 0) 321 return syntaxError("dotted list ["+cdr+"] is not allowed after "+p.car); 322 323 boolean mapKeywordsToAttributes = false; 324 Stack vec = new Stack(); 325 326 ScopeExp save_scope = current_scope; 327 for (int i = 0; i < cdr_length;) 328 { 329 if (cdr instanceof SyntaxForm) 330 { 331 SyntaxForm sf = (SyntaxForm) cdr; 332 cdr = sf.form; 333 setCurrentScope(sf.scope); 334 } 335 Pair cdr_pair = (Pair) cdr; 336 Expression arg = rewrite_car (cdr_pair, false); 337 i++; 338 339 if (mapKeywordsToAttributes) 340 { 341 if ((i & 1) == 0) { 343 Expression[] aargs = new Expression[2]; 344 aargs[0] = (Expression) vec.pop(); 345 aargs[1] = arg; 346 arg = new ApplyExp(gnu.kawa.xml.MakeAttribute.makeAttribute, aargs); 347 } 348 else 349 { 350 Object value; 351 if (arg instanceof QuoteExp 352 && (value = ((QuoteExp) arg).getValue()) instanceof Keyword 353 && i < cdr_length) 354 arg = new QuoteExp(((Keyword) value).asSymbol()); 355 else 356 mapKeywordsToAttributes = false; 357 } 358 } 359 360 vec.addElement(arg); 361 cdr = cdr_pair.cdr; 362 } 363 Expression[] args = new Expression[vec.size()]; 364 vec.copyInto(args); 365 366 if (save_scope != current_scope) 367 setCurrentScope(save_scope); 368 369 return ((LispLanguage) getLanguage()).makeApply(func, args); 370 } 371 372 public Symbol namespaceResolve (Expression context, Expression member) 373 { 374 if (context instanceof ReferenceExp && member instanceof QuoteExp) 375 { 376 ReferenceExp rexp = (ReferenceExp) context; 377 Declaration decl = rexp.getBinding(); 378 Object val; 379 if (decl == null || decl.getFlag(Declaration.IS_UNKNOWN)) 380 { 381 Object rsym = rexp.getSymbol(); 382 Symbol sym = rsym instanceof Symbol ? (Symbol) rsym 383 : env.getSymbol(rsym.toString()); 384 val = env.get(sym, null); 385 } 386 else if (decl.isNamespaceDecl()) 387 { 388 val = decl.getConstantValue(); 389 } 390 else 391 val = null; 392 if (val instanceof Namespace) 393 { 394 Namespace ns = (Namespace) val; 395 String uri = ns.getName(); 396 if (uri != null && uri.startsWith("class:")) 397 return null; 398 String mem = ((QuoteExp) member).getValue().toString().intern(); 399 return ns.getSymbol(mem); 400 } 401 } 402 return null; 403 } 404 405 public static Object stripSyntax (Object obj) 406 { 407 while (obj instanceof SyntaxForm) 408 obj = ((SyntaxForm) obj).form; 409 return obj; 410 } 411 412 public static Object safeCar (Object obj) 413 { 414 while (obj instanceof SyntaxForm) 415 obj = ((SyntaxForm) obj).form; 416 if (! (obj instanceof Pair)) 417 return null; 418 return stripSyntax(((Pair) obj).car); 419 } 420 421 public static Object safeCdr (Object obj) 422 { 423 while (obj instanceof SyntaxForm) 424 obj = ((SyntaxForm) obj).form; 425 if (! (obj instanceof Pair)) 426 return null; 427 return stripSyntax(((Pair) obj).cdr); 428 } 429 430 435 public static int listLength(Object obj) 436 { 437 int n = 0; 440 Object slow = obj; 441 Object fast = obj; 442 for (;;) 443 { 444 while (fast instanceof SyntaxForm) 446 fast = ((SyntaxForm) fast).form; 447 while (slow instanceof SyntaxForm) 448 slow = ((SyntaxForm) slow).form; 449 if (fast == LList.Empty) 450 return n; 451 if (! (fast instanceof Pair)) 452 return -1-n; 453 n++; 454 Object next = ((Pair) fast).cdr; 455 while (next instanceof SyntaxForm) 456 next = ((SyntaxForm) next).form; 457 if (next == LList.Empty) 458 return n; 459 if (! (next instanceof Pair)) 460 return -1-n; 461 slow = ((Pair)slow).cdr; 462 fast = ((Pair)next).cdr; 463 n++; 464 if (fast == slow) 465 return Integer.MIN_VALUE; 466 } 467 } 468 469 public void rewriteInBody (Object exp) 470 { 471 if (exp instanceof SyntaxForm) 472 { 473 SyntaxForm sf = (SyntaxForm) exp; 474 ScopeExp save_scope = current_scope; 475 try 476 { 477 setCurrentScope(sf.scope); 478 rewriteInBody(sf.form); 479 } 480 finally 481 { 482 setCurrentScope(save_scope); 483 } 484 } 485 else if (exp instanceof Values) 486 { 487 Object [] vals = ((Values) exp).getValues(); 488 for (int i = 0; i < vals.length; i++) 489 rewriteInBody(vals[i]); 490 } 491 else 492 formStack.add(rewrite(exp, false)); 493 } 494 495 498 public Expression rewrite (Object exp) 499 { 500 return rewrite(exp, false); 501 } 502 503 public Object namespaceResolve (Object name) 504 { 505 if (! (name instanceof String )) 506 { 507 Pair p; 508 if (name instanceof Pair 509 && safeCar(p = (Pair) name) == LispLanguage.lookup_sym 510 && p.cdr instanceof Pair 511 && (p = (Pair) p.cdr).cdr instanceof Pair) 512 { 513 Expression part1 = rewrite(p.car); 514 Expression part2 = rewrite(((Pair) p.cdr).car); 515 516 Symbol sym = namespaceResolve(part1, part2); 517 if (sym != null) 518 return sym; 519 String combinedName = GetNamedPart.combineName(part1, part2); 520 if (combinedName != null) 521 return combinedName; 522 } 523 } 524 return name; 525 } 526 527 public void setCurrentScope (ScopeExp scope) 528 { 529 super.setCurrentScope(scope); 530 while (scope != null && ! (scope instanceof PatternScope)) 531 scope = scope.outer; 532 patternScope = (PatternScope) scope; 533 } 534 535 538 public Expression rewrite (Object exp, boolean function) 539 { 540 if (exp instanceof SyntaxForm) 541 { 542 SyntaxForm sf = (SyntaxForm) exp; 543 ScopeExp save_scope = current_scope; 544 try 545 { 546 setCurrentScope(sf.scope); 547 Expression s = rewrite(sf.form, function); 548 return s; 549 } 550 finally 551 { 552 setCurrentScope(save_scope); 553 } 554 } 555 if (exp instanceof PairWithPosition) 556 return rewrite_with_position (exp, function, (PairWithPosition) exp); 557 else if (exp instanceof Pair) 558 return rewrite_pair((Pair) exp, function); 559 else if (exp instanceof String 560 || (exp instanceof Symbol && ! selfEvaluatingSymbol(exp))) 561 { 562 Declaration decl = lexical.lookup(exp, function); 563 Declaration cdecl = null; 564 565 ScopeExp scope = current_scope; 569 int decl_nesting = decl == null ? -1 : ScopeExp.nesting(decl.context); 570 String dname; 571 if (exp instanceof String 572 || (exp instanceof Symbol && ((Symbol) exp).hasEmptyNamespace())) 573 dname = exp.toString(); 574 else 575 { 576 dname = null; 577 scope = null; 578 } 579 for (;scope != null; scope = scope.outer) 580 { 581 if (scope instanceof LambdaExp 582 && scope.outer instanceof ClassExp && ((LambdaExp) scope).isClassMethod()) 584 { 585 if (decl_nesting >= ScopeExp.nesting(scope.outer)) 586 break; 587 LambdaExp caller = (LambdaExp) scope; 588 ClassExp cexp = (ClassExp) scope.outer; 589 ClassType ctype = (ClassType) cexp.getType(); 590 Object part = SlotGet.lookupMember(ctype, dname, ctype); 591 boolean contextStatic 592 = (caller == cexp.clinitMethod 593 || (caller != cexp.initMethod 594 && caller.nameDecl.isStatic())); 595 if (part == null) 596 { 597 char mode = contextStatic ? 'S' : 'V'; 598 PrimProcedure[] methods 599 = ClassMethods.getMethods(ctype, dname, 600 mode, ctype, language); 601 if (methods.length == 0) 602 continue; 603 } 604 Expression part1; 605 if (contextStatic) 607 part1 = new ReferenceExp(((ClassExp) caller.outer).nameDecl); 608 else 609 part1 = new ThisExp(caller.firstDecl()); 610 return GetNamedPart.makeExp(part1, 611 QuoteExp.getInstance(dname)); 612 } 613 } 614 615 Object nameToLookup; 616 Symbol symbol = null; 617 if (decl != null) 618 { 619 nameToLookup = decl.getSymbol(); 620 exp = null; 621 ReferenceExp rexp = getOriginalRef(decl); 622 if (rexp != null) 623 { 624 decl = rexp.getBinding(); 625 if (decl == null) 626 { 627 exp = rexp.getSymbol(); 628 nameToLookup = exp; 629 } 630 } 631 } 632 else 633 { 634 nameToLookup = exp; 635 } 636 symbol = exp instanceof String ? env.getSymbol((String ) exp) 637 : (Symbol) exp; 638 boolean separate = getLanguage().hasSeparateFunctionNamespace(); 639 if (decl != null) 640 { 641 if (! isLexical(decl) 642 || (separate && decl.isProcedureDecl())) 643 decl = null; 644 else if (current_scope instanceof TemplateScope && decl.needsContext()) 645 cdecl = ((TemplateScope) current_scope).macroContext; 646 else if (decl.getFlag(Declaration.FIELD_OR_METHOD) 647 && ! decl.isStatic()) 648 { 649 scope = currentScope(); 650 for (;;) 651 { 652 if (scope == null) 653 throw new Error ("internal error: missing "+decl); 654 if (scope.outer == decl.context) break; 656 scope = scope.outer; 657 } 658 cdecl = scope.firstDecl(); 659 } 660 } 661 else 662 { 663 Location loc 664 = env.lookup(symbol, 665 function && separate ? EnvironmentKey.FUNCTION 666 : null); 667 if (loc != null) 668 loc = loc.getBase(); 669 if (loc instanceof FieldLocation) 670 { 671 FieldLocation floc = (FieldLocation) loc; 672 try 673 { 674 decl = floc.getDeclaration(); 675 if (! inlineOk(null) 676 && decl != kawa.standard.Scheme.getNamedPartDecl) 679 decl = null; 680 if (decl != null && ! decl.isStatic()) 681 { 682 cdecl = new Declaration("(module-instance)"); 683 cdecl.setValue(new QuoteExp(floc.getInstance())); 684 } 685 } 686 catch (Throwable ex) 687 { 688 error('e', 689 "exception loading '" + exp 690 + "' - " + ex.getMessage()); 691 decl = null; 692 } 693 } 694 703 } 704 if (decl != null && decl.getContext() instanceof PatternScope) 705 return syntaxError("reference to pattern variable "+decl.getName()+" outside syntax template"); 706 707 ReferenceExp rexp = new ReferenceExp (nameToLookup, decl); 708 rexp.setContextDecl(cdecl); 709 rexp.setLine(this); 710 if (function && separate) 711 rexp.setFlag(ReferenceExp.PREFER_BINDING2); 712 return rexp; 713 } 714 else if (exp instanceof LangExp) 715 return rewrite(((LangExp) exp).getLangValue(), function); 716 else if (exp instanceof Expression) 717 return (Expression) exp; 718 else 719 return QuoteExp.getInstance(Quote.quote(exp, this)); 720 } 721 722 public static void setLine(Expression exp, Object location) 723 { 724 if (location instanceof SourceLocator) 725 exp.setLocation((SourceLocator) location); 726 } 727 728 public static void setLine(Declaration decl, Object location) 729 { 730 if (location instanceof SourceLocator) 731 decl.setLocation((SourceLocator) location); 732 } 733 734 PairWithPosition positionPair; 735 736 739 public Object pushPositionOf(Object pair) 740 { 741 if (pair instanceof SyntaxForm) 742 pair = ((SyntaxForm) pair).form; 743 if (! (pair instanceof PairWithPosition)) 744 return null; 745 PairWithPosition ppair = (PairWithPosition) pair; 746 Object saved; 747 if (positionPair == null 748 || positionPair.getFileName() != getFileName() 749 || positionPair.getLineNumber() != getLineNumber() 750 || positionPair.getColumnNumber() != getColumnNumber()) 751 { 752 saved = new PairWithPosition(this, Special.eof, positionPair); 753 } 754 else 755 saved = positionPair; 756 setLine(pair); 757 positionPair = ppair; 758 return saved; 759 } 760 761 764 public void popPositionOf(Object saved) 765 { 766 if (saved == null) 767 return; 768 setLine(saved); 769 positionPair = (PairWithPosition) saved; 770 if (positionPair.car == Special.eof) 771 positionPair = (PairWithPosition) positionPair.cdr; 772 } 773 774 775 public void setLine (Object location) 776 { 777 if (location instanceof SourceLocator) 778 setLocation((SourceLocator) location); 779 } 780 781 782 783 public void setLineOf (Expression exp) 784 { 785 if (exp instanceof QuoteExp) 786 return; 787 exp.setLocation(this); 788 } 789 790 791 public Type exp2Type(Pair typeSpecPair) 792 { 793 Object saved = pushPositionOf(typeSpecPair); 794 try 795 { 796 Expression texp = rewrite_car(typeSpecPair, false); 797 texp = new InlineCalls(this).walk(texp); 798 if (texp instanceof ErrorExp) 799 return null; 800 texp = new InlineCalls(this).walk(texp); 801 Type type = getLanguage().getTypeFor(texp); 802 if (type == null) 803 { 804 if (texp instanceof ReferenceExp) 805 error('e', "unknown type name '" 806 + ((ReferenceExp) texp).getName() + '\''); 807 else 808 error('e', 809 "invalid type spec (must be \"type\" or 'type or <type>)"); 810 return Type.pointer_type; 811 } 812 return type; 813 } 814 finally 815 { 816 popPositionOf(saved); 817 } 818 } 819 820 public Expression rewrite_with_position (Object exp, boolean function, 821 PairWithPosition pair) 822 { 823 Object saved = pushPositionOf(pair); 824 Expression result; 825 try 826 { 827 if (exp == pair) 828 result = rewrite_pair(pair, function); else 830 result = rewrite (exp, function); 831 setLineOf(result); 832 } 833 finally 834 { 835 popPositionOf(saved); 836 } 837 return result; 838 } 839 840 public static Object wrapSyntax (Object form, SyntaxForm syntax) 841 { 842 if (syntax == null || form instanceof Expression) 843 return form; 844 else 845 return syntax.fromDatumIfNeeded(form); 846 } 847 848 public Object popForms (int first) 849 { 850 int last = formStack.size(); 851 if (last == first) 852 return Values.empty; 853 Object r; 854 if (last == first + 1) 855 r = formStack.elementAt(first); 856 else 857 { 858 Values vals = new Values(); 859 for (int i = first; i < last; i++) 860 vals.writeObject(formStack.elementAt(i)); 861 r = vals; 862 } 863 formStack.setSize(first); 864 return r; 865 } 866 867 public void scanForm (Object st, ScopeExp defs) 868 { 869 if (st instanceof SyntaxForm) 870 { 871 SyntaxForm sf = (SyntaxForm) st; 872 ScopeExp save_scope = currentScope(); 873 try 874 { 875 setCurrentScope(sf.scope); 876 int first = formStack.size(); 877 scanForm(sf.form, defs); 878 formStack.add(wrapSyntax(popForms(first), sf)); 879 return; 880 } 881 finally 882 { 883 setCurrentScope(save_scope); 884 } 885 } 886 if (st instanceof Values) 887 { 888 if (st == Values.empty) 889 st = QuoteExp.voidExp; else 891 { 892 Object [] vals = ((Values) st).getValues(); 893 for (int i = 0; i < vals.length; i++) 894 scanForm(vals[i], defs); 895 return; 896 } 897 } 898 if (st instanceof Pair) 899 { 900 Pair st_pair = (Pair) st; 901 Declaration saveContext = macroContext; 902 Syntax syntax = null; 903 ScopeExp save_scope = current_scope; 904 try 905 { 906 Object obj = st_pair.car; 907 if (obj instanceof SyntaxForm) 908 { 909 SyntaxForm sf = (SyntaxForm) st_pair.car; 910 setCurrentScope(sf.scope); 911 obj = sf.form; 912 } 913 Pair p; 914 if (obj instanceof Pair 915 && (p = (Pair) obj).car == LispLanguage.lookup_sym 916 && p.cdr instanceof Pair 917 && (p = (Pair) p.cdr).cdr instanceof Pair) 918 { 919 Expression part1 = rewrite(p.car); 920 Expression part2 = rewrite(((Pair) p.cdr).car); 921 obj = namespaceResolve(part1, part2); 922 } 923 if (obj instanceof String 924 || (obj instanceof Symbol && ! selfEvaluatingSymbol(obj))) 925 { 926 Expression func = rewrite(obj, true); 927 if (func instanceof ReferenceExp) 928 { 929 Declaration decl = ((ReferenceExp) func).getBinding(); 930 if (decl != null) 931 syntax = check_if_Syntax(decl); 932 else 933 { 934 obj = resolve(obj, true); 935 if (obj instanceof Syntax) 936 syntax = (Syntax) obj; 937 } 938 } 939 } 940 else if (obj == kawa.standard.begin.begin) 944 syntax = (Syntax) obj; 945 } 946 finally 947 { 948 if (save_scope != current_scope) 949 setCurrentScope(save_scope); 950 } 951 if (syntax != null) 952 { 953 String save_filename = getFileName(); 954 int save_line = getLineNumber(); 955 int save_column = getColumnNumber(); 956 try 957 { 958 setLine(st_pair); 959 syntax.scanForm(st_pair, defs, this); 960 return; 961 } 962 finally 963 { 964 macroContext = saveContext; 965 setLine(save_filename, save_line, save_column); 966 } 967 } 968 } 969 formStack.add(st); 970 } 971 972 980 981 public Object scanBody (Object body, ScopeExp defs, boolean makeList) 982 { 983 Object list = makeList ? LList.Empty : null; 984 Pair lastPair = null; 985 while (body != LList.Empty) 986 { 987 if (body instanceof SyntaxForm) 988 { 989 SyntaxForm sf = (SyntaxForm) body; 990 ScopeExp save_scope = current_scope; 991 try 992 { 993 setCurrentScope(sf.scope); 994 int first = formStack.size(); 995 Object f = scanBody(sf.form, defs, makeList); 996 if (makeList) 997 { 998 f = wrapSyntax(f, sf); 999 if (lastPair == null) 1000 return f; 1001 lastPair.cdr = f; 1002 return list; 1003 } 1004 formStack.add(wrapSyntax(popForms(first), sf)); 1005 return null; 1006 } 1007 finally 1008 { 1009 setCurrentScope(save_scope); 1010 } 1011 } 1012 else if (body instanceof Pair) 1013 { 1014 Pair pair = (Pair) body; 1015 int first = formStack.size(); 1016 scanForm(pair.car, defs); 1017 if (getState() == Compilation.PROLOG_PARSED) 1018 { 1019 if (pair.car != pendingForm) 1023 pair = makePair(pair, pendingForm, pair.cdr); 1024 pendingForm = new Pair(kawa.standard.begin.begin, pair); 1025 return LList.Empty; 1026 } 1027 int fsize = formStack.size(); 1028 if (makeList) 1029 { 1030 for (int i = first; i < fsize; i++) 1031 { 1032 Pair npair 1033 = makePair(pair, formStack.elementAt(i), LList.Empty); 1034 if (lastPair == null) 1035 list = npair; 1036 else 1037 lastPair.cdr = npair; 1038 lastPair = npair; 1039 } 1040 formStack.setSize(first); 1041 } 1042 body = pair.cdr; 1043 } 1044 else 1045 { 1046 formStack.add(syntaxError ("body is not a proper list")); 1047 break; 1048 } 1049 } 1050 return list; 1051 } 1052 1053 public static Pair makePair(Pair pair, Object car, Object cdr) 1054 { 1055 if (pair instanceof PairWithPosition) 1056 return new PairWithPosition((PairWithPosition) pair, car, cdr); 1057 return new Pair(car, cdr); 1058 } 1059 1060 1063 1064 public Expression rewrite_body (Object exp) 1065 { 1066 Object saved = pushPositionOf(exp); 1069 LetExp defs = new LetExp(null); 1070 int first = formStack.size(); 1071 defs.outer = current_scope; 1072 current_scope = defs; 1073 try 1074 { 1075 scanBody(exp, defs, false); 1076 if (formStack.size() == first) 1077 formStack.add(syntaxError ("body with no expressions")); 1078 int ndecls = defs.countDecls(); 1079 if (ndecls != 0) 1080 { 1081 Expression[] inits = new Expression[ndecls]; 1082 for (int i = ndecls; --i >= 0; ) 1083 inits[i] = QuoteExp.undefined_exp; 1084 defs.inits = inits; 1085 } 1086 Expression body = makeBody(first, null); 1087 setLineOf(body); 1088 if (ndecls == 0) 1089 return body; 1090 defs.body = body; 1091 setLineOf(defs); 1092 return defs; 1093 } 1094 finally 1095 { 1096 pop(defs); 1097 popPositionOf(saved); 1098 } 1099 } 1100 1101 1102 public void rewriteBody (int first) 1103 { 1104 int nforms = formStack.size() - first; 1105 if (nforms == 0) 1106 return; 1107 else if (nforms == 1) 1108 { 1109 Object f = formStack.pop(); 1110 rewriteInBody(f); 1111 } 1112 else 1113 { 1114 Object [] forms = new Object [nforms]; 1115 for (int i = 0; i < nforms; i++) 1116 forms[i] = formStack.elementAt(first + i); 1117 formStack.setSize(first); 1118 for (int i = 0; i < nforms; i++) 1119 rewriteInBody(forms[i]); 1120 } 1121 } 1122 1123 1124 public Expression makeBody(int first, ScopeExp scope) 1125 { 1126 rewriteBody(first); 1127 int nforms = formStack.size() - first; 1128 if (nforms == 0) 1129 return QuoteExp.voidExp; 1130 else if (nforms == 1) 1131 { 1132 return (Expression) formStack.pop(); 1133 } 1134 else 1135 { 1136 Expression[] exps = new Expression[nforms]; 1137 for (int i = 0; i < nforms; i++) 1138 exps[i] = (Expression) formStack.elementAt(first + i); 1139 formStack.setSize(first); 1140 if (scope instanceof ModuleExp) 1141 return new ApplyExp(gnu.kawa.functions.AppendValues.appendValues, 1142 exps); 1143 else 1144 return ((LispLanguage) getLanguage()).makeBody(exps); 1145 } 1146 } 1147 1148 1149 Vector notedAccess; 1150 1151 1154 public void noteAccess (Object name, ScopeExp scope) 1155 { 1156 if (notedAccess == null) 1157 notedAccess = new Vector(); 1158 notedAccess.addElement(name); 1159 notedAccess.addElement(scope); 1160 } 1161 1162 1166 public void processAccesses () 1167 { 1168 if (notedAccess == null) 1169 return; 1170 int sz = notedAccess.size(); 1171 ScopeExp saveScope = current_scope; 1172 for (int i = 0; i < sz; i += 2) 1173 { 1174 Object name = notedAccess.elementAt(i); 1175 ScopeExp scope = (ScopeExp) notedAccess.elementAt(i+1); 1176 if (current_scope != scope) 1177 setCurrentScope(scope); 1178 Declaration decl = (Declaration) lexical.lookup(name, -1); 1179 if (decl != null && ! decl.getFlag(Declaration.IS_UNKNOWN)) 1180 { 1181 decl.getContext().currentLambda().capture(decl); 1182 decl.setCanRead(true); 1183 decl.setSimple(false); 1184 decl.setFlag(Declaration.EXTERNAL_ACCESS); 1185 } 1186 } 1187 if (current_scope != saveScope) 1188 setCurrentScope(saveScope); 1189 } 1190 1191 public void finishModule(ModuleExp mexp) 1192 { 1193 boolean moduleStatic = mexp.isStatic(); 1194 for (Declaration decl = mexp.firstDecl(); 1195 decl != null; decl = decl.nextDecl()) 1196 { 1197 if (decl.getFlag(Declaration.NOT_DEFINING)) 1198 { 1199 String msg1 = "'"; 1200 String msg2 1201 = (decl.getFlag(Declaration.EXPORT_SPECIFIED) 1202 ? "' exported but never defined" 1203 : decl.getFlag(Declaration.STATIC_SPECIFIED) 1204 ? "' declared static but never defined" 1205 : "' declared but never defined"); 1206 error('e', decl, msg1, msg2); 1207 } 1208 if (mexp.getFlag(ModuleExp.EXPORT_SPECIFIED)) 1209 { 1210 if (decl.getFlag(Declaration.EXPORT_SPECIFIED)) 1211 { 1212 if (decl.isPrivate()) 1213 { 1214 if (decl.getFlag(Declaration.PRIVATE_SPECIFIED)) 1215 error('e', decl, 1216 "'", "' is declared both private and exported"); 1217 decl.setPrivate(false); 1218 } 1219 } 1220 else 1221 decl.setPrivate(true); 1222 } 1223 if (moduleStatic) 1224 decl.setFlag(Declaration.STATIC_SPECIFIED); 1225 else if ((mexp.getFlag(ModuleExp.NONSTATIC_SPECIFIED) 1226 && ! decl.getFlag(Declaration.STATIC_SPECIFIED)) 1227 || gnu.expr.Compilation.moduleStatic < 0 1228 || mexp.getFlag(ModuleExp.SUPERTYPE_SPECIFIED)) 1229 decl.setFlag(Declaration.NONSTATIC_SPECIFIED); 1230 } 1231 if (! moduleStatic) 1232 mexp.declareThis(null); 1233 } 1234 1235 public void resolveModule(ModuleExp mexp) 1236 { 1237 int numPending = pendingImports == null ? 0 : pendingImports.size(); 1238 for (int i = 0; i < numPending; ) 1239 { 1240 ModuleInfo info = (ModuleInfo) pendingImports.elementAt(i++); 1241 ScopeExp defs = (ScopeExp) pendingImports.elementAt(i++); 1242 Expression posExp = (Expression) pendingImports.elementAt(i++); 1243 if (mexp == defs) 1244 { 1245 Expression savePos = new ReferenceExp((Object ) null); 1247 savePos.setLine(this); 1248 setLine(posExp); 1249 kawa.standard.require.importDefinitions(null, info, null, 1250 formStack, defs, this); 1251 setLine(savePos); 1252 pendingImports.setElementAt(null, i-3); 1253 pendingImports.setElementAt(null, i-2); 1254 pendingImports.setElementAt(null, i-1); 1255 } 1256 } 1257 1258 processAccesses(); 1259 1260 setModule(mexp); 1261 Compilation save_comp = Compilation.getCurrent(); 1262 try 1263 { 1264 Compilation.setCurrent(this); 1265 mexp.body = makeBody(firstForm, mexp); 1266 lexical.pop(mexp); 1267 } 1268 finally 1269 { 1270 Compilation.setCurrent(save_comp); 1271 } 1272 1273 1281 } 1282 1283 public Declaration makeRenamedAlias (Declaration decl, 1284 ScopeExp templateScope) 1285 { 1286 if (templateScope == null) 1287 return decl; return makeRenamedAlias(decl.getSymbol(), decl, templateScope); 1289 } 1290 1291 public Declaration makeRenamedAlias (Object name, 1292 Declaration decl, 1293 ScopeExp templateScope) 1294 { 1295 Declaration alias = new Declaration(name); 1296 alias.setAlias(true); 1297 alias.setPrivate(true); 1298 alias.context = templateScope; 1299 ReferenceExp ref = new ReferenceExp(decl); 1300 ref.setDontDereference(true); 1301 alias.noteValue(ref); 1302 return alias; 1303 } 1304 1305 1318 public void pushRenamedAlias (Declaration alias) 1319 { 1320 Declaration decl = getOriginalRef(alias).getBinding(); 1321 ScopeExp templateScope = alias.context; 1322 decl.setSymbol(null); 1323 Declaration old = templateScope.lookup(decl.getSymbol()); 1324 if (old != null) 1325 templateScope.remove(old); 1326 templateScope.addDeclaration(alias); 1327 if (renamedAliasStack == null) 1328 renamedAliasStack = new Stack(); 1329 renamedAliasStack.push(old); 1330 renamedAliasStack.push(alias); 1331 renamedAliasStack.push(templateScope); 1332 } 1333 1334 1335 public void popRenamedAlias (int count) 1336 { 1337 while (--count >= 0) 1338 { 1339 ScopeExp templateScope = (ScopeExp) renamedAliasStack.pop(); 1340 Declaration alias = (Declaration) renamedAliasStack.pop(); 1341 Declaration decl = getOriginalRef(alias).getBinding(); 1342 decl.setSymbol(alias.getSymbol()); 1343 templateScope.remove(alias); 1344 Object old = renamedAliasStack.pop(); 1345 if (old != null) 1346 templateScope.addDeclaration((Declaration) old); 1347 } 1348 } 1349 1350 public Declaration define (Object name, SyntaxForm nameSyntax, ScopeExp defs) 1351 { 1352 boolean aliasNeeded = nameSyntax != null && nameSyntax.scope != currentScope(); 1353 Object declName = aliasNeeded ? new String (name.toString()) : name; 1354 Declaration decl = defs.getDefine(declName, 'w', this); 1355 if (aliasNeeded) 1356 { 1357 Declaration alias = makeRenamedAlias(name, decl, nameSyntax.scope); 1358 nameSyntax.scope.addDeclaration(alias); 1359 } 1360 push(decl); 1361 return decl; 1362 } 1363} 1364 | Popular Tags |