Expression
using CLanguage.Types;
using System;
namespace CLanguage.Syntax
{
public abstract class Expression
{
public Location Location { get; set; }
public bool HasError { get; set; }
public void Emit(EmitContext ec)
{
DoEmit(ec);
}
public abstract CType GetEvaluatedCType(EmitContext ec);
protected abstract void DoEmit(EmitContext ec);
protected static int GetInstructionOffset(CBasicType aType, EmitContext ec)
{
if (!aType.IsIntegral)
throw new NotSupportedException("Arithmetic on type '" + aType + "'");
int num = 0;
switch (aType.GetSize(ec)) {
case 2:
num = 0;
break;
case 4:
num = 2;
break;
default:
throw new NotSupportedException("Arithmetic on type '" + aType + "'");
}
if (aType.Signedness == Signedness.Unsigned)
num++;
return num;
}
protected static CBasicType GetPromotedType(Expression expr, string op, EmitContext ec)
{
CType evaluatedCType = expr.GetEvaluatedCType(ec);
CBasicType cBasicType = evaluatedCType as CBasicType;
if (cBasicType == null) {
ec.Report.Error(19, "Operator '" + op + "' cannot be applied to operand of type '" + evaluatedCType + "'");
return CBasicType.SignedInt;
}
return cBasicType.IntegerPromote(ec);
}
protected static CBasicType GetArithmeticType(Expression leftExpr, Expression rightExpr, string op, EmitContext ec)
{
CType evaluatedCType = leftExpr.GetEvaluatedCType(ec);
CType evaluatedCType2 = rightExpr.GetEvaluatedCType(ec);
CBasicType cBasicType = evaluatedCType as CBasicType;
CBasicType cBasicType2 = evaluatedCType2 as CBasicType;
if (cBasicType == null || cBasicType2 == null) {
ec.Report.Error(19, "Operator '" + op + "' cannot be applied to operands of type '" + evaluatedCType + "' and '" + evaluatedCType2 + "'");
return CBasicType.SignedInt;
}
return cBasicType.ArithmeticConvert(cBasicType2, ec);
}
}
}