379 lines
8.5 KiB
C#
379 lines
8.5 KiB
C#
|
|
|
|||
|
|
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;
|
|||
|
|
}
|
|||
|
|
}*/
|
|||
|
|
}
|