📄 statementast.cs
字号:
if (m_symbol != null)
{
// Error, label already defined.
ThrowError(SymbolError.LabelAlreadyDefined(m_label.Text, m_label.Location, m_symbol.Node.LabelId.Location));
/*
s.ThrowError(SymbolEngine.SemanticChecker.Code.cLabelAlreadyDefined,
m_label.Location,
"Label '" + m_label.Text + "' is already defined at '"+
m_symbol.Node.LabelId.Location + "' in the current scope");
*/
}
m_symbol = new LabelEntry(m_label.Text, this);
s.GetCurrentContext().AddSymbol(m_symbol);
}
// Code generation
public override void Generate(CodeGen.EmitCodeGen gen)
{
gen.Generate(this);
}
}
//-----------------------------------------------------------------------------
// Statement
//-----------------------------------------------------------------------------
public class GotoStatement : Statement
{
public GotoStatement(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("GotoStatement");
o.WriteAttributeString("name", m_label.Text);
o.WriteEndElement();
}
// Semantic resolution
public override void ResolveStatement(ISemanticResolver s)
{
// Can't do anything on first pass
}
public override void ResolveStatement2(ISemanticResolver s)
{
// Since we're doing this on a second pass, all labels must have been added
m_symbol = (LabelEntry) s.EnsureSymbolType(
s.LookupSymbolWithContext(m_label, true),
typeof(LabelEntry),
m_label.Location);
}
// Code generation
public override void Generate(CodeGen.EmitCodeGen gen)
{
gen.Generate(this);
}
}
//-----------------------------------------------------------------------------
// Continue Statement
//-----------------------------------------------------------------------------
public class ContinueStatement : Statement
{
public ContinueStatement()
{
}
// Debug checking
public override void DebugCheck(ISemanticResolver s)
{
}
// Dump
public override void Dump(XmlWriter o)
{
o.WriteStartElement("ContinueStatement");
o.WriteEndElement();
}
// Semantic resolution
public override void ResolveStatement(ISemanticResolver s)
{
if (!LoopStatement.IsInsideLoop())
{
ThrowError(SymbolError.MustBeInsideLoop(this));
}
}
// Code generation
public override void Generate(CodeGen.EmitCodeGen gen)
{
gen.Generate(this);
}
}
//-----------------------------------------------------------------------------
// Break Statement
//-----------------------------------------------------------------------------
public class BreakStatement : Statement
{
public BreakStatement()
{
}
// Debug checking
public override void DebugCheck(ISemanticResolver s)
{
}
// Dump
public override void Dump(XmlWriter o)
{
o.WriteStartElement("BreakStatement");
o.WriteEndElement();
}
// Semantic resolution
public override void ResolveStatement(ISemanticResolver s)
{
if (!LoopStatement.IsInsideLoop())
{
ThrowError(SymbolError.MustBeInsideLoop(this));
/*
s.ThrowError(SemanticChecker.Code.cMustBeInsideLoop,
new FileRange(),
"'break' must occur inside a control block (do, while, for, switch)"
);
*/
}
}
// Code generation
public override void Generate(CodeGen.EmitCodeGen gen)
{
gen.Generate(this);
}
}
//-----------------------------------------------------------------------------
// Return statement
// May (or maynot) have a return expression
//-----------------------------------------------------------------------------
public class ReturnStatement : Statement
{
public ReturnStatement(Exp e)
{
m_exp = e;
// @todo - this is wrong
if (e != null)
{
m_filerange = e.Location;
}
else
{
m_filerange = new FileRange();
}
}
Exp m_exp;
//-----------------------------------------------------------------------------
// Debugging check
//-----------------------------------------------------------------------------
public override void DebugCheck(ISemanticResolver s)
{
// Expression is optional
if (m_exp != null)
{
m_exp.DebugCheck(s);
// In resolve, we already verified that exp matches the function return type.
}
}
public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)
{
if (m_exp ==null)
sb.WriteLine("return;");
else {
sb.Write("return ");
m_exp.ToSource(sb);
sb.WriteLine(';');
}
}
// Dump as XML
public override void Dump(XmlWriter o)
{
o.WriteStartElement("ReturnStatement");
if (m_exp != null)
m_exp.Dump(o);
o.WriteEndElement();
}
// Semantic resolution
public override void ResolveStatement(ISemanticResolver s)
{
MethodExpEntry m = s.GetCurrentMethod();
if (m_exp != null)
{
Exp.ResolveExpAsRight(ref m_exp, s);
// Ensure that expression we're returning matches the method's
// return type
//s.EnsureDerivedType(m.RetType, m_exp);
s.EnsureAssignable(m_exp, m.RetType.CLRType);
}
else
{
// If we're not returning an expression, then our return type should be void
if (m.RetType.CLRType != typeof(void))
{
ThrowError(SymbolError.NoReturnTypeExpected(this));
/*
s.ThrowError(SemanticChecker.Code.cNoReturnTypeExpected,
this.Location,
"Functions with void return type can't return an expression"
);
*/
}
}
}
// Code generation
public override void Generate(CodeGen.EmitCodeGen gen)
{
gen.Generate(this);
}
public Exp
Expression
{
get
{
// This may return null since not all return statements have expressions.
return m_exp;
}
}
}
#endregion // Jump statements
#endregion // Control Flow Statements
//-----------------------------------------------------------------------------
// Expression Statement - statements that just execute expressions
// with sideffects
//-----------------------------------------------------------------------------
/// <summary>
/// Statement to hold an <see cref="StatementExp"/>.
/// </summary>
/// <remarks>
/// <para><children>Children<list type="bullet"><item>
/// <see cref="StatementExp"/> - the expression to be evaluated as a statement
/// </item></list></children></para>
/// </remarks>
public class ExpStatement : Statement
{
#region Construction
public ExpStatement(StatementExp sexp)
{
Debug.Assert(sexp != null);
m_sexp = sexp;
}
#endregion
#region Properties & Data
StatementExp m_sexp;
public StatementExp StmtExp
{
get { return m_sexp; }
}
#endregion
#region Checks
public override void DebugCheck(ISemanticResolver s)
{
Debug.Assert(m_sexp != null);
m_sexp.DebugCheck(s);
}
// Dump as XML
public override void Dump(XmlWriter o)
{
o.WriteStartElement("ExpStatement");
m_sexp.Dump(o);
o.WriteEndElement();
}
public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)
{
this.m_sexp.ToSource(sb);
sb.WriteLine(';');
}
#endregion
// Semantic resolution
public override void ResolveStatement(ISemanticResolver s)
{
StatementExp.ResolveExpAsRight(ref m_sexp, s);
}
// Code generation
public override void Generate(CodeGen.EmitCodeGen gen)
{
m_sexp.GenerateAsStatement(gen);
}
}
//-----------------------------------------------------------------------------
// Constructor chain (like a special purpose method call)
//-----------------------------------------------------------------------------
public class CtorChainStatement : Statement
{
public enum ETarget
{
cThis,
cBase
}
#region Construction
// General ctor chain
public CtorChainStatement(ETarget eTarget, Exp [] arParams)
{
m_eTarget = eTarget;
m_arParams = (arParams == null) ? (new Exp[0]) : arParams;
}
// Chain to our base's default ctor
public CtorChainStatement()
{
m_eTarget = CtorChainStatement.ETarget.cBase;
m_arParams = new Exp[0];
}
public void FinishInit(MethodDecl nodeCtor)
{
Debug.Assert(m_nodeCtor == null);
m_nodeCtor = nodeCtor;
}
#endregion
#region Checks
public override void DebugCheck(ISemanticResolver s)
{
Debug.Assert(m_nodeCtor != null);
Debug.Assert(m_symTarget != null);
m_symTarget.DebugCheck(s);
foreach(Exp e in Params)
{
e.DebugCheck(s);
}
}
// Dump as XML
public override void Dump(XmlWriter o)
{
o.WriteStartElement("CtorChainStatement");
o.WriteAttributeString("target", m_eTarget.ToString());
o.WriteAttributeString("name", m_nodeCtor.Name);
foreach(Exp e in Params)
{
e.Dump(o);
}
o.WriteEndElement();
}
#endregion
#region properties & Data
ETarget m_eTarget;
public ETarget TargetType
{
get { return m_eTarget; }
}
Exp [] m_arParams;
public Exp [] Params
{
get { return m_arParams; }
}
MethodDecl m_nodeCtor;
public MethodDecl NodeCtor
{
get { return m_nodeCtor; }
}
MethodExpEntry m_symTarget;
public MethodExpEntry SymbolTarget
{
get { return m_symTarget; }
}
#endregion
#region Resolution
// Must resolve all our parameters and the specific ctor that
// we chain to.
public override void ResolveStatement(ISemanticResolver s)
{
Debug.Assert(m_nodeCtor != null);
for(int i = 0; i < Params.Length; i++)
{
Exp.ResolveExpAsRight(ref Params[i], s);
}
// Lookup what ctor we chain to.
TypeEntry tClass = m_nodeCtor.Symbol.SymbolClass;
if (TargetType == ETarget.cBase)
{
tClass = tClass.Super;
}
System.Type [] alParamTypes = new Type[Params.Length];
for(int i = 0; i < Params.Length; i++)
{
alParamTypes[i] = Params[i].CLRType;
}
bool fVarArg;
m_symTarget = tClass.LookupMethod(
s,
new Identifier(tClass.Name, this.Location),
alParamTypes,
out fVarArg);
Debug.Assert(!fVarArg);
Debug.Assert(m_symTarget != null);
Debug.Assert(m_symTarget.SymbolClass == tClass); // @todo -legit? Make sure we actually get a method from tClass?
}
#endregion
// Code generation
public override void Generate(CodeGen.EmitCodeGen gen)
{
Debug.Assert(m_nodeCtor != null);
gen.Generate(this);
}
}
} // end namespace
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -