Source Code Cross Referenced for Language.java in  » Scripting » Kawa » gnu » expr » 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 » gnu.expr 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        // Copyright (c) 2002, 2003, 2004, 2005  Per M.A. Bothner.
002:        // This is free software;  for terms and warranty disclaimer see ./COPYING.
003:
004:        package gnu.expr;
005:
006:        import gnu.mapping.*;
007:        import gnu.bytecode.*;
008:        import gnu.mapping.Location;
009:        import gnu.lists.*;
010:        import gnu.text.Lexer;
011:        import gnu.text.SourceMessages;
012:        import gnu.kawa.reflect.*;
013:        import java.io.*;
014:        import java.lang.reflect.InvocationTargetException;
015:        import gnu.kawa.lispexpr.ClassNamespace; // FIXME
016:
017:        /**
018:         * Contains various language-dependent methods.
019:         * Also contains "global" state about the executation environment,
020:         * such as the global Environment.  There can be multiple Languages
021:         * associated with different threads, representing mutiple top-levels.
022:         * (However, this functionality is incomplete.)
023:         */
024:
025:        public abstract class Language {
026:            protected static final ThreadLocation current = new ThreadLocation(
027:                    "language");
028:
029:            public static Language getDefaultLanguage() {
030:                return (Language) current.get(null);
031:            }
032:
033:            static {
034:                Environment.setGlobal(BuiltinEnvironment.getInstance());
035:            }
036:
037:            public static void setDefaultLanguage(Language language) {
038:                current.set(language);
039:            }
040:
041:            /**
042:             * List of known languages and their Language classes.
043:             * Each element is one or more language names, or filename extensions,
044:             * followed by the name of the Language sub-class.
045:             * The table is searched from the beginning.
046:             */
047:
048:            static String[][] languages = {
049:                    { "scheme", ".scm", ".sc", "kawa.standard.Scheme" },
050:                    { "krl", ".krl", "gnu.kawa.brl.BRL" },
051:                    { "brl", ".brl", "gnu.kawa.brl.BRL" },
052:                    { "emacs", "elisp", "emacs-lisp", ".el",
053:                            "gnu.jemacs.lang.ELisp" },
054:                    { "xquery", ".xquery", ".xq", ".xql",
055:                            "gnu.xquery.lang.XQuery" },
056:                    { "q2", ".q2", "gnu.q2.lang.Q2" },
057:                    { "xslt", "xsl", ".xsl", "gnu.kawa.xslt.XSLT" },
058:                    { "commonlisp", "common-lisp", "clisp", "lisp", ".lisp",
059:                            ".lsp", ".cl", "gnu.commonlisp.lang.CommonLisp" } };
060:
061:            /** Get a list of all available languages */
062:
063:            public static String[][] getLanguages() {
064:                return languages;
065:            }
066:
067:            /** Add a language to the list.
068:             *
069:             * @param langMapping is a language definition, the first index
070:             *  is the language name, subsequent indexes are file types that
071:             *  might cause the language to be used and the final index is the
072:             *  name of the class that implements the language.
073:             */
074:            public static void registerLanguage(String[] langMapping) {
075:                String[][] newLangs = new String[languages.length + 1][];
076:                System.arraycopy(languages, 0, newLangs, 0, languages.length);
077:                newLangs[newLangs.length - 1] = langMapping;
078:                languages = newLangs;
079:            }
080:
081:            /** Detect the programming language of a file based on its first line.
082:             * @return a suitable Language or null if we didn't recognize one.
083:             */
084:            public static Language detect(InputStream in) throws IOException {
085:                if (!in.markSupported())
086:                    return null;
087:                StringBuffer sbuf = new StringBuffer();
088:                in.mark(200);
089:                for (;;) {
090:                    if (sbuf.length() >= 200)
091:                        break;
092:                    int c = in.read();
093:                    if (c < 0 || c == '\n' || c == '\r')
094:                        break;
095:                    sbuf.append((char) c);
096:                }
097:                in.reset();
098:                return detect(sbuf.toString());
099:            }
100:
101:            /** Detect the programming language of a file based on its first line.
102:             * @return a suitable Language or null if we didn't recognize one.
103:             */
104:            public static Language detect(InPort port) throws IOException {
105:                StringBuffer sbuf = new StringBuffer();
106:                port.mark(300);
107:                port.readLine(sbuf, 'P');
108:                port.reset();
109:                return detect(sbuf.toString());
110:            }
111:
112:            /** Detect the programming language of a file based on its first line.
113:             * @param line the first input line
114:             * @return a suitable Language or null if we didn't recognize one.
115:             */
116:            public static Language detect(String line) {
117:                String str = line.trim();
118:                // Does the line contain the string "kawa:LANGAUGE" for a valid LANGUAGE?
119:                int k = str.indexOf("kawa:");
120:                if (k >= 0) {
121:                    int i = k + 5;
122:                    int j = i;
123:                    while (j < str.length()
124:                            && Character.isJavaIdentifierPart(str.charAt(j)))
125:                        j++;
126:                    if (j > i) {
127:                        String w = str.substring(i, j);
128:                        Language lang = getInstance(w);
129:                        if (lang != null)
130:                            return lang;
131:                    }
132:                }
133:                // Check for various Emacs language/mode patterns.
134:                if (str.indexOf("-*- scheme -*-") >= 0)
135:                    return getInstance("scheme");
136:                if (str.indexOf("-*- xquery -*-") >= 0)
137:                    return getInstance("xquery");
138:                if (str.indexOf("-*- emacs-lisp -*-") >= 0)
139:                    return getInstance("elisp");
140:                if (str.indexOf("-*- common-lisp -*-") >= 0
141:                        || str.indexOf("-*- lisp -*-") >= 0)
142:                    return getInstance("common-lisp");
143:                // Does it start with an XQuery comment or XQuery version statement?
144:                if ((str.charAt(0) == '(' && str.charAt(1) == ':')
145:                        || (str.length() >= 7 && str.substring(0, 7).equals(
146:                                "xquery ")))
147:                    return getInstance("xquery");
148:                if (str.charAt(0) == ';' && str.charAt(1) == ';')
149:                    return getInstance("scheme");
150:                return null;
151:            }
152:
153:            public static Language getInstanceFromFilenameExtension(
154:                    String filename) {
155:                int dot = filename.lastIndexOf('.');
156:                if (dot > 0) {
157:                    Language lang = Language.getInstance(filename
158:                            .substring(dot));
159:                    if (lang != null)
160:                        return lang;
161:                }
162:                return null;
163:            }
164:
165:            /** Look for a language with the given name or extension.
166:             * If name is null, look for the first language available. */
167:            public static Language getInstance(String name) {
168:                int langCount = languages.length;
169:                for (int i = 0; i < langCount; i++) {
170:                    String[] names = languages[i];
171:                    int nameCount = names.length - 1;
172:                    for (int j = nameCount; --j >= 0;) {
173:                        if (name == null || names[j].equalsIgnoreCase(name)) {
174:                            Class langClass;
175:                            try {
176:                                langClass = Class.forName(names[nameCount]);
177:                            } catch (ClassNotFoundException ex) {
178:                                // In the future, we may support languages names that
179:                                // can be implemented by more than one Language,
180:                                // so don't give up yet.
181:                                break;
182:                            }
183:                            return getInstance(names[0], langClass);
184:                        }
185:                    }
186:                }
187:                return null;
188:            }
189:
190:            protected Language() {
191:                gnu.lists.Convert.setInstance(KawaConvert.getInstance());
192:            }
193:
194:            public static Language getInstance(String langName, Class langClass) {
195:                try {
196:                    java.lang.reflect.Method method;
197:                    Class[] args = {};
198:                    try {
199:                        String capitalizedName = (Character
200:                                .toTitleCase(langName.charAt(0)) + langName
201:                                .substring(1).toLowerCase());
202:                        String methodName = "get" + capitalizedName
203:                                + "Instance";
204:                        method = langClass.getDeclaredMethod(methodName, args);
205:                    } catch (Exception ex) {
206:                        method = langClass.getDeclaredMethod("getInstance",
207:                                args);
208:                    }
209:                    return (Language) method.invoke(null, Values.noArgs);
210:                } catch (Exception ex) {
211:                    langName = langClass.getName();
212:                    Throwable th;
213:                    if (ex instanceof  InvocationTargetException)
214:                        th = ((InvocationTargetException) ex)
215:                                .getTargetException();
216:                    else
217:                        th = ex;
218:                    // th.printStackTrace();
219:                    throw new WrappedException("getInstance for '" + langName
220:                            + "' failed", th);
221:                }
222:            }
223:
224:            /** Test if a value is considered "true" in this language. */
225:            public boolean isTrue(Object value) {
226:                return value != Boolean.FALSE;
227:            }
228:
229:            public Object booleanObject(boolean b) {
230:                return b ? Boolean.TRUE : Boolean.FALSE;
231:            }
232:
233:            /** The value to return for a "void" result. */
234:            public Object noValue() {
235:                return Values.empty;
236:            }
237:
238:            /** True if functions are in a separate anme space from variable.
239:             * Is true for e.g. Common Lisp, Emacs Lisp;  false for Scheme. */
240:            public boolean hasSeparateFunctionNamespace() {
241:                return false;
242:            }
243:
244:            /** The environment for language built-ins and predefined bindings. */
245:            protected Environment environ;
246:
247:            /** If non-null, the user environment.
248:             * This allows "bunding" an Environment with a Language. This is partly to
249:             * match existing documentation, and partly for convenience from Java code.
250:             * Normally, userEnv is null, in which case the user environment is
251:             * extracted from the current thread. */
252:            protected Environment userEnv;
253:
254:            /** Get current user environment. */
255:            public final Environment getEnvironment() {
256:                return userEnv != null ? userEnv : Environment.getCurrent();
257:            }
258:
259:            static int envCounter;
260:
261:            public final Environment getNewEnvironment() {
262:                return Environment.make("environment-" + (++envCounter),
263:                        environ);
264:            }
265:
266:            public Environment getLangEnvironment() {
267:                return environ;
268:            }
269:
270:            public NamedLocation lookupBuiltin(Symbol name, Object property,
271:                    int hash) {
272:                return environ == null ? null : environ.lookup(name, property,
273:                        hash);
274:            }
275:
276:            /** Enter a value into the current environment. */
277:            public void define(String sym, Object p) {
278:                Symbol s = getSymbol(sym);
279:                environ.define(s, null, p);
280:            }
281:
282:            /** Declare in the current Environment a variable aliased to a static field.
283:             */
284:            protected void defAliasStFld(String name, String cname, String fname) {
285:                StaticFieldLocation.define(environ, getSymbol(name), null,
286:                        cname, fname);
287:            }
288:
289:            /** Declare in the current Environment a procedure bound to a static field.
290:             * @param name the procedure's source-level name.
291:             * @param cname the name of the class containing the field.
292:             * @param fname the name of the field, which should be a static
293:             *   final field whose type extends gnu.mapping.Procedure.
294:             */
295:            protected void defProcStFld(String name, String cname, String fname) {
296:                Object property = (hasSeparateFunctionNamespace() ? EnvironmentKey.FUNCTION
297:                        : null);
298:                Symbol sym = getSymbol(name);
299:                StaticFieldLocation loc = StaticFieldLocation.define(environ,
300:                        sym, property, cname, fname);
301:                loc.setProcedure();
302:            }
303:
304:            /** Declare in the current Environment a procedure bound to a static field.
305:             * @param name the procedure's source-level name.
306:             * @param cname the name of the class containing the field.
307:             * The name of the field is the mangling of <code>name</code>.
308:             */
309:            protected void defProcStFld(String name, String cname) {
310:                defProcStFld(name, cname, Compilation.mangleNameIfNeeded(name));
311:            }
312:
313:            /** Enter a named function into the current environment. */
314:            public final void defineFunction(Named proc) {
315:                Object name = proc.getSymbol();
316:                Symbol sym = (name instanceof  Symbol ? (Symbol) name
317:                        : getSymbol(name.toString()));
318:                Object property = (hasSeparateFunctionNamespace() ? EnvironmentKey.FUNCTION
319:                        : null);
320:                environ.define(sym, property, proc);
321:            }
322:
323:            /** Enter a function into the current environment.
324:             * Same as define(name,proc) for Scheme, but not for (say) Common Lisp.
325:             **/
326:            public void defineFunction(String name, Object proc) {
327:                Object property = (hasSeparateFunctionNamespace() ? EnvironmentKey.FUNCTION
328:                        : null);
329:                environ.define(getSymbol(name), property, proc);
330:            }
331:
332:            /** Import all the public fields of an object. */
333:            private void defineAll(Object object) {
334:                Class clas = object.getClass();
335:                java.lang.reflect.Field[] fields = clas.getFields();
336:                for (int i = fields.length; --i >= 0;) {
337:                    java.lang.reflect.Field field = fields[i];
338:                    String name = field.getName();
339:                    if (name.startsWith(Declaration.PRIVATE_PREFIX)
340:                            || name.endsWith("$instance"))
341:                        continue;
342:                    if ((field.getModifiers() & java.lang.reflect.Modifier.FINAL) != 0) {
343:                        try {
344:                            defineFromFieldValue(field, field.get(object));
345:                        } catch (Throwable ex) {
346:                            throw new WrappedException("error accessing field "
347:                                    + field, ex);
348:                        }
349:                    } else {
350:                        System.err.println("INTERNAL ERROR in defineAll for "
351:                                + name + " in " + clas);
352:                    }
353:                }
354:            }
355:
356:            private void defineFromFieldValue(java.lang.reflect.Field fld,
357:                    Object value) throws Throwable {
358:                if (value instanceof  Location) {
359:                    Location loc = (Location) value;
360:                    Symbol sym = loc.getKeySymbol();
361:                    if (sym != null) {
362:                        environ.addLocation(sym, loc.getKeyProperty(), loc);
363:                        return;
364:                    }
365:                } else {
366:                    Object vname;
367:                    if (value instanceof  Named)
368:                        vname = ((Named) value).getSymbol();
369:                    else
370:                        vname = null;
371:                    if (vname == null)
372:                        vname = Compilation.demangleName(fld.getName(), true)
373:                                .intern();
374:                    Symbol symbol = vname instanceof  Symbol ? (Symbol) vname
375:                            : environ.getSymbol(vname.toString());
376:                    Object prop = getEnvPropertyFor(fld, value);
377:                    environ.define(symbol, prop, value);
378:                }
379:            }
380:
381:            public Object getEnvPropertyFor(java.lang.reflect.Field fld,
382:                    Object value) {
383:                if (!hasSeparateFunctionNamespace())
384:                    return null;
385:                if (Compilation.typeProcedure.getReflectClass()
386:                        .isAssignableFrom(fld.getType()))
387:                    return EnvironmentKey.FUNCTION;
388:                return null;
389:            }
390:
391:            public Object getEnvPropertyFor(Declaration decl) {
392:                if (hasSeparateFunctionNamespace() && decl.isProcedureDecl())
393:                    return EnvironmentKey.FUNCTION;
394:                return null;
395:            }
396:
397:            public void loadClass(String name)
398:                    throws java.lang.ClassNotFoundException {
399:                try {
400:                    Class clas = Class.forName(name);
401:                    Object inst = clas.newInstance();
402:                    defineAll(inst);
403:                    if (inst instanceof  ModuleBody)
404:                        ((ModuleBody) inst).run();
405:                } catch (java.lang.ClassNotFoundException ex) {
406:                    throw ex;
407:                } catch (Exception ex) {
408:                    throw new WrappedException("cannot load " + name, ex);
409:                }
410:            }
411:
412:            public Symbol getSymbol(String name) {
413:                return environ.getSymbol(name);
414:            }
415:
416:            public Object lookup(String name) {
417:                return environ.get(name);
418:            }
419:
420:            public AbstractFormat getFormat(boolean readable) {
421:                return null;
422:            }
423:
424:            public Consumer getOutputConsumer(Writer out) {
425:                OutPort oport = out instanceof  OutPort ? (OutPort) out
426:                        : new OutPort(out);
427:                oport.objectFormat = getFormat(false);
428:                return oport;
429:            }
430:
431:            public String getName() {
432:                String name = getClass().getName();
433:                int dot = name.lastIndexOf('.');
434:                if (dot >= 0)
435:                    name = name.substring(dot + 1);
436:                return name;
437:            }
438:
439:            public abstract Lexer getLexer(InPort inp, SourceMessages messages);
440:
441:            public Compilation getCompilation(Lexer lexer,
442:                    SourceMessages messages) {
443:                return new Compilation(this , messages);
444:            }
445:
446:            /** Flag to tell parse that expression will be evaluated immediately.
447:             * I.e. we're not creating class files for future execution. */
448:            public static final int PARSE_IMMEDIATE = 1;
449:            /** Flag to tell parse to only read a single line if possible.
450:             * Multiple lines may be read if syntactically required. */
451:            public static final int PARSE_ONE_LINE = 2;
452:            /** Flag to tell parser to continue until we have the module name.
453:             * The parser is allowed to continue further, but must stop before
454:             * any module import. */
455:            public static final int PARSE_PROLOG = 4;
456:
457:            public static boolean requirePedantic;
458:
459:            /** Parse one or more expressions.
460:             * @param port the InPort to read the expressions from.
461:             * @param messages where to send error messages and warnings
462:             * @param options various flags, includding PARSE_IMMEDIATE 
463:             *   and PARSE_ONE_LINE
464:             * @return a new Compilation.
465:             *   May return null if PARSE_ONE_LINE on end-of-file.
466:             */
467:            public final Compilation parse(InPort port,
468:                    gnu.text.SourceMessages messages, int options)
469:                    throws java.io.IOException, gnu.text.SyntaxException {
470:                return parse(getLexer(port, messages), options, null);
471:            }
472:
473:            public final Compilation parse(InPort port,
474:                    gnu.text.SourceMessages messages, ModuleInfo info)
475:                    throws java.io.IOException, gnu.text.SyntaxException {
476:                return parse(getLexer(port, messages), Language.PARSE_PROLOG,
477:                        info);
478:            }
479:
480:            public final Compilation parse(Lexer lexer, int options,
481:                    ModuleInfo info) throws java.io.IOException,
482:                    gnu.text.SyntaxException {
483:                SourceMessages messages = lexer.getMessages();
484:                Compilation tr = getCompilation(lexer, messages);
485:                if (requirePedantic)
486:                    tr.pedantic = true;
487:                tr.immediate = (options & PARSE_IMMEDIATE) != 0;
488:                if ((options & PARSE_PROLOG) != 0)
489:                    tr.setState(Compilation.PROLOG_PARSING);
490:                tr.pushNewModule(lexer);
491:                if (info != null)
492:                    info.setCompilation(tr);
493:                if (!parse(tr, options))
494:                    return null;
495:                if (tr.getState() == Compilation.PROLOG_PARSING)
496:                    tr.setState(Compilation.PROLOG_PARSED);
497:                return tr;
498:            }
499:
500:            public abstract boolean parse(Compilation comp, int options)
501:                    throws java.io.IOException, gnu.text.SyntaxException;
502:
503:            /** Perform any need post-processing after we've read all the modules
504:             * to be compiled.
505:             * Using a separate pass allows compiling mutually recursive modules. */
506:            public void resolve(Compilation comp) {
507:            }
508:
509:            public Type getTypeFor(Class clas) {
510:                return Type.make(clas);
511:            }
512:
513:            public final Type getLangTypeFor(Type type) {
514:                if (!(type instanceof  ObjectType)
515:                        || ((ObjectType) type).isExisting()) {
516:                    Class clas = type.getReflectClass();
517:                    if (clas != null)
518:                        return getTypeFor(clas);
519:                }
520:                return type;
521:            }
522:
523:            public String formatType(Type type) {
524:                return type.toString();
525:            }
526:
527:            public static Type string2Type(String name) {
528:                Type t;
529:                if (name.endsWith("[]")) {
530:                    t = string2Type(name.substring(0, name.length() - 2));
531:                    if (t == null)
532:                        return null;
533:                    t = gnu.bytecode.ArrayType.make(t);
534:                } else if (gnu.bytecode.Type.isValidJavaTypeName(name))
535:                    t = gnu.bytecode.Type.getType(name);
536:                else
537:                    return null;
538:                return t;
539:            }
540:
541:            public Type getTypeFor(String name) {
542:                return string2Type(name);
543:            }
544:
545:            public final Type getTypeFor(Object spec, boolean lenient) {
546:                if (spec instanceof  Type)
547:                    return (Type) spec;
548:                if (spec instanceof  Class)
549:                    return getTypeFor((Class) spec);
550:                if (lenient
551:                        && (spec instanceof  FString
552:                                || spec instanceof  String
553:                                || (spec instanceof  Symbol && ((Symbol) spec)
554:                                        .hasEmptyNamespace()) || spec instanceof  CharSeq))
555:                    return getTypeFor(spec.toString());
556:                if (spec instanceof  Namespace) {
557:                    String uri = ((Namespace) spec).getName();
558:                    if (uri != null && uri.startsWith("class:"))
559:                        return getLangTypeFor(string2Type(uri.substring(6)));
560:                }
561:                return null;
562:            }
563:
564:            /** "Coerce" a language-specific "type specifier" object to a Type. */
565:            public final Type asType(Object spec) {
566:                Type type = getTypeFor(spec, true);
567:                return type == null ? (Type) spec : type;
568:            }
569:
570:            public final Type getTypeFor(Expression exp) {
571:                return getTypeFor(exp, true);
572:            }
573:
574:            public Type getTypeFor(Expression exp, boolean lenient) {
575:                if (exp instanceof  QuoteExp) {
576:                    return getTypeFor(((QuoteExp) exp).getValue(), lenient);
577:                } else if (exp instanceof  ReferenceExp) {
578:                    ReferenceExp rexp = (ReferenceExp) exp;
579:                    Declaration decl = Declaration.followAliases(rexp
580:                            .getBinding());
581:                    String name = rexp.getName();
582:                    if (decl != null) {
583:                        name = decl.getName();
584:                        exp = decl.getValue();
585:                        if (decl.isAlias() && exp instanceof  QuoteExp) {
586:                            Object val = ((QuoteExp) exp).getValue();
587:                            if (val instanceof  Location) {
588:                                Location loc = (Location) val;
589:                                if (loc.isBound())
590:                                    return asType(loc.get());
591:                                if (!(loc instanceof  Named))
592:                                    return null;
593:                                name = ((Named) loc).getName();
594:                            }
595:                        } else if (!decl.getFlag(Declaration.IS_UNKNOWN))
596:                            return getTypeFor(exp, lenient);
597:                    }
598:                    Object val = getEnvironment().get(name);
599:                    if (val instanceof  Type)
600:                        return (Type) val;
601:                    if (val instanceof  ClassNamespace)
602:                        return ((ClassNamespace) val).getClassType();
603:                    int len = name.length();
604:                    if (len > 2 && name.charAt(0) == '<'
605:                            && name.charAt(len - 1) == '>')
606:                        return getTypeFor(name.substring(1, len - 1));
607:                } else if (exp instanceof  ClassExp || exp instanceof  ModuleExp) {
608:                    return ((LambdaExp) exp).getType();
609:                }
610:                return null;
611:            }
612:
613:            public Declaration declFromField(ModuleExp mod, Object fvalue,
614:                    Field fld) {
615:                String fname = fld.getName();
616:                Type ftype = fld.getType();
617:                boolean isAlias = ftype.isSubtype(Compilation.typeLocation);
618:                Object fdname;
619:                // FIXME if fvalue is FieldLocation, and field is final,
620:                // get name from value of field.
621:                boolean isImportedInstance;
622:                boolean externalAccess = false;
623:                if ((isImportedInstance = fname.endsWith("$instance")))
624:                    fdname = fname;
625:                else if (fvalue instanceof  Named) // && ! isAlias
626:                    fdname = ((Named) fvalue).getSymbol();
627:                else {
628:                    // FIXME move this to demangleName
629:                    if (fname.startsWith(Declaration.PRIVATE_PREFIX)) {
630:                        externalAccess = true;
631:                        fname = fname.substring(Declaration.PRIVATE_PREFIX
632:                                .length());
633:                    }
634:                    fdname = Compilation.demangleName(fname, true).intern();
635:                }
636:                Type dtype = isAlias ? Type.pointer_type : getTypeFor(ftype
637:                        .getReflectClass());
638:                Declaration fdecl = mod.addDeclaration(fdname, dtype);
639:                boolean isStatic = (fld.getModifiers() & Access.STATIC) != 0;
640:                boolean isFinal = (fld.getModifiers() & Access.FINAL) != 0;
641:                if (isAlias)
642:                    fdecl.setIndirectBinding(true);
643:                else if (isFinal && ftype.isSubtype(Compilation.typeProcedure))
644:                    fdecl.setProcedureDecl(true);
645:                if (isStatic)
646:                    fdecl.setFlag(Declaration.STATIC_SPECIFIED);
647:                fdecl.field = fld;
648:                if (isFinal && !isAlias) // FIXME? ok for location?
649:                    fdecl.setFlag(Declaration.IS_CONSTANT);
650:                if (isImportedInstance)
651:                    fdecl.setFlag(Declaration.MODULE_REFERENCE);
652:                fdecl.setSimple(false);
653:                if (externalAccess)
654:                    fdecl.setFlag(Declaration.EXTERNAL_ACCESS
655:                            | Declaration.PRIVATE);
656:                return fdecl;
657:            }
658:
659:            public static final int VALUE_NAMESPACE = 1 << 0;
660:            public static final int FUNCTION_NAMESPACE = 1 << 1;
661:            public static final int NAMESPACE_PREFIX_NAMESPACE = 1 << 2;
662:
663:            /** Return the namespace (e.g value or function) of a Declaration.
664:             * Return a bitmask of all the namespaces "covered" by the Declaration.
665:             * Note this isn't a namespace in the XML sense; if a Declaration has
666:             * a specific namespace URI, then that is part of its symbol.
667:             * This namespace bitmap is a separate dimension, for the use of
668:             * languages that have separate namespaces for different kinds of
669:             * declarations, such as variables and functions.
670:             */
671:            public int getNamespaceOf(Declaration decl) {
672:                return VALUE_NAMESPACE;
673:            }
674:
675:            /** True if a Declaration is in the specified namespace.
676:             * @param namespace normally a bitmask as returned by getNamespaceOf. */
677:            public boolean hasNamespace(Declaration decl, int namespace) {
678:                return (getNamespaceOf(decl) & namespace) != 0;
679:            }
680:
681:            public void emitPushBoolean(boolean value, CodeAttr code) {
682:                code.emitGetStatic(value ? Compilation.trueConstant
683:                        : Compilation.falseConstant);
684:            }
685:
686:            /** Generate code to test if an object is considered true.
687:             * Assume the object has been pushed on the JVM stack.
688:             * Generate code to push true or false as appropriate. */
689:            public void emitCoerceToBoolean(CodeAttr code) {
690:                emitPushBoolean(false, code);
691:                code.emitIfNEq();
692:                code.emitPushInt(1);
693:                code.emitElse();
694:                code.emitPushInt(0);
695:                code.emitFi();
696:            }
697:
698:            public Object coerceFromObject(Class clas, Object obj) {
699:                return getTypeFor(clas).coerceFromObject(obj);
700:            }
701:
702:            public Object coerceToObject(Class clas, Object obj) {
703:                return getTypeFor(clas).coerceToObject(obj);
704:            }
705:
706:            public Object coerceToObject(int val) {
707:                return gnu.math.IntNum.make(val);
708:            }
709:
710:            public static synchronized void setDefaults(Language lang) {
711:                Language.setDefaultLanguage(lang);
712:                current.setGlobal(lang);
713:                // Assuming this is the initial (main) thread, make it's Environment
714:                // the default (global) one, so child threads can inherit from it.
715:                // Thus command-line definitions etc get inherited.
716:                if (Environment.getGlobal() == BuiltinEnvironment.getInstance())
717:                    Environment.setGlobal(Environment.getCurrent());
718:            }
719:
720:            public Procedure getPrompter() {
721:                Object property = null;
722:                if (hasSeparateFunctionNamespace())
723:                    property = EnvironmentKey.FUNCTION;
724:                Procedure prompter = (Procedure) getEnvironment().get(
725:                        getSymbol("default-prompter"), property, null);
726:                if (prompter != null)
727:                    return prompter;
728:                else
729:                    return new SimplePrompter();
730:            }
731:
732:            /** Return the result of evaluating a string as a source expression. */
733:            public final Object eval(String string) throws Throwable {
734:                return eval(new CharArrayInPort(string));
735:            }
736:
737:            /** Evaluate expression(s) read from a Reader.
738:             * This just calls eval(InPort).
739:             */
740:            public final Object eval(Reader in) throws Throwable {
741:                return eval(in instanceof  InPort ? (InPort) in : new InPort(in));
742:            }
743:
744:            /** Evaluate expression(s) read from an InPort. */
745:            public final Object eval(InPort port) throws Throwable {
746:                CallContext ctx = CallContext.getInstance();
747:                int oldIndex = ctx.startFromContext();
748:                try {
749:                    eval(port, ctx);
750:                    return ctx.getFromContext(oldIndex);
751:                } catch (Throwable ex) {
752:                    ctx.cleanupFromContext(oldIndex);
753:                    throw ex;
754:                }
755:            }
756:
757:            /** Evaluate a string and write the result value(s) on a Writer. */
758:            public final void eval(String string, Writer out) throws Throwable {
759:                eval(new CharArrayInPort(string), out);
760:            }
761:
762:            /** Evaluate a string and write the result value(s) to a PrintConsumer.
763:             * This is to disambiguate calls using OutPort or XMLPrinter,
764:             * which are both Writer and Consumer. */
765:            public final void eval(String string, PrintConsumer out)
766:                    throws Throwable {
767:                eval(string, getOutputConsumer(out));
768:            }
769:
770:            /** Evaluate a string and write the result value(s) to a Consumer. */
771:            public final void eval(String string, Consumer out)
772:                    throws Throwable {
773:                eval(new CharArrayInPort(string), out);
774:            }
775:
776:            /** Read expressions from a Reader and write the result to a Writer. */
777:            public final void eval(Reader in, Writer out) throws Throwable {
778:                eval(in, getOutputConsumer(out));
779:            }
780:
781:            /** Read expressions from a Reader and write the result to a Consumer. */
782:            public void eval(Reader in, Consumer out) throws Throwable {
783:                InPort port = in instanceof  InPort ? (InPort) in : new InPort(
784:                        in);
785:                CallContext ctx = CallContext.getInstance();
786:                Consumer save = ctx.consumer;
787:                try {
788:                    ctx.consumer = out;
789:                    eval(port, ctx);
790:                } finally {
791:                    ctx.consumer = save;
792:                }
793:            }
794:
795:            public void eval(InPort port, CallContext ctx) throws Throwable {
796:                SourceMessages messages = new SourceMessages();
797:                Language saveLang = getDefaultLanguage();
798:                setDefaultLanguage(this );
799:                try {
800:                    Compilation comp = parse(port, messages, PARSE_IMMEDIATE);
801:                    ModuleExp.evalModule(getEnvironment(), ctx, comp, null,
802:                            null);
803:                } finally {
804:                    setDefaultLanguage(saveLang);
805:                }
806:                if (messages.seenErrors())
807:                    throw new RuntimeException("invalid syntax in eval form:\n"
808:                            + messages.toString(20));
809:            }
810:
811:            static protected int env_counter = 0;
812:
813:            public void runAsApplication(String[] args) {
814:                setDefaults(this );
815:                kawa.repl.main(args);
816:            }
817:        }
818:
819:        class SimplePrompter extends Procedure1 {
820:            public String prefix = "[";
821:            public String suffix = "] ";
822:
823:            public Object apply1(Object arg) {
824:                if (arg instanceof  InPort) {
825:                    InPort port = (InPort) arg;
826:                    int line = port.getLineNumber() + 1;
827:                    if (line >= 0)
828:                        return prefix + line + suffix;
829:                }
830:                return suffix;
831:            }
832:
833:            // The compiler finds registerEnvironment by using reflection.
834:            //
835:            // public static void registerEnvironment()
836:            // { Environment.setGlobal(new ...().getEnvironment()); }
837:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.