📄 statementast.cs
字号:
// Test to make sure that break & continue are in a loop
static int m_loopcount = 0;
public static bool IsInsideLoop()
{
return m_loopcount != 0;
}
protected Exp m_expTest;
public Exp TestExp
{
get { return m_expTest; }
}
protected Statement m_stmtBody;
public Statement BodyStmt
{
get { return m_stmtBody; }
}
// Debug checking
public override void DebugCheck(ISemanticResolver s)
{
TestExp.DebugCheck(s);
BodyStmt.DebugCheck(s);
}
// Semantic resolution
public override void ResolveStatement(ISemanticResolver s)
{
Exp.ResolveExpAsRight(ref this.m_expTest, s);
m_loopcount++;
BodyStmt.ResolveStatement(s);
m_loopcount--;
//s.EnsureDerivedType(s.ResolveCLRTypeToBlueType(typeof(bool)), TestExp);
s.EnsureAssignable(TestExp, typeof(bool));
}
public override void ResolveStatement2(ISemanticResolver s)
{
m_loopcount++;
BodyStmt.ResolveStatement2(s);
m_loopcount--;
}
} // end LoopStatement
//-----------------------------------------------------------------------------
// Do Statement
//-----------------------------------------------------------------------------
public class DoStatement : LoopStatement
{
public DoStatement(
Exp expTest,
Statement stmtBody
)
: base(expTest, stmtBody)
{
}
// Dump
public override void Dump(XmlWriter o)
{
o.WriteStartElement("do");
TestExp.Dump(o);
BodyStmt.Dump(o);
o.WriteEndElement();
}
// Code generation
public override void Generate(CodeGen.EmitCodeGen gen)
{
gen.Generate(this);
}
}
//-----------------------------------------------------------------------------
// For statement. Has 2 flavors - variable initialed & no var initialized
//-----------------------------------------------------------------------------
public class ForStatement : LoopStatement
{
#region Construction
public ForStatement(
StatementExp eInit,
Exp expTest,
StatementExp eNext,
Statement stmtBody)
: base(expTest, stmtBody)
{
m_sexpInit = eInit;
m_sexpNext = eNext;
}
#endregion
#region Properties & Data
StatementExp m_sexpInit;
public StatementExp InitExp
{
get { return m_sexpInit; }
}
StatementExp m_sexpNext;
public StatementExp NextExp
{
get { return m_sexpNext; }
}
#endregion
#region Checks
// Dump
public override void Dump(XmlWriter o)
{
o.WriteStartElement("for");
InitExp.Dump(o);
TestExp.Dump(o);
NextExp.Dump(o);
BodyStmt.Dump(o);
o.WriteEndElement();
}
// Debug checking
public override void DebugCheck(ISemanticResolver s)
{
InitExp.DebugCheck(s);
NextExp.DebugCheck(s);
// Call to Loop.DebugCheck();
base.DebugCheck(s);
}
#endregion
#region Resolution
// Semantic resolution
public override void ResolveStatement(ISemanticResolver s)
{
Exp e = m_sexpInit;
Exp.ResolveExpAsRight(ref e, s);
Debug.Assert(e == m_sexpInit); // @todo - fix this
e = m_sexpNext;
Exp.ResolveExpAsRight(ref e, s);
Debug.Assert(e == m_sexpNext); // @todo -fix this
base.ResolveStatement(s);
}
#endregion
// Code generation
public override void Generate(CodeGen.EmitCodeGen gen)
{
gen.Generate(this);
}
}
//-----------------------------------------------------------------------------
// Foreach statement
// foreach (Type t in Exp) Body
// Resolves to either a For statement or a while statement
//-----------------------------------------------------------------------------
public class ForeachStatement : Statement
{
public ForeachStatement(
LocalVarDecl var,
Exp expCollection,
Statement body
)
{
Debug.Assert(var != null);
Debug.Assert(expCollection != null);
m_var = var;
m_expCollection = expCollection;
m_stmtBody = body;
}
#region Properties & Data
Statement m_stmtResolved;
public Statement ResolvedStmt
{
get { return m_stmtResolved; }
}
LocalVarDecl m_var;
Exp m_expCollection;
Statement m_stmtBody;
#endregion
#region Checks
// Dump
public override void Dump(XmlWriter o)
{
o.WriteStartElement("foreach");
m_var.Dump(o);
m_expCollection.Dump(o);
m_stmtBody.Dump(o);
if (m_stmtResolved != null)
{
o.WriteStartElement("ResolvedStatement");
m_stmtResolved.Dump(o);
o.WriteEndElement();
}
o.WriteEndElement();
}
public override void DebugCheck(ISemanticResolver s)
{
Debug.Assert(m_stmtResolved != null);
m_stmtResolved.DebugCheck(s);
/*
m_var.DebugCheck(s);
m_expCollection.DebugCheck(s);
m_stmtBody.DebugCheck(s);
*/
}
public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)
{
sb.Write("foreach(");
this.m_var.ToSource(sb);
sb.Write(" in ");
this.m_expCollection.ToSource(sb);
sb.WriteLine(')');
this.m_stmtBody.ToSource(sb);
}
#endregion
// Code generation, just pass on to our resolved statement
public override void Generate(CodeGen.EmitCodeGen gen)
{
m_stmtResolved.Generate(gen);
}
#region Resolution
// Semantic resolution
public override void ResolveStatement(ISemanticResolver s)
{
// If collection is an array, then we resolve to a for-loop around the array
Exp.ResolveExpAsRight(ref m_expCollection, s);
if (m_expCollection.CLRType.IsArray)
{
ResolveAsArray(s);
} else {
ResolveAsIEnumerator(s);
}
Debug.Assert(m_stmtResolved != null);
m_stmtResolved.ResolveStatement(s);
}
public override void ResolveStatement2(ISemanticResolver s)
{
// By now, we have the resolved statement, so just go through
// to it on the 2nd pass.
m_stmtResolved.ResolveStatement2(s);
}
// We expect to resolve this as an array. If The collection is an
// array type, we should be able to do that without any problems.
void ResolveAsArray(ISemanticResolver s)
{
#if false
// foreach(T t in C) [Body];
// Array resolves as:
{
int i;
T t;
for(i = 0; i < C.Length; i++)
{
t = A[i];
[Body]
}
}
#endif
Identifier idI = new Identifier(".temp", this.Location);
SimpleObjExp expI = new SimpleObjExp(idI);
Identifier idT = new Identifier(this.m_var.Name, Location);
// Build an AST for the resolved statement
m_stmtResolved = new BlockStatement(
new LocalVarDecl[] {
new LocalVarDecl(
idI,
//new TypeSig(new SimpleObjExp(new Identifier("int", Location)))
new ResolvedTypeSig(typeof(int), s)
),
this.m_var
},
new Statement[] {
new ForStatement(
new AssignStmtExp(
expI,
new IntExp(0, this.Location)
),
new BinaryExp(
expI,
new DotObjExp(
m_expCollection,
new Identifier("Length", Location)
),
BinaryExp.BinaryOp.cLT
),
new PrePostIncDecStmtExp(expI, false, true),
new BlockStatement(
null,
new Statement[] {
new ExpStatement(
new AssignStmtExp(
new SimpleObjExp(idT),
new ArrayAccessExp(m_expCollection, expI)
)
),
this.m_stmtBody
}
)
)
}
); // end BlockStatement
} // End resolve as array
// We expect to resolve using IEnumerator. This has several conditions,
// and so we have to do some error checking.
void ResolveAsIEnumerator(ISemanticResolver s)
{
#if false
// foreach(T t in C) [Body];
// Enumeration resolves as:
{
E e;
T t;
e = C.GetEnumerator();
while(e.MoveNext())
{
t = (T) e.Current;
[Body]
}
}
#endif
// First must find the GetEnumerator() method
bool dummy;
MethodExpEntry mGetEnumerator =
s.ResolveCLRTypeToBlueType(m_expCollection.CLRType).
LookupMethod(s, new Identifier("GetEnumerator"), new Type[0], out dummy);
Identifier idEnum = new Identifier(".Temp", Location);
SimpleObjExp expEnum = new SimpleObjExp(idEnum);
Identifier idT = new Identifier(this.m_var.Name, Location);
// Build an AST for the resolved statement
m_stmtResolved = new BlockStatement(
new LocalVarDecl[] {
new LocalVarDecl(
idEnum,
new ResolvedTypeSig(mGetEnumerator.RetType)
),
this.m_var
},
new Statement[] {
new ExpStatement(
new AssignStmtExp(
expEnum,
new MethodCallExp(m_expCollection, new Identifier("GetEnumerator", Location), new ArgExp[0])
)
),
new WhileStatement(
new MethodCallExp(
expEnum,
new Identifier("MoveNext", Location),
new ArgExp[0]
),
new BlockStatement(
null,
new Statement[]
{
new ExpStatement(
new AssignStmtExp(
new SimpleObjExp(idT),
new AST.CastObjExp(
this.m_var.Sig,
new DotObjExp(expEnum, new Identifier("Current", Location))
)
)
),
this.m_stmtBody
}
)
) // end while
} // end Statement[]
);
} // end resolve as Enumerator
#endregion
}
//-----------------------------------------------------------------------------
// While Statement
//-----------------------------------------------------------------------------
public class WhileStatement : LoopStatement
{
public WhileStatement(
Exp expTest,
Statement stmtBody
) : base(expTest, stmtBody)
{
}
// Dump
public override void Dump(XmlWriter o)
{
o.WriteStartElement("while");
TestExp.Dump(o);
BodyStmt.Dump(o);
o.WriteEndElement();
}
// Code generation
public override void Generate(CodeGen.EmitCodeGen gen)
{
gen.Generate(this);
}
}
#endregion Loop Statements
#region Jump statements
//-----------------------------------------------------------------------------
// Statement
//-----------------------------------------------------------------------------
public class LabelStatement : Statement
{
public LabelStatement(Identifier label)
{
Debug.Assert(label != null);
m_label = label;
}
protected Identifier m_label;
public Identifier LabelId
{
get { return m_label; }
}
protected LabelEntry m_symbol;
public LabelEntry Symbol
{
get { return m_symbol; }
}
// Debug checking
public override void DebugCheck(ISemanticResolver s)
{
Debug.Assert(m_symbol != null);
}
// Dump
public override void Dump(XmlWriter o)
{
o.WriteStartElement("LabelStatement");
o.WriteAttributeString("name", m_label.Text);
o.WriteEndElement();
}
// Semantic resolution
public override void ResolveStatement(ISemanticResolver s)
{
// Label must have not been defined.
m_symbol = (LabelEntry) s.LookupSymbol(s.GetCurrentContext(), m_label, false);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -