Back to index

texmacs  1.0.7.15
assoc_environment.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : assoc_environment.cpp
00004 * DESCRIPTION: association lists as environments
00005 * COPYRIGHT  : (C) 2006  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "assoc_environment.hpp"
00013 
00014 tree assoc_node::uninit (UNINIT);
00015 tree assoc_environment_rep::uninit (UNINIT);  
00016 
00017 /******************************************************************************
00018 * Standard methods for assoc environments
00019 ******************************************************************************/
00020 
00021 bool
00022 assoc_environment_rep::contains (int key) {
00023   for (int i=0; i<n; i++)
00024     if (a[i].key == key) return true;
00025   return false;
00026 }
00027 
00028 tree
00029 assoc_environment_rep::read (int key) {
00030   for (int i=0; i<n; i++)
00031     if (a[i].key == key) return a[i].val;
00032   return uninit;
00033 }
00034 
00035 void
00036 assoc_environment_rep::write (int key, const tree& val) {
00037   for (int i=0; i<n; i++)
00038     if (a[i].key == key) { a[i].val= val; return; }
00039   assoc_node* b= tm_new_array<assoc_node> (n+1);
00040   for (int i=0; i<n; i++) b[i]= a[i];
00041   b[n].key= key;
00042   b[n].val= val;
00043   tm_delete_array (a);
00044   a= b;
00045   n++;
00046 }
00047 
00048 void
00049 assoc_environment_rep::remove (int key) {
00050   for (int i=0; i<n; i++)
00051     if (a[i].key == key) {
00052       assoc_node* b= tm_new_array<assoc_node> (n-1);
00053       for (int j=0; j<i; j++) b[j]= a[j];
00054       for (int j=i+1; j<n; j++) b[j-1]= a[j];
00055       tm_delete_array (a);
00056       a= b;
00057       n--;
00058       return;
00059     }
00060 }
00061 
00062 void
00063 assoc_environment_rep::print (const string& prefix) {
00064   cout << prefix << "Assoc environment" << LF;
00065   for (int i=0; i<n; i++)
00066     cout << prefix << "| " << a[i].key
00067         << ": " << as_string ((tree_label) a[i].key)
00068         << " -> " << a[i].val << LF;
00069 }
00070 
00071 /******************************************************************************
00072 * Copying
00073 ******************************************************************************/
00074 
00075 assoc_environment
00076 copy (assoc_environment env) {
00077   int i, n= env->n;
00078   assoc_environment r (n);
00079   for (i=0; i<n; i++)
00080     r->raw_write (i, env->a[i].key, env->a[i].val);
00081   return r;
00082 }
00083 
00084 /******************************************************************************
00085 * Weak hashing
00086 ******************************************************************************/
00087 
00088 int
00089 weak_hash (assoc_environment env) {
00090   int i, n= env->n, h=0;
00091   assoc_node* a= env->a;
00092   for (i=0; i<n; i++)
00093     h= (h<<1) ^ (h>>31) ^ a[i].key ^ (weak_hash (a[i].val)<<2);
00094   return h;
00095 }
00096 
00097 bool
00098 weak_equal (assoc_environment env1, assoc_environment env2) {
00099   int i, n= env1->n;
00100   if (env2->n != n) return false;
00101   assoc_node* a1= env1->a;
00102   assoc_node* a2= env2->a;
00103   for (i=0; i<n; i++)
00104     if (a1[i].key != a2[i].key || !weak_equal (a1[i].val, a2[i].val))
00105       return false;
00106   return true;
00107 }