[Nice-commit] Nice/src/nice/tools/visibility tests.nice,NONE,1.1 impl.nice,NONE,1.1 api.nice,NONE,1.
Brought to you by:
bonniot
|
From: Daniel B. <bo...@us...> - 2005-03-06 12:56:08
|
Update of /cvsroot/nice/Nice/src/nice/tools/visibility In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24573/src/nice/tools/visibility Added Files: tests.nice impl.nice api.nice MultiMap.nice Log Message: Added the nice.tools.visibility package. Use it for global scoping of (non-type) symbols. No functionality change yet. --- NEW FILE: MultiMap.nice --- /**************************************************************************/ /* N I C E */ /* A high-level object-oriented research language */ /* (c) Daniel Bonniot 2005 */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /**************************************************************************/ package nice.tools.visibility; /** Mapping keys to lists of values. @author Daniel Bonniot (bo...@us...) */ class MultiMap<K,V> { void add(K key, V value) { ?List<V> values = map[key]; if (values == null) { values = new LinkedList(); map[key] = notNull(values); } // We could as well add at the end. // Temporarily, we add at the begining to match the previous implementation // so as not to cause random changes due to known bugs. notNull(values).add(0, value); } void remove(K key, V value) { ?List<V> values = map[key]; if (values == null) return; values.remove(value); } ?List<V> get(K key) = map[key]; private HashMap<K,List<V>> map = new HashMap(); } --- NEW FILE: impl.nice --- /**************************************************************************/ /* N I C E */ /* A high-level object-oriented research language */ /* (c) Daniel Bonniot 2005 */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /**************************************************************************/ package nice.tools.visibility; /** Implementation. @author Daniel Bonniot (bo...@us...) */ private <Sym> ?List<Sym> maybeGet(?Scope<Sym> s, String key) = s == null ? null : s.map[key]; add(Scope this, key, value, visibility) = map.add(key, value); add(Scope this, key, value, familial) { super; if (parent != null) notNull(parent).add(key, value, intimate); } add(Scope this, key, value, general) { super; publicMap.add(key, value); } remove(Scope this, key, value) { map.remove(key, value); publicMap.remove(key, value); } addImplicitOpen(Scope this, Scope scope) = opens.add(scope); <Sym> get(Scope this, root, key) = this.getScope(root).maybeGet(key) || empty; <Sym> get(Scope this, key) = map[key] || parent.maybeGet(key) || opens[key] || empty; <Sym> ?List<Sym> get(List<Scope<Sym>> scopes, String key) { ?List<Sym> res = null; for (Scope<Sym> scope : scopes) { let partial = scope.publicMap[key]; if (partial != null) { if (res == null) res = new LinkedList(); notNull(res).addAll(partial); } } return res; } private <Sym> ?Scope<Sym> getScope(Scope<Sym> this, String root) { if (this.name.equals(root)) return this; if (parent != null) { let res = notNull(parent).getScope(root); if (res != null) return res; } ?Scope<Sym> s = opens.search(Scope<Sym> s => s.name.equals(root)); return s; } --- NEW FILE: tests.nice --- /**************************************************************************/ /* N I C E */ /* A high-level object-oriented research language */ /* (c) Daniel Bonniot 2005 */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /**************************************************************************/ package nice.tools.visibility; /** Tests. @author Daniel Bonniot (bo...@us...) */ void _testSingle() { Scope<char> s = new Scope(name: "root", parent: null); List<char> res; res = s.get("foo"); assert res.size == 0; s.add("a", 'b'); res = s.get("a"); assert res.size == 1 && res[0] == 'b'; res = s.get("root", "a"); assert res.size == 1 && res[0] == 'b'; s.add("a", 'c'); res = s.get("a"); assert res.size == 2 && res.contains('b') && res.contains('c'); } void _testNesting() { Scope<char> root = new Scope(name: "root", parent: null); Scope<char> inner = new Scope(name: "inner", parent: root); List<char> res; res = inner.get("foo"); assert res.size == 0; root.add("a", 'r'); res = inner.get("a"); assert res.size == 1 && res[0] == 'r'; inner.add("a", 'i'); res = inner.get("a"); assert res.size == 1 && res[0] == 'i'; res = inner.get("root", "a"); assert res.size == 1 && res[0] == 'r'; inner.add("a", 'j'); res = inner.get("a"); assert res.size == 2 && res.contains('i') && res.contains('j'); } void _testOpen() { Scope<char> pkg1 = new Scope(name: "pkg1", parent: null); Scope<char> pkg2 = new Scope(name: "pkg2", parent: null); pkg2.add("a", '2', general); List<char> res; res = pkg1.get("a"); assert res.size == 0; pkg1.addImplicitOpen(pkg2); res = pkg1.get("a"); assert res.size == 1 && res[0] == '2'; pkg1.add("a", '1'); res = pkg1.get("a"); assert res.size == 1 && res[0] == '1'; res = pkg1.get("pkg1", "a"); assert res.size == 1 && res[0] == '1'; res = pkg1.get("pkg2", "a"); assert res.size == 1 && res[0] == '2'; pkg1.add("a", '0'); res = pkg1.get("a"); assert res.size == 2 && res.contains('0') && res.contains('1'); } void _testNestingOpen() { Scope<char> root = new Scope(name: "root", parent: null); Scope<char> pkg1 = new Scope(name: "pkg1", parent: root); Scope<char> pkg2 = new Scope(name: "pkg2", parent: null); root.add("a", '0'); pkg2.add("a", '2'); List<char> res; res = pkg1.get("a"); assert res.size == 1 && res[0] == '0'; pkg1.addImplicitOpen(pkg2); res = pkg1.get("a"); assert res.size == 1 && res[0] == '0'; pkg1.add("a", '1'); res = pkg1.get("a"); assert res.size == 1 && res[0] == '1'; res = pkg1.get("root", "a"); assert res.size == 1 && res[0] == '0'; res = pkg1.get("pkg2", "a"); assert res.size == 1 && res[0] == '2'; pkg1.add("a", '+'); res = pkg1.get("a"); assert res.size == 2 && res.contains('1') && res.contains('+'); } void _testMultiOpen() { Scope<char> cur = new Scope(name: "cur", parent: null); Scope<char> pkg1 = new Scope(name: "pkg1", parent: null); Scope<char> pkg2 = new Scope(name: "pkg2", parent: null); cur.addImplicitOpen(pkg1); cur.addImplicitOpen(pkg2); pkg1.add("a", '1', general); List<char> res; res = cur.get("a"); assert res.size == 1 && res[0] == '1'; pkg2.add("a", '2', general); res = cur.get("a"); assert res.size == 2 && res.contains('1') && res.contains('2'); cur.add("a", '0'); res = cur.get("a"); assert res.size == 1 && res[0] == '0'; res = cur.get("pkg1", "a"); assert res.size == 1 && res[0] == '1'; res = cur.get("pkg2", "a"); assert res.size == 1 && res[0] == '2'; } void _testVisibility() { Scope<char> root = new Scope(name: "root", parent: null); Scope<char> inner1 = new Scope(name: "inner1", parent: root); Scope<char> inner2 = new Scope(name: "inner2", parent: root); List<char> res; inner1.add("i", 'i', intimate); res = inner1.get("i"); assert res.size == 1 && res[0] == 'i'; res = inner2.get("i"); assert res.size == 0; res = root.get("i"); assert res.size == 0; root.add("i", 'r', intimate); res = inner1.get("i"); assert res.size == 1 && res[0] == 'i'; res = inner1.get("root", "i"); assert res.size == 1 && res[0] == 'r'; res = inner2.get("root", "i"); assert res.size == 1 && res[0] == 'r'; inner1.add("f", 'f', familial); res = inner1.get("f"); assert res.size == 1 && res[0] == 'f'; res = inner2.get("f"); assert res.size == 1 && res[0] == 'f'; res = root.get("f"); assert res.size == 1 && res[0] == 'f'; } void _testGeneralVisibility() { Scope<char> pkg1 = new Scope(name: "pkg1", parent: null); Scope<char> pkg2 = new Scope(name: "pkg2", parent: null); pkg1.addImplicitOpen(pkg2); pkg2.add("b", '4'); pkg2.add("c", '5', familial); List<char> res; res = pkg1.get("b"); assert res.size == 0; res = pkg1.get("c"); assert res.size == 0; pkg2.add("a", '2', general); res = pkg1.get("a"); assert res.size == 1 && res[0] == '2'; pkg1.add("a", '1'); res = pkg1.get("a"); assert res.size == 1 && res[0] == '1'; res = pkg1.get("pkg1", "a"); assert res.size == 1 && res[0] == '1'; res = pkg1.get("pkg2", "a"); assert res.size == 1 && res[0] == '2' ; pkg1.add("a", '0'); res = pkg1.get("a"); assert res.size == 2 && res.contains('0') && res.contains('1'); } --- NEW FILE: api.nice --- /**************************************************************************/ /* N I C E */ /* A high-level object-oriented research language */ /* (c) Daniel Bonniot 2005 */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /**************************************************************************/ package nice.tools.visibility; /** A generic visibility system. @author Daniel Bonniot (bo...@us...) */ enum Visibility { intimate, familial, general } class Scope<Sym> { String name; final ?Scope<Sym> parent; void add(String, Sym, Visibility visibility = intimate); void remove(String, Sym); List<Sym> get(String root, String key); List<Sym> get(String key); void addImplicitOpen(Scope<Sym>); private MultiMap<String, Sym> map = new MultiMap(); private MultiMap<String, Sym> publicMap = new MultiMap(); private List<Scope<Sym>> opens = new LinkedList(); private List<Sym> empty = new Sym[0]; } |