📄 expast.cs
字号:
// Leftside: get_Item(idx, value);
System.Type [] alParams = new Type [] {
a.ExpIndex.CLRType,
m_expRight.CLRType
};
TypeEntry t = s.ResolveCLRTypeToBlueType(a.Left.CLRType);
MethodExpEntry m = t.LookupIndexer(a.Left.Location, s, alParams, true);
Exp e = new MethodCallExp(
a.Left,
m,
new ArgExp[] {
new ArgExp(EArgFlow.cIn, a.ExpIndex),
new ArgExp(EArgFlow.cIn, m_expRight)
},
s);
Exp.ResolveExpAsRight(ref e, s);
e.SetLocation(this.Location);
return e;
}
}
// Check for transforming properties into MethodCalls
if (m_oeLeft is PropertyExp)
{
PropertyExp p = (PropertyExp) m_oeLeft;
Exp e = new MethodCallExp(
p.InstanceExp,
p.Symbol.SymbolSet,
new ArgExp[] {
new ArgExp(EArgFlow.cIn, m_expRight)
},
s);
Exp.ResolveExpAsRight(ref e, s);
e.SetLocation(this.Location);
return e;
}
CalcCLRType(s);
// Ensure type match
s.EnsureAssignable(m_expRight, m_oeLeft.CLRType);
return this;
}
// Type of an assignment is the type of the Right Side
protected override Type CalcCLRTypeHelper(ISemanticResolver s)
{
return m_oeLeft.CLRType;
}
#endregion
// Code generation as an expression
public override void GenerateAsRight(CodeGen.EmitCodeGen gen)
{
gen.Generate(this);
}
public override void GenerateAsStatement(CodeGen.EmitCodeGen gen)
{
gen.GenerateAsStatement(this);
}
#region Properties & Data
protected Exp m_oeLeft;
public Exp Left
{
get { return m_oeLeft; }
}
protected Exp m_expRight;
public Exp Right
{
get { return m_expRight; }
}
#endregion
}
//-----------------------------------------------------------------------------
// Pre & Post inc / dec
//-----------------------------------------------------------------------------
public class PrePostIncDecStmtExp : StatementExp
{
#region Construction
public PrePostIncDecStmtExp(
Exp e,
bool fPre, bool fInc)
{
m_exp = e;
m_fPre = fPre;
m_fInc = fInc;
}
#endregion
#region Properties & Data
Exp m_exp;
public Exp Arg
{
get { return m_exp; }
}
bool m_fPre;
bool m_fInc;
public bool IsPre
{
get { return m_fPre; }
}
public bool IsInc
{
get { return m_fInc; }
}
#endregion
#region Checks
public override void DebugCheck(ISemanticResolver s)
{
Debug.Assert(Arg != null);
Arg.DebugCheck(s);
}
// Dump as XML
public override void Dump(XmlWriter o)
{
o.WriteStartElement("PrePostIncDecStmtExp");
o.WriteAttributeString("IsPre", IsPre.ToString());
o.WriteAttributeString("IsInc", IsInc.ToString());
Arg.Dump(o);
o.WriteEndElement();
}
public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)
{
string stOp = (IsInc) ? "++" : "--";
if (IsPre)
sb.Write(stOp);
Arg.ToSource(sb);
if (!IsPre)
sb.Write(stOp);
}
#endregion
#region Resolution
// Semantic resolution
protected override Exp ResolveExpAsRight(ISemanticResolver s)
{
// We have a problem. If our arg is a property, then we need to
// transform this x++ --> x = x + 1
// But we can't always transform since we can overload the ++, -- operators.
// So resolve our arg, see if it's a property, and then transform if it is.
// Since we update the Arg, we must resolve it as a left value
Exp.ResolveExpAsLeft(ref this.m_exp, s);
// First check if we have an overload
// Check if we're a property
if (m_exp is PropertyExp)
{
Exp e = null;
int iDelta = IsInc ? 1 : -1;
e = new AssignStmtExp(
m_exp,
new BinaryExp(
m_exp,
new IntExp(iDelta, this.m_filerange),
BinaryExp.BinaryOp.cAdd
)
);
Exp.ResolveExpAsRight(ref e, s);
return e;
}
CalcCLRType(s);
// Ensure type match, unless we have an overload.
s.EnsureAssignable(Arg, typeof(int));
return this;
}
// Type of an assignment is the type of the Right Side
protected override Type CalcCLRTypeHelper(ISemanticResolver s)
{
return Arg.CLRType;
}
#endregion
// Code generation as an expression
public override void GenerateAsRight(CodeGen.EmitCodeGen gen)
{
gen.Generate(this);
}
public override void GenerateAsStatement(CodeGen.EmitCodeGen gen)
{
gen.GenerateAsStatement(this);
}
}
#endregion // Statement Exp
#region ?: operator
//-----------------------------------------------------------------------------
// Conditional Expression
//-----------------------------------------------------------------------------
public class IfExp : Exp
{
#region Construction
public IfExp(
Exp expTest,
Exp expTrue,
Exp expFalse
)
{
Debug.Assert(expTest != null);
Debug.Assert(expTrue != null);
Debug.Assert(expFalse != null);
m_expTest = expTest;
m_expTrue = expTrue;
m_expFalse = expFalse;
}
#endregion
#region Properties & Data
Exp m_expTest;
Exp m_expTrue;
Exp m_expFalse;
public Exp TestExp
{
get { return m_expTest;}
}
public Exp TrueExp
{
get { return m_expTrue; }
}
public Exp FalseExp
{
get { return m_expFalse; }
}
#endregion
#region Checks
public override void DebugCheck(ISemanticResolver s)
{
m_expTest.DebugCheck(s);
m_expTrue.DebugCheck(s);
m_expFalse.DebugCheck(s);
}
public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)
{
sb.Write('(');
this.m_expTest.ToSource(sb);
sb.Write('?');
this.m_expTrue.ToSource(sb);
sb.Write(':');
this.m_expFalse.ToSource(sb);
sb.Write(')');
}
// Dump as XML
public override void Dump(XmlWriter o)
{
o.WriteStartElement("IFExp");
o.WriteStartElement("Test Expression");
m_expTest.Dump(o);
o.WriteEndElement();
o.WriteStartElement("True Expression");
m_expTrue.Dump(o);
o.WriteEndElement();
o.WriteStartElement("False Expression");
m_expFalse.Dump(o);
o.WriteEndElement();
o.WriteEndElement();
}
#endregion
// Semantic resolution
protected override Exp ResolveExpAsRight(ISemanticResolver s)
{
ResolveExpAsRight(ref this.m_expTest, s);
ResolveExpAsRight(ref this.m_expTrue, s);
ResolveExpAsRight(ref this.m_expFalse, s);
s.EnsureAssignable(m_expTest, typeof(bool));
CalcCLRType(s);
return this;
}
// Code generation
public override void GenerateAsRight(CodeGen.EmitCodeGen gen)
{
gen.Generate(this);
}
public override void GenerateAddrOf(CodeGen.EmitCodeGen gen)
{
gen.GenerateAddrOf(this);
}
// typeof ?: operator.
// Rules for determining type: Say you have (b ? t : f) where
// t is type T, f is type F.
// - If T ==F, type is T
// - if implicit convert T -> F, then type is F
// - if implicit convert F -> T, then type is T
// - else error
protected override Type CalcCLRTypeHelper(ISemanticResolver s)
{
Type t = m_expTrue.CLRType;
Type f = m_expFalse.CLRType;
// If both ops are null, then we'll be null too
if (t == null && f == null)
return null;
// If these are compound types, may not have reference equality,
// but the IsAssignable tests will still pass and so we're ok.
if (t == f)
return t;
if (TypeEntry.IsAssignable(t, f))
return f;
if (TypeEntry.IsAssignable(f, t))
return t;
// Else we have error
//ThrowError_BadTypeIfExp(s, this); // won't return
ThrowError(SymbolError.BadTypeIfExp(this));
return null;
}
}
#endregion
#region Operator Expressions (binary, unary)
//-----------------------------------------------------------------------------
// Is boolean operator
//-----------------------------------------------------------------------------
public class IsExp : Exp
{
#region Construction
public IsExp(
Exp expTest,
TypeSig tTarget
)
{
Debug.Assert(expTest != null);
Debug.Assert(tTarget != null);
m_expTest = expTest;
m_tTarget = tTarget;
//m_filerange = FileRange.Merge(expTest.Location, tTarget.Location);
}
#endregion
#region Properties & Data
Exp m_expTest;
public Exp Left
{
get { return m_expTest; }
}
TypeSig m_tTarget;
public TypeEntry TargetType
{
get { return m_tTarget.BlueType; }
}
public override void DebugCheck(ISemanticResolver s)
{
m_expTest.DebugCheck(s);
m_tTarget.DebugCheck(s);
}
#endregion
#region Checks
// Dump as XML
public override void Dump(XmlWriter o)
{
o.WriteStartElement("IsExp");
m_expTest.Dump(o);
m_tTarget.Dump(o);
o.WriteEndElement();
}
public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)
{
sb.Write('(');
m_expTest.ToSource(sb);
sb.Write(" is ");
m_tTarget.ToSource(sb);
sb.Write(')');
}
#endregion
#region Resolution
// Semantic resolution
protected override Exp ResolveExpAsRight(ISemanticResolver s)
{
ResolveExpAsRight(ref m_expTest, s);
m_tTarget.ResolveType(s);
CalcCLRType(s);
return this;
}
// 'Is' operator is always boolean
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -