📄 statementast.cs
字号:
// For each catch handler, make sure that it's type doesn't shadow
// a previous handler.
for(int j = 0; j < i; j++)
{
CatchHandler cPrev = CatchHandlers[j];
if (s.IsDerivedType(cPrev.CatchType, c.CatchType))
{
//ThrowError_ShadowCatchHandlers(s, this.Location, c.CatchType.CLRType, cPrev.CatchType.CLRType);
ThrowError(SymbolError.ShadowCatchHandlers(this.Location, c.CatchType.CLRType, cPrev.CatchType.CLRType));
}
}
} // end for
if (m_stmtFinally != null)
m_stmtFinally.ResolveStatement(s);
}
public override void ResolveStatement2(ISemanticResolver s)
{
m_stmtTry.ResolveStatement2(s);
foreach(CatchHandler c in CatchHandlers)
{
c.ResolveHandler2(s);
}
if (m_stmtFinally != null)
m_stmtFinally.ResolveStatement2(s);
}
#endregion
// Code generation
public override void Generate(CodeGen.EmitCodeGen gen)
{
gen.Generate(this);
}
}
//-----------------------------------------------------------------------------
// Throw
// -> 'throw' 'obj expression'
//-----------------------------------------------------------------------------
public class ThrowStatement : Statement
{
public ThrowStatement(
Exp oeException // can be null for a rethrow
)
{
m_oeException = oeException;
}
#region Properties & Data
Exp m_oeException;
public Exp ExceptionExp
{
get {return m_oeException; }
}
#endregion
#region Checks
public override void DebugCheck(ISemanticResolver s)
{
if (m_oeException != null)
m_oeException.DebugCheck(s);
}
// Dump as XML
public override void Dump(XmlWriter o)
{
o.WriteStartElement("ThrowStatement");
if (m_oeException != null)
ExceptionExp.Dump(o);
o.WriteEndElement();
}
#endregion
// Semantic resolution
public override void ResolveStatement(ISemanticResolver s)
{
if (m_oeException != null)
{
Exp.ResolveExpAsRight(ref m_oeException, s);
//Debug.Assert(m_oeException.SymbolMode == ObjExp.Mode.cExpEntry);
// Must derive from System.Exception
s.EnsureAssignable(m_oeException, typeof(System.Exception));
}
}
// Code generation
public override void Generate(CodeGen.EmitCodeGen gen)
{
gen.Generate(this);
}
}
#endregion
#region Control Flow statements
#region Switch Statement
//-----------------------------------------------------------------------------
// Switch statement
//-----------------------------------------------------------------------------
public class SwitchStatement : Statement
{
public SwitchStatement(
Exp expTest,
SwitchSection [] sections
)
{
m_expTest = expTest;
m_sections = sections;
m_proxy = null;
}
#region Properties & Data
Exp m_expTest;
public Exp ExpTest
{
get { return m_expTest; }
}
SwitchSection [] m_sections;
public SwitchSection[] Sections
{
get { return m_sections; }
}
Statement m_proxy;
public Statement ResolvedStatement
{
get { return m_proxy; }
}
#endregion
#region Checks
public override void DebugCheck(ISemanticResolver s)
{
if (m_proxy != null)
m_proxy.DebugCheck(s);
else
{
m_expTest.DebugCheck(s);
foreach(SwitchSection c in Sections)
c.DebugCheck(s);
}
}
// Dump as XML
public override void Dump(XmlWriter o)
{
o.WriteStartElement("SwitchStatement");
if (m_proxy != null)
m_proxy.Dump(o);
o.WriteEndElement();
}
#endregion
#region Resolution
public override void ResolveStatement(ISemanticResolver s)
{
if (m_proxy != null)
return;
// Resolve by converting into a giant if-statement
#if false
Transform:
switch(e)
{
case A1:
case A2:
S_A;
case B1:
SB;
default:
S_Default;
}
Into:
do {
T x = [e];
if ((x == A1) || (x == A2))
S_A;
if ((x == B1))
S_B;
S_Default;
} while(false);
#endif
Exp.ResolveExpAsRight(ref m_expTest, s);
TypeSig T = new ResolvedTypeSig(m_expTest.CLRType, s);
LocalVarDecl declare_x = new LocalVarDecl(
new Identifier(".temp", this.Location),
T);
declare_x.ResolveVarDecl(s);
LocalExp x = new LocalExp(declare_x.LocalSymbol);
Statement [] sList = new Statement[m_sections.Length + 1];
// T x = [e];
sList[0] = new ExpStatement(
new AssignStmtExp(x, this.m_expTest)
);
// @todo - this assumes that 'default' is last.
int iSection = 0;
foreach(SwitchSection c in this.m_sections)
{
Statement t;
if (c.IsDefaultCase)
{
t = c.StmtBody;
} else {
// Create ((x == A1) || (x == A2))
Exp [] labels = c.CaseExps;
Exp e2 = null;
for(int i = 0; i < labels.Length; i++)
{
Exp e = new BinaryExp(
x,
labels[i],
BinaryExp.BinaryOp.cEqu
);
if (e2 == null)
e2 = e;
else
e2 = new BinaryExp(e, e2, BinaryExp.BinaryOp.cOr);
}
// Create if () S_A else
t = new IfStatement(e2, c.StmtBody, null);
}
sList[iSection + 1] = t;
iSection++;
} // end for each section
m_proxy = new BlockStatement(
new LocalVarDecl[] { declare_x},
sList
);
// This is pure evil. We drop the whole thing in an do..while(false)
// loop so that we can catch the 'break' statements in the switchsections.
m_proxy = new DoStatement(new BoolExp(false, Location), m_proxy);
m_proxy.ResolveStatement(s);
}
public override void ResolveStatement2(ISemanticResolver s)
{
m_proxy.ResolveStatement2(s);
}
#endregion
public override void Generate(CodeGen.EmitCodeGen gen)
{
m_proxy.Generate(gen);
//gen.Generate(this);
}
}
// Each switch section has a set of expressions, and then a Statement
// to execute if the expressions are true.
public class SwitchSection
{
#region Construction
// Default, has no expressions
public SwitchSection(
Statement stmt
)
{
m_CaseExp = null;
m_stmt = stmt;
}
// Arbitrary number of cases
public SwitchSection(
Exp [] expTests,
Statement stmt
)
{
Debug.Assert(expTests != null);
Debug.Assert(expTests.Length != 0);
m_CaseExp = expTests;
m_stmt = stmt;
}
#endregion
#region Checks
public void DebugCheck(ISemanticResolver s)
{
if (!this.IsDefaultCase)
{
foreach(Exp e in m_CaseExp)
e.DebugCheck(s);
}
StmtBody.DebugCheck(s);
}
#endregion
#region Properties & Data
Exp [] m_CaseExp;
public Exp[] CaseExps
{
get { return m_CaseExp; }
}
Statement m_stmt;
public Statement StmtBody
{
get { return m_stmt; }
}
public bool IsDefaultCase
{
get { return m_CaseExp == null; }
}
#endregion
}
#endregion Switch Statement
//-----------------------------------------------------------------------------
// If-then-else statement
//-----------------------------------------------------------------------------
public class IfStatement : Statement
{
public IfStatement(
Exp exp, // must be non-null
Statement stmtThen, // must be non-null
Statement stmtElse // null if no else-clause
)
{
Debug.Assert(exp != null);
m_exp = exp;
m_stmtThen = stmtThen;
m_stmtElse = stmtElse;
}
//-----------------------------------------------------------------------------
// Debugging check
//-----------------------------------------------------------------------------
public override void DebugCheck(ISemanticResolver s)
{
Debug.Assert(m_exp != null);
Debug.Assert(m_stmtThen != null);
m_exp.DebugCheck(s);
System.Type clrType = m_exp.CalcCLRType(s);
Debug.Assert((clrType == typeof(bool)) ||
(clrType.IsByRef && (clrType.GetElementType() == typeof(bool))));
m_stmtThen.DebugCheck(s);
if (m_stmtElse != null)
m_stmtElse.DebugCheck(s);
}
protected Exp m_exp;
public Exp TestExp
{
get { return m_exp; }
}
protected Statement m_stmtThen;
public Statement ThenStmt
{
get { return m_stmtThen; }
}
protected Statement m_stmtElse;
public Statement ElseStmt
{
get { return m_stmtElse; }
}
#region Checks
// Dump
public override void Dump(XmlWriter o)
{
o.WriteStartElement("If");
m_exp.Dump(o);
o.WriteStartElement("then_clause");
m_stmtThen.Dump(o);
o.WriteEndElement();
if (m_stmtElse != null)
{
o.WriteStartElement("else_clause");
m_stmtElse.Dump(o);
o.WriteEndElement();
}
o.WriteEndElement(); // if
}
public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)
{
sb.Write("if (");
this.m_exp.ToSource(sb);
sb.WriteLine(")");
sb.Indent++;
m_stmtThen.ToSource(sb);
sb.Indent--;
if (m_stmtElse != null)
{
sb.WriteLine("else");
sb.Indent++;
m_stmtElse.ToSource(sb);
sb.Indent--;
}
}
#endregion
// Semantic resolution
public override void ResolveStatement(ISemanticResolver s)
{
Exp.ResolveExpAsRight(ref m_exp, s);
m_stmtThen.ResolveStatement(s);
if (m_stmtElse != null)
{
m_stmtElse.ResolveStatement(s);
}
}
public override void ResolveStatement2(ISemanticResolver s)
{
m_stmtThen.ResolveStatement2(s);
if (m_stmtElse != null)
{
m_stmtElse.ResolveStatement2(s);
}
}
// Code generation
public override void Generate(CodeGen.EmitCodeGen gen)
{
gen.Generate(this);
}
}
#region Loop Statements
//-----------------------------------------------------------------------------
// Loop Statement
//-----------------------------------------------------------------------------
public abstract class LoopStatement : Statement
{
public LoopStatement(
Exp expTest,
Statement stmtBody
)
{
Debug.Assert(expTest != null);
Debug.Assert(stmtBody != null);
m_expTest = expTest;
m_stmtBody = stmtBody;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -