📄 semanticchecker.cs
字号:
// the string names. Unfortunately, the defualt Type.Equals() doesn't
// do it like that.
int iExpected = (objA.ToString() == objB.ToString()) ? 0 : 1;
Debug.Assert(iExpected == iActual);
#endif
return iActual;
#else
// Another emit bug:
// We have a Type problem. If we go from 1) T --> 2) T[] --> 3) T
// the T in 1 & 3 may be different, but we expect them to be the same.
int iExpected = (objA.ToString() == objB.ToString()) ? 0 : 1;
//Debug.Assert(iExpected == iActual);
return iExpected;
#endif
}
// Fast comparison
// This is nice, but won't work due to silly bugs in the frameworks (see above).
int CompareFast(object objA, object objB)
{
Type tA = (Type) objA;
Type tB = (Type) objB;
if (tA.IsEnum && !tB.IsEnum)
return 1;
if (!tA.IsEnum && tB.IsEnum)
return 1;
if (tA.IsEnum && tB.IsEnum)
return (tA.FullName == tB.FullName) ? 0 : 1;
return (tA == tB) ? 0 : 1;
}
}
protected Hashtable m_hashClrType = new Hashtable (1000, new TypeHashProvider(), new TypeHashProvider());
#endregion
ICLRtypeProvider m_provider;
#region Main checking routine
//-----------------------------------------------------------------------------
// Main checking routine
// Return true if successful, else false
//-----------------------------------------------------------------------------
public bool DoCheck(
AST.ProgramDecl p,
ICLRtypeProvider provider,
Assembly [] refs
)
{
Debug.Assert(provider != null);
Debug.Assert(p != null);
m_provider = provider;
string stSubPhase = "";
try
{
m_scopeGlobal = new Scope("Global", null, null);
// Import symbols
stSubPhase = "importing assemblies";
ImportAssembly(GetMscorlib());
AddDefaultTypes(m_scopeGlobal);
foreach(Assembly a in refs)
{
ImportAssembly(a);
}
// Pass 1 - Resolve the namespaces and stub the types.
// This will stub all scopes and create a lexical-scope tree.
stSubPhase = "resolving namespaces";
p.ResolveNamespace(this, m_scopeGlobal);
// Pass 2 - Resolve Types (to both CLR & Blue)
stSubPhase = "resolving to clr types";
p.ResolveTypes(this, provider);
// Pass 3 - resolve class member declarations (Methods & fields)
stSubPhase = "resolving member declarations";
p.ResolveMemberDecls(this, provider);
// Pass 4 - resolve method bodies
stSubPhase = "resolving member bodies";
p.ResolveBodies(this);
// Final Debug verify before codegen
stSubPhase = "final debug check";
p.DebugCheck(this);
m_scopeGlobal.DebugCheck(this);
p.NotifyResolutionDone();
return true;
}
// Strip away SymbolErrors; we've already reported them when we first threw them.
catch (SymbolError.SymbolErrorException)
{
return false;
}
catch(System.Exception e)
{
Blue.Driver.PrintError_InternalError(e, "Symbol Resolution(" + stSubPhase + ")");
return false;
}
}
#endregion
#region Manage the scope stack
/*
// AST call back on this to push / pop / query scopes
// Can only push a scope once before popping it
public void PushScope(Scope scope)
{
Debug.Assert(scope != null);
Debug.Assert(scope.m_parent == null);
Scope t = m_top;
m_top = scope;
scope.m_parent = t;
}
protected Scope m_top; // top of stack
// Pops off the top scope. If top scope doesn't match scope,
// then scope stack is corrupted and we throw an exception
public void PopScope(Scope scope)
{
Scope t= m_top;
Debug.Assert(m_top == scope);
m_top = m_top.m_parent;
t.m_parent = null;
}
// Get the current scope. Used to add symbols
public Scope GetCurrentScope()
{
return m_top;
}
*/
//-----------------------------------------------------------------------------
// Set the current class that we're processing
//-----------------------------------------------------------------------------
protected TypeEntry m_curClass;
public void SetCurrentClass(TypeEntry type)
{
m_curClass = type;
}
public TypeEntry GetCurrentClass()
{
return m_curClass;
}
protected MethodExpEntry m_curMethod;
public void SetCurrentMethod(MethodExpEntry m)
{
m_curMethod = m;
}
public MethodExpEntry GetCurrentMethod()
{
return m_curMethod;
}
#endregion
#region Hookup to Provider
// Given a symbol for an array type, get the corresponding CLR type.
public System.Type GetArrayType(ArrayTypeEntry sym)
{
System.Type t = m_provider.CreateCLRArrayType(sym);
Debug.Assert(t != null);
return t;
}
// get a reference type
public System.Type GetRefToType(System.Type tElem)
{
System.Type t = m_provider.CreateCLRReferenceType(tElem);
Debug.Assert(t != null);
return t;
}
#endregion
#region Lookup functions
// We only need Lookup() during the resolve phase (because that's the only time
// we need to convert text into symbols)
// After that, we can just use the symbols directly
// Lookup an entry in a specific scope
// If it doesn't exist, then return null if !fMustExist and throw if fMustExist
public SymEntry LookupSymbol(Scope scope, Identifier id, bool fMustExist)
{
SymEntry s = scope.LookupSymbol(id.Text);
if (fMustExist && s == null)
{
ThrowError(SymbolError.UndefinedSymbol(id));
}
return s;
}
// Get rid of this function
public SymEntry LookupSymbol(Scope scope, string st, bool fMustExist)
{
SymEntry s = scope.LookupSymbol(st);
bool f= false;
if (f) {
System.Xml.XmlWriter o = new System.Xml.XmlTextWriter(new System.IO.StreamWriter("dump.xml"));
scope.Dump(o, true);
o.Close();
}
if (fMustExist && s == null)
{
FileRange range = new FileRange();
range.Filename = "<not specified>";
Identifier id = new Identifier(st, range);
//ThrowError_UndefinedSymbol(id);
ThrowError(SymbolError.UndefinedSymbol(id));
}
return s;
}
// Lookup a system type
// Context-free
public TypeEntry LookupSystemType(string st)
{
NamespaceEntry nsSystem = (NamespaceEntry) LookupSymbol(m_scopeGlobal, "System", true);
Scope scopeSystem = nsSystem.ChildScope;
SymEntry s = LookupSymbol(scopeSystem, st, true);
// An end-user program can't lookup system types, so this assert should be fine.
Debug.Assert(s is TypeEntry, "Expected '" + st + "' is a type");
return s as TypeEntry;
}
// Sets the current context that we lookup symbols against.
// Returns the previous current context, which should be
// passed to RestoreContext()
public virtual Scope SetCurrentContext(Scope scopeNewContext)
{
Scope prev = m_CurrentContext;
m_CurrentContext = scopeNewContext;
return prev;
}
public virtual void RestoreContext(Scope scopePreviousContext)
{
m_CurrentContext = scopePreviousContext;
}
public virtual Scope GetCurrentContext()
{
return m_CurrentContext;
}
Scope m_CurrentContext;
// Lookup a symbol in the current context.
// The context includes the lexical scope stack, super scopes,
// and using directives
// If it doesn't exist, then return null if !fMustExist and throw exception if fMustExist
public virtual SymEntry LookupSymbolWithContext(Identifier id, bool fMustExist)
{
string strName = id.Text;
// Search through stack of lexical scopes
SymEntry sym = null;
Scope t = m_CurrentContext;
while(t != null)
{
sym = LookupSymbol(t, id, false); // <-- smart lookup, go through ILookupController
if (sym != null)
return sym;
t = t.m_LexicalParent;
}
// Don't need this any more with ILookupControllers
#if false
// Check using directives if not found in the current scope stack
// Do this by traversing the scope stack and looking for UserNamespaceEntry
// (we can never be in an imported namespace, so that's ok)
t = m_CurrentContext;
while (t != null)
{
AST.NamespaceDecl node = t.Node as AST.NamespaceDecl;
if (node != null)
{
sym = node.LookupSymbolInUsingDirectives(this, id);
if (sym != null)
return sym;
}
t = t.m_LexicalParent;
}
#endif
// Symbol not found
if (fMustExist)
{
//ThrowError_UndefinedSymbol(id);
ThrowError(SymbolError.UndefinedSymbol(id));
}
return null;
}
#endregion
#if DEBUG
#region Debugging
// Debugging helper to print the current context
public virtual void Dump()
{
Console.WriteLine("*** Dump of current SemanticChecker state [");
m_CurrentContext.DumpTree();
m_CurrentContext.DumpKeys();
Console.WriteLine("Current class:{0}",
(m_curClass == null) ? "null" : m_curClass.ToString());
Console.WriteLine("Current method:{0}",
(m_curMethod == null) ? "null" : m_curMethod.PrettyDecoratedName);
Console.WriteLine("]");
}
#endregion
#endif
} // end class SemanticChecker
} // end namespace
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -