Source Code Cross Referenced for Translator.java in  » Scripting » Kawa » kawa » lang » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » Kawa » kawa.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package kawa.lang;
0002:
0003:        import gnu.mapping.*;
0004:        import gnu.expr.*;
0005:        import gnu.kawa.reflect.*;
0006:        import gnu.bytecode.Type;
0007:        import gnu.bytecode.ClassType;
0008:        import gnu.text.SourceMessages;
0009:        import gnu.lists.*;
0010:        import gnu.kawa.lispexpr.*;
0011:        import java.util.*;
0012:        import gnu.kawa.functions.GetNamedPart;
0013:        import gnu.text.SourceLocator;
0014:
0015:        /** Used to translate from source to Expression.
0016:         * The result has macros expanded, lexical names bound, etc, and is
0017:         * ready for code generation.
0018:         * This is sometimes called a "compilation environment",
0019:         * but we modify it as we go along - there is a single Translator for
0020:         * each top-level form.
0021:         */
0022:
0023:        public class Translator extends Compilation {
0024:            // Global environment used to look for syntax/macros.
0025:            private Environment env;
0026:
0027:            /** Set if we're processing (as opposed to expanding)
0028:             * a <code>define-syntax</code> or <code>defmacro</code>. */
0029:            public Macro currentMacroDefinition;
0030:
0031:            /** Innermost current scope of pattern variable,
0032:             * from a <code>syntax-case</code>. */
0033:            public PatternScope patternScope;
0034:
0035:            public Declaration templateScopeDecl;
0036:
0037:            /** A variable to hold the matched values for syntax-case
0038:             * pattern variables. */
0039:            public Declaration matchArray;
0040:
0041:            /** A stack of aliases pushed by <code>pushRenamedAlias</code>. */
0042:            Stack renamedAliasStack;
0043:
0044:            public Stack formStack = new Stack();
0045:            public int firstForm;
0046:            public Object pendingForm;
0047:
0048:            public LambdaExp curMethodLambda;
0049:
0050:            /** Return true if decl is lexical and not fluid. */
0051:            public boolean isLexical(Declaration decl) {
0052:                if (decl == null)
0053:                    return false;
0054:                if (!decl.isFluid())
0055:                    return true;
0056:                ScopeExp scope = currentScope();
0057:                ScopeExp context = decl.getContext();
0058:                for (;; scope = scope.outer) {
0059:                    if (scope == null)
0060:                        return false;
0061:                    if (scope == context)
0062:                        return true;
0063:                    if (scope instanceof  LambdaExp
0064:                            && !((LambdaExp) scope).getInlineOnly())
0065:                        return false;
0066:                }
0067:            }
0068:
0069:            private static Expression errorExp = new ErrorExp(
0070:                    "unknown syntax error");
0071:
0072:            public Translator(Language language, SourceMessages messages) {
0073:                super (language, messages);
0074:                this .env = Environment.getCurrent();
0075:            }
0076:
0077:            public final Environment getGlobalEnvironment() {
0078:                return env;
0079:            }
0080:
0081:            public Expression parse(Object input) {
0082:                return rewrite(input);
0083:            }
0084:
0085:            public final Expression rewrite_car(Pair pair, SyntaxForm syntax) {
0086:                if (syntax == null || syntax.scope == current_scope
0087:                        || pair.car instanceof  SyntaxForm)
0088:                    return rewrite_car(pair, false);
0089:                ScopeExp save_scope = current_scope;
0090:                try {
0091:                    setCurrentScope(syntax.scope);
0092:                    return rewrite_car(pair, false);
0093:                } finally {
0094:                    setCurrentScope(save_scope);
0095:                }
0096:            }
0097:
0098:            public final Expression rewrite_car(Pair pair, boolean function) {
0099:                Object car = pair.car;
0100:                if (pair instanceof  PairWithPosition)
0101:                    return rewrite_with_position(car, function,
0102:                            (PairWithPosition) pair);
0103:                else
0104:                    return rewrite(car, function);
0105:            }
0106:
0107:            Syntax currentSyntax;
0108:
0109:            public Syntax getCurrentSyntax() {
0110:                return currentSyntax;
0111:            }
0112:
0113:            /**  The module instance containing the current macro.
0114:             * This is only used temporarily, set when resolving a Declaration
0115:             * bound to a macro, and used to set the macroContext field of the
0116:             * TemplateScope created when expanding the macro's template(s). */
0117:            Declaration macroContext;
0118:
0119:            /**
0120:             * Apply a Syntax object.
0121:             * @param syntax the Syntax object whose rewrite method we call
0122:             * @param form the syntax form (including the macro name)
0123:             * @return the re-written form as an Expression object
0124:             */
0125:            Expression apply_rewrite(Syntax syntax, Pair form) {
0126:                Expression exp = errorExp;
0127:                Syntax saveSyntax = currentSyntax;
0128:                currentSyntax = syntax;
0129:                try {
0130:                    exp = syntax.rewriteForm(form, this );
0131:                } finally {
0132:                    currentSyntax = saveSyntax;
0133:                }
0134:                return exp;
0135:            }
0136:
0137:            /** Check if declaraton is an alias for some other name.
0138:             * This is needed to chase identifiers renamed for hygienic macro
0139:             * expansion - see SyntaxRules.expand. */
0140:            static ReferenceExp getOriginalRef(Declaration decl) {
0141:                if (decl != null && decl.isAlias() && !decl.isIndirectBinding()) {
0142:                    Expression value = decl.getValue();
0143:                    if (value instanceof  ReferenceExp)
0144:                        return (ReferenceExp) value;
0145:                }
0146:                return null;
0147:            }
0148:
0149:            final boolean selfEvaluatingSymbol(Object obj) {
0150:                return ((LispLanguage) getLanguage()).selfEvaluatingSymbol(obj);
0151:            }
0152:
0153:            /** True iff a form matches a literal symbol. */
0154:            public final boolean matches(Object form, String literal) {
0155:                return matches(form, null, literal);
0156:            }
0157:
0158:            public boolean matches(Object form, SyntaxForm syntax,
0159:                    String literal) {
0160:                if (syntax != null) {
0161:                    // FIXME
0162:                }
0163:                if (form instanceof  SyntaxForm) {
0164:                    // FIXME
0165:                    return literal == ((SyntaxForm) form).form;
0166:                }
0167:                if (form instanceof  Symbol && !selfEvaluatingSymbol(form)) {
0168:                    ReferenceExp rexp = getOriginalRef(lexical.lookup(form, -1));
0169:                    if (rexp != null)
0170:                        form = rexp.getSymbol();
0171:                }
0172:                return form == literal;
0173:            }
0174:
0175:            public Declaration lookup(Object name, int namespace) {
0176:                Declaration decl = lexical.lookup(name, namespace);
0177:                if (decl != null && getLanguage().hasNamespace(decl, namespace))
0178:                    return decl;
0179:                return currentModule().lookup(name, getLanguage(), namespace);
0180:            }
0181:
0182:            /** Find global Declaration, creating one if not found. */
0183:            public Declaration lookupGlobal(Object name) {
0184:                return lookupGlobal(name, -1);
0185:            }
0186:
0187:            /** Find global Declaration, creating one if not found. */
0188:            public Declaration lookupGlobal(Object name, int namespace) {
0189:                ModuleExp module = currentModule();
0190:                Declaration decl = module
0191:                        .lookup(name, getLanguage(), namespace);
0192:                if (decl == null) {
0193:                    decl = module.getNoDefine(name);
0194:                    decl.setIndirectBinding(true);
0195:                }
0196:                return decl;
0197:            }
0198:
0199:            /** Check if a Declaration is bound to a Syntax.
0200:             * @param decl the Declaration to check
0201:             * @return the Syntax bound to decl, or null.
0202:             * In the former case, macroContext may be set as a side effect.
0203:             */
0204:            Syntax check_if_Syntax(Declaration decl) {
0205:                Declaration d = Declaration.followAliases(decl);
0206:
0207:                Expression dval = d.getValue();
0208:                if (dval != null && d.getFlag(Declaration.IS_SYNTAX)) {
0209:                    try {
0210:                        if (decl.getValue() instanceof  ReferenceExp) {
0211:                            Declaration context = ((ReferenceExp) decl
0212:                                    .getValue()).contextDecl();
0213:                            if (context != null)
0214:                                macroContext = context;
0215:                            else if (current_scope instanceof  TemplateScope)
0216:                                macroContext = ((TemplateScope) current_scope).macroContext;
0217:                        } else if (current_scope instanceof  TemplateScope)
0218:                            macroContext = ((TemplateScope) current_scope).macroContext;
0219:                        Object obj = dval.eval(env);
0220:                        return obj instanceof  Syntax ? (Syntax) obj : null;
0221:                    } catch (Throwable ex) {
0222:                        ex.printStackTrace();
0223:                        error('e', "unable to evaluate macro for "
0224:                                + decl.getSymbol());
0225:                    }
0226:                }
0227:                return null;
0228:            }
0229:
0230:            public Expression rewrite_pair(Pair p, boolean function) {
0231:                if (p.car instanceof  Syntax)
0232:                    return apply_rewrite((Syntax) p.car, p);
0233:                Object cdr = p.cdr;
0234:
0235:                Expression func = rewrite_car(p, true);
0236:                Object proc = null;
0237:                ReferenceExp ref = null;
0238:                if (func instanceof  ReferenceExp) {
0239:                    ref = (ReferenceExp) func;
0240:                    Declaration decl = ref.getBinding();
0241:                    if (decl == null) {
0242:                        Object sym = ref.getSymbol();
0243:                        Symbol symbol;
0244:                        String name;
0245:                        if (sym instanceof  Symbol && !selfEvaluatingSymbol(sym)) {
0246:                            symbol = (Symbol) sym;
0247:                            name = symbol.getName();
0248:                        } else {
0249:                            name = sym.toString();
0250:                            symbol = env.getSymbol(name);
0251:                        }
0252:                        proc = env
0253:                                .get(
0254:                                        symbol,
0255:                                        getLanguage()
0256:                                                .hasSeparateFunctionNamespace() ? EnvironmentKey.FUNCTION
0257:                                                : null, null);
0258:                        if (proc instanceof  Syntax)
0259:                            return apply_rewrite((Syntax) proc, p);
0260:                        if (proc instanceof  AutoloadProcedure) {
0261:                            try {
0262:                                proc = ((AutoloadProcedure) proc).getLoaded();
0263:                            } catch (RuntimeException ex) {
0264:                                proc = null;
0265:                            }
0266:                        }
0267:                    } else {
0268:                        Declaration saveContext = macroContext;
0269:                        Syntax syntax = check_if_Syntax(decl);
0270:                        if (syntax != null) {
0271:                            Expression e = apply_rewrite(syntax, p);
0272:                            macroContext = saveContext;
0273:                            return e;
0274:                        }
0275:                    }
0276:
0277:                    ref.setProcedureName(true);
0278:                    if (getLanguage().hasSeparateFunctionNamespace())
0279:                        func.setFlag(ReferenceExp.PREFER_BINDING2);
0280:                }
0281:
0282:                int cdr_length = listLength(cdr);
0283:
0284:                if (cdr_length == -1)
0285:                    return syntaxError("circular list is not allowed after "
0286:                            + p.car);
0287:                if (cdr_length < 0)
0288:                    return syntaxError("dotted list [" + cdr
0289:                            + "] is not allowed after " + p.car);
0290:
0291:                boolean mapKeywordsToAttributes = false;
0292:                Stack vec = new Stack();
0293:
0294:                ScopeExp save_scope = current_scope;
0295:                for (int i = 0; i < cdr_length;) {
0296:                    if (cdr instanceof  SyntaxForm) {
0297:                        SyntaxForm sf = (SyntaxForm) cdr;
0298:                        cdr = sf.form;
0299:                        setCurrentScope(sf.scope);
0300:                    }
0301:                    Pair cdr_pair = (Pair) cdr;
0302:                    Expression arg = rewrite_car(cdr_pair, false);
0303:                    i++;
0304:
0305:                    if (mapKeywordsToAttributes) {
0306:                        if ((i & 1) == 0) // Previous iteration was a keyword
0307:                        {
0308:                            Expression[] aargs = new Expression[2];
0309:                            aargs[0] = (Expression) vec.pop();
0310:                            aargs[1] = arg;
0311:                            arg = new ApplyExp(
0312:                                    gnu.kawa.xml.MakeAttribute.makeAttribute,
0313:                                    aargs);
0314:                        } else {
0315:                            Object value;
0316:                            if (arg instanceof  QuoteExp
0317:                                    && (value = ((QuoteExp) arg).getValue()) instanceof  Keyword
0318:                                    && i < cdr_length)
0319:                                arg = new QuoteExp(((Keyword) value).asSymbol());
0320:                            else
0321:                                mapKeywordsToAttributes = false;
0322:                        }
0323:                    }
0324:
0325:                    vec.addElement(arg);
0326:                    cdr = cdr_pair.cdr;
0327:                }
0328:                Expression[] args = new Expression[vec.size()];
0329:                vec.copyInto(args);
0330:
0331:                if (save_scope != current_scope)
0332:                    setCurrentScope(save_scope);
0333:
0334:                return ((LispLanguage) getLanguage()).makeApply(func, args);
0335:            }
0336:
0337:            public Symbol namespaceResolve(Expression context, Expression member) {
0338:                if (context instanceof  ReferenceExp
0339:                        && member instanceof  QuoteExp) {
0340:                    ReferenceExp rexp = (ReferenceExp) context;
0341:                    Declaration decl = rexp.getBinding();
0342:                    Object val;
0343:                    if (decl == null || decl.getFlag(Declaration.IS_UNKNOWN)) {
0344:                        Object rsym = rexp.getSymbol();
0345:                        Symbol sym = rsym instanceof  Symbol ? (Symbol) rsym
0346:                                : env.getSymbol(rsym.toString());
0347:                        val = env.get(sym, null);
0348:                    } else if (decl.isNamespaceDecl()) {
0349:                        val = decl.getConstantValue();
0350:                    } else
0351:                        val = null;
0352:                    if (val instanceof  Namespace) {
0353:                        Namespace ns = (Namespace) val;
0354:                        String uri = ns.getName();
0355:                        if (uri != null && uri.startsWith("class:"))
0356:                            return null;
0357:                        String mem = ((QuoteExp) member).getValue().toString()
0358:                                .intern();
0359:                        return ns.getSymbol(mem);
0360:                    }
0361:                }
0362:                return null;
0363:            }
0364:
0365:            public static Object stripSyntax(Object obj) {
0366:                while (obj instanceof  SyntaxForm)
0367:                    obj = ((SyntaxForm) obj).form;
0368:                return obj;
0369:            }
0370:
0371:            public static Object safeCar(Object obj) {
0372:                while (obj instanceof  SyntaxForm)
0373:                    obj = ((SyntaxForm) obj).form;
0374:                if (!(obj instanceof  Pair))
0375:                    return null;
0376:                return stripSyntax(((Pair) obj).car);
0377:            }
0378:
0379:            public static Object safeCdr(Object obj) {
0380:                while (obj instanceof  SyntaxForm)
0381:                    obj = ((SyntaxForm) obj).form;
0382:                if (!(obj instanceof  Pair))
0383:                    return null;
0384:                return stripSyntax(((Pair) obj).cdr);
0385:            }
0386:
0387:            /** Returns the length of a syntax list.
0388:             * Returns Integer.MIN_VALUE for cyclic lists.
0389:             * For impure lists returns the negative of one more than
0390:             * the number of pairs before the "dot".
0391:             * Similar to LList.listLength, but descends into SyntaxForm. */
0392:            public static int listLength(Object obj) {
0393:                // Based on list-length implementation in
0394:                // Guy L Steele jr: "Common Lisp:  The Language", 2nd edition, page 414
0395:                int n = 0;
0396:                Object slow = obj;
0397:                Object fast = obj;
0398:                for (;;) {
0399:                    // 'n' is number of previous Pairs before 'fast' cursor.
0400:                    while (fast instanceof  SyntaxForm)
0401:                        fast = ((SyntaxForm) fast).form;
0402:                    while (slow instanceof  SyntaxForm)
0403:                        slow = ((SyntaxForm) slow).form;
0404:                    if (fast == LList.Empty)
0405:                        return n;
0406:                    if (!(fast instanceof  Pair))
0407:                        return -1 - n;
0408:                    n++;
0409:                    Object next = ((Pair) fast).cdr;
0410:                    while (next instanceof  SyntaxForm)
0411:                        next = ((SyntaxForm) next).form;
0412:                    if (next == LList.Empty)
0413:                        return n;
0414:                    if (!(next instanceof  Pair))
0415:                        return -1 - n;
0416:                    slow = ((Pair) slow).cdr;
0417:                    fast = ((Pair) next).cdr;
0418:                    n++;
0419:                    if (fast == slow)
0420:                        return Integer.MIN_VALUE;
0421:                }
0422:            }
0423:
0424:            public void rewriteInBody(Object exp) {
0425:                if (exp instanceof  SyntaxForm) {
0426:                    SyntaxForm sf = (SyntaxForm) exp;
0427:                    ScopeExp save_scope = current_scope;
0428:                    try {
0429:                        setCurrentScope(sf.scope);
0430:                        rewriteInBody(sf.form);
0431:                    } finally {
0432:                        setCurrentScope(save_scope);
0433:                    }
0434:                } else if (exp instanceof  Values) {
0435:                    Object[] vals = ((Values) exp).getValues();
0436:                    for (int i = 0; i < vals.length; i++)
0437:                        rewriteInBody(vals[i]);
0438:                } else
0439:                    formStack.add(rewrite(exp, false));
0440:            }
0441:
0442:            /**
0443:             * Re-write a Scheme expression in S-expression format into internal form.
0444:             */
0445:            public Expression rewrite(Object exp) {
0446:                return rewrite(exp, false);
0447:            }
0448:
0449:            public Object namespaceResolve(Object name) {
0450:                if (!(name instanceof  String)) {
0451:                    Pair p;
0452:                    if (name instanceof  Pair
0453:                            && safeCar(p = (Pair) name) == LispLanguage.lookup_sym
0454:                            && p.cdr instanceof  Pair
0455:                            && (p = (Pair) p.cdr).cdr instanceof  Pair) {
0456:                        Expression part1 = rewrite(p.car);
0457:                        Expression part2 = rewrite(((Pair) p.cdr).car);
0458:
0459:                        Symbol sym = namespaceResolve(part1, part2);
0460:                        if (sym != null)
0461:                            return sym;
0462:                        String combinedName = GetNamedPart.combineName(part1,
0463:                                part2);
0464:                        if (combinedName != null)
0465:                            return combinedName;
0466:                    }
0467:                }
0468:                return name;
0469:            }
0470:
0471:            public void setCurrentScope(ScopeExp scope) {
0472:                super .setCurrentScope(scope);
0473:                while (scope != null && !(scope instanceof  PatternScope))
0474:                    scope = scope.outer;
0475:                patternScope = (PatternScope) scope;
0476:            }
0477:
0478:            /**
0479:             * Re-write a Scheme expression in S-expression format into internal form.
0480:             */
0481:            public Expression rewrite(Object exp, boolean function) {
0482:                if (exp instanceof  SyntaxForm) {
0483:                    SyntaxForm sf = (SyntaxForm) exp;
0484:                    ScopeExp save_scope = current_scope;
0485:                    try {
0486:                        setCurrentScope(sf.scope);
0487:                        Expression s = rewrite(sf.form, function);
0488:                        return s;
0489:                    } finally {
0490:                        setCurrentScope(save_scope);
0491:                    }
0492:                }
0493:                if (exp instanceof  PairWithPosition)
0494:                    return rewrite_with_position(exp, function,
0495:                            (PairWithPosition) exp);
0496:                else if (exp instanceof  Pair)
0497:                    return rewrite_pair((Pair) exp, function);
0498:                else if (exp instanceof  String
0499:                        || (exp instanceof  Symbol && !selfEvaluatingSymbol(exp))) {
0500:                    Declaration decl = lexical.lookup(exp, function);
0501:                    Declaration cdecl = null;
0502:
0503:                    // If we're nested inside a class (in a ClassExp) then the field
0504:                    // and methods names of this class and super-classes/interfaces
0505:                    // need to be searched.
0506:                    ScopeExp scope = current_scope;
0507:                    int decl_nesting = decl == null ? -1 : ScopeExp
0508:                            .nesting(decl.context);
0509:                    String dname;
0510:                    if (exp instanceof  String
0511:                            || (exp instanceof  Symbol && ((Symbol) exp)
0512:                                    .hasEmptyNamespace()))
0513:                        dname = exp.toString();
0514:                    else {
0515:                        dname = null;
0516:                        scope = null;
0517:                    }
0518:                    for (; scope != null; scope = scope.outer) {
0519:                        if (scope instanceof  LambdaExp
0520:                                && scope.outer instanceof  ClassExp // redundant? FIXME
0521:                                && ((LambdaExp) scope).isClassMethod()) {
0522:                            if (decl_nesting >= ScopeExp.nesting(scope.outer))
0523:                                break;
0524:                            LambdaExp caller = (LambdaExp) scope;
0525:                            ClassExp cexp = (ClassExp) scope.outer;
0526:                            ClassType ctype = (ClassType) cexp.getType();
0527:                            Object part = SlotGet.lookupMember(ctype, dname,
0528:                                    ctype);
0529:                            boolean contextStatic = (caller == cexp.clinitMethod || (caller != cexp.initMethod && caller.nameDecl
0530:                                    .isStatic()));
0531:                            if (part == null) {
0532:                                char mode = contextStatic ? 'S' : 'V';
0533:                                PrimProcedure[] methods = ClassMethods
0534:                                        .getMethods(ctype, dname, mode, ctype,
0535:                                                language);
0536:                                if (methods.length == 0)
0537:                                    continue;
0538:                            }
0539:                            Expression part1;
0540:                            // FIXME We're throwing away 'part', which is wasteful.
0541:                            if (contextStatic)
0542:                                part1 = new ReferenceExp(
0543:                                        ((ClassExp) caller.outer).nameDecl);
0544:                            else
0545:                                part1 = new ThisExp(caller.firstDecl());
0546:                            return GetNamedPart.makeExp(part1, QuoteExp
0547:                                    .getInstance(dname));
0548:                        }
0549:                    }
0550:
0551:                    Object nameToLookup;
0552:                    Symbol symbol = null;
0553:                    if (decl != null) {
0554:                        nameToLookup = decl.getSymbol();
0555:                        exp = null;
0556:                        ReferenceExp rexp = getOriginalRef(decl);
0557:                        if (rexp != null) {
0558:                            decl = rexp.getBinding();
0559:                            if (decl == null) {
0560:                                exp = rexp.getSymbol();
0561:                                nameToLookup = exp;
0562:                            }
0563:                        }
0564:                    } else {
0565:                        nameToLookup = exp;
0566:                    }
0567:                    symbol = exp instanceof  String ? env
0568:                            .getSymbol((String) exp) : (Symbol) exp;
0569:                    boolean separate = getLanguage()
0570:                            .hasSeparateFunctionNamespace();
0571:                    if (decl != null) {
0572:                        if (!isLexical(decl)
0573:                                || (separate && decl.isProcedureDecl()))
0574:                            decl = null;
0575:                        else if (current_scope instanceof  TemplateScope
0576:                                && decl.needsContext())
0577:                            cdecl = ((TemplateScope) current_scope).macroContext;
0578:                        else if (decl.getFlag(Declaration.FIELD_OR_METHOD)
0579:                                && !decl.isStatic()) {
0580:                            scope = currentScope();
0581:                            for (;;) {
0582:                                if (scope == null)
0583:                                    throw new Error("internal error: missing "
0584:                                            + decl);
0585:                                if (scope.outer == decl.context) // I.e. same class.
0586:                                    break;
0587:                                scope = scope.outer;
0588:                            }
0589:                            cdecl = scope.firstDecl();
0590:                        }
0591:                    } else {
0592:                        Location loc = env.lookup(symbol,
0593:                                function && separate ? EnvironmentKey.FUNCTION
0594:                                        : null);
0595:                        if (loc != null)
0596:                            loc = loc.getBase();
0597:                        if (loc instanceof  FieldLocation) {
0598:                            FieldLocation floc = (FieldLocation) loc;
0599:                            try {
0600:                                decl = floc.getDeclaration();
0601:                                if (!inlineOk(null)
0602:                                // A kludge - we get a bunch of testsuite failures
0603:                                        // if we don't inline $lookup$.  FIXME.
0604:                                        && decl != kawa.standard.Scheme.getNamedPartDecl)
0605:                                    decl = null;
0606:                                if (decl != null && !decl.isStatic()) {
0607:                                    cdecl = new Declaration("(module-instance)");
0608:                                    cdecl.setValue(new QuoteExp(floc
0609:                                            .getInstance()));
0610:                                }
0611:                            } catch (Throwable ex) {
0612:                                error('e', "exception loading '" + exp + "' - "
0613:                                        + ex.getMessage());
0614:                                decl = null;
0615:                            }
0616:                        }
0617:                        /*
0618:                            else if (Compilation.inlineOk && function)
0619:                              {
0620:                        // Questionable.  fail with new set_b implementation,
0621:                        // which just call rewrite_car on the lhs,
0622:                        // if we don't require function to be true.  FIXME.
0623:                                decl = Declaration.getDeclaration(proc);
0624:                              }
0625:                         */
0626:                    }
0627:                    if (decl != null
0628:                            && decl.getContext() instanceof  PatternScope)
0629:                        return syntaxError("reference to pattern variable "
0630:                                + decl.getName() + " outside syntax template");
0631:
0632:                    ReferenceExp rexp = new ReferenceExp(nameToLookup, decl);
0633:                    rexp.setContextDecl(cdecl);
0634:                    rexp.setLine(this );
0635:                    if (function && separate)
0636:                        rexp.setFlag(ReferenceExp.PREFER_BINDING2);
0637:                    return rexp;
0638:                } else if (exp instanceof  LangExp)
0639:                    return rewrite(((LangExp) exp).getLangValue(), function);
0640:                else if (exp instanceof  Expression)
0641:                    return (Expression) exp;
0642:                else
0643:                    return QuoteExp.getInstance(Quote.quote(exp, this ));
0644:            }
0645:
0646:            public static void setLine(Expression exp, Object location) {
0647:                if (location instanceof  SourceLocator)
0648:                    exp.setLocation((SourceLocator) location);
0649:            }
0650:
0651:            public static void setLine(Declaration decl, Object location) {
0652:                if (location instanceof  SourceLocator)
0653:                    decl.setLocation((SourceLocator) location);
0654:            }
0655:
0656:            PairWithPosition positionPair;
0657:
0658:            /** Note current line number position from a PairWithPosition.
0659:             * Return an object to pass to popPositionOf.
0660:             */
0661:            public Object pushPositionOf(Object pair) {
0662:                if (pair instanceof  SyntaxForm)
0663:                    pair = ((SyntaxForm) pair).form;
0664:                if (!(pair instanceof  PairWithPosition))
0665:                    return null;
0666:                PairWithPosition ppair = (PairWithPosition) pair;
0667:                Object saved;
0668:                if (positionPair == null
0669:                        || positionPair.getFileName() != getFileName()
0670:                        || positionPair.getLineNumber() != getLineNumber()
0671:                        || positionPair.getColumnNumber() != getColumnNumber()) {
0672:                    saved = new PairWithPosition(this , Special.eof,
0673:                            positionPair);
0674:                } else
0675:                    saved = positionPair;
0676:                setLine(pair);
0677:                positionPair = ppair;
0678:                return saved;
0679:            }
0680:
0681:            /** Restore  line number position from a previous pushPositionOf.
0682:             * @param saved value returned by matching pushPositionOf.
0683:             */
0684:            public void popPositionOf(Object saved) {
0685:                if (saved == null)
0686:                    return;
0687:                setLine(saved);
0688:                positionPair = (PairWithPosition) saved;
0689:                if (positionPair.car == Special.eof)
0690:                    positionPair = (PairWithPosition) positionPair.cdr;
0691:            }
0692:
0693:            /** Set the line position of the argument to the current position. */
0694:
0695:            public void setLineOf(Expression exp) {
0696:                if (exp instanceof  QuoteExp)
0697:                    return;
0698:                exp.setLocation(this );
0699:            }
0700:
0701:            /** Extract a type from the car of a pair. */
0702:            public Type exp2Type(Pair typeSpecPair) {
0703:                Object saved = pushPositionOf(typeSpecPair);
0704:                try {
0705:                    Expression texp = rewrite_car(typeSpecPair, false);
0706:                    texp = new InlineCalls(this ).walk(texp);
0707:                    if (texp instanceof  ErrorExp)
0708:                        return null;
0709:                    texp = new InlineCalls(this ).walk(texp);
0710:                    Type type = getLanguage().getTypeFor(texp);
0711:                    if (type == null) {
0712:                        if (texp instanceof  ReferenceExp)
0713:                            error('e', "unknown type name '"
0714:                                    + ((ReferenceExp) texp).getName() + '\'');
0715:                        else
0716:                            error('e',
0717:                                    "invalid type spec (must be \"type\" or 'type or <type>)");
0718:                        return Type.pointer_type;
0719:                    }
0720:                    return type;
0721:                } finally {
0722:                    popPositionOf(saved);
0723:                }
0724:            }
0725:
0726:            public Expression rewrite_with_position(Object exp,
0727:                    boolean function, PairWithPosition pair) {
0728:                Object saved = pushPositionOf(pair);
0729:                Expression result;
0730:                try {
0731:                    if (exp == pair)
0732:                        result = rewrite_pair(pair, function); // To avoid a cycle
0733:                    else
0734:                        result = rewrite(exp, function);
0735:                    setLineOf(result);
0736:                } finally {
0737:                    popPositionOf(saved);
0738:                }
0739:                return result;
0740:            }
0741:
0742:            public static Object wrapSyntax(Object form, SyntaxForm syntax) {
0743:                if (syntax == null || form instanceof  Expression)
0744:                    return form;
0745:                else
0746:                    return syntax.fromDatumIfNeeded(form);
0747:            }
0748:
0749:            public Object popForms(int first) {
0750:                int last = formStack.size();
0751:                if (last == first)
0752:                    return Values.empty;
0753:                Object r;
0754:                if (last == first + 1)
0755:                    r = formStack.elementAt(first);
0756:                else {
0757:                    Values vals = new Values();
0758:                    for (int i = first; i < last; i++)
0759:                        vals.writeObject(formStack.elementAt(i));
0760:                    r = vals;
0761:                }
0762:                formStack.setSize(first);
0763:                return r;
0764:            }
0765:
0766:            public void scanForm(Object st, ScopeExp defs) {
0767:                if (st instanceof  SyntaxForm) {
0768:                    SyntaxForm sf = (SyntaxForm) st;
0769:                    ScopeExp save_scope = currentScope();
0770:                    try {
0771:                        setCurrentScope(sf.scope);
0772:                        int first = formStack.size();
0773:                        scanForm(sf.form, defs);
0774:                        formStack.add(wrapSyntax(popForms(first), sf));
0775:                        return;
0776:                    } finally {
0777:                        setCurrentScope(save_scope);
0778:                    }
0779:                }
0780:                if (st instanceof  Values) {
0781:                    if (st == Values.empty)
0782:                        st = QuoteExp.voidExp; // From #!void
0783:                    else {
0784:                        Object[] vals = ((Values) st).getValues();
0785:                        for (int i = 0; i < vals.length; i++)
0786:                            scanForm(vals[i], defs);
0787:                        return;
0788:                    }
0789:                }
0790:                if (st instanceof  Pair) {
0791:                    Pair st_pair = (Pair) st;
0792:                    Declaration saveContext = macroContext;
0793:                    Syntax syntax = null;
0794:                    ScopeExp save_scope = current_scope;
0795:                    try {
0796:                        Object obj = st_pair.car;
0797:                        if (obj instanceof  SyntaxForm) {
0798:                            SyntaxForm sf = (SyntaxForm) st_pair.car;
0799:                            setCurrentScope(sf.scope);
0800:                            obj = sf.form;
0801:                        }
0802:                        Pair p;
0803:                        if (obj instanceof  Pair
0804:                                && (p = (Pair) obj).car == LispLanguage.lookup_sym
0805:                                && p.cdr instanceof  Pair
0806:                                && (p = (Pair) p.cdr).cdr instanceof  Pair) {
0807:                            Expression part1 = rewrite(p.car);
0808:                            Expression part2 = rewrite(((Pair) p.cdr).car);
0809:                            obj = namespaceResolve(part1, part2);
0810:                        }
0811:                        if (obj instanceof  String
0812:                                || (obj instanceof  Symbol && !selfEvaluatingSymbol(obj))) {
0813:                            Expression func = rewrite(obj, true);
0814:                            if (func instanceof  ReferenceExp) {
0815:                                Declaration decl = ((ReferenceExp) func)
0816:                                        .getBinding();
0817:                                if (decl != null)
0818:                                    syntax = check_if_Syntax(decl);
0819:                                else {
0820:                                    obj = resolve(obj, true);
0821:                                    if (obj instanceof  Syntax)
0822:                                        syntax = (Syntax) obj;
0823:                                }
0824:                            }
0825:                        }
0826:                        // Recognize deferred begin created in scanBody for pendingForms.
0827:                        // A seemingly-cleaned (obj instanceof Syntax) causes problems
0828:                        // with some Syntax forms, such as define.
0829:                        else if (obj == kawa.standard.begin.begin)
0830:                            syntax = (Syntax) obj;
0831:                    } finally {
0832:                        if (save_scope != current_scope)
0833:                            setCurrentScope(save_scope);
0834:                    }
0835:                    if (syntax != null) {
0836:                        String save_filename = getFileName();
0837:                        int save_line = getLineNumber();
0838:                        int save_column = getColumnNumber();
0839:                        try {
0840:                            setLine(st_pair);
0841:                            syntax.scanForm(st_pair, defs, this );
0842:                            return;
0843:                        } finally {
0844:                            macroContext = saveContext;
0845:                            setLine(save_filename, save_line, save_column);
0846:                        }
0847:                    }
0848:                }
0849:                formStack.add(st);
0850:            }
0851:
0852:            /** Recursive helper method for rewrite_body.
0853:             * Scan body for definitions, adding partially macro-expanded
0854:             * expressions into the <code>formStack</code>.
0855:             * @param makeList if true, return a list representation of the scanned
0856:             *   forms (not including declarations); else forms are push on formStack
0857:             * @return a list of forms if <code>makeList</code> (possibly wrapped
0858:             * in a <code>SyntaxForm</code>); otherwise <code>null</code>.
0859:             */
0860:
0861:            public Object scanBody(Object body, ScopeExp defs, boolean makeList) {
0862:                Object list = makeList ? LList.Empty : null;
0863:                Pair lastPair = null;
0864:                while (body != LList.Empty) {
0865:                    if (body instanceof  SyntaxForm) {
0866:                        SyntaxForm sf = (SyntaxForm) body;
0867:                        ScopeExp save_scope = current_scope;
0868:                        try {
0869:                            setCurrentScope(sf.scope);
0870:                            int first = formStack.size();
0871:                            Object f = scanBody(sf.form, defs, makeList);
0872:                            if (makeList) {
0873:                                f = wrapSyntax(f, sf);
0874:                                if (lastPair == null)
0875:                                    return f;
0876:                                lastPair.cdr = f;
0877:                                return list;
0878:                            }
0879:                            formStack.add(wrapSyntax(popForms(first), sf));
0880:                            return null;
0881:                        } finally {
0882:                            setCurrentScope(save_scope);
0883:                        }
0884:                    } else if (body instanceof  Pair) {
0885:                        Pair pair = (Pair) body;
0886:                        int first = formStack.size();
0887:                        scanForm(pair.car, defs);
0888:                        if (getState() == Compilation.PROLOG_PARSED) {
0889:                            // We've seen a require form during the initial pass when
0890:                            // we're looking module names.  Defer the require and any
0891:                            // following forms in this body.
0892:                            if (pair.car != pendingForm)
0893:                                pair = makePair(pair, pendingForm, pair.cdr);
0894:                            pendingForm = new Pair(kawa.standard.begin.begin,
0895:                                    pair);
0896:                            return LList.Empty;
0897:                        }
0898:                        int fsize = formStack.size();
0899:                        if (makeList) {
0900:                            for (int i = first; i < fsize; i++) {
0901:                                Pair npair = makePair(pair, formStack
0902:                                        .elementAt(i), LList.Empty);
0903:                                if (lastPair == null)
0904:                                    list = npair;
0905:                                else
0906:                                    lastPair.cdr = npair;
0907:                                lastPair = npair;
0908:                            }
0909:                            formStack.setSize(first);
0910:                        }
0911:                        body = pair.cdr;
0912:                    } else {
0913:                        formStack.add(syntaxError("body is not a proper list"));
0914:                        break;
0915:                    }
0916:                }
0917:                return list;
0918:            }
0919:
0920:            public static Pair makePair(Pair pair, Object car, Object cdr) {
0921:                if (pair instanceof  PairWithPosition)
0922:                    return new PairWithPosition((PairWithPosition) pair, car,
0923:                            cdr);
0924:                return new Pair(car, cdr);
0925:            }
0926:
0927:            /**
0928:             * Re-write a Scheme <body> in S-expression format into internal form.
0929:             */
0930:
0931:            public Expression rewrite_body(Object exp) {
0932:                // NOTE we have both a rewrite_body and a rewriteBody.
0933:                // This is confusing, at the least.  FIXME.
0934:                Object saved = pushPositionOf(exp);
0935:                LetExp defs = new LetExp(null);
0936:                int first = formStack.size();
0937:                defs.outer = current_scope;
0938:                current_scope = defs;
0939:                try {
0940:                    scanBody(exp, defs, false);
0941:                    if (formStack.size() == first)
0942:                        formStack.add(syntaxError("body with no expressions"));
0943:                    int ndecls = defs.countDecls();
0944:                    if (ndecls != 0) {
0945:                        Expression[] inits = new Expression[ndecls];
0946:                        for (int i = ndecls; --i >= 0;)
0947:                            inits[i] = QuoteExp.undefined_exp;
0948:                        defs.inits = inits;
0949:                    }
0950:                    Expression body = makeBody(first, null);
0951:                    setLineOf(body);
0952:                    if (ndecls == 0)
0953:                        return body;
0954:                    defs.body = body;
0955:                    setLineOf(defs);
0956:                    return defs;
0957:                } finally {
0958:                    pop(defs);
0959:                    popPositionOf(saved);
0960:                }
0961:            }
0962:
0963:            /* Rewrite forms on formStack above first. */
0964:            public void rewriteBody(int first) {
0965:                int nforms = formStack.size() - first;
0966:                if (nforms == 0)
0967:                    return;
0968:                else if (nforms == 1) {
0969:                    Object f = formStack.pop();
0970:                    rewriteInBody(f);
0971:                } else {
0972:                    Object[] forms = new Object[nforms];
0973:                    for (int i = 0; i < nforms; i++)
0974:                        forms[i] = formStack.elementAt(first + i);
0975:                    formStack.setSize(first);
0976:                    for (int i = 0; i < nforms; i++)
0977:                        rewriteInBody(forms[i]);
0978:                }
0979:            }
0980:
0981:            /** Combine a list of zero or more expression forms into a "body". */
0982:            public Expression makeBody(int first, ScopeExp scope) {
0983:                rewriteBody(first);
0984:                int nforms = formStack.size() - first;
0985:                if (nforms == 0)
0986:                    return QuoteExp.voidExp;
0987:                else if (nforms == 1) {
0988:                    return (Expression) formStack.pop();
0989:                } else {
0990:                    Expression[] exps = new Expression[nforms];
0991:                    for (int i = 0; i < nforms; i++)
0992:                        exps[i] = (Expression) formStack.elementAt(first + i);
0993:                    formStack.setSize(first);
0994:                    if (scope instanceof  ModuleExp)
0995:                        return new ApplyExp(
0996:                                gnu.kawa.functions.AppendValues.appendValues,
0997:                                exps);
0998:                    else
0999:                        return ((LispLanguage) getLanguage()).makeBody(exps);
1000:                }
1001:            }
1002:
1003:            /** Storage used by noteAccess and processAccesses. */
1004:            Vector notedAccess;
1005:
1006:            /** Note that we reference name in a given scope.
1007:             * This may be called when defining a macro, at scan-time,
1008:             * and the name may be bound to a declaration we haven't seen yet. */
1009:            public void noteAccess(Object name, ScopeExp scope) {
1010:                if (notedAccess == null)
1011:                    notedAccess = new Vector();
1012:                notedAccess.addElement(name);
1013:                notedAccess.addElement(scope);
1014:            }
1015:
1016:            /** Check references recorded by noteAccess.
1017:             * Resolve now to a Declaration, and note the access.
1018:             * This is needed in case an exported macro references a private Declaration.
1019:             */
1020:            public void processAccesses() {
1021:                if (notedAccess == null)
1022:                    return;
1023:                int sz = notedAccess.size();
1024:                ScopeExp saveScope = current_scope;
1025:                for (int i = 0; i < sz; i += 2) {
1026:                    Object name = notedAccess.elementAt(i);
1027:                    ScopeExp scope = (ScopeExp) notedAccess.elementAt(i + 1);
1028:                    if (current_scope != scope)
1029:                        setCurrentScope(scope);
1030:                    Declaration decl = (Declaration) lexical.lookup(name, -1);
1031:                    if (decl != null && !decl.getFlag(Declaration.IS_UNKNOWN)) {
1032:                        decl.getContext().currentLambda().capture(decl);
1033:                        decl.setCanRead(true);
1034:                        decl.setSimple(false);
1035:                        decl.setFlag(Declaration.EXTERNAL_ACCESS);
1036:                    }
1037:                }
1038:                if (current_scope != saveScope)
1039:                    setCurrentScope(saveScope);
1040:            }
1041:
1042:            public void finishModule(ModuleExp mexp) {
1043:                boolean moduleStatic = mexp.isStatic();
1044:                for (Declaration decl = mexp.firstDecl(); decl != null; decl = decl
1045:                        .nextDecl()) {
1046:                    if (decl.getFlag(Declaration.NOT_DEFINING)) {
1047:                        String msg1 = "'";
1048:                        String msg2 = (decl
1049:                                .getFlag(Declaration.EXPORT_SPECIFIED) ? "' exported but never defined"
1050:                                : decl.getFlag(Declaration.STATIC_SPECIFIED) ? "' declared static but never defined"
1051:                                        : "' declared but never defined");
1052:                        error('e', decl, msg1, msg2);
1053:                    }
1054:                    if (mexp.getFlag(ModuleExp.EXPORT_SPECIFIED)) {
1055:                        if (decl.getFlag(Declaration.EXPORT_SPECIFIED)) {
1056:                            if (decl.isPrivate()) {
1057:                                if (decl.getFlag(Declaration.PRIVATE_SPECIFIED))
1058:                                    error('e', decl, "'",
1059:                                            "' is declared both private and exported");
1060:                                decl.setPrivate(false);
1061:                            }
1062:                        } else
1063:                            decl.setPrivate(true);
1064:                    }
1065:                    if (moduleStatic)
1066:                        decl.setFlag(Declaration.STATIC_SPECIFIED);
1067:                    else if ((mexp.getFlag(ModuleExp.NONSTATIC_SPECIFIED) && !decl
1068:                            .getFlag(Declaration.STATIC_SPECIFIED))
1069:                            || gnu.expr.Compilation.moduleStatic < 0
1070:                            || mexp.getFlag(ModuleExp.SUPERTYPE_SPECIFIED))
1071:                        decl.setFlag(Declaration.NONSTATIC_SPECIFIED);
1072:                }
1073:                if (!moduleStatic)
1074:                    mexp.declareThis(null);
1075:            }
1076:
1077:            public void resolveModule(ModuleExp mexp) {
1078:                int numPending = pendingImports == null ? 0 : pendingImports
1079:                        .size();
1080:                for (int i = 0; i < numPending;) {
1081:                    ModuleInfo info = (ModuleInfo) pendingImports
1082:                            .elementAt(i++);
1083:                    ScopeExp defs = (ScopeExp) pendingImports.elementAt(i++);
1084:                    Expression posExp = (Expression) pendingImports
1085:                            .elementAt(i++);
1086:                    if (mexp == defs) {
1087:                        // process(BODY_PARSED);
1088:                        Expression savePos = new ReferenceExp((Object) null);
1089:                        savePos.setLine(this );
1090:                        setLine(posExp);
1091:                        kawa.standard.require.importDefinitions(null, info,
1092:                                null, formStack, defs, this );
1093:                        setLine(savePos);
1094:                        pendingImports.setElementAt(null, i - 3);
1095:                        pendingImports.setElementAt(null, i - 2);
1096:                        pendingImports.setElementAt(null, i - 1);
1097:                    }
1098:                }
1099:
1100:                processAccesses();
1101:
1102:                setModule(mexp);
1103:                Compilation save_comp = Compilation.getCurrent();
1104:                try {
1105:                    Compilation.setCurrent(this );
1106:                    mexp.body = makeBody(firstForm, mexp);
1107:                    lexical.pop(mexp);
1108:                } finally {
1109:                    Compilation.setCurrent(save_comp);
1110:                }
1111:
1112:                /* DEBUGGING:
1113:                OutPort err = OutPort.errDefault ();
1114:                err.print ("[Re-written expression for load/compile: ");
1115:                mexp.print (err);
1116:                //err.print ("\nbefore load<"+mod.getClass().getName()+">");
1117:                err.println();
1118:                err.flush();
1119:                 */
1120:            }
1121:
1122:            public Declaration makeRenamedAlias(Declaration decl,
1123:                    ScopeExp templateScope) {
1124:                if (templateScope == null)
1125:                    return decl; // ???
1126:                return makeRenamedAlias(decl.getSymbol(), decl, templateScope);
1127:            }
1128:
1129:            public Declaration makeRenamedAlias(Object name, Declaration decl,
1130:                    ScopeExp templateScope) {
1131:                Declaration alias = new Declaration(name);
1132:                alias.setAlias(true);
1133:                alias.setPrivate(true);
1134:                alias.context = templateScope;
1135:                ReferenceExp ref = new ReferenceExp(decl);
1136:                ref.setDontDereference(true);
1137:                alias.noteValue(ref);
1138:                return alias;
1139:            }
1140:
1141:            /** Push an alias for a declaration in a scope.
1142:             * If the name of <code>decl</code> came from a syntax template
1143:             * whose immediate scope is <code>templateScope</code>,
1144:             * then the same syntax template may contain local variable references
1145:             * that are also in the same <code>templateScope</code>.
1146:             * Such variable references will <em>not</em> look in the current
1147:             * "physical" scope, where we just created <code>decl</code>, but
1148:             * will instead search the "lexical" <code>templateScope</scope>.
1149:             * So that such references can resolve to <code>decl</code>, we
1150:             * create an alias in <code>templateScope</code> that points
1151:             * to <code>decl</code>.  We record that we did this in the
1152:             * <code> renamedLiasStack</code>, so we can remove the alias later.
1153:             */
1154:            public void pushRenamedAlias(Declaration alias) {
1155:                Declaration decl = getOriginalRef(alias).getBinding();
1156:                ScopeExp templateScope = alias.context;
1157:                decl.setSymbol(null);
1158:                Declaration old = templateScope.lookup(decl.getSymbol());
1159:                if (old != null)
1160:                    templateScope.remove(old);
1161:                templateScope.addDeclaration(alias);
1162:                if (renamedAliasStack == null)
1163:                    renamedAliasStack = new Stack();
1164:                renamedAliasStack.push(old);
1165:                renamedAliasStack.push(alias);
1166:                renamedAliasStack.push(templateScope);
1167:            }
1168:
1169:            /** Remove one or more aliases created by <code>pushRenamedAlias</code>. */
1170:            public void popRenamedAlias(int count) {
1171:                while (--count >= 0) {
1172:                    ScopeExp templateScope = (ScopeExp) renamedAliasStack.pop();
1173:                    Declaration alias = (Declaration) renamedAliasStack.pop();
1174:                    Declaration decl = getOriginalRef(alias).getBinding();
1175:                    decl.setSymbol(alias.getSymbol());
1176:                    templateScope.remove(alias);
1177:                    Object old = renamedAliasStack.pop();
1178:                    if (old != null)
1179:                        templateScope.addDeclaration((Declaration) old);
1180:                }
1181:            }
1182:
1183:            public Declaration define(Object name, SyntaxForm nameSyntax,
1184:                    ScopeExp defs) {
1185:                boolean aliasNeeded = nameSyntax != null
1186:                        && nameSyntax.scope != currentScope();
1187:                Object declName = aliasNeeded ? new String(name.toString())
1188:                        : name;
1189:                Declaration decl = defs.getDefine(declName, 'w', this );
1190:                if (aliasNeeded) {
1191:                    Declaration alias = makeRenamedAlias(name, decl,
1192:                            nameSyntax.scope);
1193:                    nameSyntax.scope.addDeclaration(alias);
1194:                }
1195:                push(decl);
1196:                return decl;
1197:            }
1198:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.