pascalabcnet/TreeConverter/SymbolTable/NVSymbolTable.cs

379 lines
8.5 KiB
C#
Raw Normal View History

2015-05-14 22:35:07 +03:00

using System;
using System.Collections;
namespace TreeConverter
{
public abstract class scope : base_scope
{
private Hashtable ht=new Hashtable();
public string name_to_symtab(string name)
{
return name.ToLower();
}
public void add_name(string name,SymbolInfo si)
{
name=name_to_symtab(name);
object o=ht[name];
if (o==null)
{
SymbolInfoArrayList syal=new SymbolInfoArrayList();
syal.Add(si);
ht[name]=syal;
return;
}
else
{
/*if (si.symbol_kind==symbol_kind.sk_none)
{
throw new CompilerInternalError("Duplicate name definition");
}*/
SymbolInfoArrayList syal1=(SymbolInfoArrayList)o;
syal1.Add(si);
return;
}
}
public virtual SymbolInfo find_only_in_namespace(string name)
{
name=name_to_symtab(name);
object o=ht[name];
if (o==null)
{
return null;
}
SymbolInfoArrayList syal=(SymbolInfoArrayList)o;
int i=1;
while(i<syal.Count)
{
syal[i-1].Next=syal[i];
i++;
}
syal[i-1].Next=null;
return syal[0];
}
public static SymbolInfo split_lists(SymbolInfo si_left,SymbolInfo si_right)
{
if (si_left==null)
{
return si_right;
}
if (si_right==null)
{
return si_left;
}
SymbolInfo si=si_left;
while(si.Next!=null)
{
si=si.Next;
}
si.Next=si_right;
return si_left;
}
//ВНИМАНИЕ. В этом методе, поиск в another_scopes производится в том порядке, в котором они передаются.
//И в выходном списке эти узлы будут в соответствующем порядке.
//Преобразователь дерева простматривая этот список, и встретив два абсолютно одинаковых метода
//выкинет из списка, встреченный последним.
//Т.е. если первое из another_namespace - пространство имен класса,
//а второе - пространство имен, в котором объявлен метод, то найденные в классе методы будут
//расположены в списке раньше, чем найденные в пространстве имен.
//Таким образом если и в классе и в пространстве имен, окружающем метод, есть два перегруженных
//метода с одинаковым списком параметров, то метод в пространстве имен, окружающем метод,
//будет проигнорирован.
public SymbolInfo find_and_split(string name,bool brake_if_find,params base_scope[] another_scopes)
{
SymbolInfo si_first=this.find_only_in_namespace(name);
if (si_first!=null)
{
if ((brake_if_find)||(si_first.symbol_kind==symbol_kind.sk_none))
{
return si_first;
}
}
name=name_to_symtab(name);
foreach(scope sc in another_scopes)
{
if (sc==null)
{
continue;
}
SymbolInfo si_second=sc.find(name);
if (si_second==null)
{
continue;
}
if (si_first==null)
{
if ((brake_if_find)||(si_second.symbol_kind==symbol_kind.sk_none))
{
return si_second;
}
si_first=si_second;
continue;
}
if (si_second.symbol_kind==symbol_kind.sk_none)
{
break;
}
si_first=split_lists(si_first,si_second);
}
return si_first;
}
public SymbolInfo find_in_all_and_split(string name,params base_scope[] another_scopes)
{
return find_and_split(name,false,another_scopes);
}
}
public class function_scope : scope
{
private base_scope _up_scope;
public function_scope(base_scope up_scope)
{
_up_scope=up_scope;
}
public override SymbolInfo find(string name)
{
return find_in_all_and_split(name,_up_scope);
}
public override base_scope top_scope
{
get
{
return _up_scope;
}
}
}
public class type_scope : scope
{
private base_scope _base_type_scope;
private base_scope _comprehensive_scope;
public type_scope(base_scope base_type_scope,base_scope comprehensive_scope)
{
_base_type_scope=base_type_scope;
_comprehensive_scope=comprehensive_scope;
}
public override SymbolInfo find(string name)
{
return find_in_all_and_split(name,_base_type_scope,_comprehensive_scope);
}
public SymbolInfo find_in_type(string name)
{
return find_in_all_and_split(name,_base_type_scope);
}
public base_scope comprehensive_scope
{
get
{
return _comprehensive_scope;
}
set
{
_comprehensive_scope=value;
}
}
public base_scope base_type_scope
{
get
{
return _base_type_scope;
}
set
{
_base_type_scope=value;
}
}
public override base_scope top_scope
{
get
{
return _base_type_scope;
}
}
}
public class namespace_scope : scope
{
private base_scope _up_scope;
public namespace_scope(base_scope up_scope)
{
_up_scope=up_scope;
}
public override SymbolInfo find(string name)
{
return find_in_all_and_split(name,_up_scope);
}
public override base_scope top_scope
{
get
{
return _up_scope;
}
}
}
public class interface_scope : scope
{
private base_scope[] _used_units_scopes;
public interface_scope(base_scope[] used_units_scopes)
{
_used_units_scopes=new base_scope[used_units_scopes.Length];
for(int i=0;i<used_units_scopes.Length;i++)
{
_used_units_scopes[used_units_scopes.Length-i-1]=used_units_scopes[i];
}
}
public override SymbolInfo find(string name)
{
return find_in_all_and_split(name,_used_units_scopes);
}
public override base_scope top_scope
{
get
{
return null;
}
}
}
public class implementation_scope : scope
{
private base_scope[] _used_units_scopes;
private interface_scope _iscope;
public implementation_scope(interface_scope iscope,base_scope[] used_units_scopes)
{
_iscope=iscope;
_used_units_scopes=new base_scope[used_units_scopes.Length+1];
_used_units_scopes[0]=iscope;
for(int i=0;i<used_units_scopes.Length;i++)
{
_used_units_scopes[used_units_scopes.Length-i]=used_units_scopes[i];
}
}
public override SymbolInfo find(string name)
{
return find_in_all_and_split(name,_used_units_scopes);
}
public override SymbolInfo find_only_in_namespace(string name)
{
if (_used_units_scopes[0]==null)
{
return base.find_only_in_namespace(name);
}
return split_lists(base.find_only_in_namespace(name),_iscope.find_only_in_namespace(name));
}
public override base_scope top_scope
{
get
{
return _used_units_scopes[0];
}
}
}
public class method_scope : scope
{
private base_scope _type_scope;
private base_scope _comprehensive_namespace_scope;
public method_scope(base_scope _type_scope,base_scope comprehensive_namespace_scope)
{
this._type_scope=_type_scope;
_comprehensive_namespace_scope=comprehensive_namespace_scope;
}
public override SymbolInfo find(string name)
{
return find_and_split(name,true,_type_scope,_comprehensive_namespace_scope);
}
public override base_scope top_scope
{
get
{
return _type_scope;
}
}
}
/*public class SymbolTable
{
public function_scope create_function_scope(base_scope up_scope)
{
return new function_scope(up_scope);
}
public type_scope create_type_scope(base_scope base_type_scope,base_scope comprehensive_namespace_scope)
{
return new type_scope(base_type_scope,comprehensive_namespace_scope);
}
public namespace_scope create_namespace_scope(base_scope up_scope)
{
return new namespace_scope(up_scope);
}
public interface_scope create_interface_scope(base_scope[] used_units_scopes)
{
return new interface_scope(used_units_scopes);
}
public implementation_scope create_implementation_scope(interface_scope _interface_scope,base_scope[] used_units_scopes)
{
return new implementation_scope(_interface_scope,used_units_scopes);
}
public method_scope create_method_scope(base_scope base_type_scope,base_scope comprehensive_namespace_scope)
{
return new method_scope(base_type_scope,comprehensive_namespace_scope);
}
public int get_relative_scope_depth(base_scope upper,base_scope lower)
{
int depth=0;
base_scope bs=lower;
while ((bs!=null)&&(upper!=bs))
{
bs=bs.top_scope;
depth++;
}
if (lower==null)
{
throw new CompilerInternalError("Can not execute static depth");
}
return depth;
}
}*/
}