Nice/src/nice/tools/visibility tests.nice,NONE,1.1 impl.nice,NONE,1.1 api.nice,NONE,1.1 MultiMap.nice,NONE,1.1

Daniel Bonniot <[email protected]>
Newsgroups gmane.comp.lang.nice.cvs
Message-ID <[email protected]>
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 ([email protected])
 */

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 ([email protected])
 */

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 ([email protected])
 */

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 ([email protected])
 */

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];
}



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.