001: /**************************************************************************/
002: /* N I C E */
003: /* A high-level object-oriented research language */
004: /* (c) Daniel Bonniot 2002 */
005: /* */
006: /* This program is free software; you can redistribute it and/or modify */
007: /* it under the terms of the GNU General Public License as published by */
008: /* the Free Software Foundation; either version 2 of the License, or */
009: /* (at your option) any later version. */
010: /* */
011: /**************************************************************************/package bossa.syntax;
012:
013: import java.util.*;
014: import bossa.util.*;
015: import mlsub.typing.TypeSymbol;
016:
017: /**
018: A Scope level for types.
019:
020: @version $Date: 2005/04/18 19:04:58 $
021: @author Daniel Bonniot (bonniot@users.sourceforge.net)
022: */
023: public class TypeScope implements TypeMap {
024: public TypeScope(TypeScope outer) {
025: this .outer = outer;
026: this .map = new HashMap();
027: }
028:
029: // only for GlobalTypeScope
030: void setPackage(bossa.modules.Package pkg) {
031: }
032:
033: bossa.modules.Package getPackage() {
034: return null;
035: }
036:
037: public mlsub.typing.TypeConstructor globalLookup(String name,
038: Location loc) {
039: return null;
040: }
041:
042: void addSymbol(TypeSymbol s) throws DuplicateName {
043: addMapping(s.toString(), s);
044: }
045:
046: void addSymbols(Collection c) throws DuplicateName {
047: Iterator i = c.iterator();
048: while (i.hasNext())
049: addSymbol((TypeSymbol) i.next());
050: }
051:
052: void addSymbols(TypeSymbol[] c) throws DuplicateName {
053: for (int i = c.length; --i >= 0;)
054: addSymbol(c[i]);
055: }
056:
057: class DuplicateName extends Exception {
058: DuplicateName(String name) {
059: super (name + " is already declared");
060: }
061: }
062:
063: void addMapping(String name, TypeSymbol s) throws DuplicateName {
064: Object old = map.put(name, s);
065: if (old != null)
066: throw new DuplicateName(name);
067: }
068:
069: /** Change a previous mapping. */
070: void updateMapping(String name, TypeSymbol s) {
071: map.put(name, s);
072: }
073:
074: void addMappings(Collection names, TypeSymbol[] symbols)
075: throws DuplicateName {
076: if (symbols != null && names.size() != symbols.length)
077: throw new mlsub.typing.BadSizeEx(symbols.length, names
078: .size());
079:
080: int n = 0;
081: for (Iterator in = names.iterator(); in.hasNext();)
082: addMapping((String) in.next(), symbols[n++]);
083: }
084:
085: void addMappingsLS(Collection names, TypeSymbol[] symbols)
086: throws DuplicateName {
087: if (symbols != null && names.size() != symbols.length)
088: throw new mlsub.typing.BadSizeEx(symbols.length, names
089: .size());
090:
091: int n = 0;
092: for (Iterator in = names.iterator(); in.hasNext();)
093: addMapping(((LocatedString) in.next()).toString(),
094: symbols[n++]);
095: }
096:
097: TypeSymbol get(String name) {
098: TypeSymbol typeSymbol = (TypeSymbol) map.get(name);
099: if (typeSymbol != null)
100: return typeSymbol;
101: // A workaround required to find Nice classes having a '$' in the name.
102: // Such classes are placed into the scope with their correct name,
103: // but when looked up from the bytecode, the '$' is replaced with a '.'.
104: // Therefore we'll try to replace '.' back into '$'.
105: int dot;
106: while (true) {
107: dot = name.lastIndexOf('.');
108: if (-1 == dot)
109: return null;
110: name = name.substring(0, dot) + '$'
111: + name.substring(dot + 1);
112: typeSymbol = (TypeSymbol) map.get(name);
113: if (typeSymbol != null)
114: return typeSymbol;
115: }
116: }
117:
118: public final TypeSymbol lookup(String name) {
119: return lookup(name, null);
120: }
121:
122: public final TypeSymbol lookup(LocatedString name) {
123: return lookup(name.toString(), name.location());
124: }
125:
126: TypeSymbol lookup(String name, Location loc) {
127: TypeSymbol res = get(name);
128: if (res != null)
129: return res;
130:
131: if (outer != null)
132: return outer.lookup(name, loc);
133:
134: return null;
135: }
136:
137: /****************************************************************
138: * Debugging
139: ****************************************************************/
140:
141: public String toString() {
142: return map.toString() + (outer != null ? ";;\n" + outer : "");
143: }
144:
145: private TypeScope outer;
146: private Map map;
147: }
|